# Quality-Scale Audit: `broadlink` > Audit snapshot per `docs/03-quality-scale-audit-rubric.md`; re-verify against `dev` before execution. ## 1. Integration profile | Attribute | Value | |---|---| | Domain | `broadlink` | | IoT class | `local_polling` | | Primary library | `broadlink` (python-broadlink) — **synchronous sockets**, called via executor | | Declared `quality_scale` | none declared | | Install base | Top-40; very popular in IR/RF remote-control setups (RM4 Pro/Mini), plus SP smart plugs, A1 sensors | | Issue volume | Medium-high — auth errors after device firmware/cloud lock ("device is locked"), entity naming confusion, learn-command UX, devices going unavailable on busy networks | | CODEOWNERS | Yes — single long-standing code owner; historically responsive but bandwidth-limited | **Why selected:** large install base, learn/send IR-RF is a core community workflow, and the integration predates several modern conventions (it carries its own update-manager abstraction rather than `DataUpdateCoordinator`, services with sparse validation, no diagnostics, no reauth). ## 2. Rule-by-rule audit ### Bronze | Rule | Status | Evidence / Gap | |---|---|---| | `config-flow` | ✅ | Flow with DHCP discovery; handles auth, lock detection, factory-reset hint. | | `test-before-configure` | ✅ | `hello`/`auth` performed before entry creation. | | `unique-config-entry` | ✅ | MAC-based unique ID. | | `config-flow-test-coverage` | 🟡 | Good baseline; "device locked" and firmware-error branches need coverage check. | | `entity-unique-id` | ✅ | MAC-derived unique IDs across platforms. | | `has-entity-name` | ❌ | **Key gap.** Several platforms still construct names as `f"{device.name} ..."` instead of `_attr_has_entity_name = True` + translated `_attr_name`/`translation_key`. Affects sensor, switch, remote, climate (hysen thermostats). User-visible rename: must follow the entity-naming migration guidance (no unique-ID changes, names update only for entities without user overrides). | | `runtime-data` | 🟡 | Verify `entry.runtime_data` migration; the custom `BroadlinkDevice` wrapper historically lived in `hass.data[DOMAIN].devices`. | | `appropriate-polling` | 🟡 | Custom `BroadlinkUpdateManager` per device type with its own intervals/backoff. Functionally fine; rule asks for justified intervals — document them. Full coordinator migration is **optional** and only with owner buy-in (backlog BL-6, stretch). | | `entity-event-setup` | ➖ | No event entities. | | `action-setup` | 🟡 | `remote.learn_command` / `send_command` are platform services (correct), but the legacy `broadlink.*` helper services (if still present) must be registered in `async_setup` and validate entries per current rules. | | `common-modules` | 🟡 | Has `entity.py`/`updater.py`; naming differs from convention (`coordinator.py`) — cosmetic, defer. | | `dependency-transparency` | ✅ | PyPI, public source. | | `docs-*` (Bronze set) | 🟡 | Learn-command docs are good; removal instructions and supported-device matrix need refresh (RM4 sub-models). | | `brands` | ✅ | Present. | ### Silver | Rule | Status | Evidence / Gap | |---|---|---| | `config-entry-unloading` | ✅ | Implemented. | | `reauthentication-flow` | ❌ | **Key gap.** When a device returns auth failure (after firmware update or cloud lock), the entry fails setup with a log message; users must remove/re-add. Implement reauth flow triggered by `AuthenticationError` from the library; for *locked* devices, reauth step should surface the documented unlock procedure as a flow description, since unlocking happens in the vendor app. | | `action-exceptions` | 🟡 | `send_command` failures sometimes only log; should raise `HomeAssistantError` with translated message (device offline, command not learned, storage full on RM). | | `entity-unavailable` | ✅ | Update manager flips availability after consecutive failures. | | `log-when-unavailable` | 🟡 | Verify log-once semantics; current backoff logs at WARNING on each threshold crossing. | | `parallel-updates` | ❌ | Not declared. Library is sync-over-executor with per-device socket; declare `PARALLEL_UPDATES = 1` on action-heavy platforms (`remote`, `switch`, `climate`) after measuring, `0` where the update manager already serializes. | | `integration-owner` | ✅ | Present. | | `test-coverage` | 🟡 | Solid for config flow and remote; `climate` (hysen) and `time`/`sensor` platforms under-covered. | | `docs-configuration-parameters` | 🟡 | Options flow parameters (timeout) under-documented. | ### Gold (selected) | Rule | Status | Notes | |---|---|---| | `diagnostics` | ❌ | **Pulled into scope** (BL-5): device type/model, fw version, lock state, update-manager statistics — redact MAC/host. Directly aids the dominant "device unavailable / locked" reports. | | `discovery` | ✅ | DHCP. | | `entity-device-class` / `entity-category` | 🟡 | A1 sensor device classes fine; some switches missing `entity_category` for config-ish entities. Defer unless trivial alongside BL-2. | ## 3. Gap summary and proposed work items | ID | Work item | Rule(s) | Size | Risk | |---|---|---|---|---| | BL-1 | Implement reauthentication flow (auth-failure trigger, locked-device guidance step, flow tests) | `reauthentication-flow` | M | Medium — owner review essential; touches setup-retry logic | | BL-2 | Migrate all platforms to `has_entity_name` + translation keys, preserving unique IDs | `has-entity-name`, `entity-translations` (partial) | M | Medium — user-visible naming; follow migration guidance exactly, one platform per commit | | BL-3 | Translated exceptions on remote/switch/climate command failures | `action-exceptions`, `exception-translations` (partial) | S | Low | | BL-4 | Declare `PARALLEL_UPDATES`; verify/finish `runtime_data` migration; log-once unavailability | `parallel-updates`, `runtime-data`, `log-when-unavailable` | S | Low | | BL-5 | Add `diagnostics.py` with redaction | `diagnostics` | S | Low | | BL-6 | *(Stretch, owner-gated)* Migrate `BroadlinkUpdateManager` to `DataUpdateCoordinator` | `appropriate-polling`, `common-modules` | L | High — do **not** start without explicit owner endorsement | | BL-7 | Coverage: climate + sensor platforms to ≥95 %; docs refresh (removal, parameters, device matrix) | `test-coverage`, `docs-*` | M | Low | | BL-8 | Add `quality_scale.yaml`; declare Bronze, then Silver after BL-1…BL-4, BL-7 | meta | XS | Low | **Target outcome:** unscored → **Silver** + diagnostics. BL-6 is explicitly out of the funded commitment and listed only so the owner can opt in. ## 4. Maintainer-coordination notes - Single code owner: batch communication, propose the full plan in one tracking issue, and keep PRs ≤400 changed lines. Expect review latency; pipeline PRs so at most two are open concurrently (per engagement plan §5). - BL-2 naming migration is the riskiest user-facing change in this audit set; include before/after entity-name tables in the PR description and link the entity-naming ADR.