Add some Xiaomi BLE sensor translations (#142109)

This commit is contained in:
Robert Resch 2025-04-05 22:51:43 +02:00 committed by GitHub
parent 6da37691ff
commit 33cbebc727
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 46 additions and 20 deletions

View File

@ -9,9 +9,11 @@ from xiaomi_ble.parser import ExtendedSensorDeviceClass
from homeassistant.components.bluetooth.passive_update_processor import (
PassiveBluetoothDataUpdate,
PassiveBluetoothEntityKey,
PassiveBluetoothProcessorEntity,
)
from homeassistant.components.sensor import (
EntityDescription,
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
@ -78,6 +80,7 @@ SENSOR_DESCRIPTIONS = {
icon="mdi:omega",
native_unit_of_measurement=Units.OHM,
state_class=SensorStateClass.MEASUREMENT,
translation_key="impedance",
),
# Mass sensor (kg)
(DeviceClass.MASS, Units.MASS_KILOGRAMS): SensorEntityDescription(
@ -93,6 +96,7 @@ SENSOR_DESCRIPTIONS = {
native_unit_of_measurement=UnitOfMass.KILOGRAMS,
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.DIAGNOSTIC,
translation_key="weight_non_stabilized",
),
(DeviceClass.MOISTURE, Units.PERCENTAGE): SensorEntityDescription(
key=f"{DeviceClass.MOISTURE}_{Units.PERCENTAGE}",
@ -180,18 +184,20 @@ def sensor_update_to_bluetooth_data_update(
sensor_update: SensorUpdate,
) -> PassiveBluetoothDataUpdate[float | None]:
"""Convert a sensor update to a bluetooth data update."""
entity_descriptions: dict[PassiveBluetoothEntityKey, EntityDescription] = {
device_key_to_bluetooth_entity_key(device_key): SENSOR_DESCRIPTIONS[
(description.device_class, description.native_unit_of_measurement)
]
for device_key, description in sensor_update.entity_descriptions.items()
if description.device_class
}
return PassiveBluetoothDataUpdate(
devices={
device_id: sensor_device_info_to_hass_device_info(device_info)
for device_id, device_info in sensor_update.devices.items()
},
entity_descriptions={
device_key_to_bluetooth_entity_key(device_key): SENSOR_DESCRIPTIONS[
(description.device_class, description.native_unit_of_measurement)
]
for device_key, description in sensor_update.entity_descriptions.items()
if description.device_class
},
entity_descriptions=entity_descriptions,
entity_data={
device_key_to_bluetooth_entity_key(device_key): cast(
float | None, sensor_values.native_value
@ -201,6 +207,17 @@ def sensor_update_to_bluetooth_data_update(
entity_names={
device_key_to_bluetooth_entity_key(device_key): sensor_values.name
for device_key, sensor_values in sensor_update.entity_values.items()
# Add names where the entity description has neither a translation_key nor
# a device_class
if (
description := entity_descriptions.get(
device_key_to_bluetooth_entity_key(device_key)
)
)
is None
or (
description.translation_key is None and description.device_class is None
)
},
)

View File

@ -227,6 +227,14 @@
}
}
}
},
"sensor": {
"impedance": {
"name": "Impedance"
},
"weight_non_stabilized": {
"name": "Weight non stabilized"
}
}
}
}

View File

@ -694,21 +694,21 @@ async def test_miscale_v1_uuid(hass: HomeAssistant) -> None:
assert len(hass.states.async_all()) == 2
mass_non_stabilized_sensor = hass.states.get(
"sensor.mi_smart_scale_b5dc_mass_non_stabilized"
"sensor.mi_smart_scale_b5dc_weight_non_stabilized"
)
mass_non_stabilized_sensor_attr = mass_non_stabilized_sensor.attributes
assert mass_non_stabilized_sensor.state == "86.55"
assert (
mass_non_stabilized_sensor_attr[ATTR_FRIENDLY_NAME]
== "Mi Smart Scale (B5DC) Mass Non Stabilized"
== "Mi Smart Scale (B5DC) Weight non stabilized"
)
assert mass_non_stabilized_sensor_attr[ATTR_UNIT_OF_MEASUREMENT] == "kg"
assert mass_non_stabilized_sensor_attr[ATTR_STATE_CLASS] == "measurement"
mass_sensor = hass.states.get("sensor.mi_smart_scale_b5dc_mass")
mass_sensor = hass.states.get("sensor.mi_smart_scale_b5dc_weight")
mass_sensor_attr = mass_sensor.attributes
assert mass_sensor.state == "86.55"
assert mass_sensor_attr[ATTR_FRIENDLY_NAME] == "Mi Smart Scale (B5DC) Mass"
assert mass_sensor_attr[ATTR_FRIENDLY_NAME] == "Mi Smart Scale (B5DC) Weight"
assert mass_sensor_attr[ATTR_UNIT_OF_MEASUREMENT] == "kg"
assert mass_sensor_attr[ATTR_STATE_CLASS] == "measurement"
@ -736,22 +736,23 @@ async def test_miscale_v2_uuid(hass: HomeAssistant) -> None:
assert len(hass.states.async_all()) == 3
mass_non_stabilized_sensor = hass.states.get(
"sensor.mi_body_composition_scale_b5dc_mass_non_stabilized"
"sensor.mi_body_composition_scale_b5dc_weight_non_stabilized"
)
mass_non_stabilized_sensor_attr = mass_non_stabilized_sensor.attributes
assert mass_non_stabilized_sensor.state == "85.15"
assert (
mass_non_stabilized_sensor_attr[ATTR_FRIENDLY_NAME]
== "Mi Body Composition Scale (B5DC) Mass Non Stabilized"
== "Mi Body Composition Scale (B5DC) Weight non stabilized"
)
assert mass_non_stabilized_sensor_attr[ATTR_UNIT_OF_MEASUREMENT] == "kg"
assert mass_non_stabilized_sensor_attr[ATTR_STATE_CLASS] == "measurement"
mass_sensor = hass.states.get("sensor.mi_body_composition_scale_b5dc_mass")
mass_sensor = hass.states.get("sensor.mi_body_composition_scale_b5dc_weight")
mass_sensor_attr = mass_sensor.attributes
assert mass_sensor.state == "85.15"
assert (
mass_sensor_attr[ATTR_FRIENDLY_NAME] == "Mi Body Composition Scale (B5DC) Mass"
mass_sensor_attr[ATTR_FRIENDLY_NAME]
== "Mi Body Composition Scale (B5DC) Weight"
)
assert mass_sensor_attr[ATTR_UNIT_OF_MEASUREMENT] == "kg"
assert mass_sensor_attr[ATTR_STATE_CLASS] == "measurement"
@ -845,7 +846,7 @@ async def test_sleepy_device(hass: HomeAssistant) -> None:
assert len(hass.states.async_all()) == 2
mass_non_stabilized_sensor = hass.states.get(
"sensor.mi_smart_scale_b5dc_mass_non_stabilized"
"sensor.mi_smart_scale_b5dc_weight_non_stabilized"
)
assert mass_non_stabilized_sensor.state == "86.55"
@ -866,7 +867,7 @@ async def test_sleepy_device(hass: HomeAssistant) -> None:
await hass.async_block_till_done()
mass_non_stabilized_sensor = hass.states.get(
"sensor.mi_smart_scale_b5dc_mass_non_stabilized"
"sensor.mi_smart_scale_b5dc_weight_non_stabilized"
)
# Sleepy devices should keep their state over time
@ -896,7 +897,7 @@ async def test_sleepy_device_restore_state(hass: HomeAssistant) -> None:
assert len(hass.states.async_all()) == 2
mass_non_stabilized_sensor = hass.states.get(
"sensor.mi_smart_scale_b5dc_mass_non_stabilized"
"sensor.mi_smart_scale_b5dc_weight_non_stabilized"
)
assert mass_non_stabilized_sensor.state == "86.55"
@ -917,7 +918,7 @@ async def test_sleepy_device_restore_state(hass: HomeAssistant) -> None:
await hass.async_block_till_done()
mass_non_stabilized_sensor = hass.states.get(
"sensor.mi_smart_scale_b5dc_mass_non_stabilized"
"sensor.mi_smart_scale_b5dc_weight_non_stabilized"
)
# Sleepy devices should keep their state over time
@ -930,7 +931,7 @@ async def test_sleepy_device_restore_state(hass: HomeAssistant) -> None:
await hass.async_block_till_done()
mass_non_stabilized_sensor = hass.states.get(
"sensor.mi_smart_scale_b5dc_mass_non_stabilized"
"sensor.mi_smart_scale_b5dc_weight_non_stabilized"
)
# Sleepy devices should keep their state over time and restore it