mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Move deCONZ services to their own file (#26645)
This commit is contained in:
parent
1d3f2d20d2
commit
5885c3f353
@ -10,10 +10,10 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
|
||||||
# Loading the config flow file will register the flow
|
|
||||||
from .config_flow import get_master_gateway
|
from .config_flow import get_master_gateway
|
||||||
from .const import CONF_BRIDGEID, CONF_MASTER_GATEWAY, DEFAULT_PORT, DOMAIN, _LOGGER
|
from .const import CONF_BRIDGEID, CONF_MASTER_GATEWAY, DEFAULT_PORT, DOMAIN
|
||||||
from .gateway import DeconzGateway
|
from .gateway import DeconzGateway
|
||||||
|
from .services import async_setup_services, async_unload_services
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema(
|
CONFIG_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
@ -28,28 +28,6 @@ CONFIG_SCHEMA = vol.Schema(
|
|||||||
extra=vol.ALLOW_EXTRA,
|
extra=vol.ALLOW_EXTRA,
|
||||||
)
|
)
|
||||||
|
|
||||||
SERVICE_DECONZ = "configure"
|
|
||||||
|
|
||||||
SERVICE_FIELD = "field"
|
|
||||||
SERVICE_ENTITY = "entity"
|
|
||||||
SERVICE_DATA = "data"
|
|
||||||
|
|
||||||
SERVICE_SCHEMA = vol.All(
|
|
||||||
vol.Schema(
|
|
||||||
{
|
|
||||||
vol.Optional(SERVICE_ENTITY): cv.entity_id,
|
|
||||||
vol.Optional(SERVICE_FIELD): cv.matches_regex("/.*"),
|
|
||||||
vol.Required(SERVICE_DATA): dict,
|
|
||||||
vol.Optional(CONF_BRIDGEID): str,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
cv.has_at_least_one_key(SERVICE_ENTITY, SERVICE_FIELD),
|
|
||||||
)
|
|
||||||
|
|
||||||
SERVICE_DEVICE_REFRESH = "device_refresh"
|
|
||||||
|
|
||||||
SERVICE_DEVICE_REFRESCH_SCHEMA = vol.All(vol.Schema({vol.Optional(CONF_BRIDGEID): str}))
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass, config):
|
async def async_setup(hass, config):
|
||||||
"""Load configuration for deCONZ component.
|
"""Load configuration for deCONZ component.
|
||||||
@ -89,100 +67,10 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
|
|
||||||
await gateway.async_update_device_registry()
|
await gateway.async_update_device_registry()
|
||||||
|
|
||||||
async def async_configure(call):
|
await async_setup_services(hass)
|
||||||
"""Set attribute of device in deCONZ.
|
|
||||||
|
|
||||||
Entity is used to resolve to a device path (e.g. '/lights/1').
|
|
||||||
Field is a string representing either a full path
|
|
||||||
(e.g. '/lights/1/state') when entity is not specified, or a
|
|
||||||
subpath (e.g. '/state') when used together with entity.
|
|
||||||
Data is a json object with what data you want to alter
|
|
||||||
e.g. data={'on': true}.
|
|
||||||
{
|
|
||||||
"field": "/lights/1/state",
|
|
||||||
"data": {"on": true}
|
|
||||||
}
|
|
||||||
See Dresden Elektroniks REST API documentation for details:
|
|
||||||
http://dresden-elektronik.github.io/deconz-rest-doc/rest/
|
|
||||||
"""
|
|
||||||
field = call.data.get(SERVICE_FIELD, "")
|
|
||||||
entity_id = call.data.get(SERVICE_ENTITY)
|
|
||||||
data = call.data[SERVICE_DATA]
|
|
||||||
|
|
||||||
gateway = get_master_gateway(hass)
|
|
||||||
if CONF_BRIDGEID in call.data:
|
|
||||||
gateway = hass.data[DOMAIN][call.data[CONF_BRIDGEID]]
|
|
||||||
|
|
||||||
if entity_id:
|
|
||||||
try:
|
|
||||||
field = gateway.deconz_ids[entity_id] + field
|
|
||||||
except KeyError:
|
|
||||||
_LOGGER.error("Could not find the entity %s", entity_id)
|
|
||||||
return
|
|
||||||
|
|
||||||
await gateway.api.async_put_state(field, data)
|
|
||||||
|
|
||||||
hass.services.async_register(
|
|
||||||
DOMAIN, SERVICE_DECONZ, async_configure, schema=SERVICE_SCHEMA
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_refresh_devices(call):
|
|
||||||
"""Refresh available devices from deCONZ."""
|
|
||||||
gateway = get_master_gateway(hass)
|
|
||||||
if CONF_BRIDGEID in call.data:
|
|
||||||
gateway = hass.data[DOMAIN][call.data[CONF_BRIDGEID]]
|
|
||||||
|
|
||||||
groups = set(gateway.api.groups.keys())
|
|
||||||
lights = set(gateway.api.lights.keys())
|
|
||||||
scenes = set(gateway.api.scenes.keys())
|
|
||||||
sensors = set(gateway.api.sensors.keys())
|
|
||||||
|
|
||||||
await gateway.api.async_load_parameters()
|
|
||||||
|
|
||||||
gateway.async_add_device_callback(
|
|
||||||
"group",
|
|
||||||
[
|
|
||||||
group
|
|
||||||
for group_id, group in gateway.api.groups.items()
|
|
||||||
if group_id not in groups
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
gateway.async_add_device_callback(
|
|
||||||
"light",
|
|
||||||
[
|
|
||||||
light
|
|
||||||
for light_id, light in gateway.api.lights.items()
|
|
||||||
if light_id not in lights
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
gateway.async_add_device_callback(
|
|
||||||
"scene",
|
|
||||||
[
|
|
||||||
scene
|
|
||||||
for scene_id, scene in gateway.api.scenes.items()
|
|
||||||
if scene_id not in scenes
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
gateway.async_add_device_callback(
|
|
||||||
"sensor",
|
|
||||||
[
|
|
||||||
sensor
|
|
||||||
for sensor_id, sensor in gateway.api.sensors.items()
|
|
||||||
if sensor_id not in sensors
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
hass.services.async_register(
|
|
||||||
DOMAIN,
|
|
||||||
SERVICE_DEVICE_REFRESH,
|
|
||||||
async_refresh_devices,
|
|
||||||
schema=SERVICE_DEVICE_REFRESCH_SCHEMA,
|
|
||||||
)
|
|
||||||
|
|
||||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, gateway.shutdown)
|
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, gateway.shutdown)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -191,8 +79,7 @@ async def async_unload_entry(hass, config_entry):
|
|||||||
gateway = hass.data[DOMAIN].pop(config_entry.data[CONF_BRIDGEID])
|
gateway = hass.data[DOMAIN].pop(config_entry.data[CONF_BRIDGEID])
|
||||||
|
|
||||||
if not hass.data[DOMAIN]:
|
if not hass.data[DOMAIN]:
|
||||||
hass.services.async_remove(DOMAIN, SERVICE_DECONZ)
|
await async_unload_services(hass)
|
||||||
hass.services.async_remove(DOMAIN, SERVICE_DEVICE_REFRESH)
|
|
||||||
|
|
||||||
elif gateway.master:
|
elif gateway.master:
|
||||||
await async_update_master_gateway(hass, config_entry)
|
await async_update_master_gateway(hass, config_entry)
|
||||||
|
157
homeassistant/components/deconz/services.py
Normal file
157
homeassistant/components/deconz/services.py
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
"""deCONZ services."""
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
|
||||||
|
from .config_flow import get_master_gateway
|
||||||
|
from .const import CONF_BRIDGEID, DOMAIN, _LOGGER
|
||||||
|
|
||||||
|
DECONZ_SERVICES = "deconz_services"
|
||||||
|
|
||||||
|
SERVICE_FIELD = "field"
|
||||||
|
SERVICE_ENTITY = "entity"
|
||||||
|
SERVICE_DATA = "data"
|
||||||
|
|
||||||
|
SERVICE_CONFIGURE_DEVICE = "configure"
|
||||||
|
SERVICE_CONFIGURE_DEVICE_SCHEMA = vol.All(
|
||||||
|
vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Optional(SERVICE_ENTITY): cv.entity_id,
|
||||||
|
vol.Optional(SERVICE_FIELD): cv.matches_regex("/.*"),
|
||||||
|
vol.Required(SERVICE_DATA): dict,
|
||||||
|
vol.Optional(CONF_BRIDGEID): str,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.has_at_least_one_key(SERVICE_ENTITY, SERVICE_FIELD),
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_DEVICE_REFRESH = "device_refresh"
|
||||||
|
SERVICE_DEVICE_REFRESH_SCHEMA = vol.All(vol.Schema({vol.Optional(CONF_BRIDGEID): str}))
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_services(hass):
|
||||||
|
"""Set up services for deCONZ integration."""
|
||||||
|
if hass.data.get(DECONZ_SERVICES, False):
|
||||||
|
return
|
||||||
|
|
||||||
|
hass.data[DECONZ_SERVICES] = True
|
||||||
|
|
||||||
|
async def async_call_deconz_service(service_call):
|
||||||
|
"""Call correct deCONZ service."""
|
||||||
|
service = service_call.service
|
||||||
|
service_data = service_call.data
|
||||||
|
|
||||||
|
if service == SERVICE_CONFIGURE_DEVICE:
|
||||||
|
await async_configure_service(hass, service_data)
|
||||||
|
|
||||||
|
elif service == SERVICE_DEVICE_REFRESH:
|
||||||
|
await async_refresh_devices_service(hass, service_data)
|
||||||
|
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_CONFIGURE_DEVICE,
|
||||||
|
async_call_deconz_service,
|
||||||
|
schema=SERVICE_CONFIGURE_DEVICE_SCHEMA,
|
||||||
|
)
|
||||||
|
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_DEVICE_REFRESH,
|
||||||
|
async_call_deconz_service,
|
||||||
|
schema=SERVICE_DEVICE_REFRESH_SCHEMA,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_services(hass):
|
||||||
|
"""Unload deCONZ services."""
|
||||||
|
if not hass.data.get(DECONZ_SERVICES):
|
||||||
|
return
|
||||||
|
|
||||||
|
hass.data[DECONZ_SERVICES] = False
|
||||||
|
|
||||||
|
hass.services.async_remove(DOMAIN, SERVICE_CONFIGURE_DEVICE)
|
||||||
|
hass.services.async_remove(DOMAIN, SERVICE_DEVICE_REFRESH)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_configure_service(hass, data):
|
||||||
|
"""Set attribute of device in deCONZ.
|
||||||
|
|
||||||
|
Entity is used to resolve to a device path (e.g. '/lights/1').
|
||||||
|
Field is a string representing either a full path
|
||||||
|
(e.g. '/lights/1/state') when entity is not specified, or a
|
||||||
|
subpath (e.g. '/state') when used together with entity.
|
||||||
|
Data is a json object with what data you want to alter
|
||||||
|
e.g. data={'on': true}.
|
||||||
|
{
|
||||||
|
"field": "/lights/1/state",
|
||||||
|
"data": {"on": true}
|
||||||
|
}
|
||||||
|
See Dresden Elektroniks REST API documentation for details:
|
||||||
|
http://dresden-elektronik.github.io/deconz-rest-doc/rest/
|
||||||
|
"""
|
||||||
|
field = data.get(SERVICE_FIELD, "")
|
||||||
|
entity_id = data.get(SERVICE_ENTITY)
|
||||||
|
data = data[SERVICE_DATA]
|
||||||
|
|
||||||
|
gateway = get_master_gateway(hass)
|
||||||
|
if CONF_BRIDGEID in data:
|
||||||
|
gateway = hass.data[DOMAIN][data[CONF_BRIDGEID]]
|
||||||
|
|
||||||
|
if entity_id:
|
||||||
|
try:
|
||||||
|
field = gateway.deconz_ids[entity_id] + field
|
||||||
|
except KeyError:
|
||||||
|
_LOGGER.error("Could not find the entity %s", entity_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
await gateway.api.async_put_state(field, data)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_refresh_devices_service(hass, data):
|
||||||
|
"""Refresh available devices from deCONZ."""
|
||||||
|
gateway = get_master_gateway(hass)
|
||||||
|
if CONF_BRIDGEID in data:
|
||||||
|
gateway = hass.data[DOMAIN][data[CONF_BRIDGEID]]
|
||||||
|
|
||||||
|
groups = set(gateway.api.groups.keys())
|
||||||
|
lights = set(gateway.api.lights.keys())
|
||||||
|
scenes = set(gateway.api.scenes.keys())
|
||||||
|
sensors = set(gateway.api.sensors.keys())
|
||||||
|
|
||||||
|
await gateway.api.async_load_parameters()
|
||||||
|
|
||||||
|
gateway.async_add_device_callback(
|
||||||
|
"group",
|
||||||
|
[
|
||||||
|
group
|
||||||
|
for group_id, group in gateway.api.groups.items()
|
||||||
|
if group_id not in groups
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
gateway.async_add_device_callback(
|
||||||
|
"light",
|
||||||
|
[
|
||||||
|
light
|
||||||
|
for light_id, light in gateway.api.lights.items()
|
||||||
|
if light_id not in lights
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
gateway.async_add_device_callback(
|
||||||
|
"scene",
|
||||||
|
[
|
||||||
|
scene
|
||||||
|
for scene_id, scene in gateway.api.scenes.items()
|
||||||
|
if scene_id not in scenes
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
gateway.async_add_device_callback(
|
||||||
|
"sensor",
|
||||||
|
[
|
||||||
|
sensor
|
||||||
|
for sensor_id, sensor in gateway.api.sensors.items()
|
||||||
|
if sensor_id not in sensors
|
||||||
|
],
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user