Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions custom_components/ble_monitor/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,16 @@ class BLEMonitorBinarySensorEntityDescription(
device_class=None,
force_update=False,
),
BLEMonitorBinarySensorEntityDescription(
key="stabilized",
sensor_class="BaseBinarySensor",
update_behavior="Instantly",
name="ble stabilized",
icon="mdi:scale-bathroom",
unique_id="stabilized_",
device_class=None,
force_update=False,
),
BLEMonitorBinarySensorEntityDescription(
key="fingerprint",
sensor_class="BaseBinarySensor",
Expand Down Expand Up @@ -2158,8 +2168,8 @@ class BLEMonitorBinarySensorEntityDescription(
'YLKG07YL/YLKG08YL' : [["rssi"], ["dimmer"], []],
'SU001-T' : [["battery", "rssi"], [], ["motion", "switch"]],
'ATC' : [["temperature", "humidity", "battery", "voltage", "rssi"], [], ["switch", "opening"]],
'Mi Scale V1' : [["rssi"], ["weight", "non-stabilized weight"], ["weight removed"]],
'Mi Scale V2' : [["rssi"], ["weight", "stabilized weight", "non-stabilized weight", "impedance"], ["weight removed"]],
'Mi Scale V1' : [["rssi"], ["weight", "non-stabilized weight"], ["weight removed", "stabilized"]],
'Mi Scale V2' : [["rssi"], ["weight", "stabilized weight", "non-stabilized weight", "impedance"], ["weight removed", "stabilized"]],
'Mi Band' : [["rssi", "heart rate", "steps"], [], []],
'TZC4' : [["rssi"], ["weight", "non-stabilized weight", "impedance"], []],
'QJ-J' : [["rssi"], ["weight", "non-stabilized weight", "impedance"], []],
Expand Down
44 changes: 44 additions & 0 deletions custom_components/ble_monitor/test/test_miscale_parser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
"""The tests for the Mi Scale ble_parser."""
from types import SimpleNamespace

from ble_monitor.binary_sensor import BaseBinarySensor
from ble_monitor.ble_parser import BleParser
from ble_monitor.const import BINARY_SENSOR_TYPES, MEASUREMENT_DICT
from ble_monitor.sensor import WeightSensor

# Real Mi Scale V1 advertisements from
# https://github.com/custom-components/ble_monitor/issues/366
Expand Down Expand Up @@ -50,6 +55,17 @@ def test_miscale_v1(self):
assert sensor_msg["stabilized"] == 1
assert sensor_msg["rssi"] == -59

weight_removed_sensor = BaseBinarySensor.__new__(BaseBinarySensor)
weight_removed_sensor._type = "mac"
weight_removed_sensor._device_type = "Mi Scale V1"
weight_removed_sensor.entity_description = SimpleNamespace(
key="weight removed"
)
weight_removed_sensor._extra_state_attributes = {}
weight_removed_sensor.collect(sensor_msg)
assert weight_removed_sensor._newstate == 1
assert weight_removed_sensor._extra_state_attributes["weight"] == 87.2

def test_miscale_v1_ext(self):
"""Test Mi Scale v1 parser (extended advertisement)."""
data_string = "043e390d011300008995c08c47c80100ff7fc70000000000000000001f02010603021d1809ff5701c8478cc095890d161d18821400e507040b101708"
Expand Down Expand Up @@ -129,9 +145,37 @@ def test_miscale_v2_impedance(self):
assert sensor_msg["weight unit"] == "kg"
assert sensor_msg["weight removed"] == 0
assert sensor_msg["stabilized"] == 1
assert sensor_msg["stabilized weight"] == 85.15
assert sensor_msg["weight"] == 85.15
assert sensor_msg["impedance"] == 428
assert sensor_msg["rssi"] == -66

weight_sensor = WeightSensor.__new__(WeightSensor)
weight_sensor._type = "mac"
weight_sensor.entity_description = SimpleNamespace(
key="non-stabilized weight"
)
weight_sensor._extra_state_attributes = {}
weight_sensor.pending_update = False
weight_sensor.collect(sensor_msg, period_cnt=0)
assert weight_sensor._extra_state_attributes["stabilized"] is True

def test_miscale_stabilized_binary_sensor_mapping(self):
"""Test Mi Scale V1 and V2 expose the parsed stabilization flag."""
for device_type in ("Mi Scale V1", "Mi Scale V2"):
assert MEASUREMENT_DICT[device_type][2] == [
"weight removed",
"stabilized",
]

description = next(
item for item in BINARY_SENSOR_TYPES if item.key == "stabilized"
)
assert description.sensor_class == "BaseBinarySensor"
assert description.update_behavior == "Instantly"
assert description.unique_id == "stabilized_"
assert description.device_class is None

def test_miscale_v1_stale_first_packet(self):
"""Test that the stale first packet from issue 366 remains suppressed."""
ble_parser = BleParser(filter_duplicates=True)
Expand Down
3 changes: 3 additions & 0 deletions docs/_devices/Xiaomi_XMTZC01HM_XMTZC04HM.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ physical_description:
broadcasted_properties:
- weight
- non-stabilized weight
- stabilized
- weight removed
- rssi
broadcasted_property_notes:
- property: weight
note: is only reported after the scale is stabilized
- property: non-stabilized weight
note: is reporting all weight measurements
- property: stabilized
note: reports the stabilization flag transmitted by the scale
broadcast_rate:
active_scan:
encryption_key:
Expand Down
3 changes: 3 additions & 0 deletions docs/_devices/Xiaomi_XMTZC02HM_XMTZC05HM_NUN4049CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ broadcasted_properties:
- weight
- non-stabilized weight
- stabilized weight
- stabilized
- weight removed
- impedance
- rssi
Expand All @@ -18,6 +19,8 @@ broadcasted_property_notes:
note: is updated, even if the impedance has not been calculated and send by the scale. This sensor is updated slightly before the weight sensor, even if you step off the scale before the white line starts flashing, but the `weight` measurement does not always correspond to the `impedance` measurement.
- property: non-stabilized weight
note: this sensor is reporting all weight measurements
- property: stabilized
note: reports the stabilization flag transmitted by the scale
broadcast_rate:
active_scan:
encryption_key:
Expand Down
Loading