Skip to content

Make entity naming and entity_id independent of pet name - #80

Merged
kylegordon merged 2 commits into
masterfrom
fix-entity-naming-pet-name-independent
Aug 16, 2026
Merged

Make entity naming and entity_id independent of pet name#80
kylegordon merged 2 commits into
masterfrom
fix-entity-naming-pet-name-independent

Conversation

@kylegordon

Copy link
Copy Markdown
Owner

Summary

  • Entity friendly names were built as f"{pet_name} {suffix}" (e.g. "Fluffy Battery Level"). With has_entity_name unset, HA slugged that combined string into the entity_id at first creation — so renaming the pet later left the entity_id permanently stuck on the old name (e.g. sensor.fluffy_battery_level), even though unique_id was already correctly keyed on device.id.
  • Sets _attr_has_entity_name = True on all sensor, binary sensor, and device tracker entities, with per-entity suffix names (e.g. "Battery Level", "At Home", "Charging"). HA now composes the displayed friendly name from the device name (still the pet's name, pulled live from device.details.name on every coordinator refresh) + the entity's own name.
  • Pins _attr_suggested_object_id to a device.id-based slug (e.g. pettracer_12345_battery_level) so newly created entities get an entity_id that's stable regardless of pet renames.
  • The device tracker entity (which represents the pet itself) sets _attr_name = None so its friendly name is exactly the device name, matching prior behavior.
  • This only affects newly created entities going forward — existing installs keep their current entity_ids untouched (HA doesn't auto-migrate entity_id, and neither does this change, to avoid silently breaking dashboards/automations that reference the old ids).

Test plan

  • Updated tests/test_sensor.py, tests/test_binary_sensor.py, tests/test_device_tracker.py to assert the new name/_attr_suggested_object_id/_attr_has_entity_name values.
  • Full suite passes: 74 passed, 98% coverage (pytest --cov=custom_components.pettracer --cov-report=term -v), above the CI 90% gate.
  • ruff check clean on the three modified platform files.

🤖 Generated with Claude Code

Entity friendly names were built as f"{pet_name} {suffix}", and with
has_entity_name unset, HA slugged that string into the entity_id at
first creation. Renaming a pet later left the entity_id permanently
stuck on the old name even though unique_id (already keyed on
device.id) and the device registry name stayed correct.

Switch to has_entity_name=True with per-entity suffix names (e.g.
"Battery Level", "At Home") so HA composes the displayed name from
the device (pet name) + entity name, and pin _attr_suggested_object_id
to a device.id-based slug so newly created entities get pet-name-
independent entity_ids (e.g. sensor.pettracer_12345_battery_level).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates PetTracer entities so new entity IDs are based on stable device IDs rather than pet names.

Changes:

  • Enables Home Assistant entity-name composition across all platforms.
  • Adds device-ID-based suggested object IDs.
  • Updates unit tests for naming attributes.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
custom_components/pettracer/sensor.py Updates sensor naming and suggested IDs.
custom_components/pettracer/binary_sensor.py Updates binary sensor naming and suggested IDs.
custom_components/pettracer/device_tracker.py Delegates tracker naming to the device.
tests/test_sensor.py Updates sensor naming assertions.
tests/test_binary_sensor.py Updates binary sensor naming assertions.
tests/test_device_tracker.py Updates tracker naming assertions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/test_sensor.py
Comment on lines +71 to +73
assert sensor.name == "Battery Level"
assert sensor._attr_has_entity_name is True
assert sensor._attr_suggested_object_id == "pettracer_12345_battery_level"

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added regression tests in 5abd8c1 (test_sensor_device_info_reflects_pet_rename, test_at_home_binary_sensor_device_info_reflects_pet_rename, test_device_tracker_device_info_reflects_pet_rename) that construct the entity, mutate mock_device.details.name, refresh coordinator.data, and assert device_info["name"]" picks up the new name while unique_id/_attr_suggested_object_id/device_info["identifiers"]stay fixed — this is exactly what caught the constructor-cached device name bug you flagged below. I stopped short of driving this through a fullentity_platform/entity-registry registration (real hass.states/entity_id` assignment), since these tests already unit-test each entity's own attribute computation directly and the existing test suite in this repo deliberately avoids full platform-forwarding setup for speed/isolation. Happy to add a true end-to-end registration test as a follow-up if you'd like that extra coverage.

Comment on lines 44 to 46
self._device_name = (
device.details.name if device.details else f"PetTracer {device.id}"
)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed and fixed in 5abd8c1device_info was reading self._device_name/self._device.sw, both captured once in __init__ and never refreshed. It now calls _get_device_data() (already used by every other property in these classes) to get the latest device on each access, falling back to the constructor-time device if it's momentarily missing from coordinator data. Same bug existed in sensor.py and binary_sensor.py too, so fixed all three.

…snapshot

Copilot review on #80 caught that device_info's name and sw_version
were read from self._device_name/self._device, both captured once in
__init__ and never refreshed. _get_device_data() already exists on
every entity for exactly this purpose but device_info wasn't using
it, so a pet rename (or firmware update) would never reach the device
registry until Home Assistant restarted and re-instantiated the
entity.

device_info now looks up the latest device via _get_device_data(),
falling back to the constructor-time device if it's momentarily
absent from coordinator data. Adds regression tests across all three
platforms asserting device_info name updates on rename while
unique_id/suggested_object_id stay fixed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (1)

custom_components/pettracer/device_tracker.py:60

  • device_info is consumed when Home Assistant registers the entity; it is not re-read on each CoordinatorEntity refresh. Therefore returning the latest device here does not update the device-registry name, so a PetTracer rename still leaves the composed friendly names on the old pet name. Register a coordinator listener that calls the HA device registry's update API for this identifier when the API name changes, and cover the behavior with an entity/device-registry test rather than directly reading this property.
        device = self._get_device_data() or self._device
        device_name = (
            device.details.name if device.details else f"PetTracer {self._device_id}"
        )

@kylegordon
kylegordon merged commit 5232688 into master Aug 16, 2026
20 checks passed
@kylegordon
kylegordon deleted the fix-entity-naming-pet-name-independent branch August 16, 2026 11:04
@github-actions github-actions Bot mentioned this pull request Aug 11, 2026
kylegordon added a commit that referenced this pull request Aug 16, 2026
## What's Changed
* Add tests for uncovered exception and edge-case branches by
@kylegordon in #69
* chore(deps): update pytest-homeassistant-custom-component requirement
from >=0.13.342 to >=0.13.345 by @dependabot[bot] in
#71
* chore(deps): update pytest-homeassistant-custom-component requirement
from >=0.13.345 to >=0.13.346 by @dependabot[bot] in
#72
* chore(deps): update pytest-homeassistant-custom-component requirement
from >=0.13.346 to >=0.13.348 by @dependabot[bot] in
#74
* chore(deps): update pytest-homeassistant-custom-component requirement
from >=0.13.348 to >=0.13.350 by @dependabot[bot] in
#75
* chore(deps): bump actions/setup-python from 6 to 7 by @dependabot[bot]
in #73
* chore(deps): update pytest-homeassistant-custom-component requirement
from >=0.13.350 to >=0.13.354 by @dependabot[bot] in
#76
* gh aw daily-repo by @kylegordon in
#77
* Add agentic workflow grumpy-reviewer by @kylegordon in
#78
* Make entity naming and entity_id independent of pet name by
@kylegordon in #80
* Pin Copilot CLI version in grumpy-reviewer to avoid toolcache ENOENT
by @kylegordon in #84


**Full Changelog**:
v1.0.8...v1.0.9

Co-authored-by: kylegordon <231528+kylegordon@users.noreply.github.com>
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.

2 participants