mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 20:27:08 +00:00
Add support for Homeowner and Phantom Keypads (#79958)
This commit is contained in:
parent
5a0609ae8b
commit
45a30546ec
@ -232,16 +232,20 @@ def _async_register_button_devices(
|
|||||||
# use the parent_device for HA device info
|
# use the parent_device for HA device info
|
||||||
ha_device = bridge_devices[device["parent_device"]]
|
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
|
continue
|
||||||
seen.add(ha_device["serial"])
|
seen.add(ha_device_serial)
|
||||||
|
|
||||||
area, name = _area_and_name_from_name(ha_device["name"])
|
area, name = _area_and_name_from_name(ha_device["name"])
|
||||||
device_args: dict[str, Any] = {
|
device_args: dict[str, Any] = {
|
||||||
"name": f"{area} {name}",
|
"name": f"{area} {name}",
|
||||||
"manufacturer": MANUFACTURER,
|
"manufacturer": MANUFACTURER,
|
||||||
"config_entry_id": config_entry_id,
|
"config_entry_id": config_entry_id,
|
||||||
"identifiers": {(DOMAIN, ha_device["serial"])},
|
"identifiers": {(DOMAIN, ha_device_serial)},
|
||||||
"model": f"{ha_device['model']} ({ha_device['type']})",
|
"model": f"{ha_device['model']} ({ha_device['type']})",
|
||||||
"via_device": (DOMAIN, bridge_device["serial"]),
|
"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
|
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]:
|
def _area_and_name_from_name(device_name: str) -> tuple[str, str]:
|
||||||
"""Return the area and name from the devices internal name."""
|
"""Return the area and name from the devices internal name."""
|
||||||
if "_" in device_name:
|
if "_" in device_name:
|
||||||
@ -301,16 +309,20 @@ def _async_subscribe_pico_remote_events(
|
|||||||
# use the parent_device for HA device info
|
# use the parent_device for HA device info
|
||||||
ha_device = bridge_devices[device["parent_device"]]
|
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"])
|
type_ = _lutron_model_to_device_type(ha_device["model"], ha_device["type"])
|
||||||
area, name = _area_and_name_from_name(ha_device["name"])
|
area, name = _area_and_name_from_name(ha_device["name"])
|
||||||
leap_button_number = device["button_number"]
|
leap_button_number = device["button_number"]
|
||||||
lip_button_number = async_get_lip_button(type_, leap_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(
|
hass.bus.async_fire(
|
||||||
LUTRON_CASETA_BUTTON_EVENT,
|
LUTRON_CASETA_BUTTON_EVENT,
|
||||||
{
|
{
|
||||||
ATTR_SERIAL: ha_device["serial"],
|
ATTR_SERIAL: ha_device_serial,
|
||||||
ATTR_TYPE: type_,
|
ATTR_TYPE: type_,
|
||||||
ATTR_BUTTON_NUMBER: lip_button_number,
|
ATTR_BUTTON_NUMBER: lip_button_number,
|
||||||
ATTR_LEAP_BUTTON_NUMBER: leap_button_number,
|
ATTR_LEAP_BUTTON_NUMBER: leap_button_number,
|
||||||
|
@ -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 = {
|
DEVICE_TYPE_SCHEMA_MAP = {
|
||||||
"Pico2Button": PICO_2_BUTTON_TRIGGER_SCHEMA,
|
"Pico2Button": PICO_2_BUTTON_TRIGGER_SCHEMA,
|
||||||
@ -329,6 +350,8 @@ DEVICE_TYPE_SCHEMA_MAP = {
|
|||||||
"SunnataKeypad_2Button": SUNNATA_KEYPAD_2_BUTTON_TRIGGER_SCHEMA,
|
"SunnataKeypad_2Button": SUNNATA_KEYPAD_2_BUTTON_TRIGGER_SCHEMA,
|
||||||
"SunnataKeypad_3ButtonRaiseLower": SUNNATA_KEYPAD_3_BUTTON_RAISE_LOWER_TRIGGER_SCHEMA,
|
"SunnataKeypad_3ButtonRaiseLower": SUNNATA_KEYPAD_3_BUTTON_RAISE_LOWER_TRIGGER_SCHEMA,
|
||||||
"SunnataKeypad_4Button": SUNNATA_KEYPAD_4_BUTTON_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 = {
|
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_2Button": SUNNATA_KEYPAD_2_BUTTON_BUTTON_TYPES_TO_LEAP,
|
||||||
"SunnataKeypad_3ButtonRaiseLower": SUNNATA_KEYPAD_3_BUTTON_RAISE_LOWER_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,
|
"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 = {
|
LEAP_TO_DEVICE_TYPE_SUBTYPE_MAP = {
|
||||||
@ -373,6 +398,8 @@ TRIGGER_SCHEMA = vol.Any(
|
|||||||
SUNNATA_KEYPAD_2_BUTTON_TRIGGER_SCHEMA,
|
SUNNATA_KEYPAD_2_BUTTON_TRIGGER_SCHEMA,
|
||||||
SUNNATA_KEYPAD_3_BUTTON_RAISE_LOWER_TRIGGER_SCHEMA,
|
SUNNATA_KEYPAD_3_BUTTON_RAISE_LOWER_TRIGGER_SCHEMA,
|
||||||
SUNNATA_KEYPAD_4_BUTTON_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:
|
def _device_model_to_type(device_registry_model: str) -> str:
|
||||||
"""Convert a lutron_caseta device registry entry model to type."""
|
"""Convert a lutron_caseta device registry entry model to type."""
|
||||||
model, p_device_type = device_registry_model.split(" ")
|
model_list = device_registry_model.split(" ")
|
||||||
device_type = p_device_type.replace("(", "").replace(")", "")
|
device_type = model_list.pop().replace("(", "").replace(")", "")
|
||||||
return _lutron_model_to_device_type(model, device_type)
|
return _lutron_model_to_device_type(" ".join(model_list), device_type)
|
||||||
|
|
||||||
|
|
||||||
def _lutron_model_to_device_type(model: str, device_type: str) -> str:
|
def _lutron_model_to_device_type(model: str, device_type: str) -> str:
|
||||||
|
@ -67,6 +67,25 @@ MOCK_BUTTON_DEVICES = [
|
|||||||
"model": "RRST-W4B-XX",
|
"model": "RRST-W4B-XX",
|
||||||
"serial": 43845547,
|
"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 == []
|
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):
|
async def test_if_fires_on_button_event(hass, calls, device_reg):
|
||||||
"""Test for press trigger firing."""
|
"""Test for press trigger firing."""
|
||||||
await _async_setup_lutron_with_picos(hass, device_reg)
|
await _async_setup_lutron_with_picos(hass, device_reg)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user