Skip to content

Commit a88eb91

Browse files
committed
Add support for switchbot presence sensor
1 parent d8cbcc1 commit a88eb91

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

homeassistant/components/switchbot/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
SupportedModels.HYGROMETER_CO2.value: [Platform.SENSOR],
4747
SupportedModels.CONTACT.value: [Platform.BINARY_SENSOR, Platform.SENSOR],
4848
SupportedModels.MOTION.value: [Platform.BINARY_SENSOR, Platform.SENSOR],
49+
SupportedModels.PRESENCE_SENSOR.value: [Platform.BINARY_SENSOR, Platform.SENSOR],
4950
SupportedModels.HUMIDIFIER.value: [Platform.HUMIDIFIER, Platform.SENSOR],
5051
SupportedModels.LOCK.value: [
5152
Platform.BINARY_SENSOR,

homeassistant/components/switchbot/const.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class SupportedModels(StrEnum):
2626
CONTACT = "contact"
2727
PLUG = "plug"
2828
MOTION = "motion"
29+
PRESENCE_SENSOR = "presence_sensor"
2930
HUMIDIFIER = "humidifier"
3031
LOCK = "lock"
3132
LOCK_PRO = "lock_pro"
@@ -108,6 +109,7 @@ class SupportedModels(StrEnum):
108109
SwitchbotModel.METER_PRO_C: SupportedModels.HYGROMETER_CO2,
109110
SwitchbotModel.CONTACT_SENSOR: SupportedModels.CONTACT,
110111
SwitchbotModel.MOTION_SENSOR: SupportedModels.MOTION,
112+
SwitchbotModel.PRESENCE_SENSOR: SupportedModels.PRESENCE_SENSOR,
111113
SwitchbotModel.LEAK: SupportedModels.LEAK,
112114
SwitchbotModel.REMOTE: SupportedModels.REMOTE,
113115
SwitchbotModel.HUBMINI_MATTER: SupportedModels.HUBMINI_MATTER,

tests/components/switchbot/__init__.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,3 +1248,28 @@ def make_advertisement(
12481248
connectable=True,
12491249
tx_power=-127,
12501250
)
1251+
1252+
1253+
PRESENCE_SENSOR_SERVICE_INFO = BluetoothServiceInfoBleak(
1254+
name="Presence Sensor",
1255+
manufacturer_data={2409: b"\xb0\xe9\xfe\xb8r\x9c\xbe\xcc\x00\x1a\x00\x82"},
1256+
service_data={
1257+
"0000fd3d-0000-1000-8000-00805f9b34fb": b"\x00 d\x00\x10\xcc\xc8",
1258+
},
1259+
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
1260+
address="AA:BB:CC:DD:EE:FF",
1261+
rssi=-60,
1262+
source="local",
1263+
advertisement=generate_advertisement_data(
1264+
local_name="Presence Sensor",
1265+
manufacturer_data={2409: b"\xb0\xe9\xfe\xb8r\x9c\xbe\xcc\x00\x1a\x00\x82"},
1266+
service_data={
1267+
"0000fd3d-0000-1000-8000-00805f9b34fb": b"\x00 d\x00\x10\xcc\xc8"
1268+
},
1269+
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
1270+
),
1271+
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Presence Sensor"),
1272+
time=0,
1273+
connectable=False,
1274+
tx_power=-127,
1275+
)

tests/components/switchbot/test_sensor.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
HUBMINI_MATTER_SERVICE_INFO,
3232
LEAK_SERVICE_INFO,
3333
PLUG_MINI_EU_SERVICE_INFO,
34+
PRESENCE_SENSOR_SERVICE_INFO,
3435
RELAY_SWITCH_2PM_SERVICE_INFO,
3536
REMOTE_SERVICE_INFO,
3637
WOHAND_SERVICE_INFO,
@@ -793,3 +794,57 @@ async def test_climate_panel_sensor(hass: HomeAssistant) -> None:
793794

794795
assert await hass.config_entries.async_unload(entry.entry_id)
795796
await hass.async_block_till_done()
797+
798+
799+
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
800+
async def test_presence_sensor(hass: HomeAssistant) -> None:
801+
"""Test setting up creates the sensors for Presence Sensor."""
802+
await async_setup_component(hass, DOMAIN, {})
803+
inject_bluetooth_service_info(hass, PRESENCE_SENSOR_SERVICE_INFO)
804+
805+
entry = MockConfigEntry(
806+
domain=DOMAIN,
807+
data={
808+
CONF_ADDRESS: "AA:BB:CC:DD:EE:FF",
809+
CONF_NAME: "test-name",
810+
CONF_SENSOR_TYPE: "presence_sensor",
811+
},
812+
unique_id="aabbccddeeff",
813+
)
814+
entry.add_to_hass(hass)
815+
816+
assert await hass.config_entries.async_setup(entry.entry_id)
817+
await hass.async_block_till_done()
818+
819+
assert len(hass.states.async_all("sensor")) == 3
820+
assert len(hass.states.async_all("binary_sensor")) == 2
821+
822+
battery_sensor = hass.states.get("sensor.test_name_battery")
823+
battery_sensor_attrs = battery_sensor.attributes
824+
assert battery_sensor
825+
assert battery_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Battery"
826+
assert battery_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
827+
828+
light_level_sensor = hass.states.get("sensor.test_name_light_level")
829+
light_level_sensor_attrs = light_level_sensor.attributes
830+
assert light_level_sensor
831+
assert light_level_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Light level"
832+
833+
rssi_sensor = hass.states.get("sensor.test_name_bluetooth_signal")
834+
rssi_sensor_attrs = rssi_sensor.attributes
835+
assert rssi_sensor
836+
assert rssi_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Bluetooth signal"
837+
assert rssi_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "dBm"
838+
839+
light_sensor = hass.states.get("binary_sensor.test_name_light")
840+
light_sensor_attrs = light_sensor.attributes
841+
assert light_sensor
842+
assert light_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Light"
843+
844+
motion_sensor = hass.states.get("binary_sensor.test_name_motion")
845+
motion_sensor_attrs = motion_sensor.attributes
846+
assert motion_sensor
847+
assert motion_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Motion"
848+
849+
assert await hass.config_entries.async_unload(entry.entry_id)
850+
await hass.async_block_till_done()

0 commit comments

Comments
 (0)