Add support for toothbrushes to xiaomi-ble (#97276)

* Add support for toothbrushes to xiaomi-ble

* use str for string
This commit is contained in:
Ernst Klamer 2023-08-05 23:13:21 +02:00 committed by GitHub
parent e4d9daf746
commit 0caeac1a82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 8 deletions

View File

@ -72,6 +72,9 @@ BINARY_SENSOR_DESCRIPTIONS = {
key=ExtendedBinarySensorDeviceClass.PRY_THE_DOOR,
device_class=BinarySensorDeviceClass.TAMPER,
),
ExtendedBinarySensorDeviceClass.TOOTHBRUSH: BinarySensorEntityDescription(
key=ExtendedBinarySensorDeviceClass.TOOTHBRUSH,
),
}

View File

@ -24,5 +24,5 @@
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/xiaomi_ble",
"iot_class": "local_push",
"requirements": ["xiaomi-ble==0.20.0"]
"requirements": ["xiaomi-ble==0.21.1"]
}

View File

@ -2,6 +2,7 @@
from __future__ import annotations
from xiaomi_ble import DeviceClass, SensorUpdate, Units
from xiaomi_ble.parser import ExtendedSensorDeviceClass
from homeassistant import config_entries
from homeassistant.components.bluetooth.passive_update_processor import (
@ -25,6 +26,7 @@ from homeassistant.const import (
UnitOfMass,
UnitOfPressure,
UnitOfTemperature,
UnitOfTime,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -129,13 +131,23 @@ SENSOR_DESCRIPTIONS = {
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.DIAGNOSTIC,
),
# Used for e.g. consumable sensor on WX08ZM
(None, Units.PERCENTAGE): SensorEntityDescription(
key=str(Units.PERCENTAGE),
device_class=None,
# Used for e.g. consumable sensor on WX08ZM and M1S-T500
(ExtendedSensorDeviceClass.CONSUMABLE, Units.PERCENTAGE): SensorEntityDescription(
key=str(ExtendedSensorDeviceClass.CONSUMABLE),
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
),
# Used for score after brushing with a toothbrush
(ExtendedSensorDeviceClass.SCORE, None): SensorEntityDescription(
key=str(ExtendedSensorDeviceClass.SCORE),
state_class=SensorStateClass.MEASUREMENT,
),
# Used for counting during brushing
(ExtendedSensorDeviceClass.COUNTER, Units.TIME_SECONDS): SensorEntityDescription(
key=str(ExtendedSensorDeviceClass.COUNTER),
native_unit_of_measurement=UnitOfTime.SECONDS,
state_class=SensorStateClass.MEASUREMENT,
),
}
@ -153,7 +165,7 @@ def sensor_update_to_bluetooth_data_update(
(description.device_class, description.native_unit_of_measurement)
]
for device_key, description in sensor_update.entity_descriptions.items()
if description.native_unit_of_measurement
if description.device_class
},
entity_data={
device_key_to_bluetooth_entity_key(device_key): sensor_values.native_value

View File

@ -2698,7 +2698,7 @@ wyoming==1.1.0
xbox-webapi==2.0.11
# homeassistant.components.xiaomi_ble
xiaomi-ble==0.20.0
xiaomi-ble==0.21.1
# homeassistant.components.knx
xknx==2.11.2

View File

@ -1983,7 +1983,7 @@ wyoming==1.1.0
xbox-webapi==2.0.11
# homeassistant.components.xiaomi_ble
xiaomi-ble==0.20.0
xiaomi-ble==0.21.1
# homeassistant.components.knx
xknx==2.11.2

View File

@ -132,6 +132,40 @@ async def test_xiaomi_consumable(hass: HomeAssistant) -> None:
await hass.async_block_till_done()
async def test_xiaomi_score(hass: HomeAssistant) -> None:
"""Make sure that score sensors are correctly mapped."""
entry = MockConfigEntry(
domain=DOMAIN,
unique_id="ED:DE:34:3F:48:0C",
data={"bindkey": "1330b99cded13258acc391627e9771f7"},
)
entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 0
inject_bluetooth_service_info_bleak(
hass,
make_advertisement(
"ED:DE:34:3F:48:0C",
b"\x48\x58\x06\x08\xc9H\x0e\xf1\x12\x81\x07\x973\xfc\x14\x00\x00VD\xdbA",
),
)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 2
sensor = hass.states.get("sensor.smart_toothbrush_480c_score")
sensor_attr = sensor.attributes
assert sensor.state == "83"
assert sensor_attr[ATTR_FRIENDLY_NAME] == "Smart Toothbrush 480C Score"
assert sensor_attr[ATTR_STATE_CLASS] == "measurement"
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
async def test_xiaomi_battery_voltage(hass: HomeAssistant) -> None:
"""Make sure that battery voltage sensors are correctly mapped."""
entry = MockConfigEntry(