diff --git a/src/thermobeacon_ble/parser.py b/src/thermobeacon_ble/parser.py index 477ba47..5f5da50 100644 --- a/src/thermobeacon_ble/parser.py +++ b/src/thermobeacon_ble/parser.py @@ -27,20 +27,13 @@ class ThermoBeaconDevice: DEVICE_TYPES = { - 0x01: ThermoBeaconDevice("CGG1", ""), - 0x04: ThermoBeaconDevice("CGH1", "Door/Window Sensor"), # Door/Window Sensor - 0x07: ThermoBeaconDevice("CGG1", ""), - 0x09: ThermoBeaconDevice("CGP1W", ""), - 0x16: ThermoBeaconDevice("CGG1", "ThermoBeacon Temp RH M"), - 0x12: ThermoBeaconDevice("CGPR1", "Motion & Light"), - 0x1E: ThermoBeaconDevice("CGC1", "BT Clock Lite"), - 0x0C: ThermoBeaconDevice("CGD1", "Alarm Clock"), - 0x0E: ThermoBeaconDevice("CGDN1", "Air Monitor Lite"), - 0x0F: ThermoBeaconDevice("CGM1", "Lee Guitars Thermo-Hygrometer"), + 0x10: ThermoBeaconDevice("16", "Lanyard/mini hygrometer"), + 0x11: ThermoBeaconDevice("17", "Smart hygrometer"), + 0x15: ThermoBeaconDevice("21", "Smart hygrometer"), } +MFR_IDS = set(DEVICE_TYPES) - -SERVICE_DATA_UUID = "0000fdcd-0000-1000-8000-00805f9b34fb" +SERVICE_UUID = "0000fff0-0000-1000-8000-00805f9b34fb" class ThermoBeaconBluetoothDeviceData(BluetoothData): @@ -49,22 +42,25 @@ class ThermoBeaconBluetoothDeviceData(BluetoothData): def _start_update(self, service_info: BluetoothServiceInfo) -> None: """Update from BLE advertisement data.""" _LOGGER.debug("Parsing thermobeacon BLE advertisement data: %s", service_info) - lower_name = service_info.name.lower() - if SERVICE_DATA_UUID not in service_info.service_data: + if SERVICE_UUID not in service_info.service_uuids: return - unpadded_data = service_info.service_data[SERVICE_DATA_UUID] - data = b"\x00\x00\x00\x00" + unpadded_data - device_id = data[5] - if not (device := DEVICE_TYPES.get(device_id)): - _LOGGER.debug("Device type %s is not supported", device_id) + if not MFR_IDS.intersection(service_info.manufacturer_data): return - if device.name: - name = device.name - elif lower_name.startswith("thermobeacon "): - name = service_info.name[9:] - else: - name = service_info.name - self.set_device_type(device.model) + changed_manufacturer_data = self.changed_manufacturer_data(service_info) + if changed_manufacturer_data is None: + return + last_id = list(changed_manufacturer_data)[-1] + data = ( + int(last_id).to_bytes(2, byteorder="little") + + changed_manufacturer_data[last_id] + ) + msg_length = len(data) + if msg_length not in (20, 22): + return + device_id = data[0] + device_type = DEVICE_TYPES[device_id] + name = device_type.name + self.set_device_type(device_id) self.set_title(f"{name} {short_address(service_info.address)}") self.set_device_name(f"{name} {short_address(service_info.address)}") self.set_device_manufacturer("ThermoBeacon") @@ -73,72 +69,30 @@ def _start_update(self, service_info: BluetoothServiceInfo) -> None: def _process_update(self, data: bytes) -> None: """Update from BLE advertisement data.""" _LOGGER.debug("Parsing ThermoBeacon BLE advertisement data: %s", data) - msg_length = len(data) - if msg_length < 12: + if len(data) != 22: return - xdata_point = 14 - while xdata_point < msg_length: - xdata_id = data[xdata_point - 2] - xdata_size = data[xdata_point - 1] - if xdata_point + xdata_size <= msg_length: - self._process_xdata( - xdata_id, - xdata_size, - data[xdata_point : xdata_point + xdata_size], # noqa: E203 - ) - xdata_point += xdata_size + 2 - - def _process_xdata(self, xdata_id: int, xdata_size: int, xdata: bytes) -> None: - if xdata_id == 0x01 and xdata_size == 4: - (temp, humi) = unpack("= 3000: + batt = 100 + elif volt >= 2600: + batt = 60 + (volt - 2600) * 0.1 + elif volt >= 2500: + batt = 40 + (volt - 2500) * 0.2 + elif volt >= 2450: + batt = 20 + (volt - 2450) * 0.4 else: - _LOGGER.debug( - "Unknown data received from ThermoBeacon device: %s", - xdata.hex(), - ) + batt = 0 + + self.update_predefined_sensor(SensorLibrary.BATTERY__PERCENTAGE, batt) + self.update_predefined_sensor(SensorLibrary.TEMPERATURE__CELSIUS, temp / 16) + self.update_predefined_sensor(SensorLibrary.HUMIDITY__PERCENTAGE, humi / 16) + self.update_predefined_sensor( + SensorLibrary.VOLTAGE__ELECTRIC_POTENTIAL_VOLT, volt / 1000 + ) + self.update_predefined_binary_sensor( + BinarySensorDeviceClass.OCCUPANCY, bool(button_pushed) + ) diff --git a/tests/test_parser.py b/tests/test_parser.py index 0ad33cc..2c26276 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1,4 +1,3 @@ -import pytest from bluetooth_sensor_state_data import BluetoothServiceInfo, SensorUpdate from sensor_state_data import ( BinarySensorDescription, @@ -19,373 +18,67 @@ def test_can_create(): ThermoBeaconBluetoothDeviceData() -LIGHT_AND_MOTION = BluetoothServiceInfo( - name="ThermoBeacon Motion & Light", - manufacturer_data={}, - service_uuids=[], +MFR_20 = BluetoothServiceInfo( + name="ThermoBeacon", address="aa:bb:cc:dd:ee:ff", rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"H\x12" - b"\xcd\xd5`4-X\x08\x04\x00\r\x00\x00\x0f\x01\xee" + service_data={}, + manufacturer_data={ + 16: b"\x00\x00\xb0\x02\x00\x00G\xa4\xe2\x0c\x80\x01\xb6\x02J\x00\x00\x00" }, + service_uuids=["0000fff0-0000-1000-8000-00805f9b34fb"], source="local", ) -MOTION_AND_LIGHT_ENSURE_SUPPORTED = BluetoothServiceInfo( - name="ThermoBeacon Motion & Light", - manufacturer_data={}, - service_uuids=[], +MFR_22 = BluetoothServiceInfo( + name="ThermoBeacon", address="aa:bb:cc:dd:ee:ff", rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"H\x12\xcd\xd5`4-X\x08\x04\x01\xe8\x00\x00\x0f\x01{" + service_data={}, + manufacturer_data={ + 21: b"\x00\x00\xf0\x05\x00\x00\xd7n\xbe\x01e\x00\x00\x00\xa7\x01\x00\x00\x00\x00" }, + service_uuids=["0000fff0-0000-1000-8000-00805f9b34fb"], source="local", ) -ALARM_CLOCK = BluetoothServiceInfo( - name="ThermoBeacon Alarm Clock", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"\x08\x0c" - b"4MV4-X\x01\x04 \x01\xb2\x01\x02\x01d" - }, - source="local", -) - - -AIR_MONITOR = BluetoothServiceInfo( - name="ThermoBeacon Air Monitor Lite", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"\x88\x0e\xd6\x88\x8f\xe6" - b"HT\x01\x04\x03\x01\x16" - b"\x02\x12\x04\x02\x00\x02\x00\x13\x02%\x02" - }, - source="local", -) - - -CLOCK_LITE = BluetoothServiceInfo( - name="ThermoBeacon BT Clock Lite", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"\x08\x1e\xf3&T4-X\x01\x046\x01\xcc\x01\x02\x01d" - }, - source="local", -) - -NO_VALID_DATA = BluetoothServiceInfo( - name="ThermoBeacon Motion & Light", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - # No valid data yet - "0000fdcd-0000-1000-8000-00805f9b34fb": b"0X\x83\n\x02\xcd\xd5`4-X\x08" - }, - source="local", -) - - -LEES_GUITARS = BluetoothServiceInfo( - name="Lee Guitars Thermo-Hygrometer", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"\x8a\x0f\xd1,c4-X\x01\x04\x00\x01\x12\x02\x02\x01(" - }, - source="local", -) - - -LEES_GUITARS_PASSIVE = BluetoothServiceInfo( - name="", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"\x8a\x0f\xd1,c4-X\x01\x04\x00\x01\x12\x02\x02\x01(" - }, - source="local", -) - -LEES_GUITARS_PASSIVE_ADDR = BluetoothServiceInfo( - name="aa:bb:cc:dd:ee:ff", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"\x8a\x0f\xd1,c4-X\x01\x04\x00\x01\x12\x02\x02\x01(" - }, - source="local", -) - - -QINGPING_DOOR_WINDOW = BluetoothServiceInfo( - name="ThermoBeacon Door/Window Sensor", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"\xc8\x04M:@4-X\x04\x01\x01\x0f\x01\xef" - }, - source="local", -) - - -QINGPING_TEMP_RH_M = BluetoothServiceInfo( - name="ThermoBeacon Temp RH M", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"\x08\x16\xa7%\x144-X\x01\x04\xd8\x00\xbb\x01\x02\x01d" - }, - source="local", -) - - -def test_supported_motion_and_light(): +def test_with_20_byte_update(): parser = ThermoBeaconBluetoothDeviceData() - parser.supported(MOTION_AND_LIGHT_ENSURE_SUPPORTED) is True - assert parser.title == "Motion & Light " "EEFF" + parser.supported(MFR_20) is True + assert parser.title == "Lanyard/mini hygrometer EEFF" def test_supported_set_the_title(): parser = ThermoBeaconBluetoothDeviceData() - parser.supported(NO_VALID_DATA) is False - parser.supported(LIGHT_AND_MOTION) is True - assert parser.title == "Motion & Light " "EEFF" - - -def test_motion_and_light_signal_only(): - parser = ThermoBeaconBluetoothDeviceData() - assert parser.update(LIGHT_AND_MOTION) == SensorUpdate( - title="Motion & Light EEFF", - devices={ - None: SensorDeviceInfo( - name="Motion & Light " "EEFF", - model="CGPR1", - manufacturer="ThermoBeacon", - sw_version=None, - hw_version=None, - ) - }, - entity_descriptions={ - DeviceKey(key="illuminance", device_id=None): SensorDescription( - device_key=DeviceKey(key="illuminance", device_id=None), - device_class=SensorDeviceClass.ILLUMINANCE, - native_unit_of_measurement=Units.LIGHT_LUX, - ), - DeviceKey(key="signal_strength", device_id=None): SensorDescription( - device_key=DeviceKey(key="signal_strength", device_id=None), - device_class=SensorDeviceClass.SIGNAL_STRENGTH, - native_unit_of_measurement=Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - ), - }, - entity_values={ - DeviceKey(key="illuminance", device_id=None): SensorValue( - device_key=DeviceKey(key="illuminance", device_id=None), - name="Illuminance", - native_value=13, - ), - DeviceKey(key="signal_strength", device_id=None): SensorValue( - device_key=DeviceKey(key="signal_strength", device_id=None), - name="Signal " "Strength", - native_value=-60, - ), - }, - binary_entity_descriptions={ - DeviceKey(key="motion", device_id=None): BinarySensorDescription( - device_key=DeviceKey(key="motion", device_id=None), - device_class=BinarySensorDeviceClass.MOTION, - ) - }, - binary_entity_values={ - DeviceKey(key="motion", device_id=None): BinarySensorValue( - device_key=DeviceKey(key="motion", device_id=None), - name="Motion", - native_value=False, - ) - }, - ) - - -def test_motion_and_light_battery_update(): - parser = ThermoBeaconBluetoothDeviceData() - service_info = BluetoothServiceInfo( - name="ThermoBeacon Motion & Light", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"\x08\x12" - b"\xcd\xd5`4-X\x02\x01d\x0f\x01\x98\t\x04<\x01\x00\x00" - }, - source="local", - ) - result = parser.update(service_info) - assert result == SensorUpdate( - title="Motion & Light EEFF", - devices={ - None: SensorDeviceInfo( - name="Motion & Light " "EEFF", - model="CGPR1", - manufacturer="ThermoBeacon", - sw_version=None, - hw_version=None, - ) - }, - entity_descriptions={ - DeviceKey(key="battery", device_id=None): SensorDescription( - device_key=DeviceKey(key="battery", device_id=None), - device_class=SensorDeviceClass.BATTERY, - native_unit_of_measurement=Units.PERCENTAGE, - ), - DeviceKey(key="illuminance", device_id=None): SensorDescription( - device_key=DeviceKey(key="illuminance", device_id=None), - device_class=SensorDeviceClass.ILLUMINANCE, - native_unit_of_measurement=Units.LIGHT_LUX, - ), - DeviceKey(key="signal_strength", device_id=None): SensorDescription( - device_key=DeviceKey(key="signal_strength", device_id=None), - device_class=SensorDeviceClass.SIGNAL_STRENGTH, - native_unit_of_measurement=Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - ), - }, - entity_values={ - DeviceKey(key="battery", device_id=None): SensorValue( - device_key=DeviceKey(key="battery", device_id=None), - name="Battery", - native_value=100, - ), - DeviceKey(key="illuminance", device_id=None): SensorValue( - device_key=DeviceKey(key="illuminance", device_id=None), - name="Illuminance", - native_value=316, - ), - DeviceKey(key="signal_strength", device_id=None): SensorValue( - device_key=DeviceKey(key="signal_strength", device_id=None), - name="Signal " "Strength", - native_value=-60, - ), - }, - binary_entity_descriptions={}, - binary_entity_values={}, - ) - - -def test_has_motion(): - parser = ThermoBeaconBluetoothDeviceData() - service_info = BluetoothServiceInfo( - name="ThermoBeacon Motion & Light", - manufacturer_data={}, - service_uuids=[], - address="aa:bb:cc:dd:ee:ff", - rssi=-60, - service_data={ - "0000fdcd-0000-1000-8000-00805f9b34fb": b"H\x12" - b"\xcd\xd5`4-X\x08\x04\x01-\x01\x00\x0f\x01\xb7" - }, - source="local", - ) - result = parser.update(service_info) - assert result == SensorUpdate( - title="Motion & Light EEFF", - devices={ - None: SensorDeviceInfo( - name="Motion & Light " "EEFF", - model="CGPR1", - manufacturer="ThermoBeacon", - sw_version=None, - hw_version=None, - ) - }, - entity_descriptions={ - DeviceKey(key="signal_strength", device_id=None): SensorDescription( - device_key=DeviceKey(key="signal_strength", device_id=None), - device_class=SensorDeviceClass.SIGNAL_STRENGTH, - native_unit_of_measurement=Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - ), - DeviceKey(key="illuminance", device_id=None): SensorDescription( - device_key=DeviceKey(key="illuminance", device_id=None), - device_class=SensorDeviceClass.ILLUMINANCE, - native_unit_of_measurement=Units.LIGHT_LUX, - ), - }, - entity_values={ - DeviceKey(key="signal_strength", device_id=None): SensorValue( - device_key=DeviceKey(key="signal_strength", device_id=None), - name="Signal " "Strength", - native_value=-60, - ), - DeviceKey(key="illuminance", device_id=None): SensorValue( - device_key=DeviceKey(key="illuminance", device_id=None), - name="Illuminance", - native_value=301, - ), - }, - binary_entity_descriptions={ - DeviceKey(key="motion", device_id=None): BinarySensorDescription( - device_key=DeviceKey(key="motion", device_id=None), - device_class=BinarySensorDeviceClass.MOTION, - ) - }, - binary_entity_values={ - DeviceKey(key="motion", device_id=None): BinarySensorValue( - device_key=DeviceKey(key="motion", device_id=None), - name="Motion", - native_value=True, - ) - }, - ) + parser.supported(MFR_22) is True + assert parser.title == "Smart hygrometer EEFF" -def test_alarm_clock(): +def test_22_byte_update(): parser = ThermoBeaconBluetoothDeviceData() - parsed = parser.update(ALARM_CLOCK) - assert parsed == SensorUpdate( - title="Alarm Clock EEFF", + assert parser.update(MFR_22) == SensorUpdate( + title="Smart hygrometer EEFF", devices={ None: SensorDeviceInfo( - name="Alarm Clock EEFF", - model="CGD1", + name="Smart hygrometer EEFF", + model=21, manufacturer="ThermoBeacon", sw_version=None, hw_version=None, ) }, entity_descriptions={ - DeviceKey(key="signal_strength", device_id=None): SensorDescription( - device_key=DeviceKey(key="signal_strength", device_id=None), - device_class=SensorDeviceClass.SIGNAL_STRENGTH, - native_unit_of_measurement=Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - ), DeviceKey(key="humidity", device_id=None): SensorDescription( device_key=DeviceKey(key="humidity", device_id=None), device_class=SensorDeviceClass.HUMIDITY, native_unit_of_measurement=Units.PERCENTAGE, ), + DeviceKey(key="voltage", device_id=None): SensorDescription( + device_key=DeviceKey(key="voltage", device_id=None), + device_class=SensorDeviceClass.VOLTAGE, + native_unit_of_measurement=Units.ELECTRIC_POTENTIAL_VOLT, + ), DeviceKey(key="temperature", device_id=None): SensorDescription( device_key=DeviceKey(key="temperature", device_id=None), device_class=SensorDeviceClass.TEMPERATURE, @@ -396,74 +89,6 @@ def test_alarm_clock(): device_class=SensorDeviceClass.BATTERY, native_unit_of_measurement=Units.PERCENTAGE, ), - }, - entity_values={ - DeviceKey(key="signal_strength", device_id=None): SensorValue( - device_key=DeviceKey(key="signal_strength", device_id=None), - name="Signal " "Strength", - native_value=-60, - ), - DeviceKey(key="humidity", device_id=None): SensorValue( - device_key=DeviceKey(key="humidity", device_id=None), - name="Humidity", - native_value=43.4, - ), - DeviceKey(key="temperature", device_id=None): SensorValue( - device_key=DeviceKey(key="temperature", device_id=None), - name="Temperature", - native_value=28.8, - ), - DeviceKey(key="battery", device_id=None): SensorValue( - device_key=DeviceKey(key="battery", device_id=None), - name="Battery", - native_value=100, - ), - }, - binary_entity_descriptions={}, - binary_entity_values={}, - ) - - -def test_air_monitor(): - parser = ThermoBeaconBluetoothDeviceData() - parsed = parser.update(AIR_MONITOR) - assert parsed == SensorUpdate( - title="Air Monitor Lite EEFF", - devices={ - None: SensorDeviceInfo( - name="Air Monitor Lite EEFF", - model="CGDN1", - manufacturer="ThermoBeacon", - sw_version=None, - hw_version=None, - ) - }, - entity_descriptions={ - DeviceKey(key="pm25", device_id=None): SensorDescription( - device_key=DeviceKey(key="pm25", device_id=None), - device_class=SensorDeviceClass.PM25, - native_unit_of_measurement=Units.CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - ), - DeviceKey(key="temperature", device_id=None): SensorDescription( - device_key=DeviceKey(key="temperature", device_id=None), - device_class=SensorDeviceClass.TEMPERATURE, - native_unit_of_measurement=Units.TEMP_CELSIUS, - ), - DeviceKey(key="humidity", device_id=None): SensorDescription( - device_key=DeviceKey(key="humidity", device_id=None), - device_class=SensorDeviceClass.HUMIDITY, - native_unit_of_measurement=Units.PERCENTAGE, - ), - DeviceKey(key="carbon_dioxide", device_id=None): SensorDescription( - device_key=DeviceKey(key="carbon_dioxide", device_id=None), - device_class=SensorDeviceClass.CO2, - native_unit_of_measurement=Units.CONCENTRATION_PARTS_PER_MILLION, - ), - DeviceKey(key="pm10", device_id=None): SensorDescription( - device_key=DeviceKey(key="pm10", device_id=None), - device_class=SensorDeviceClass.PM10, - native_unit_of_measurement=Units.CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - ), DeviceKey(key="signal_strength", device_id=None): SensorDescription( device_key=DeviceKey(key="signal_strength", device_id=None), device_class=SensorDeviceClass.SIGNAL_STRENGTH, @@ -471,273 +96,43 @@ def test_air_monitor(): ), }, entity_values={ - DeviceKey(key="pm25", device_id=None): SensorValue( - device_key=DeviceKey(key="pm25", device_id=None), - name="Pm25", - native_value=2, - ), - DeviceKey(key="temperature", device_id=None): SensorValue( - device_key=DeviceKey(key="temperature", device_id=None), - name="Temperature", - native_value=25.9, - ), DeviceKey(key="humidity", device_id=None): SensorValue( device_key=DeviceKey(key="humidity", device_id=None), name="Humidity", - native_value=53.4, - ), - DeviceKey(key="carbon_dioxide", device_id=None): SensorValue( - device_key=DeviceKey(key="carbon_dioxide", device_id=None), - name="Carbon " "Dioxide", - native_value=549, - ), - DeviceKey(key="pm10", device_id=None): SensorValue( - device_key=DeviceKey(key="pm10", device_id=None), - name="Pm10", - native_value=2, - ), - DeviceKey(key="signal_strength", device_id=None): SensorValue( - device_key=DeviceKey(key="signal_strength", device_id=None), - name="Signal " "Strength", - native_value=-60, - ), - }, - binary_entity_descriptions={}, - binary_entity_values={}, - ) - - -def test_clock_lite(): - parser = ThermoBeaconBluetoothDeviceData() - parsed = parser.update(CLOCK_LITE) - assert parsed == SensorUpdate( - title="BT Clock Lite EEFF", - devices={ - None: SensorDeviceInfo( - name="BT Clock Lite EEFF", - model="CGC1", - manufacturer="ThermoBeacon", - sw_version=None, - hw_version=None, - ) - }, - entity_descriptions={ - DeviceKey(key="temperature", device_id=None): SensorDescription( - device_key=DeviceKey(key="temperature", device_id=None), - device_class=SensorDeviceClass.TEMPERATURE, - native_unit_of_measurement=Units.TEMP_CELSIUS, - ), - DeviceKey(key="battery", device_id=None): SensorDescription( - device_key=DeviceKey(key="battery", device_id=None), - device_class=SensorDeviceClass.BATTERY, - native_unit_of_measurement=Units.PERCENTAGE, + native_value=26.4375, ), - DeviceKey(key="signal_strength", device_id=None): SensorDescription( - device_key=DeviceKey(key="signal_strength", device_id=None), - device_class=SensorDeviceClass.SIGNAL_STRENGTH, - native_unit_of_measurement=Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - ), - DeviceKey(key="humidity", device_id=None): SensorDescription( - device_key=DeviceKey(key="humidity", device_id=None), - device_class=SensorDeviceClass.HUMIDITY, - native_unit_of_measurement=Units.PERCENTAGE, + DeviceKey(key="voltage", device_id=None): SensorValue( + device_key=DeviceKey(key="voltage", device_id=None), + name="Voltage", + native_value=0.101, ), - }, - entity_values={ DeviceKey(key="temperature", device_id=None): SensorValue( device_key=DeviceKey(key="temperature", device_id=None), name="Temperature", - native_value=31.0, + native_value=0.0, ), DeviceKey(key="battery", device_id=None): SensorValue( device_key=DeviceKey(key="battery", device_id=None), name="Battery", - native_value=100, + native_value=0, ), DeviceKey(key="signal_strength", device_id=None): SensorValue( device_key=DeviceKey(key="signal_strength", device_id=None), name="Signal " "Strength", native_value=-60, ), - DeviceKey(key="humidity", device_id=None): SensorValue( - device_key=DeviceKey(key="humidity", device_id=None), - name="Humidity", - native_value=46.0, - ), - }, - binary_entity_descriptions={}, - binary_entity_values={}, - ) - - -@pytest.mark.parametrize( - "adv", [LEES_GUITARS_PASSIVE, LEES_GUITARS, LEES_GUITARS_PASSIVE_ADDR] -) -def test_lees_gutairs(adv): - parser = ThermoBeaconBluetoothDeviceData() - parsed = parser.update(adv) - assert parsed == SensorUpdate( - title="Lee Guitars Thermo-Hygrometer EEFF", - devices={ - None: SensorDeviceInfo( - name="Lee Guitars " "Thermo-Hygrometer EEFF", - model="CGM1", - manufacturer="ThermoBeacon", - sw_version=None, - hw_version=None, - ) - }, - entity_descriptions={ - DeviceKey(key="signal_strength", device_id=None): SensorDescription( - device_key=DeviceKey(key="signal_strength", device_id=None), - device_class=SensorDeviceClass.SIGNAL_STRENGTH, - native_unit_of_measurement=Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - ), - DeviceKey(key="battery", device_id=None): SensorDescription( - device_key=DeviceKey(key="battery", device_id=None), - device_class=SensorDeviceClass.BATTERY, - native_unit_of_measurement=Units.PERCENTAGE, - ), - DeviceKey(key="temperature", device_id=None): SensorDescription( - device_key=DeviceKey(key="temperature", device_id=None), - device_class=SensorDeviceClass.TEMPERATURE, - native_unit_of_measurement=Units.TEMP_CELSIUS, - ), - DeviceKey(key="humidity", device_id=None): SensorDescription( - device_key=DeviceKey(key="humidity", device_id=None), - device_class=SensorDeviceClass.HUMIDITY, - native_unit_of_measurement=Units.PERCENTAGE, - ), - }, - entity_values={ - DeviceKey(key="signal_strength", device_id=None): SensorValue( - device_key=DeviceKey(key="signal_strength", device_id=None), - name="Signal " "Strength", - native_value=-60, - ), - DeviceKey(key="battery", device_id=None): SensorValue( - device_key=DeviceKey(key="battery", device_id=None), - name="Battery", - native_value=40, - ), - DeviceKey(key="temperature", device_id=None): SensorValue( - device_key=DeviceKey(key="temperature", device_id=None), - name="Temperature", - native_value=25.6, - ), - DeviceKey(key="humidity", device_id=None): SensorValue( - device_key=DeviceKey(key="humidity", device_id=None), - name="Humidity", - native_value=53.0, - ), - }, - binary_entity_descriptions={}, - binary_entity_values={}, - ) - - -def test_door_window(): - parser = ThermoBeaconBluetoothDeviceData() - parsed = parser.update(QINGPING_DOOR_WINDOW) - assert parsed == SensorUpdate( - title="Door/Window Sensor EEFF", - devices={ - None: SensorDeviceInfo( - name="Door/Window Sensor EEFF", - model="CGH1", - manufacturer="ThermoBeacon", - sw_version=None, - hw_version=None, - ) - }, - entity_descriptions={ - DeviceKey(key="signal_strength", device_id=None): SensorDescription( - device_key=DeviceKey(key="signal_strength", device_id=None), - device_class=SensorDeviceClass.SIGNAL_STRENGTH, - native_unit_of_measurement=Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - ) - }, - entity_values={ - DeviceKey(key="signal_strength", device_id=None): SensorValue( - device_key=DeviceKey(key="signal_strength", device_id=None), - name="Signal " "Strength", - native_value=-60, - ) }, binary_entity_descriptions={ - DeviceKey(key="door", device_id=None): BinarySensorDescription( - device_key=DeviceKey(key="door", device_id=None), - device_class=BinarySensorDeviceClass.DOOR, + DeviceKey(key="occupancy", device_id=None): BinarySensorDescription( + device_key=DeviceKey(key="occupancy", device_id=None), + device_class=BinarySensorDeviceClass.OCCUPANCY, ) }, binary_entity_values={ - DeviceKey(key="door", device_id=None): BinarySensorValue( - device_key=DeviceKey(key="door", device_id=None), - name="Door", + DeviceKey(key="occupancy", device_id=None): BinarySensorValue( + device_key=DeviceKey(key="occupancy", device_id=None), + name="Occupancy", native_value=False, ) }, ) - - -def test_temp_rh_m(): - parser = ThermoBeaconBluetoothDeviceData() - parsed = parser.update(QINGPING_TEMP_RH_M) - assert parsed == SensorUpdate( - title="ThermoBeacon Temp RH M EEFF", - devices={ - None: SensorDeviceInfo( - name="ThermoBeacon Temp RH M EEFF", - model="CGG1", - manufacturer="ThermoBeacon", - sw_version=None, - hw_version=None, - ) - }, - entity_descriptions={ - DeviceKey(key="temperature", device_id=None): SensorDescription( - device_key=DeviceKey(key="temperature", device_id=None), - device_class=SensorDeviceClass.TEMPERATURE, - native_unit_of_measurement=Units.TEMP_CELSIUS, - ), - DeviceKey(key="humidity", device_id=None): SensorDescription( - device_key=DeviceKey(key="humidity", device_id=None), - device_class=SensorDeviceClass.HUMIDITY, - native_unit_of_measurement=Units.PERCENTAGE, - ), - DeviceKey(key="battery", device_id=None): SensorDescription( - device_key=DeviceKey(key="battery", device_id=None), - device_class=SensorDeviceClass.BATTERY, - native_unit_of_measurement=Units.PERCENTAGE, - ), - DeviceKey(key="signal_strength", device_id=None): SensorDescription( - device_key=DeviceKey(key="signal_strength", device_id=None), - device_class=SensorDeviceClass.SIGNAL_STRENGTH, - native_unit_of_measurement=Units.SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - ), - }, - entity_values={ - DeviceKey(key="temperature", device_id=None): SensorValue( - device_key=DeviceKey(key="temperature", device_id=None), - name="Temperature", - native_value=21.6, - ), - DeviceKey(key="humidity", device_id=None): SensorValue( - device_key=DeviceKey(key="humidity", device_id=None), - name="Humidity", - native_value=44.3, - ), - DeviceKey(key="battery", device_id=None): SensorValue( - device_key=DeviceKey(key="battery", device_id=None), - name="Battery", - native_value=100, - ), - DeviceKey(key="signal_strength", device_id=None): SensorValue( - device_key=DeviceKey(key="signal_strength", device_id=None), - name="Signal " "Strength", - native_value=-60, - ), - }, - binary_entity_descriptions={}, - binary_entity_values={}, - )