Expose SwitchBot keypad duress alarm (#178620)

This commit is contained in:
Florian
2026-08-14 14:34:49 +02:00
committed by GitHub
parent 61743d1df9
commit 4cbec3d9a5
5 changed files with 131 additions and 7 deletions
@@ -107,6 +107,28 @@ BINARY_SENSOR_TYPES: dict[str, SwitchbotBinarySensorEntityDescription] = {
entity_category=EntityCategory.DIAGNOSTIC,
device_class=BinarySensorDeviceClass.BATTERY_CHARGING,
),
"duress_alarm": SwitchbotBinarySensorEntityDescription(
key="duress_alarm",
translation_key="duress_alarm",
device_class=BinarySensorDeviceClass.SAFETY,
),
"high_temperature": SwitchbotBinarySensorEntityDescription(
key="high_temperature",
translation_key="high_temperature",
device_class=BinarySensorDeviceClass.HEAT,
entity_category=EntityCategory.DIAGNOSTIC,
),
"lockout_alarm": SwitchbotBinarySensorEntityDescription(
key="lockout_alarm",
translation_key="lockout_alarm",
device_class=BinarySensorDeviceClass.PROBLEM,
),
"low_temperature": SwitchbotBinarySensorEntityDescription(
key="low_temperature",
translation_key="low_temperature",
device_class=BinarySensorDeviceClass.COLD,
entity_category=EntityCategory.DIAGNOSTIC,
),
"tamper_alarm": SwitchbotBinarySensorEntityDescription(
key="tamper_alarm",
device_class=BinarySensorDeviceClass.TAMPER,
@@ -154,6 +154,21 @@ SENSOR_TYPES: dict[str, SwitchBotSensorEntityDescription] = {
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.PM25,
),
"pir_triggered_level": SwitchBotSensorEntityDescription(
key="pir_triggered_level",
translation_key="pir_triggered_level",
entity_category=EntityCategory.DIAGNOSTIC,
),
"radar_triggered_distance": SwitchBotSensorEntityDescription(
key="radar_triggered_distance",
translation_key="radar_triggered_distance",
entity_category=EntityCategory.DIAGNOSTIC,
),
"radar_triggered_level": SwitchBotSensorEntityDescription(
key="radar_triggered_level",
translation_key="radar_triggered_level",
entity_category=EntityCategory.DIAGNOSTIC,
),
}
@@ -100,11 +100,23 @@
"door_unlocked_alarm": {
"name": "Unlocked alarm"
},
"duress_alarm": {
"name": "Duress alarm"
},
"half_lock_calibration": {
"name": "Half-lock calibration"
},
"half_locked": {
"name": "Half locked"
},
"high_temperature": {
"name": "High temperature"
},
"lockout_alarm": {
"name": "Lockout alarm"
},
"low_temperature": {
"name": "Low temperature"
}
},
"button": {
@@ -350,6 +362,15 @@
"light_level": {
"name": "Light level"
},
"pir_triggered_level": {
"name": "PIR triggered level"
},
"radar_triggered_distance": {
"name": "Radar triggered distance"
},
"radar_triggered_level": {
"name": "Radar triggered level"
},
"water_level": {
"name": "Water level",
"state": {
+2 -2
View File
@@ -1513,7 +1513,7 @@ KEYPAD_VISION_INFO = BluetoothServiceInfoBleak(
KEYPAD_VISION_PRO_INFO = BluetoothServiceInfoBleak(
name="Keypad Vision Pro",
manufacturer_data={2409: b"\xb0\xe9\xfe\xde\xb6\x8c+`\x00\x00\x00\x00\x00\x002"},
manufacturer_data={2409: b"\xb0\xe9\xfe\xde\xb6\x8c+`\xc5\x00\x00\x00\x00\x002"},
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"\x00\x00`\x01\x11Q\x98"},
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
address="AA:BB:CC:DD:EE:FF",
@@ -1522,7 +1522,7 @@ KEYPAD_VISION_PRO_INFO = BluetoothServiceInfoBleak(
advertisement=generate_advertisement_data(
local_name="Keypad Vision Pro",
manufacturer_data={
2409: b"\xb0\xe9\xfe\xde\xb6\x8c+`\x00\x00\x00\x00\x00\x002"
2409: b"\xb0\xe9\xfe\xde\xb6\x8c+`\xc5\x00\x00\x00\x00\x002"
},
service_data={
"0000fd3d-0000-1000-8000-00805f9b34fb": b"\x00\x00`\x01\x11Q\x98"
+71 -5
View File
@@ -1003,10 +1003,34 @@ async def test_presence_sensor_battery_range_mapping(
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
@pytest.mark.parametrize(
("adv_info", "sensor_type", "charging_state"),
(
"adv_info",
"sensor_type",
"charging_state",
"duress_state",
"lockout_state",
"temperature_alarm_state",
"trigger_sensors",
),
[
(KEYPAD_VISION_INFO, "keypad_vision", STATE_ON),
(KEYPAD_VISION_PRO_INFO, "keypad_vision_pro", STATE_OFF),
(
KEYPAD_VISION_INFO,
"keypad_vision",
STATE_ON,
STATE_OFF,
STATE_OFF,
STATE_OFF,
{"pir_triggered_level": "2"},
),
(
KEYPAD_VISION_PRO_INFO,
"keypad_vision_pro",
STATE_OFF,
STATE_ON,
STATE_ON,
STATE_ON,
{"radar_triggered_distance": "0", "radar_triggered_level": "0"},
),
],
)
async def test_keypad_vision_sensor(
@@ -1014,6 +1038,10 @@ async def test_keypad_vision_sensor(
adv_info: BluetoothServiceInfoBleak,
sensor_type: str,
charging_state: str,
duress_state: str,
lockout_state: str,
temperature_alarm_state: str,
trigger_sensors: dict[str, str],
) -> None:
"""Test setting up creates the sensors for Keypad Vision (Pro)."""
await async_setup_component(hass, DOMAIN, {})
@@ -1039,8 +1067,8 @@ async def test_keypad_vision_sensor(
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert len(hass.states.async_all("sensor")) == 2
assert len(hass.states.async_all("binary_sensor")) == 2
assert len(hass.states.async_all("sensor")) == 2 + len(trigger_sensors)
assert len(hass.states.async_all("binary_sensor")) == 6
battery_sensor = hass.states.get("sensor.test_name_battery")
battery_sensor_attrs = battery_sensor.attributes
@@ -1066,6 +1094,44 @@ async def test_keypad_vision_sensor(
assert charging_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Charging"
assert charging_sensor.state == charging_state
duress_sensor = hass.states.get("binary_sensor.test_name_duress_alarm")
duress_sensor_attrs = duress_sensor.attributes
assert duress_sensor
assert duress_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Duress alarm"
assert duress_sensor_attrs[ATTR_DEVICE_CLASS] == "safety"
assert duress_sensor.state == duress_state
lockout_sensor = hass.states.get("binary_sensor.test_name_lockout_alarm")
lockout_sensor_attrs = lockout_sensor.attributes
assert lockout_sensor
assert lockout_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Lockout alarm"
assert lockout_sensor_attrs[ATTR_DEVICE_CLASS] == "problem"
assert lockout_sensor.state == lockout_state
high_temperature_sensor = hass.states.get(
"binary_sensor.test_name_high_temperature"
)
assert high_temperature_sensor
assert high_temperature_sensor.state == temperature_alarm_state
low_temperature_sensor = hass.states.get(
"binary_sensor.test_name_low_temperature"
)
assert low_temperature_sensor
assert low_temperature_sensor.state == temperature_alarm_state
expected_names = {
"pir_triggered_level": "PIR triggered level",
"radar_triggered_distance": "Radar triggered distance",
"radar_triggered_level": "Radar triggered level",
}
for key, expected_state in trigger_sensors.items():
trigger_sensor = hass.states.get(f"sensor.test_name_{key}")
assert trigger_sensor
assert trigger_sensor.attributes[ATTR_FRIENDLY_NAME] == (
f"test-name {expected_names[key]}"
)
assert trigger_sensor.state == expected_state
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()