Add support for Homeowner and Phantom Keypads (#79958)

This commit is contained in:
Kevin Addeman 2022-10-09 18:17:06 -04:00 committed by GitHub
parent 5a0609ae8b
commit 45a30546ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 78 additions and 8 deletions

View File

@ -232,16 +232,20 @@ def _async_register_button_devices(
# use the parent_device for HA device info
ha_device = bridge_devices[device["parent_device"]]
if "serial" not in ha_device or ha_device["serial"] in seen:
ha_device_serial = _handle_none_keypad_serial(
ha_device, bridge_device["serial"]
)
if "serial" not in ha_device or ha_device_serial in seen:
continue
seen.add(ha_device["serial"])
seen.add(ha_device_serial)
area, name = _area_and_name_from_name(ha_device["name"])
device_args: dict[str, Any] = {
"name": f"{area} {name}",
"manufacturer": MANUFACTURER,
"config_entry_id": config_entry_id,
"identifiers": {(DOMAIN, ha_device["serial"])},
"identifiers": {(DOMAIN, ha_device_serial)},
"model": f"{ha_device['model']} ({ha_device['type']})",
"via_device": (DOMAIN, bridge_device["serial"]),
}
@ -255,6 +259,10 @@ def _async_register_button_devices(
return button_devices_by_dr_id, device_info_by_device_id
def _handle_none_keypad_serial(keypad_device: dict, bridge_serial: int) -> str:
return keypad_device["serial"] or f"{bridge_serial}_{keypad_device['device_id']}"
def _area_and_name_from_name(device_name: str) -> tuple[str, str]:
"""Return the area and name from the devices internal name."""
if "_" in device_name:
@ -301,16 +309,20 @@ def _async_subscribe_pico_remote_events(
# use the parent_device for HA device info
ha_device = bridge_devices[device["parent_device"]]
ha_device_serial = _handle_none_keypad_serial(
ha_device, bridge_devices[BRIDGE_DEVICE_ID]["serial"]
)
type_ = _lutron_model_to_device_type(ha_device["model"], ha_device["type"])
area, name = _area_and_name_from_name(ha_device["name"])
leap_button_number = device["button_number"]
lip_button_number = async_get_lip_button(type_, leap_button_number)
hass_device = dev_reg.async_get_device({(DOMAIN, ha_device["serial"])})
hass_device = dev_reg.async_get_device({(DOMAIN, ha_device_serial)})
hass.bus.async_fire(
LUTRON_CASETA_BUTTON_EVENT,
{
ATTR_SERIAL: ha_device["serial"],
ATTR_SERIAL: ha_device_serial,
ATTR_TYPE: type_,
ATTR_BUTTON_NUMBER: lip_button_number,
ATTR_LEAP_BUTTON_NUMBER: leap_button_number,

View File

@ -315,6 +315,27 @@ SUNNATA_KEYPAD_4_BUTTON_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
}
)
HOMEOWNER_KEYPAD_BUTTON_TYPES_TO_LEAP = {
"button_1": 1,
"button_2": 2,
"button_3": 3,
"button_4": 4,
"button_5": 5,
"button_6": 6,
"button_7": 7,
}
HOMEOWNER_KEYPAD_BUTTON_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(HOMEOWNER_KEYPAD_BUTTON_TYPES_TO_LEAP),
}
)
PHANTOM_KEYPAD_BUTTON_TYPES_TO_LEAP: dict[str, int] = {}
PHANTOM_KEYPAD_BUTTON_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(PHANTOM_KEYPAD_BUTTON_TYPES_TO_LEAP),
}
)
DEVICE_TYPE_SCHEMA_MAP = {
"Pico2Button": PICO_2_BUTTON_TRIGGER_SCHEMA,
@ -329,6 +350,8 @@ DEVICE_TYPE_SCHEMA_MAP = {
"SunnataKeypad_2Button": SUNNATA_KEYPAD_2_BUTTON_TRIGGER_SCHEMA,
"SunnataKeypad_3ButtonRaiseLower": SUNNATA_KEYPAD_3_BUTTON_RAISE_LOWER_TRIGGER_SCHEMA,
"SunnataKeypad_4Button": SUNNATA_KEYPAD_4_BUTTON_TRIGGER_SCHEMA,
"HomeownerKeypad": HOMEOWNER_KEYPAD_BUTTON_TRIGGER_SCHEMA,
"PhantomKeypad": PHANTOM_KEYPAD_BUTTON_TRIGGER_SCHEMA,
}
DEVICE_TYPE_SUBTYPE_MAP_TO_LIP = {
@ -356,6 +379,8 @@ DEVICE_TYPE_SUBTYPE_MAP_TO_LEAP = {
"SunnataKeypad_2Button": SUNNATA_KEYPAD_2_BUTTON_BUTTON_TYPES_TO_LEAP,
"SunnataKeypad_3ButtonRaiseLower": SUNNATA_KEYPAD_3_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LEAP,
"SunnataKeypad_4Button": SUNNATA_KEYPAD_4_BUTTON_BUTTON_TYPES_TO_LEAP,
"HomeownerKeypad": HOMEOWNER_KEYPAD_BUTTON_TYPES_TO_LEAP,
"PhantomKeypad": PHANTOM_KEYPAD_BUTTON_TYPES_TO_LEAP,
}
LEAP_TO_DEVICE_TYPE_SUBTYPE_MAP = {
@ -373,6 +398,8 @@ TRIGGER_SCHEMA = vol.Any(
SUNNATA_KEYPAD_2_BUTTON_TRIGGER_SCHEMA,
SUNNATA_KEYPAD_3_BUTTON_RAISE_LOWER_TRIGGER_SCHEMA,
SUNNATA_KEYPAD_4_BUTTON_TRIGGER_SCHEMA,
HOMEOWNER_KEYPAD_BUTTON_TRIGGER_SCHEMA,
PHANTOM_KEYPAD_BUTTON_TRIGGER_SCHEMA,
)
@ -429,9 +456,9 @@ async def async_get_triggers(
def _device_model_to_type(device_registry_model: str) -> str:
"""Convert a lutron_caseta device registry entry model to type."""
model, p_device_type = device_registry_model.split(" ")
device_type = p_device_type.replace("(", "").replace(")", "")
return _lutron_model_to_device_type(model, device_type)
model_list = device_registry_model.split(" ")
device_type = model_list.pop().replace("(", "").replace(")", "")
return _lutron_model_to_device_type(" ".join(model_list), device_type)
def _lutron_model_to_device_type(model: str, device_type: str) -> str:

View File

@ -67,6 +67,25 @@ MOCK_BUTTON_DEVICES = [
"model": "RRST-W4B-XX",
"serial": 43845547,
},
{
"device_id": "786",
"Name": "Example Homeowner Keypad",
"ID": 3,
"Area": {"Name": "Front Steps"},
"Buttons": [
{"Number": 12},
{"Number": 13},
{"Number": 14},
{"Number": 15},
{"Number": 16},
{"Number": 17},
{"Number": 18},
],
"leap_name": "Front Steps_Example Homeowner Keypad",
"type": "HomeownerKeypad",
"model": "Homeowner Keypad",
"serial": None,
},
]
@ -178,6 +197,18 @@ async def test_get_triggers_for_non_button_device(hass, device_reg):
assert triggers == []
async def test_none_serial_keypad(hass, device_reg):
"""Test serial assignment for keypads without serials."""
config_entry_id = await _async_setup_lutron_with_picos(hass, device_reg)
keypad_device = device_reg.async_get_or_create(
config_entry_id=config_entry_id,
identifiers={(DOMAIN, "1234_786")},
)
assert keypad_device is not None
async def test_if_fires_on_button_event(hass, calls, device_reg):
"""Test for press trigger firing."""
await _async_setup_lutron_with_picos(hass, device_reg)