diff --git a/homeassistant/components/rfxtrx/__init__.py b/homeassistant/components/rfxtrx/__init__.py index 90393589263..e405aadfe06 100644 --- a/homeassistant/components/rfxtrx/__init__.py +++ b/homeassistant/components/rfxtrx/__init__.py @@ -7,7 +7,6 @@ import logging from typing import Any, NamedTuple, cast import RFXtrx as rfxtrxmod -import voluptuous as vol from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( @@ -20,7 +19,7 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STOP, Platform, ) -from homeassistant.core import Event, HomeAssistant, ServiceCall, callback +from homeassistant.core import Event, HomeAssistant, callback from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import config_validation as cv, device_registry as dr from homeassistant.helpers.device_registry import EventDeviceRegistryUpdatedData @@ -30,9 +29,9 @@ from homeassistant.helpers.dispatcher import ( ) from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.typing import ConfigType from .const import ( - ATTR_EVENT, CONF_AUTOMATIC_ADD, CONF_DATA_BITS, CONF_PROTOCOLS, @@ -40,9 +39,9 @@ from .const import ( DEVICE_PACKET_TYPE_LIGHTING4, DOMAIN, EVENT_RFXTRX_EVENT, - SERVICE_SEND, SIGNAL_EVENT, ) +from .services import async_setup_services DEFAULT_OFF_DELAY = 2.0 @@ -59,18 +58,6 @@ class DeviceTuple(NamedTuple): id_string: str -def _bytearray_string(data: Any) -> bytearray: - val = cv.string(data) - try: - return bytearray.fromhex(val) - except ValueError as err: - raise vol.Invalid( - "Data must be a hex string with multiple of two characters" - ) from err - - -SERVICE_SEND_SCHEMA = vol.Schema({ATTR_EVENT: _bytearray_string}) - PLATFORMS = [ Platform.BINARY_SENSOR, Platform.COVER, @@ -81,6 +68,15 @@ PLATFORMS = [ Platform.SWITCH, ] +CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) + + +async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: + """Set up RFXtrx services.""" + hass.data.setdefault(DOMAIN, {}) + async_setup_services(hass) + return True + async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up the RFXtrx component.""" @@ -97,12 +93,10 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: if not await hass.config_entries.async_unload_platforms(entry, PLATFORMS): return False - hass.services.async_remove(DOMAIN, SERVICE_SEND) - rfx_object = hass.data[DOMAIN][DATA_RFXOBJECT] await hass.async_add_executor_job(rfx_object.close_connection) - hass.data.pop(DOMAIN) + hass.data[DOMAIN].pop(DATA_RFXOBJECT) return True @@ -284,13 +278,6 @@ async def async_setup_internal(hass: HomeAssistant, entry: ConfigEntry) -> None: hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _shutdown_rfxtrx) ) - def send(call: ServiceCall) -> None: - event = call.data[ATTR_EVENT] - rfx_object.transport.send(event) - - # pylint: disable-next=home-assistant-service-registered-in-setup-entry - hass.services.async_register(DOMAIN, SERVICE_SEND, send, schema=SERVICE_SEND_SCHEMA) - async def async_setup_platform_entry( hass: HomeAssistant, diff --git a/homeassistant/components/rfxtrx/services.py b/homeassistant/components/rfxtrx/services.py new file mode 100644 index 00000000000..c1981dbc122 --- /dev/null +++ b/homeassistant/components/rfxtrx/services.py @@ -0,0 +1,37 @@ +"""Support for RFXtrx services.""" + +from typing import Any + +import voluptuous as vol + +from homeassistant.core import HomeAssistant, ServiceCall, callback +from homeassistant.exceptions import HomeAssistantError +from homeassistant.helpers import config_validation as cv + +from .const import ATTR_EVENT, DATA_RFXOBJECT, DOMAIN, SERVICE_SEND + + +def _bytearray_string(data: Any) -> bytearray: + val = cv.string(data) + try: + return bytearray.fromhex(val) + except ValueError as err: + raise vol.Invalid( + "Data must be a hex string with multiple of two characters" + ) from err + + +SERVICE_SEND_SCHEMA = vol.Schema({ATTR_EVENT: _bytearray_string}) + + +@callback +def async_setup_services(hass: HomeAssistant) -> None: + """Register the RFXtrx services.""" + + def send(call: ServiceCall) -> None: + rfx_object = hass.data.get(DOMAIN, {}).get(DATA_RFXOBJECT) + if rfx_object is None: + raise HomeAssistantError("RFXtrx is not connected, cannot send event") + rfx_object.transport.send(call.data[ATTR_EVENT]) + + hass.services.async_register(DOMAIN, SERVICE_SEND, send, schema=SERVICE_SEND_SCHEMA)