diff --git a/custom_components/xiaomi_gateway3/core/converters/mibeacon.py b/custom_components/xiaomi_gateway3/core/converters/mibeacon.py index e0a2acee..ddc316f9 100644 --- a/custom_components/xiaomi_gateway3/core/converters/mibeacon.py +++ b/custom_components/xiaomi_gateway3/core/converters/mibeacon.py @@ -313,3 +313,19 @@ def decode(self, device: "XDevice", payload: dict, data: str): if value == device.extra.get("battery"): payload[self.attr] = value device.extra["battery"] = value + + +class BLEScaleS400(BaseConv): + def decode(self, device: "XDevice", payload: dict, value: int): + weight = value & 0x7FF + heart_rate = (value >> 11) & 0xFF + impedance = value >> 18 + if weight != 0: + payload["weight"] = weight / 10 + if 0 < heart_rate < 127: + payload["heart_rate"] = heart_rate + 50 + if impedance != 0: + if weight != 0: + payload["impedance_high"] = impedance / 10 + else: + payload["impedance_low"] = impedance / 10 diff --git a/custom_components/xiaomi_gateway3/core/devices.py b/custom_components/xiaomi_gateway3/core/devices.py index 8cb00bab..b805fad3 100644 --- a/custom_components/xiaomi_gateway3/core/devices.py +++ b/custom_components/xiaomi_gateway3/core/devices.py @@ -2016,6 +2016,16 @@ MapConv("action", mi="5.e.1013.p.1", map={1: BUTTON_1_DOUBLE, 2: BUTTON_2_DOUBLE, 3: BUTTON_3_DOUBLE, 4: BUTTON_4_DOUBLE}), MapConv("action", mi="5.e.1014.p.1", map={1: BUTTON_1_HOLD, 2: BUTTON_2_HOLD, 3: BUTTON_3_HOLD, 4: BUTTON_4_HOLD}), ] +}, { + # https://home.miot-spec.com/spec/yunmai.scales.ms107 + 18639: ["Xiaomi", "Body Composition Scale S400", "BHR7793GL", "yunmai.scales.ms103"], + "spec": [ + BaseConv("weight", "sensor", entity={"icon": "mdi:human", "units": "kg"}), + BaseConv("heart_rate", "sensor", entity={"icon": "mdi:heart-pulse", "units": "bpm"}), + BaseConv("impedance_low", "sensor", entity={"icon": "mdi:omega", "units": "ohm"}), + BaseConv("impedance_high", "sensor", entity={"icon": "mdi:omega", "units": "ohm"}), + BLEScaleS400("raw_data", mi="11.e.1022.p.2"), + ], }, { # https://home.miot-spec.com/spec/izq.sensor_occupy.ble 18788: ["ZiQing", "IZQ Presence Sensor Loong", "IZQ-BLE", "izq.sensor_occupy.ble"], diff --git a/tests/test_conv_ble.py b/tests/test_conv_ble.py index a379178e..21b5185c 100644 --- a/tests/test_conv_ble.py +++ b/tests/test_conv_ble.py @@ -328,3 +328,32 @@ def test_14523(): p = device.decode({"eid": 18956, "edata": ""}) assert p == {"action": "single"} + + +def test_18639(): + device = XDevice(18639) + + p = device.decode( + {"siid": 11, "eiid": 1022, "arguments": [{"piid": 2, "value": 260823}]} + ) + assert p == {"weight": 72.7} + + p = device.decode( + {"siid": 11, "eiid": 1022, "arguments": [{"piid": 2, "value": 1338768096}]} + ) + assert p == {"impedance_high": 510.6, "weight": 73.6} + + p = device.decode( + {"siid": 11, "eiid": 1022, "arguments": [{"piid": 2, "value": 1234960384}]} + ) + assert p == {"impedance_low": 471.1} + + p = device.decode( + {"siid": 11, "eiid": 1022, "arguments": [{"piid": 2, "value": 1343068894}]} + ) + assert p == {"impedance_high": 512.3, "weight": 73.4} + + p = device.decode( + {"siid": 11, "eiid": 1022, "arguments": [{"piid": 2, "value": 1240727552}]} + ) + assert p == {"impedance_low": 473.3}