Skip to content

Stop sending the deprecated via_device in DeviceInfo - #1651

Open
DerkSchooltink wants to merge 2 commits into
Zendure:masterfrom
DerkSchooltink:fix/deprecated-via-device
Open

DerkSchooltink wants to merge 2 commits into
Zendure:masterfrom
DerkSchooltink:fix/deprecated-via-device

Conversation

@DerkSchooltink

Copy link
Copy Markdown

Follow-up to #1650, which fixed the async_get_device half of the 2027.8 deprecations and left this one out on purpose. Stacked on that branch for its device_by_identifier helper — the diff will shrink to one file plus a test once #1650 lands; until then it also shows that PR's commit.

Problem

DeviceInfo["via_device"] is deprecated — identifiers are no longer unique across config entries — and removed in HA 2027.8.0. Until then every device add that carries it logs:

Detected that custom integration 'zendure_ha' calls `device_registry.async_get_or_create`
with a deprecated `via_device` parameter; use `via_device_id` instead

We set it once, in EntityDevice.__init__, for battery packs reached through their hub. On 2026.9.1 that is two of the five startup warnings (@davinkevin's breakdown in #1650: sensor.py:53 and binary_sensor.py:37, which is where self.add([self]) hands the device info to the core).

Why this is not a rename

via_device_id wants the parent's registry id, not an identifier tuple, and that changes two things:

  • When it is resolved. The core resolved via_device itself when the entity was added. The id has to be looked up when the device is constructed, which for a battery pack is inside the hub's packData handler. In practice the hub is registered by then, but the window is new.
  • What happens when it is not. An unresolvable via_device logged a warning and created the device anyway. An unresolvable via_device_id raises DeviceInfoError inside async_get_or_create, and the whole entity add fails.

So link_via_device looks the parent up through device_by_identifier and, if it is not registered yet, skips the link with a warning instead of sending an id that would fail the add. The device still gets created; only the "connected via" line is missing, same as the old failure mode.

Version gate

via_device_id only exists in DeviceInfo from HA 2026.8.0. I checked 2026.7.3: the key is absent and async_get_or_create has no such parameter, so it raises TypeError — which entity_platform catches and turns into a failed entity add. hacs.json still declares 2025.4.0, so the key is sent only where DeviceInfo declares it ("via_device_id" in DeviceInfo.__optional_keys__), and via_device otherwise. Same feature-probe approach as #1650, and the same offer stands: happy to switch to a version check or raise the minimum HA instead.

Testing

The pinned test env is HA 2026.7.3, so CI only exercises the old-key branch. The new-key branch is covered by faking the capability probe, the unresolved-parent case asserts the link is skipped and logged, and an end-to-end test constructs an EntityDevice with a parent and registers its device info against the real registry, asserting via_device_id on the result. On HA ≥ 2026.8 that last test would not merely warn if the old key were still sent — report_usage raises when the call has no integration frame above it, as it does when a test calls the registry directly.

Ran the full suite both ways: 23 passed on 2026.7.3 (old key) and 23 passed on 2026.9.1 (new key).

Not verified: a live HA startup with real hardware. The end-to-end test covers the registry call itself; a run on a real install with battery packs would confirm the two warnings are gone and the packs still show "connected via" their hub.

HA deprecated `device_registry.async_get_device` because identifiers are no
longer unique across config entries. It is scheduled for removal in 2027.8.0
and already logs a warning on every call, four of which we make:
  entity.py    EntityDevice.__init__, EntityDevice.updateVersion
  migration.py Migration.check_device (twice)
The replacement, `async_get_device_by_identifier`, is scoped to a config
entry -- but it only exists from HA 2026.8.0, and hacs.json still declares a
minimum of 2025.4.0. Swapping the calls outright would break every install on
an older core, so `entity.device_by_identifier` prefers the new API and falls
back to the old one where it is absent.
Scoping to our entry is safe: identifiers are unique within an entry and the
manifest sets single_config_entry, so there is exactly one to scope to and the
lookup returns what the registry-wide call returned.
The pinned test environment runs HA 2026.7.3, which predates the replacement,
so the new-API branch is covered with a fake registry rather than left
untested. Verified both ways: the suite passes on 2026.7.3 (fallback) and on
2026.9.0 (entry-scoped), and on 2026.9.0 the old call reports deprecated usage
once where device_by_identifier reports none, both returning the same device.
Left alone deliberately: DeviceInfo's `via_device` in EntityDevice.__init__ is
also deprecated (removed in 2027.8.0, replaced by `via_device_id`). That one
needs the parent's registry id rather than an identifier tuple, and the parent
is not guaranteed to be registered when the child is constructed, so it wants
its own change.
HA deprecated DeviceInfo's `via_device` (an identifier tuple) in favour of
`via_device_id` (a registry id); it is removed in 2027.8.0 and logs a
warning on every device add until then. We set it once, in
EntityDevice.__init__, for battery packs reached through their hub.

The replacement is not a drop-in rename. The core resolved `via_device`
itself when the entity was added, whereas `via_device_id` has to be looked
up when the device is constructed -- and a `via_device_id` the core cannot
resolve raises DeviceInfoError, which fails the entity add, where an
unresolvable `via_device` only logged. So link_via_device looks the parent
up through device_by_identifier and, if it is not registered yet, skips the
link with a warning rather than sending an id that would fail the add.

`via_device_id` also only exists from HA 2026.8.0; on older cores
async_get_or_create rejects the key with a TypeError, which entity_platform
turns into a failed entity add. hacs.json still declares 2025.4.0, so the
key is only sent where DeviceInfo declares it, and the old key otherwise.

The pinned test environment runs HA 2026.7.3, which predates the
replacement, so the new-core branch is covered by faking the capability
probe. The end-to-end test runs against the real registry on whichever
core is installed and asserts the child ends up under its parent. Verified
on 2026.7.3 (old key) and 2026.9.1 (new key): 23 passed on both.

Stacked on fix/deprecated-async-get-device (Zendure#1650) for its
device_by_identifier helper.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant