From fc0ff143d695beedd190cc002e1173c8c17f5783 Mon Sep 17 00:00:00 2001 From: Jc2k Date: Thu, 11 Aug 2022 22:11:26 +0100 Subject: [PATCH] feat: intial support for binary_sensor devices (#12) --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- src/xiaomi_ble/parser.py | 25 ++++++++++++++++++++----- tests/test_parser.py | 19 +++++++++++++++---- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/poetry.lock b/poetry.lock index a94412d..c34a49c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -87,7 +87,7 @@ typing-extensions = ">=4.2.0" [[package]] name = "bleak-retry-connector" -version = "1.4.0" +version = "1.5.0" description = "A connector for Bleak Clients that handles transient connection failures" category = "main" optional = false @@ -163,7 +163,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "6.4.2" +version = "6.4.3" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -612,7 +612,7 @@ use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "sensor-state-data" -version = "2.0.2" +version = "2.1.2" description = "Models for storing and converting Sensor Data state" category = "main" optional = false @@ -802,7 +802,7 @@ docs = ["myst-parser", "Sphinx", "sphinx-rtd-theme"] [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "410ae02b6c954802dddfa281dba63fc4bc1e10ba64a9cd4f49ca5932181d5139" +content-hash = "db11060377f39b6fd3c0aad7712fc13e5ff1611133318e881509291b5bd7e1b2" [metadata.files] alabaster = [] diff --git a/pyproject.toml b/pyproject.toml index 9a4090b..c079ac2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ Sphinx = {version = "^5.0", optional = true} sphinx-rtd-theme = {version = "^1.0", optional = true} myst-parser = {version = "^0.18", optional = true} home-assistant-bluetooth = ">=1.3.0" -sensor-state-data = ">=2.0.2" +sensor-state-data = ">=2.1.2" bluetooth-sensor-state-data = ">=1.5.0" pycryptodomex = ">=3.15.0" bleak-retry-connector = ">=1.4.0" diff --git a/src/xiaomi_ble/parser.py b/src/xiaomi_ble/parser.py index c67bd48..e27daf8 100644 --- a/src/xiaomi_ble/parser.py +++ b/src/xiaomi_ble/parser.py @@ -19,7 +19,13 @@ from bluetooth_sensor_state_data import BluetoothData from Cryptodome.Cipher import AES from home_assistant_bluetooth import BluetoothServiceInfo -from sensor_state_data import DeviceClass, SensorLibrary, SensorUpdate, Units +from sensor_state_data import ( + BinarySensorDeviceClass, + DeviceClass, + SensorLibrary, + SensorUpdate, + Units, +) from .const import CHARACTERISTIC_BATTERY, TIMEOUT_1DAY from .devices import DEVICE_TYPES @@ -304,7 +310,10 @@ def obj000f( if device_type in ["MJYD02YL", "RTCGQ02LM"]: # MJYD02YL: 1 - moving no light, 100 - moving with light # RTCGQ02LM: 0 - moving no light, 256 - moving with light - return {"motion": 1, "motion timer": 1, "light": int(illum >= 100)} + device.update_predefined_binary_sensor( + BinarySensorDeviceClass.LIGHT, bool(illum >= 100) + ) + return {"motion": 1, "motion timer": 1} elif device_type == "CGPR1": # CGPR1: moving, value is illumination in lux device.update_predefined_sensor(SensorLibrary.LIGHT__LIGHT_LUX, illum) @@ -525,7 +534,9 @@ def obj1007( if device_type in ["MJYD02YL", "MCCGQ02HL"]: # 100 means light, else dark (0 or 1) # MCCGQ02HL might use obj1018 for light sensor, just added here to be sure. - return {"light": 1 if illum == 100 else 0} + device.update_predefined_binary_sensor( + BinarySensorDeviceClass.LIGHT, illum == 100 + ) elif device_type in ["HHCCJCY01", "GCLS002"]: # illumination in lux device.update_predefined_sensor(SensorLibrary.LIGHT__LIGHT_LUX, illum) @@ -603,14 +614,18 @@ def obj1014( xobj: bytes, device: XiaomiBluetoothDeviceData, device_type: str ) -> dict[str, Any]: """Moisture""" - return {"moisture": xobj[0]} + device.update_predefined_binary_sensor( + BinarySensorDeviceClass.MOISTURE, xobj[0] > 0 + ) + return {} def obj1015( xobj: bytes, device: XiaomiBluetoothDeviceData, device_type: str ) -> dict[str, Any]: """Smoke""" - return {"smoke detector": xobj[0]} + device.update_predefined_binary_sensor(BinarySensorDeviceClass.SMOKE, xobj[0] > 0) + return {} def obj1017( diff --git a/tests/test_parser.py b/tests/test_parser.py index 8fa23f4..1a28ffb 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -5,6 +5,9 @@ import pytest from home_assistant_bluetooth import BluetoothServiceInfo from sensor_state_data import ( + BinarySensorDescription, + BinarySensorDeviceClass, + BinarySensorValue, DeviceClass, DeviceKey, SensorDescription, @@ -23,6 +26,7 @@ KEY_ILLUMINANCE = DeviceKey(key="illuminance", device_id=None) KEY_CONDUCTIVITY = DeviceKey(key="conductivity", device_id=None) KEY_MOISTURE = DeviceKey(key="moisture", device_id=None) +KEY_SMOKE = DeviceKey(key="smoke", device_id=None) @pytest.fixture(autouse=True) @@ -686,12 +690,19 @@ def test_Xiaomi_JTYJGD03MI_smoke(): name="Signal Strength", device_key=KEY_SIGNAL_STRENGTH, native_value=-60 ), }, + binary_entity_descriptions={ + KEY_SMOKE: BinarySensorDescription( + device_key=KEY_SMOKE, + device_class=BinarySensorDeviceClass.SMOKE, + ), + }, + binary_entity_values={ + KEY_SMOKE: BinarySensorValue( + name="Smoke", device_key=KEY_SMOKE, native_value=True + ), + }, ) - assert device.unhandled == { - "smoke detector": 1, - } - def test_Xiaomi_JTYJGD03MI_press(): """Test Xiaomi parser for JTYJGD03MI."""