diff --git a/homeassistant/components/govee_ble/binary_sensor.py b/homeassistant/components/govee_ble/binary_sensor.py index 82033300797..e5966124216 100644 --- a/homeassistant/components/govee_ble/binary_sensor.py +++ b/homeassistant/components/govee_ble/binary_sensor.py @@ -31,6 +31,14 @@ BINARY_SENSOR_DESCRIPTIONS = { key=GoveeBLEBinarySensorDeviceClass.WINDOW, device_class=BinarySensorDeviceClass.WINDOW, ), + GoveeBLEBinarySensorDeviceClass.MOTION: BinarySensorEntityDescription( + key=GoveeBLEBinarySensorDeviceClass.MOTION, + device_class=BinarySensorDeviceClass.MOTION, + ), + GoveeBLEBinarySensorDeviceClass.OCCUPANCY: BinarySensorEntityDescription( + key=GoveeBLEBinarySensorDeviceClass.OCCUPANCY, + device_class=BinarySensorDeviceClass.OCCUPANCY, + ), } diff --git a/homeassistant/components/govee_ble/manifest.json b/homeassistant/components/govee_ble/manifest.json index 0e425977211..d9827e9155c 100644 --- a/homeassistant/components/govee_ble/manifest.json +++ b/homeassistant/components/govee_ble/manifest.json @@ -38,6 +38,10 @@ "local_name": "GV5126*", "connectable": false }, + { + "local_name": "GVH5127*", + "connectable": false + }, { "manufacturer_id": 1, "service_uuid": "0000ec88-0000-1000-8000-00805f9b34fb", @@ -111,6 +115,11 @@ { "manufacturer_id": 61320, "connectable": false + }, + { + "manufacturer_id": 34819, + "manufacturer_data_start": [236, 0, 0, 1], + "connectable": false } ], "codeowners": ["@bdraco", "@PierreAronnax"], diff --git a/homeassistant/generated/bluetooth.py b/homeassistant/generated/bluetooth.py index 222cf44d989..cda011d1bef 100644 --- a/homeassistant/generated/bluetooth.py +++ b/homeassistant/generated/bluetooth.py @@ -167,6 +167,11 @@ BLUETOOTH: Final[list[dict[str, bool | str | int | list[int]]]] = [ "domain": "govee_ble", "local_name": "GV5126*", }, + { + "connectable": False, + "domain": "govee_ble", + "local_name": "GVH5127*", + }, { "connectable": False, "domain": "govee_ble", @@ -256,6 +261,17 @@ BLUETOOTH: Final[list[dict[str, bool | str | int | list[int]]]] = [ "domain": "govee_ble", "manufacturer_id": 61320, }, + { + "connectable": False, + "domain": "govee_ble", + "manufacturer_data_start": [ + 236, + 0, + 0, + 1, + ], + "manufacturer_id": 34819, + }, { "domain": "homekit_controller", "manufacturer_data_start": [ diff --git a/tests/components/govee_ble/__init__.py b/tests/components/govee_ble/__init__.py index 838abb3d19c..66c5b0b832c 100644 --- a/tests/components/govee_ble/__init__.py +++ b/tests/components/govee_ble/__init__.py @@ -187,3 +187,32 @@ GVH5124_2_SERVICE_INFO = BluetoothServiceInfo( service_uuids=[], source="local", ) + + +GVH5127_MOTION_SERVICE_INFO = BluetoothServiceInfo( + name="GVH51275E3F", + address="D0:C9:07:1B:5E:3F", + rssi=-61, + manufacturer_data={34819: b"\xec\x00\x01\x01\x01\x11"}, + service_data={}, + service_uuids=[], + source="Core Bluetooth", +) +GVH5127_PRESENT_SERVICE_INFO = BluetoothServiceInfo( + name="GVH51275E3F", + address="D0:C9:07:1B:5E:3F", + rssi=-60, + manufacturer_data={34819: b"\xec\x00\x01\x01\x01\x01"}, + service_data={}, + service_uuids=[], + source="Core Bluetooth", +) +GVH5127_ABSENT_SERVICE_INFO = BluetoothServiceInfo( + name="GVH51275E3F", + address="D0:C9:07:1B:5E:3F", + rssi=-53, + manufacturer_data={34819: b"\xec\x00\x01\x01\x00\x00"}, + service_data={}, + service_uuids=[], + source="Core Bluetooth", +) diff --git a/tests/components/govee_ble/test_binary_sensor.py b/tests/components/govee_ble/test_binary_sensor.py index a0acf4c461e..cf8b54ef54f 100644 --- a/tests/components/govee_ble/test_binary_sensor.py +++ b/tests/components/govee_ble/test_binary_sensor.py @@ -4,7 +4,13 @@ from homeassistant.components.govee_ble.const import CONF_DEVICE_TYPE, DOMAIN from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.core import HomeAssistant -from . import GV5123_CLOSED_SERVICE_INFO, GV5123_OPEN_SERVICE_INFO +from . import ( + GV5123_CLOSED_SERVICE_INFO, + GV5123_OPEN_SERVICE_INFO, + GVH5127_ABSENT_SERVICE_INFO, + GVH5127_MOTION_SERVICE_INFO, + GVH5127_PRESENT_SERVICE_INFO, +) from tests.common import MockConfigEntry from tests.components.bluetooth import inject_bluetooth_service_info @@ -37,3 +43,42 @@ async def test_window_sensor(hass: HomeAssistant) -> None: assert motion_sensor.state == STATE_OFF assert await hass.config_entries.async_unload(entry.entry_id) await hass.async_block_till_done() + + +async def test_presence_sensor(hass: HomeAssistant) -> None: + """Test the presence sensor.""" + entry = MockConfigEntry( + domain=DOMAIN, + unique_id=GVH5127_ABSENT_SERVICE_INFO.address, + data={CONF_DEVICE_TYPE: "H5127"}, + ) + 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, GVH5127_ABSENT_SERVICE_INFO) + await hass.async_block_till_done() + assert len(hass.states.async_all()) == 2 + + motion_sensor = hass.states.get("binary_sensor.h51275e3f_motion") + assert motion_sensor.state == STATE_OFF + occupancy_sensor = hass.states.get("binary_sensor.h51275e3f_occupancy") + assert occupancy_sensor.state == STATE_OFF + + inject_bluetooth_service_info(hass, GVH5127_PRESENT_SERVICE_INFO) + await hass.async_block_till_done() + + motion_sensor = hass.states.get("binary_sensor.h51275e3f_motion") + assert motion_sensor.state == STATE_OFF + occupancy_sensor = hass.states.get("binary_sensor.h51275e3f_occupancy") + assert occupancy_sensor.state == STATE_ON + + inject_bluetooth_service_info(hass, GVH5127_MOTION_SERVICE_INFO) + await hass.async_block_till_done() + + motion_sensor = hass.states.get("binary_sensor.h51275e3f_motion") + assert motion_sensor.state == STATE_ON + occupancy_sensor = hass.states.get("binary_sensor.h51275e3f_occupancy") + assert occupancy_sensor.state == STATE_ON