# Per-Integration Gap Audit: `denonavr` > Status legend, method, and sizing: see [`docs/03-quality-scale-audit-rubric.md`](../03-quality-scale-audit-rubric.md). > Snapshot findings; 🔍 items must be re-verified against `dev` before implementation. ## 1. Snapshot | Field | Value | |---|---| | Domain | `denonavr` | | Category | AV receiver (Denon / Marantz) | | IoT class | `local_push` (HTTP polling + telnet event channel) | | Backing library | `denonavr` (async, actively maintained) | | Platforms | `media_player` | | Custom services | `get_command`, plus audio-tuning services (`set_dynamic_eq`, `set_audyssey_*` family) 🔍 | | Declared `quality_scale` | none (unrated) | | Code owners | Listed in `CODEOWNERS`; library author is among them 🔍 | | Popularity band (M1 dataset) | High — top-100 media device integration | | Issue-volume band (M1 dataset) | High — themes: receiver becomes unavailable after network blip, telnet reconnection, multi-zone confusion, slow source switching | **Why selected:** high install base, high issue volume, single-platform surface (audits and tests stay contained), and an unrated quality scale despite a healthy upstream library — a textbook "polish multiplies existing value" target. ## 2. Architecture summary Each config entry represents one receiver; multi-zone support creates one `media_player` entity per zone (Main/Zone2/Zone3). The `denonavr` library handles device probing (capability discovery via Appcommand/AVR-X detection), state updates, and an optional telnet connection for push updates. Discovery is via SSDP. There is no authentication (reauth N/A); however a `reconfigure`-style need exists because receivers change IPs and the entry stores host. ## 3. Gap audit | # | Dimension | Status | Evidence / notes | |---|---|---|---| | D1 | Config flow completeness | 🟡 Partial | SSDP discovery + manual host entry present; unique ID from serial/MAC prevents duplicates; options flow (show-all-sources, zones, update audyssey) present. Gaps: verify SSDP-driven host updates for already-configured entries (`async_update_entry` on rediscovery) 🔍; add explicit `reconfigure` step for static-IP installs where SSDP is blocked (a recurring issue theme). | | D2 | Reauth & credentials | ➖ N/A | No authentication in protocol. Mark `exempt` in `quality_scale.yaml` with rationale. | | D3 | Runtime data & typing | 🟡 Partial 🔍 | Receiver object held in `hass.data` at snapshot; migrate to typed `runtime_data`. Type hints partial in `media_player.py`; the decorator-based command wrappers historically lose signature typing — tighten with `ParamSpec`. Not in `.strict-typing`. | | D4 | Update strategy | 🟡 Partial | Hybrid: polling + telnet push. No coordinator (acceptable — per-entity update with library cache is the established pattern here; rubric does not force a coordinator where push is primary). Gaps: confirm `PARALLEL_UPDATES` set; verify polling backs off / is skipped while telnet is healthy 🔍; M1 issues show duplicate update storms on flaky networks. | | D5 | Diagnostics & repairs | ❌ Gap | No `diagnostics.py`. Payload should include: receiver model/firmware, zone topology, capability flags (Appcommand vs status-xml), telnet connection state, redacted host/serial. This is the top triage need given the issue themes. | | D6 | Entity naming & device registry | 🟡 Partial 🔍 | Device registry entry with manufacturer/model/serial present. Verify `has_entity_name`; zone entities historically named " Zone2" via composed strings rather than entity-name semantics (main zone should be `_attr_name = None`). | | D7 | Error handling & availability | 🟡 Partial | Setup raises `ConfigEntryNotReady` on connect failure. Gaps: availability flapping on transient HTTP timeouts (should tolerate N consecutive failures before marking unavailable — match library retry semantics); telnet disconnect handling should schedule reconnect with backoff and log once, not per-attempt (log-spam complaints in issue tracker). Service handlers raise untranslated errors. | | D8 | Test coverage | 🟡 Partial | Config-flow tests good (SSDP + manual + options). Media player platform tests thin: no snapshot tests, no zone-entity tests, no telnet-callback state-update tests, no service tests. | | D9 | Documentation & strings | 🟡 Partial | `data_description` incomplete; docs lack: multi-zone explanation, telnet on/off guidance, and a troubleshooting section for "unavailable after router reboot" (top issue). Service field descriptions need an audit against current schemas 🔍 | | D10 | Quality-scale declaration | ❌ Gap | Undeclared. Bronze achievable within this program; Silver requires the availability work (D7) which is also the highest user value — plan both. | ## 4. Detailed findings ### D7 — Availability & reconnection (highest-impact gap) The largest issue cluster is entities sticking unavailable or flapping after network interruptions. Plan: (a) tolerate transient update failures with a bounded failure-count before flipping `available`; (b) centralize telnet reconnect with exponential backoff inside the integration's existing connection helper, logging at `WARNING` once and `DEBUG` thereafter; (c) on SSDP rediscovery with changed host, update the entry and reload. Each lands as a separate PR per sizing conventions. ### D1 — Reconfigure step For installs without SSDP (VLAN-separated AV gear is common), add a `reconfigure` flow allowing host changes with validation against the stored unique ID (serial), so users stop deleting/re-adding entries (losing entity customizations — a frequent complaint). ## 5. Work items | ID | Title | Dimensions | Effort | Depends on | |---|---|---|---|---| | DEN-01 | Migrate to typed `ConfigEntry.runtime_data` | D3 | S | — | | DEN-02 | Add `diagnostics.py` (capabilities, zones, telnet state; redacted) + tests | D5 | S | DEN-01 | | DEN-03 | Availability debounce + telnet reconnect/backoff + log hygiene; tests | D7, D8 | M | DEN-01 | | DEN-04 | SSDP rediscovery host-update verification/fix + `reconfigure` flow + tests | D1 | M | — | | DEN-05 | `has_entity_name` migration (main zone `name=None`, zones translated) | D6 | S | — | | DEN-06 | Snapshot + zone + service tests for `media_player` | D8 | M | DEN-05 | | DEN-07 | Translation-backed service/command exceptions | D7, D9 | S | — | | DEN-08 | Strings `data_description` + docs page expansion (docs repo PR) | D9 | S | — | | DEN-09 | Declare `quality_scale: bronze` + checklist (`reauth: exempt`) | D10 | S | DEN-02, DEN-03, DEN-06 | Target tier: **Bronze declared, Silver-track** (Silver gate = D7 work + docs). ## 6. Risks & coordination notes - The backing library author is a code owner: propose D7 changes in a tracking issue first — some reconnection logic may belong upstream in `denonavr` rather than in core, and the owner should make that call. Budget for an upstream PR alternative. - Zone entity naming changes must preserve entity IDs; friendly-name-only migration. - Verify current service schema names against `services.yaml` on `dev` 🔍 — the Audyssey service family has been renamed in the past.