Add pico remote support to non-pro lutron caseta bridges (#61032)

pull/62364/head
J. Nick Koston 2021-12-19 01:41:02 -06:00 committed by GitHub
parent 832184bacd
commit e834382b9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 234 additions and 146 deletions

View File

@ -1,19 +1,19 @@
"""Component for interacting with a Lutron Caseta system."""
from __future__ import annotations
import asyncio
import contextlib
import logging
import ssl
from aiolip import LIP
from aiolip.data import LIPMode
from aiolip.protocol import LIP_BUTTON_PRESS
import async_timeout
from pylutron_caseta import BUTTON_STATUS_PRESSED
from pylutron_caseta.smartbridge import Smartbridge
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_HOST, Platform
from homeassistant.core import callback
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
import homeassistant.helpers.config_validation as cv
@ -26,12 +26,12 @@ from .const import (
ATTR_AREA_NAME,
ATTR_BUTTON_NUMBER,
ATTR_DEVICE_NAME,
ATTR_LEAP_BUTTON_NUMBER,
ATTR_SERIAL,
ATTR_TYPE,
BRIDGE_DEVICE,
BRIDGE_DEVICE_ID,
BRIDGE_LEAP,
BRIDGE_LIP,
BRIDGE_TIMEOUT,
BUTTON_DEVICES,
CONF_CA_CERTS,
@ -41,6 +41,10 @@ from .const import (
LUTRON_CASETA_BUTTON_EVENT,
MANUFACTURER,
)
from .device_trigger import (
DEVICE_TYPE_SUBTYPE_MAP_TO_LIP,
LEAP_TO_DEVICE_TYPE_SUBTYPE_MAP,
)
_LOGGER = logging.getLogger(__name__)
@ -97,8 +101,11 @@ async def async_setup(hass, base_config):
return True
async def async_setup_entry(hass, config_entry):
async def async_setup_entry(
hass: HomeAssistant, config_entry: config_entries.ConfigEntry
) -> bool:
"""Set up a bridge from a config entry."""
entry_id = config_entry.entry_id
host = config_entry.data[CONF_HOST]
keyfile = hass.config.path(config_entry.data[CONF_KEYFILE])
certfile = hass.config.path(config_entry.data[CONF_CERTFILE])
@ -130,85 +137,30 @@ async def async_setup_entry(hass, config_entry):
devices = bridge.get_devices()
bridge_device = devices[BRIDGE_DEVICE_ID]
_async_register_bridge_device(hass, config_entry.entry_id, bridge_device)
buttons = bridge.buttons
_async_register_bridge_device(hass, entry_id, bridge_device)
button_devices = _async_register_button_devices(
hass, entry_id, bridge_device, buttons
)
_async_subscribe_pico_remote_events(hass, bridge, buttons)
# Store this bridge (keyed by entry_id) so it can be retrieved by the
# platforms we're setting up.
hass.data[DOMAIN][config_entry.entry_id] = {
hass.data[DOMAIN][entry_id] = {
BRIDGE_LEAP: bridge,
BRIDGE_DEVICE: bridge_device,
BUTTON_DEVICES: {},
BRIDGE_LIP: None,
BUTTON_DEVICES: button_devices,
}
if bridge.lip_devices:
# If the bridge also supports LIP (Lutron Integration Protocol)
# we can fire events when pico buttons are pressed to allow
# pico remotes to control other devices.
await async_setup_lip(hass, config_entry, bridge.lip_devices)
hass.config_entries.async_setup_platforms(config_entry, PLATFORMS)
return True
async def async_setup_lip(hass, config_entry, lip_devices):
"""Connect to the bridge via Lutron Integration Protocol to watch for pico remotes."""
host = config_entry.data[CONF_HOST]
config_entry_id = config_entry.entry_id
data = hass.data[DOMAIN][config_entry_id]
bridge_device = data[BRIDGE_DEVICE]
bridge = data[BRIDGE_LEAP]
lip = LIP()
try:
await lip.async_connect(host)
except asyncio.TimeoutError:
_LOGGER.warning(
"Failed to connect to via LIP at %s:23, Pico and Shade remotes will not be available; "
"Enable Telnet Support in the Lutron app under Settings >> Advanced >> Integration",
host,
)
return
_LOGGER.debug("Connected to Lutron Caseta bridge via LIP at %s:23", host)
button_devices_by_lip_id = _async_merge_lip_leap_data(lip_devices, bridge)
button_devices_by_dr_id = _async_register_button_devices(
hass, config_entry_id, bridge_device, button_devices_by_lip_id
)
_async_subscribe_pico_remote_events(hass, lip, button_devices_by_lip_id)
data[BUTTON_DEVICES] = button_devices_by_dr_id
data[BRIDGE_LIP] = lip
@callback
def _async_merge_lip_leap_data(lip_devices, bridge):
"""Merge the leap data into the lip data."""
sensor_devices = bridge.get_devices_by_domain("sensor")
button_devices_by_id = {
id: device for id, device in lip_devices.items() if "Buttons" in device
}
sensor_devices_by_name = {device["name"]: device for device in sensor_devices}
# Add the leap data into the lip data
# so we know the type, model, and serial
for device in button_devices_by_id.values():
area = device.get("Area", {}).get("Name", "")
name = device["Name"]
leap_name = f"{area}_{name}"
device["leap_name"] = leap_name
leap_device_data = sensor_devices_by_name.get(leap_name)
if leap_device_data is None:
continue
for key in ("type", "model", "serial"):
if (val := leap_device_data.get(key)) is not None:
device[key] = val
_LOGGER.debug("Button Devices: %s", button_devices_by_id)
return button_devices_by_id
@callback
def _async_register_bridge_device(hass, config_entry_id, bridge_device):
def _async_register_bridge_device(
hass: HomeAssistant, config_entry_id: str, bridge_device: dict
) -> None:
"""Register the bridge device in the device registry."""
device_registry = dr.async_get(hass)
device_registry.async_get_or_create(
@ -217,24 +169,30 @@ def _async_register_bridge_device(hass, config_entry_id, bridge_device):
config_entry_id=config_entry_id,
identifiers={(DOMAIN, bridge_device["serial"])},
model=f"{bridge_device['model']} ({bridge_device['type']})",
configuration_url="https://device-login.lutron.com",
)
@callback
def _async_register_button_devices(
hass, config_entry_id, bridge_device, button_devices_by_id
):
hass: HomeAssistant,
config_entry_id: str,
bridge_device,
button_devices_by_id: dict[int, dict],
) -> dict[str, dr.DeviceEntry]:
"""Register button devices (Pico Remotes) in the device registry."""
device_registry = dr.async_get(hass)
button_devices_by_dr_id = {}
seen = set()
for device in button_devices_by_id.values():
if "serial" not in device:
if "serial" not in device or device["serial"] in seen:
continue
seen.add(device["serial"])
dr_device = device_registry.async_get_or_create(
name=device["leap_name"],
suggested_area=device["leap_name"].split("_")[0],
name=device["name"],
suggested_area=device["name"].split("_")[0],
manufacturer=MANUFACTURER,
config_entry_id=config_entry_id,
identifiers={(DOMAIN, device["serial"])},
@ -248,54 +206,74 @@ def _async_register_button_devices(
@callback
def _async_subscribe_pico_remote_events(hass, lip, button_devices_by_id):
def _async_subscribe_pico_remote_events(
hass: HomeAssistant,
bridge_device: Smartbridge,
button_devices_by_id: dict[int, dict],
):
"""Subscribe to lutron events."""
@callback
def _async_lip_event(lip_message):
if lip_message.mode != LIPMode.DEVICE:
return
device = button_devices_by_id.get(lip_message.integration_id)
def _async_button_event(button_id, event_type):
device = button_devices_by_id.get(button_id)
if not device:
return
if lip_message.value == LIP_BUTTON_PRESS:
if event_type == BUTTON_STATUS_PRESSED:
action = ACTION_PRESS
else:
action = ACTION_RELEASE
type_ = device["type"]
name = device["name"]
button_number = device["button_number"]
# The original implementation used LIP instead of LEAP
# so we need to convert the button number to maintain compat
sub_type_to_lip_button = DEVICE_TYPE_SUBTYPE_MAP_TO_LIP[type_]
leap_button_to_sub_type = LEAP_TO_DEVICE_TYPE_SUBTYPE_MAP[type_]
if (sub_type := leap_button_to_sub_type.get(button_number)) is None:
_LOGGER.error(
"Unknown LEAP button number %s is not in %s for %s (%s)",
button_number,
leap_button_to_sub_type,
name,
type_,
)
return
lip_button_number = sub_type_to_lip_button[sub_type]
hass.bus.async_fire(
LUTRON_CASETA_BUTTON_EVENT,
{
ATTR_SERIAL: device.get("serial"),
ATTR_TYPE: device.get("type"),
ATTR_BUTTON_NUMBER: lip_message.action_number,
ATTR_DEVICE_NAME: device["Name"],
ATTR_AREA_NAME: device.get("Area", {}).get("Name"),
ATTR_SERIAL: device["serial"],
ATTR_TYPE: type_,
ATTR_BUTTON_NUMBER: lip_button_number,
ATTR_LEAP_BUTTON_NUMBER: button_number,
ATTR_DEVICE_NAME: name,
ATTR_AREA_NAME: name.split("_")[0],
ATTR_ACTION: action,
},
)
lip.subscribe(_async_lip_event)
asyncio.create_task(lip.async_run())
async def async_unload_entry(hass, config_entry):
"""Unload the bridge bridge from a config entry."""
data = hass.data[DOMAIN][config_entry.entry_id]
data[BRIDGE_LEAP].close()
if data[BRIDGE_LIP]:
await data[BRIDGE_LIP].async_stop()
unload_ok = await hass.config_entries.async_unload_platforms(
config_entry, PLATFORMS
for button_id in button_devices_by_id:
bridge_device.add_button_subscriber(
str(button_id),
lambda event_type, button_id=button_id: _async_button_event(
button_id, event_type
),
)
if unload_ok:
hass.data[DOMAIN].pop(config_entry.entry_id)
async def async_unload_entry(
hass: HomeAssistant, entry: config_entries.ConfigEntry
) -> bool:
"""Unload the bridge bridge from a config entry."""
data = hass.data[DOMAIN][entry.entry_id]
smartbridge: Smartbridge = data[BRIDGE_LEAP]
await smartbridge.close()
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok

View File

@ -11,7 +11,6 @@ ERROR_CANNOT_CONNECT = "cannot_connect"
ABORT_REASON_CANNOT_CONNECT = "cannot_connect"
BRIDGE_LEAP = "leap"
BRIDGE_LIP = "lip"
BRIDGE_DEVICE = "bridge_device"
BUTTON_DEVICES = "button_devices"
LUTRON_CASETA_BUTTON_EVENT = "lutron_caseta_button_event"
@ -22,7 +21,8 @@ MANUFACTURER = "Lutron Electronics Co., Inc"
ATTR_SERIAL = "serial"
ATTR_TYPE = "type"
ATTR_BUTTON_NUMBER = "button_number"
ATTR_LEAP_BUTTON_NUMBER = "leap_button_number"
ATTR_BUTTON_NUMBER = "button_number" # LIP button number
ATTR_DEVICE_NAME = "device_name"
ATTR_AREA_NAME = "area_name"
ATTR_ACTION = "action"

View File

@ -46,106 +46,180 @@ LUTRON_BUTTON_TRIGGER_SCHEMA = DEVICE_TRIGGER_BASE_SCHEMA.extend(
)
PICO_2_BUTTON_BUTTON_TYPES = {
PICO_2_BUTTON_BUTTON_TYPES_TO_LIP = {
"on": 2,
"off": 4,
}
PICO_2_BUTTON_BUTTON_TYPES_TO_LEAP = {
"on": 0,
"off": 2,
}
LEAP_TO_PICO_2_BUTTON_BUTTON_TYPES = {
v: k for k, v in PICO_2_BUTTON_BUTTON_TYPES_TO_LEAP.items()
}
PICO_2_BUTTON_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(PICO_2_BUTTON_BUTTON_TYPES),
vol.Required(CONF_SUBTYPE): vol.In(PICO_2_BUTTON_BUTTON_TYPES_TO_LIP),
}
)
PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES = {
PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LIP = {
"on": 2,
"off": 4,
"raise": 5,
"lower": 6,
}
PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LEAP = {
"on": 0,
"off": 2,
"raise": 3,
"lower": 4,
}
LEAP_TO_PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES = {
v: k for k, v in PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LEAP.items()
}
PICO_2_BUTTON_RAISE_LOWER_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES),
vol.Required(CONF_SUBTYPE): vol.In(
PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LIP
),
}
)
PICO_3_BUTTON_BUTTON_TYPES = {
PICO_3_BUTTON_BUTTON_TYPES_TO_LIP = {
"on": 2,
"stop": 3,
"off": 4,
}
PICO_3_BUTTON_BUTTON_TYPES_TO_LEAP = {
"on": 0,
"stop": 1,
"off": 2,
}
LEAP_TO_PICO_3_BUTTON_BUTTON_TYPES = {
v: k for k, v in PICO_3_BUTTON_BUTTON_TYPES_TO_LEAP.items()
}
PICO_3_BUTTON_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(PICO_3_BUTTON_BUTTON_TYPES),
vol.Required(CONF_SUBTYPE): vol.In(PICO_3_BUTTON_BUTTON_TYPES_TO_LIP),
}
)
PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES = {
PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LIP = {
"on": 2,
"stop": 3,
"off": 4,
"raise": 5,
"lower": 6,
}
PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LEAP = {
"on": 0,
"stop": 1,
"off": 2,
"raise": 3,
"lower": 4,
}
LEAP_TO_PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES = {
v: k for k, v in PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LEAP.items()
}
PICO_3_BUTTON_RAISE_LOWER_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES),
vol.Required(CONF_SUBTYPE): vol.In(
PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LIP
),
}
)
PICO_4_BUTTON_BUTTON_TYPES = {
PICO_4_BUTTON_BUTTON_TYPES_TO_LIP = {
"button_1": 8,
"button_2": 9,
"button_3": 10,
"button_4": 11,
}
PICO_4_BUTTON_BUTTON_TYPES_TO_LEAP = {
"button_1": 1,
"button_2": 2,
"button_3": 3,
"button_4": 4,
}
LEAP_TO_PICO_4_BUTTON_BUTTON_TYPES = {
v: k for k, v in PICO_4_BUTTON_BUTTON_TYPES_TO_LEAP.items()
}
PICO_4_BUTTON_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(PICO_4_BUTTON_BUTTON_TYPES),
vol.Required(CONF_SUBTYPE): vol.In(PICO_4_BUTTON_BUTTON_TYPES_TO_LIP),
}
)
PICO_4_BUTTON_ZONE_BUTTON_TYPES = {
PICO_4_BUTTON_ZONE_BUTTON_TYPES_TO_LIP = {
"on": 8,
"raise": 9,
"lower": 10,
"off": 11,
}
PICO_4_BUTTON_ZONE_BUTTON_TYPES_TO_LEAP = {
"on": 1,
"raise": 2,
"lower": 3,
"off": 4,
}
LEAP_TO_PICO_4_BUTTON_ZONE_BUTTON_TYPES = {
v: k for k, v in PICO_4_BUTTON_ZONE_BUTTON_TYPES_TO_LEAP.items()
}
PICO_4_BUTTON_ZONE_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(PICO_4_BUTTON_ZONE_BUTTON_TYPES),
vol.Required(CONF_SUBTYPE): vol.In(PICO_4_BUTTON_ZONE_BUTTON_TYPES_TO_LIP),
}
)
PICO_4_BUTTON_SCENE_BUTTON_TYPES = {
PICO_4_BUTTON_SCENE_BUTTON_TYPES_TO_LIP = {
"button_1": 8,
"button_2": 9,
"button_3": 10,
"off": 11,
}
PICO_4_BUTTON_SCENE_BUTTON_TYPES_TO_LEAP = {
"button_1": 1,
"button_2": 2,
"button_3": 3,
"off": 4,
}
LEAP_TO_PICO_4_BUTTON_SCENE_BUTTON_TYPES = {
v: k for k, v in PICO_4_BUTTON_SCENE_BUTTON_TYPES_TO_LEAP.items()
}
PICO_4_BUTTON_SCENE_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(PICO_4_BUTTON_SCENE_BUTTON_TYPES),
vol.Required(CONF_SUBTYPE): vol.In(PICO_4_BUTTON_SCENE_BUTTON_TYPES_TO_LIP),
}
)
PICO_4_BUTTON_2_GROUP_BUTTON_TYPES = {
PICO_4_BUTTON_2_GROUP_BUTTON_TYPES_TO_LIP = {
"group_1_button_1": 8,
"group_1_button_2": 9,
"group_2_button_1": 10,
"group_2_button_2": 11,
}
PICO_4_BUTTON_2_GROUP_BUTTON_TYPES_TO_LEAP = {
"group_1_button_1": 1,
"group_1_button_2": 2,
"group_2_button_1": 3,
"group_2_button_2": 4,
}
LEAP_TO_PICO_4_BUTTON_2_GROUP_BUTTON_TYPES = {
v: k for k, v in PICO_4_BUTTON_2_GROUP_BUTTON_TYPES_TO_LEAP.items()
}
PICO_4_BUTTON_2_GROUP_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(PICO_4_BUTTON_2_GROUP_BUTTON_TYPES),
vol.Required(CONF_SUBTYPE): vol.In(PICO_4_BUTTON_2_GROUP_BUTTON_TYPES_TO_LIP),
}
)
FOUR_GROUP_REMOTE_BUTTON_TYPES = {
FOUR_GROUP_REMOTE_BUTTON_TYPES_TO_LIP = {
"open_all": 2,
"stop_all": 3,
"close_all": 4,
@ -172,9 +246,39 @@ FOUR_GROUP_REMOTE_BUTTON_TYPES = {
"raise_4": 37,
"lower_4": 38,
}
FOUR_GROUP_REMOTE_BUTTON_TYPES_TO_LEAP = {
"open_all": 0,
"stop_all": 1,
"close_all": 2,
"raise_all": 3,
"lower_all": 4,
"open_1": 5,
"stop_1": 6,
"close_1": 7,
"raise_1": 8,
"lower_1": 9,
"open_2": 10,
"stop_2": 11,
"close_2": 12,
"raise_2": 13,
"lower_2": 14,
"open_3": 15,
"stop_3": 16,
"close_3": 17,
"raise_3": 18,
"lower_3": 19,
"open_4": 20,
"stop_4": 21,
"close_4": 22,
"raise_4": 23,
"lower_4": 24,
}
LEAP_TO_FOUR_GROUP_REMOTE_BUTTON_TYPES = {
v: k for k, v in FOUR_GROUP_REMOTE_BUTTON_TYPES_TO_LEAP.items()
}
FOUR_GROUP_REMOTE_TRIGGER_SCHEMA = LUTRON_BUTTON_TRIGGER_SCHEMA.extend(
{
vol.Required(CONF_SUBTYPE): vol.In(FOUR_GROUP_REMOTE_BUTTON_TYPES),
vol.Required(CONF_SUBTYPE): vol.In(FOUR_GROUP_REMOTE_BUTTON_TYPES_TO_LIP),
}
)
@ -190,16 +294,28 @@ DEVICE_TYPE_SCHEMA_MAP = {
"FourGroupRemote": FOUR_GROUP_REMOTE_TRIGGER_SCHEMA,
}
DEVICE_TYPE_SUBTYPE_MAP = {
"Pico2Button": PICO_2_BUTTON_BUTTON_TYPES,
"Pico2ButtonRaiseLower": PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES,
"Pico3Button": PICO_3_BUTTON_BUTTON_TYPES,
"Pico3ButtonRaiseLower": PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES,
"Pico4Button": PICO_4_BUTTON_BUTTON_TYPES,
"Pico4ButtonScene": PICO_4_BUTTON_SCENE_BUTTON_TYPES,
"Pico4ButtonZone": PICO_4_BUTTON_ZONE_BUTTON_TYPES,
"Pico4Button2Group": PICO_4_BUTTON_2_GROUP_BUTTON_TYPES,
"FourGroupRemote": FOUR_GROUP_REMOTE_BUTTON_TYPES,
DEVICE_TYPE_SUBTYPE_MAP_TO_LIP = {
"Pico2Button": PICO_2_BUTTON_BUTTON_TYPES_TO_LIP,
"Pico2ButtonRaiseLower": PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LIP,
"Pico3Button": PICO_3_BUTTON_BUTTON_TYPES_TO_LIP,
"Pico3ButtonRaiseLower": PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES_TO_LIP,
"Pico4Button": PICO_4_BUTTON_BUTTON_TYPES_TO_LIP,
"Pico4ButtonScene": PICO_4_BUTTON_SCENE_BUTTON_TYPES_TO_LIP,
"Pico4ButtonZone": PICO_4_BUTTON_ZONE_BUTTON_TYPES_TO_LIP,
"Pico4Button2Group": PICO_4_BUTTON_2_GROUP_BUTTON_TYPES_TO_LIP,
"FourGroupRemote": FOUR_GROUP_REMOTE_BUTTON_TYPES_TO_LIP,
}
LEAP_TO_DEVICE_TYPE_SUBTYPE_MAP = {
"Pico2Button": LEAP_TO_PICO_2_BUTTON_BUTTON_TYPES,
"Pico2ButtonRaiseLower": LEAP_TO_PICO_2_BUTTON_RAISE_LOWER_BUTTON_TYPES,
"Pico3Button": LEAP_TO_PICO_3_BUTTON_BUTTON_TYPES,
"Pico3ButtonRaiseLower": LEAP_TO_PICO_3_BUTTON_RAISE_LOWER_BUTTON_TYPES,
"Pico4Button": LEAP_TO_PICO_4_BUTTON_BUTTON_TYPES,
"Pico4ButtonScene": LEAP_TO_PICO_4_BUTTON_SCENE_BUTTON_TYPES,
"Pico4ButtonZone": LEAP_TO_PICO_4_BUTTON_ZONE_BUTTON_TYPES,
"Pico4Button2Group": LEAP_TO_PICO_4_BUTTON_2_GROUP_BUTTON_TYPES,
"FourGroupRemote": LEAP_TO_FOUR_GROUP_REMOTE_BUTTON_TYPES,
}
TRIGGER_SCHEMA = vol.Any(
@ -238,7 +354,7 @@ async def async_get_triggers(
if not (device := get_button_device_by_dr_id(hass, device_id)):
raise InvalidDeviceAutomationConfig(f"Device not found: {device_id}")
valid_buttons = DEVICE_TYPE_SUBTYPE_MAP.get(device["type"], [])
valid_buttons = DEVICE_TYPE_SUBTYPE_MAP_TO_LIP.get(device["type"], [])
for trigger in SUPPORTED_INPUTS_EVENTS_TYPES:
for subtype in valid_buttons:
@ -273,7 +389,7 @@ async def async_attach_trigger(
device_type = _device_model_to_type(device.model)
_, serial = list(device.identifiers)[0]
schema = DEVICE_TYPE_SCHEMA_MAP.get(device_type)
valid_buttons = DEVICE_TYPE_SUBTYPE_MAP.get(device_type)
valid_buttons = DEVICE_TYPE_SUBTYPE_MAP_TO_LIP.get(device_type)
config = schema(config)
event_config = {
event_trigger.CONF_PLATFORM: CONF_EVENT,

View File

@ -2,7 +2,7 @@
"domain": "lutron_caseta",
"name": "Lutron Cas\u00e9ta",
"documentation": "https://www.home-assistant.io/integrations/lutron_caseta",
"requirements": ["pylutron-caseta==0.11.0", "aiolip==1.1.6"],
"requirements": ["pylutron-caseta==0.13.0"],
"config_flow": true,
"zeroconf": ["_leap._tcp.local."],
"homekit": {

View File

@ -209,9 +209,6 @@ aiolifx==0.7.0
# homeassistant.components.lifx
aiolifx_effects==0.2.2
# homeassistant.components.lutron_caseta
aiolip==1.1.6
# homeassistant.components.lookin
aiolookin==0.1.0
@ -1625,7 +1622,7 @@ pylitejet==0.3.0
pylitterbot==2021.12.0
# homeassistant.components.lutron_caseta
pylutron-caseta==0.11.0
pylutron-caseta==0.13.0
# homeassistant.components.lutron
pylutron==0.2.8

View File

@ -142,9 +142,6 @@ aiohue==3.0.6
# homeassistant.components.apache_kafka
aiokafka==0.6.0
# homeassistant.components.lutron_caseta
aiolip==1.1.6
# homeassistant.components.lookin
aiolookin==0.1.0
@ -995,7 +992,7 @@ pylitejet==0.3.0
pylitterbot==2021.12.0
# homeassistant.components.lutron_caseta
pylutron-caseta==0.11.0
pylutron-caseta==0.13.0
# homeassistant.components.mailgun
pymailgunner==1.4