# Quality-Scale Audit: `samsungtv` > Audit snapshot prepared against the rubric in `docs/03-quality-scale-audit-rubric.md`. > All findings reference the integration source under `homeassistant/components/samsungtv/` > and must be re-verified against the current `dev` branch immediately before any PR is > opened (see §6 "Verification protocol" in the rubric). ## 1. Integration profile | Attribute | Value | |---|---| | Domain | `samsungtv` | | IoT class | `local_push` (WebSocket) / `local_polling` (legacy) | | Primary libraries | `samsungtvws` (WebSocket, 2016+ TVs), `samsungctl` (legacy), `async-upnp-client` (DMR rendering control), `wakeonlan` | | Declared `quality_scale` in manifest | none declared (treated as "legacy/unscored") | | Estimated active installs (analytics.home-assistant.io) | Top-25 device integration; consistently >150k reporting installs | | Open issue volume (rolling 12 mo) | High — dominated by: TV unreachable after standby, WS token invalidation, wrong power state, Tizen 7+ authentication changes | | CODEOWNERS | Yes — multiple active code owners; coordination required before structural changes | **Why selected:** very high install base, persistent issue churn concentrated in a small number of root causes (token/reauth lifecycle, power-state detection), and a realistic path from unscored to **Silver** with targeted work rather than a rewrite. ## 2. Rule-by-rule audit Status legend: ✅ Pass · 🟡 Partial · ❌ Fail · ➖ Exempt/N-A (must be recorded in `quality_scale.yaml` with justification) ### Bronze | Rule | Status | Evidence / Gap | |---|---|---| | `config-flow` | ✅ | Full UI flow; SSDP, DHCP and zeroconf discovery sources implemented. | | `test-before-configure` | ✅ | Flow connects and fetches device info before creating the entry. | | `unique-config-entry` | ✅ | Unique ID from device UDN/MAC; duplicate aborts in place. | | `config-flow-test-coverage` | 🟡 | Flow tests exist and are broad, but several abort/error branches around legacy-protocol fallback and DHCP-triggered updates are uncovered. Measure with `pytest --cov` per rubric §4. | | `entity-unique-id` | ✅ | Media player and remote entities carry stable unique IDs. | | `has-entity-name` | 🟡 | Media player uses device name as entity name (correct pattern), but verify `_attr_has_entity_name = True` is set on **all** platforms including `remote`. | | `runtime-data` | 🟡 | Verify migration to `entry.runtime_data` (typed `ConfigEntry[SamsungTVDataUpdateCoordinator]`); older `hass.data[DOMAIN]` pattern may persist in helper modules. | | `appropriate-polling` | ✅ | Push via WebSocket where available; polling fallback at conservative interval. | | `entity-event-setup` | ✅ | WS event subscriptions registered in `async_added_to_hass`. | | `action-setup` | ➖ | No custom service actions registered (standard media_player services only). | | `common-modules` | 🟡 | Coordinator exists; confirm `coordinator.py` / `entity.py` module split matches current architecture guidance. | | `dependency-transparency` | ✅ | All libs published on PyPI with public source. | | `docs-high-level-description` / `docs-installation-instructions` / `docs-removal-instructions` / `docs-actions` | 🟡 | Docs page is long-lived and mostly complete; removal instructions and a clean actions section need verification against current doc templates. | | `brands` | ✅ | Brand assets present. | ### Silver | Rule | Status | Evidence / Gap | |---|---|---| | `config-entry-unloading` | ✅ | Unload implemented; WS sessions closed. | | `reauthentication-flow` | 🟡 | **Key gap.** A reauth flow exists for token rejection on WS, but a large share of reported issues are "TV shows PIN prompt repeatedly" / token invalidated by firmware update without a clean reauth trigger. Audit task: ensure `ConfigEntryAuthFailed` is raised from every code path where the TV returns `unauthorized`/`ms.channel.unauthorized`, including the encrypted-WS (2014–2015 H/J models) path. | | `action-exceptions` | 🟡 | Some command failures log instead of raising `HomeAssistantError`; turn-on without WOL data should raise a translated error. | | `entity-unavailable` | 🟡 | Power-state inference (fake-standby on Tizen) produces wrong availability; needs a documented state machine and tests. This is the #1 issue-tracker theme. | | `log-when-unavailable` | 🟡 | Verify single log-once-on-loss / log-once-on-restore pattern; current code may log repeatedly on each failed poll. | | `parallel-updates` | 🟡 | `PARALLEL_UPDATES` not explicitly declared on all platforms; declare `= 0` (coordinator/push) per rules. | | `integration-owner` | ✅ | Active code owners. | | `test-coverage` (≥95 % per platform) | 🟡 | Core flows tested; `remote` platform and encrypted-WS bridge under-covered. | | `docs-configuration-parameters` / `docs-installation-parameters` | 🟡 | Options (WOL MAC override, session settings) partially documented. | ### Gold (selected rules — Gold is **not** in scope for this program; recorded for completeness) | Rule | Status | Notes | |---|---|---| | `diagnostics` | ❌ | No `diagnostics.py`. High-value: a redacted dump of device info, WS capability list, and power-state machine state would cut triage time on the dominant issue classes dramatically. **Pulled into scope as an exception** (see backlog item ST-5) because it directly serves issue-volume reduction. | | `discovery` | ✅ | SSDP/DHCP/zeroconf present. | | `repair-issues` | ❌ | Out of scope. | | `strict-typing` | ❌ | Not in `.strict-typing`; out of scope (Platinum). | ## 3. Gap summary and proposed work items | ID | Work item | Rule(s) | Size | Risk | |---|---|---|---|---| | ST-1 | Audit + complete reauth trigger coverage: raise `ConfigEntryAuthFailed` on all unauthorized paths (WS, encrypted WS, legacy); add flow tests for each trigger | `reauthentication-flow` | M (≤400 LoC incl. tests) | Medium — touches bridge abstraction; coordinate with code owners first | | ST-2 | Document and test the power-state/availability state machine; implement log-once unavailable pattern | `entity-unavailable`, `log-when-unavailable` | M | Medium — behavior change visible to users; needs explicit code-owner sign-off | | ST-3 | Declare `PARALLEL_UPDATES`, verify `has_entity_name` on remote platform, migrate residual `hass.data` to `runtime_data` | `parallel-updates`, `has-entity-name`, `runtime-data` | S (≤150 LoC) | Low | | ST-4 | Raise coverage: remote platform + uncovered config-flow branches to ≥95 % | `test-coverage`, `config-flow-test-coverage` | M (tests only) | Low | | ST-5 | Add `diagnostics.py` with redaction (token, MAC, host) | `diagnostics` | S | Low | | ST-6 | Docs: removal instructions, parameter tables, actions section to template | `docs-*` | S (docs repo PR) | Low | | ST-7 | Add/level `quality_scale.yaml`, declare Bronze→Silver once ST-1…ST-4 land | meta | XS | Low | **Target outcome:** unscored → **Silver**, plus diagnostics. Estimated total: 5 code PRs + 1 docs PR, each independently reviewable per the PR-sizing conventions in `docs/04-community-engagement-plan.md`. ## 4. Maintainer-coordination notes - Code owners are active and have strong opinions on the bridge abstraction (WS vs. legacy vs. encrypted). **Open an architecture discussion issue before ST-1/ST-2**, referencing concrete issue numbers from the tracker as motivation. - Do not attempt to refactor the three-protocol bridge; all work fits inside the existing abstraction. - The encrypted-WS path is hard to test against real hardware; rely on recorded fixtures already in the test suite and extend them rather than inventing new mocks.