From 7ef145d4cede595d48d96835eed4d00c00ddbd3b Mon Sep 17 00:00:00 2001 From: PierreAronnax Date: Tue, 27 Dec 2022 21:11:41 +0100 Subject: [PATCH] Return unavailable if Govee BLE sensor is in error (#84547) Co-authored-by: J. Nick Koston --- CODEOWNERS | 4 +-- .../components/govee_ble/manifest.json | 4 +-- homeassistant/components/govee_ble/sensor.py | 13 ++++++-- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/govee_ble/__init__.py | 13 ++++++++ tests/components/govee_ble/test_sensor.py | 33 +++++++++++++++++-- 7 files changed, 60 insertions(+), 11 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 398201ff637..e86433d2db0 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -437,8 +437,8 @@ build.json @home-assistant/supervisor /tests/components/google_sheets/ @tkdrob /homeassistant/components/google_travel_time/ @eifinger /tests/components/google_travel_time/ @eifinger -/homeassistant/components/govee_ble/ @bdraco -/tests/components/govee_ble/ @bdraco +/homeassistant/components/govee_ble/ @bdraco @PierreAronnax +/tests/components/govee_ble/ @bdraco @PierreAronnax /homeassistant/components/gpsd/ @fabaff /homeassistant/components/gree/ @cmroche /tests/components/gree/ @cmroche diff --git a/homeassistant/components/govee_ble/manifest.json b/homeassistant/components/govee_ble/manifest.json index 8272ab5d20e..ad54aa4bc43 100644 --- a/homeassistant/components/govee_ble/manifest.json +++ b/homeassistant/components/govee_ble/manifest.json @@ -73,8 +73,8 @@ "connectable": false } ], - "requirements": ["govee-ble==0.19.3"], + "requirements": ["govee-ble==0.21.0"], "dependencies": ["bluetooth"], - "codeowners": ["@bdraco"], + "codeowners": ["@bdraco", "@PierreAronnax"], "iot_class": "local_push" } diff --git a/homeassistant/components/govee_ble/sensor.py b/homeassistant/components/govee_ble/sensor.py index 6014585ffe6..ce603b5b5a6 100644 --- a/homeassistant/components/govee_ble/sensor.py +++ b/homeassistant/components/govee_ble/sensor.py @@ -4,6 +4,7 @@ from __future__ import annotations from typing import Optional, Union from govee_ble import DeviceClass, DeviceKey, SensorUpdate, Units +from govee_ble.parser import ERROR from homeassistant import config_entries from homeassistant.components.bluetooth.passive_update_processor import ( @@ -116,13 +117,21 @@ async def async_setup_entry( class GoveeBluetoothSensorEntity( PassiveBluetoothProcessorEntity[ - PassiveBluetoothDataProcessor[Optional[Union[float, int]]] + PassiveBluetoothDataProcessor[Optional[Union[float, int, str]]] ], SensorEntity, ): """Representation of a govee ble sensor.""" @property - def native_value(self) -> int | float | None: + def available(self) -> bool: + """Return False if sensor is in error.""" + return ( + self.processor.entity_data.get(self.entity_key) != ERROR + and super().available + ) + + @property + def native_value(self) -> float | int | str | None: """Return the native value.""" return self.processor.entity_data.get(self.entity_key) diff --git a/requirements_all.txt b/requirements_all.txt index 4bd953723ab..fb9cf6bda3c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -803,7 +803,7 @@ googlemaps==2.5.1 goslide-api==0.5.1 # homeassistant.components.govee_ble -govee-ble==0.19.3 +govee-ble==0.21.0 # homeassistant.components.remote_rpi_gpio gpiozero==1.6.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 1196a52e511..60a84f0353e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -607,7 +607,7 @@ google-nest-sdm==2.1.0 googlemaps==2.5.1 # homeassistant.components.govee_ble -govee-ble==0.19.3 +govee-ble==0.21.0 # homeassistant.components.gree greeclimate==1.3.0 diff --git a/tests/components/govee_ble/__init__.py b/tests/components/govee_ble/__init__.py index c440317fa43..54e7c1ee777 100644 --- a/tests/components/govee_ble/__init__.py +++ b/tests/components/govee_ble/__init__.py @@ -36,3 +36,16 @@ GVH5177_SERVICE_INFO = BluetoothServiceInfo( service_data={}, source="local", ) + +GVH5178_SERVICE_INFO_ERROR = BluetoothServiceInfo( + name="B51782BC8", + address="A4:C1:38:75:2B:C8", + rssi=-66, + manufacturer_data={ + 1: b"\x01\x01\x01\x00\x03\xe7\xe4\x00\x01", + 76: b"\x02\x15INTELLI_ROCKS_HWPu\xf2\xff\xc2", + }, + service_data={}, + service_uuids=["0000ec88-0000-1000-8000-00805f9b34fb"], + source="local", +) diff --git a/tests/components/govee_ble/test_sensor.py b/tests/components/govee_ble/test_sensor.py index 0e52d2278c3..b27868c44bf 100644 --- a/tests/components/govee_ble/test_sensor.py +++ b/tests/components/govee_ble/test_sensor.py @@ -3,9 +3,13 @@ from homeassistant.components.govee_ble.const import DOMAIN from homeassistant.components.sensor import ATTR_STATE_CLASS -from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT +from homeassistant.const import ( + ATTR_FRIENDLY_NAME, + ATTR_UNIT_OF_MEASUREMENT, + STATE_UNAVAILABLE, +) -from . import GVH5075_SERVICE_INFO +from . import GVH5075_SERVICE_INFO, GVH5178_SERVICE_INFO_ERROR from tests.common import MockConfigEntry from tests.components.bluetooth import inject_bluetooth_service_info @@ -29,10 +33,33 @@ async def test_sensors(hass): temp_sensor = hass.states.get("sensor.h5075_2762_temperature") temp_sensor_attribtes = temp_sensor.attributes - assert temp_sensor.state == "21.34" + assert temp_sensor.state == "21.3" assert temp_sensor_attribtes[ATTR_FRIENDLY_NAME] == "H5075 2762 Temperature" assert temp_sensor_attribtes[ATTR_UNIT_OF_MEASUREMENT] == "°C" assert temp_sensor_attribtes[ATTR_STATE_CLASS] == "measurement" assert await hass.config_entries.async_unload(entry.entry_id) await hass.async_block_till_done() + + +async def test_gvh5178_error(hass): + """Test H5178 Remote in error marks state as unavailable.""" + entry = MockConfigEntry( + domain=DOMAIN, + unique_id="A4:C1:38:75:2B:C8", + ) + entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + assert len(hass.states.async_all()) == 0 + inject_bluetooth_service_info(hass, GVH5178_SERVICE_INFO_ERROR) + await hass.async_block_till_done() + assert len(hass.states.async_all()) == 4 + + temp_sensor = hass.states.get("sensor.b51782bc8_remote_temperature") + assert temp_sensor.state == STATE_UNAVAILABLE + + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done()