Skip to content

Add entity translations to Govee BLE - #177644

Merged
joostlek merged 8 commits into
devfrom
govee_ble_entity_translations
Aug 5, 2026
Merged

joostlek merged 8 commits into
devfrom
govee_ble_entity_translations

Conversation

@piitaya

@piitaya piitaya commented Jul 30, 2026

Copy link
Copy Markdown
Member

Proposed change

Sensor and binary sensor names come from the govee-ble library as hardcoded English strings, so they are never translated. Stop passing the library names and rely on the translated device class names instead, following what was done for OralB (#97402), Bluemaestro (#102424) and BTHome (#156060). The grill thermometer probe sensors cannot be distinguished by device class alone, so they get dedicated entity descriptions with translation keys.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request:
  • Link to developer documentation pull request:
  • Link to frontend pull request:

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies a diff between library versions and ideally a link to the changelog/release notes is added to the PR description.

To help with the load of incoming pull requests:

Copilot AI review requested due to automatic review settings July 30, 2026 12:49
@piitaya
piitaya requested a review from bdraco as a code owner July 30, 2026 12:49
@home-assistant home-assistant Bot added cla-signed code-quality has-tests integration: govee_ble Top 200 Integration is ranked within the top 200 by usage labels Jul 30, 2026
@home-assistant

Copy link
Copy Markdown
Contributor

Hey there @bdraco, mind taking a look at this pull request as it has been labeled with an integration (govee_ble) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of govee_ble can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant mark-draft Mark the pull request as draft.
  • @home-assistant ready-for-review Remove the draft status from the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign govee_ble Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant update-branch Update the pull request branch with the base branch.
  • @home-assistant add-label needs-more-information Add a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) to the pull request.
  • @home-assistant remove-label needs-more-information Remove a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) on the pull request.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds translatable sensor and binary sensor names to Govee BLE.

Changes:

  • Uses device-class translations instead of library names.
  • Adds translation keys for grill probes.
  • Adds probe-name tests and fixtures.

Reviewed changes

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

Show a summary per file
File Description
homeassistant/components/govee_ble/sensor.py Adds translated sensor descriptions.
homeassistant/components/govee_ble/binary_sensor.py Removes library-provided names.
homeassistant/components/govee_ble/strings.json Adds probe translations.
tests/components/govee_ble/test_sensor.py Tests translated names.
tests/components/govee_ble/__init__.py Adds probe advertisements.

Comment thread homeassistant/components/govee_ble/sensor.py Outdated
Comment thread homeassistant/components/govee_ble/binary_sensor.py Outdated
Copilot AI review requested due to automatic review settings July 30, 2026 12:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 5 out of 5 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

homeassistant/components/govee_ble/binary_sensor.py:71

  • Clear or version the persisted binary-sensor names before relying on translated names. PassiveBluetoothDataUpdate.update() only merges incoming entity_names, so this empty mapping never removes the English names restored by passive_update_processor.py:212-216; restored entities then set _attr_name from that cache at lines 676-677 and existing installations keep the untranslated library names.
        entity_names={},

homeassistant/components/govee_ble/sensor.py:123

  • Invalidate or version the persisted sensor processor data before switching names and descriptions. On upgrade, async_register_coordinator() reconstructs entities from the old restore data first: the old English name is still applied, and probe entities retain the restored generic description without these translation keys; subsequent merge-only updates replace the mappings but not the descriptions already attached to entity instances.
            device_key_to_bluetooth_entity_key(device_key): (
                PROBE_SENSOR_DESCRIPTIONS.get(device_key.key)
                or SENSOR_DESCRIPTIONS[
                    (description.device_class, description.native_unit_of_measurement)
                ]

Copilot AI review requested due to automatic review settings July 30, 2026 13:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 7 out of 7 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (5)

homeassistant/components/govee_ble/binary_sensor.py:71

  • Add an assertion that binary sensors now receive device-class translated names. The sensor-side translation behavior is tested, but this separate conversion path also drops all library names and currently has no friendly-name coverage, so regressions in the binary-sensor naming path would pass unnoticed.
        entity_names={},

homeassistant/components/bluetooth/passive_update_processor.py:176

  • Preserve omission as “no update” and use explicit None to clear a name. PassiveBluetoothDataUpdate is a merge-style API, and test_naming already establishes entity_names={key: None} as the unnamed representation; treating every value/description update without a name as deletion can silently erase names supplied by parsers that send partial updates.
        for key in new_data.entity_data.keys() | new_data.entity_descriptions.keys():
            if (
                key not in new_data.entity_names
                and self.entity_names.get(key) is not None
            ):
                changed_entity_keys.add(key)
                self.entity_names[key] = None

homeassistant/components/bluetooth/passive_update_processor.py:176

  • Clear restored names before constructing entities, or synchronize the entity’s cached name here. Restore data is dispatched during processor registration, and PassiveBluetoothProcessorEntity.__init__ copies the restored value into _attr_name; changing only self.entity_names after the first advertisement never resets that attribute, so upgraded Govee entities retain the old English name until another restart.
        for key in new_data.entity_data.keys() | new_data.entity_descriptions.keys():
            if (
                key not in new_data.entity_names
                and self.entity_names.get(key) is not None
            ):
                changed_entity_keys.add(key)
                self.entity_names[key] = None

homeassistant/components/govee_ble/sensor.py:105

  • Add coverage for the dedicated humidity-probe description. Unlike the generated temperature entries, this hand-written branch has different class, unit, key, and placeholder values, but neither new service-info case exercises it.
    "humidity_probe_1": SensorEntityDescription(
        key="humidity_probe_1",
        translation_key="humidity_probe",
        translation_placeholders={"probe_id": "1"},
        device_class=SensorDeviceClass.HUMIDITY,
        native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
        state_class=SensorStateClass.MEASUREMENT,
    )

homeassistant/components/govee_ble/sensor.py:124

  • Invalidate or migrate restored sensor descriptions when introducing these probe translations. Existing probe entities are constructed from the serialized pre-change generic temperature description before the first advertisement, and later replacing the processor’s description mapping does not replace each entity’s cached entity_description; consequently upgraded probe entities do not adopt these translation keys/placeholders until a subsequent restart.
            device_key_to_bluetooth_entity_key(device_key): (
                PROBE_SENSOR_DESCRIPTIONS.get(device_key.key)
                or SENSOR_DESCRIPTIONS[
                    (description.device_class, description.native_unit_of_measurement)
                ]
            )

Copilot AI review requested due to automatic review settings July 30, 2026 13:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 7 out of 7 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (5)

homeassistant/components/govee_ble/binary_sensor.py:71

  • Add a test assertion for the translated binary-sensor friendly name. The existing binary-sensor tests only verify state, so this separate conversion path can keep or regain a library-provided English name without any test failing.
        entity_names={},

homeassistant/components/bluetooth/passive_update_processor.py:178

  • Clear restored names before restored entities are instantiated. async_register_coordinator() dispatches restore data first, so PassiveBluetoothProcessorEntity.__init__() copies the old name into _attr_name; this later mapping update only writes state and cannot switch an existing Govee entity to its translated name during that session. The restore data needs migration/versioning before the initial dispatch, or entities need an explicit name-change path.
        if not new_data.entity_names:
            for key in (
                new_data.entity_data.keys() | new_data.entity_descriptions.keys()
            ):
                if self.entity_names.get(key) is not None:
                    changed_entity_keys.add(key)
                    self.entity_names[key] = None

homeassistant/components/govee_ble/sensor.py:124

  • Migrate restored probe descriptions before entities are created. Existing installations restore the previous generic temperature description and instantiate the entity before the first advertisement reaches this mapping; later replacing processor.entity_descriptions does not replace the entity's bound entity_description, so these probes do not receive the new translation key until a subsequent restart after storage is rewritten.
            device_key_to_bluetooth_entity_key(device_key): (
                PROBE_SENSOR_DESCRIPTIONS.get(device_key.key)
                or SENSOR_DESCRIPTIONS[
                    (description.device_class, description.native_unit_of_measurement)
                ]
            )

homeassistant/components/bluetooth/passive_update_processor.py:178

  • Keep an empty entity_names mapping as “no name updates.” PassiveBluetoothDataUpdate is explicitly designed for partial advertisements, and None is already the deletion value for an individual key; treating the default empty mapping as deletion makes an ordinary data-only partial update erase names supplied by an earlier update. Emit {key: None} explicitly from integrations that are dropping names instead.
        if not new_data.entity_names:
            for key in (
                new_data.entity_data.keys() | new_data.entity_descriptions.keys()
            ):
                if self.entity_names.get(key) is not None:
                    changed_entity_keys.add(key)
                    self.entity_names[key] = None

homeassistant/components/govee_ble/sensor.py:105

  • Add coverage for the dedicated humidity-probe description. The new advertisements exercise only the generated temperature descriptions, leaving this hand-written key, humidity class/unit, translation key, and placeholder branch unverified.
    "humidity_probe_1": SensorEntityDescription(
        key="humidity_probe_1",
        translation_key="humidity_probe",
        translation_placeholders={"probe_id": "1"},
        device_class=SensorDeviceClass.HUMIDITY,
        native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
        state_class=SensorStateClass.MEASUREMENT,
    )

Copilot AI review requested due to automatic review settings July 30, 2026 13:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 5 out of 5 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

homeassistant/components/govee_ble/binary_sensor.py:71

  • Add coverage showing that binary sensors now use translated device-class names. Existing test_binary_sensor.py cases only assert state, so the binary-sensor half of this change could keep or regain the library-provided English name without failing any test; use a non-English language so the translated name differs from the library string.
        entity_names={},

Copilot AI review requested due to automatic review settings July 30, 2026 13:33
Comment thread tests/components/govee_ble/test_sensor.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 5 out of 5 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

homeassistant/components/govee_ble/binary_sensor.py:74

  • Add an upgrade-path test that seeds a restored English binary-sensor name and verifies this None entry replaces it. Existing binary-sensor tests assert only state values, so neither translated naming nor the persisted-name clearing behavior is currently exercised.
        # None overrides names restored from storage, {} would keep them
        entity_names={
            device_key_to_bluetooth_entity_key(device_key): None
            for device_key in sensor_update.binary_entity_values

homeassistant/components/govee_ble/sensor.py:135

  • Add an upgrade-path test that seeds a restored English sensor name and verifies this None entry replaces it. The current tests only exercise fresh entities, where omitting entity_names entirely would produce the same translated result, so the persistence behavior added for existing installations can regress unnoticed.
        # None overrides names restored from storage, {} would keep them
        entity_names={
            device_key_to_bluetooth_entity_key(device_key): None
            for device_key in sensor_update.entity_values

homeassistant/components/govee_ble/sensor.py:102

  • Add coverage for the dedicated humidity-probe description. The new probe tests cover only the temperature and alarm variants, leaving this separately constructed translation key, placeholder, device class, and unit unverified.
    "humidity_probe_1": SensorEntityDescription(
        key="humidity_probe_1",
        translation_key="humidity_probe",
        translation_placeholders={"probe_id": "1"},
        device_class=SensorDeviceClass.HUMIDITY,

Copilot AI review requested due to automatic review settings July 30, 2026 13:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 5 out of 5 changed files in this pull request and generated no new comments.

@piitaya
piitaya requested a review from joostlek August 4, 2026 15:57
@joostlek
joostlek merged commit b78da24 into dev Aug 5, 2026
34 checks passed
@joostlek
joostlek deleted the govee_ble_entity_translations branch August 5, 2026 12:19
raman325 added a commit to raman325/home-assistant that referenced this pull request Aug 5, 2026
* upstream/dev: (361 commits)
  Improve Z-Wave heat alarm binary sensors discovery (home-assistant#177486)
  Use entity attribute enums in logbook (home-assistant#178254)
  Import DOMAIN constants in Google Assistant (home-assistant#178262)
  Import DOMAIN constants in Alexa (home-assistant#178260)
  Raise ServiceValidationError for invalid vizio source and sound mode (home-assistant#177588)
  Fixes home-assistant#173399 Seerr webhook registration (home-assistant#177201)
  Adapt mqtt to set via_device_id in DeviceInfo (home-assistant#178234)
  Use base entity attribute enums in MQTT base blocked attributes (home-assistant#178231)
  ProxmoxVE component change Hibernate button to Suspend and fix API call path (home-assistant#177205)
  Fix via_device in fritz linking to itself (home-assistant#178226)
  Fix via_device in tplink linking to itself (home-assistant#178228)
  Adapt hortimax to set via_device_id in DeviceInfo (home-assistant#178233)
  Add entity translations to Govee BLE (home-assistant#177644)
  Add FireAvert (home-assistant#178224)
  Bump plugwise to v1.14.4 (home-assistant#177957)
  Do not probe Pi-hole v6 API version with a wrong password (home-assistant#178143)
  Bump ttls to 1.10.0 (home-assistant#177418)
  Add Reolink anti-flicker entity (home-assistant#177411)
  Add Reolink time synchronization button (home-assistant#177352)
  Add input_button support to button.pressed trigger (home-assistant#178161)
  ...

# Conflicts:
#	homeassistant/components/vizio/config_flow.py
#	tests/components/vizio/conftest.py
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants