From 672313c8abe1dcbb8ff20dcb4065feb29d9d8530 Mon Sep 17 00:00:00 2001 From: Ernst Klamer Date: Sun, 23 Jul 2023 13:11:05 +0200 Subject: [PATCH] Add support for MiScale V1 (#97081) --- .../components/xiaomi_ble/manifest.json | 6 +- homeassistant/generated/bluetooth.py | 5 ++ requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/xiaomi_ble/__init__.py | 18 +++++- tests/components/xiaomi_ble/test_sensor.py | 62 ++++++++++++++++--- 6 files changed, 81 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/xiaomi_ble/manifest.json b/homeassistant/components/xiaomi_ble/manifest.json index 683a5dab9dd..e2b327c6823 100644 --- a/homeassistant/components/xiaomi_ble/manifest.json +++ b/homeassistant/components/xiaomi_ble/manifest.json @@ -6,6 +6,10 @@ "connectable": false, "service_data_uuid": "0000181b-0000-1000-8000-00805f9b34fb" }, + { + "connectable": false, + "service_data_uuid": "0000181d-0000-1000-8000-00805f9b34fb" + }, { "connectable": false, "service_data_uuid": "0000fd50-0000-1000-8000-00805f9b34fb" @@ -20,5 +24,5 @@ "dependencies": ["bluetooth_adapters"], "documentation": "https://www.home-assistant.io/integrations/xiaomi_ble", "iot_class": "local_push", - "requirements": ["xiaomi-ble==0.19.1"] + "requirements": ["xiaomi-ble==0.20.0"] } diff --git a/homeassistant/generated/bluetooth.py b/homeassistant/generated/bluetooth.py index b99b621c614..7b0aa78d69e 100644 --- a/homeassistant/generated/bluetooth.py +++ b/homeassistant/generated/bluetooth.py @@ -525,6 +525,11 @@ BLUETOOTH: list[dict[str, bool | str | int | list[int]]] = [ "domain": "xiaomi_ble", "service_data_uuid": "0000181b-0000-1000-8000-00805f9b34fb", }, + { + "connectable": False, + "domain": "xiaomi_ble", + "service_data_uuid": "0000181d-0000-1000-8000-00805f9b34fb", + }, { "connectable": False, "domain": "xiaomi_ble", diff --git a/requirements_all.txt b/requirements_all.txt index e31b5a32d70..0429a807259 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2687,7 +2687,7 @@ wyoming==1.1.0 xbox-webapi==2.0.11 # homeassistant.components.xiaomi_ble -xiaomi-ble==0.19.1 +xiaomi-ble==0.20.0 # homeassistant.components.knx xknx==2.11.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 00f14b65a13..e07523e1892 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1969,7 +1969,7 @@ wyoming==1.1.0 xbox-webapi==2.0.11 # homeassistant.components.xiaomi_ble -xiaomi-ble==0.19.1 +xiaomi-ble==0.20.0 # homeassistant.components.knx xknx==2.11.1 diff --git a/tests/components/xiaomi_ble/__init__.py b/tests/components/xiaomi_ble/__init__.py index 879ab4f7bc4..197745b70f1 100644 --- a/tests/components/xiaomi_ble/__init__.py +++ b/tests/components/xiaomi_ble/__init__.py @@ -105,6 +105,22 @@ HHCCJCY10_SERVICE_INFO = BluetoothServiceInfoBleak( connectable=False, ) +MISCALE_V1_SERVICE_INFO = BluetoothServiceInfoBleak( + name="MISCA", + address="50:FB:19:1B:B5:DC", + device=generate_ble_device("00:00:00:00:00:00", None), + rssi=-60, + manufacturer_data={}, + service_data={ + "0000181d-0000-1000-8000-00805f9b34fb": b"\x22\x9e\x43\xe5\x07\x04\x0b\x10\x13\x01" + }, + service_uuids=["0000181d-0000-1000-8000-00805f9b34fb"], + source="local", + advertisement=generate_advertisement_data(local_name="Not it"), + time=0, + connectable=False, +) + MISCALE_V2_SERVICE_INFO = BluetoothServiceInfoBleak( name="MIBFS", address="50:FB:19:1B:B5:DC", @@ -112,7 +128,7 @@ MISCALE_V2_SERVICE_INFO = BluetoothServiceInfoBleak( rssi=-60, manufacturer_data={}, service_data={ - "0000181b-0000-1000-8000-00805f9b34fb": b"\x02\xa6\xe7\x07\x07\x07\x0b\x1f\x1d\x1f\x02\xfa-" + "0000181b-0000-1000-8000-00805f9b34fb": b"\x02&\xb2\x07\x05\x04\x0f\x02\x01\xac\x01\x86B" }, service_uuids=["0000181b-0000-1000-8000-00805f9b34fb"], source="local", diff --git a/tests/components/xiaomi_ble/test_sensor.py b/tests/components/xiaomi_ble/test_sensor.py index 40d89a8214d..fff8d9b20f1 100644 --- a/tests/components/xiaomi_ble/test_sensor.py +++ b/tests/components/xiaomi_ble/test_sensor.py @@ -6,6 +6,7 @@ from homeassistant.core import HomeAssistant from . import ( HHCCJCY10_SERVICE_INFO, + MISCALE_V1_SERVICE_INFO, MISCALE_V2_SERVICE_INFO, MMC_T201_1_SERVICE_INFO, make_advertisement, @@ -513,6 +514,48 @@ async def test_hhccjcy10_uuid(hass: HomeAssistant) -> None: await hass.async_block_till_done() +async def test_miscale_v1_uuid(hass: HomeAssistant) -> None: + """Test MiScale V1 UUID. + + This device uses a different UUID compared to the other Xiaomi sensors. + """ + entry = MockConfigEntry( + domain=DOMAIN, + unique_id="50:FB:19:1B:B5:DC", + ) + entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + inject_bluetooth_service_info_bleak(hass, MISCALE_V1_SERVICE_INFO) + + await hass.async_block_till_done() + assert len(hass.states.async_all()) == 2 + + mass_non_stabilized_sensor = hass.states.get( + "sensor.mi_smart_scale_b5dc_mass_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" + ) + 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_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_UNIT_OF_MEASUREMENT] == "kg" + assert mass_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_miscale_v2_uuid(hass: HomeAssistant) -> None: """Test MiScale V2 UUID. @@ -533,35 +576,34 @@ 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_2_b5dc_mass_non_stabilized" + "sensor.mi_body_composition_scale_b5dc_mass_non_stabilized" ) mass_non_stabilized_sensor_attr = mass_non_stabilized_sensor.attributes - assert mass_non_stabilized_sensor.state == "58.85" + assert mass_non_stabilized_sensor.state == "85.15" assert ( mass_non_stabilized_sensor_attr[ATTR_FRIENDLY_NAME] - == "Mi Body Composition Scale 2 (B5DC) Mass Non Stabilized" + == "Mi Body Composition Scale (B5DC) Mass 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_2_b5dc_mass") + mass_sensor = hass.states.get("sensor.mi_body_composition_scale_b5dc_mass") mass_sensor_attr = mass_sensor.attributes - assert mass_sensor.state == "58.85" + assert mass_sensor.state == "85.15" assert ( - mass_sensor_attr[ATTR_FRIENDLY_NAME] - == "Mi Body Composition Scale 2 (B5DC) Mass" + mass_sensor_attr[ATTR_FRIENDLY_NAME] == "Mi Body Composition Scale (B5DC) Mass" ) assert mass_sensor_attr[ATTR_UNIT_OF_MEASUREMENT] == "kg" assert mass_sensor_attr[ATTR_STATE_CLASS] == "measurement" impedance_sensor = hass.states.get( - "sensor.mi_body_composition_scale_2_b5dc_impedance" + "sensor.mi_body_composition_scale_b5dc_impedance" ) impedance_sensor_attr = impedance_sensor.attributes - assert impedance_sensor.state == "543" + assert impedance_sensor.state == "428" assert ( impedance_sensor_attr[ATTR_FRIENDLY_NAME] - == "Mi Body Composition Scale 2 (B5DC) Impedance" + == "Mi Body Composition Scale (B5DC) Impedance" ) assert impedance_sensor_attr[ATTR_UNIT_OF_MEASUREMENT] == "ohm" assert impedance_sensor_attr[ATTR_STATE_CLASS] == "measurement"