Skip to content
Snippets Groups Projects
Unverified Commit 901b2b4b authored by David F. Mulcahey's avatar David F. Mulcahey Committed by GitHub
Browse files

new websocket api way (#21533)

parent b8a94c30
No related branches found
No related tags found
No related merge requests found
......@@ -14,7 +14,8 @@ import homeassistant.helpers.config_validation as cv
from .core.const import (
DOMAIN, ATTR_CLUSTER_ID, ATTR_CLUSTER_TYPE, ATTR_ATTRIBUTE, ATTR_VALUE,
ATTR_MANUFACTURER, ATTR_COMMAND, ATTR_COMMAND_TYPE, ATTR_ARGS, IN, OUT,
CLIENT_COMMANDS, SERVER_COMMANDS, SERVER, NAME, ATTR_ENDPOINT_ID)
CLIENT_COMMANDS, SERVER_COMMANDS, SERVER, NAME, ATTR_ENDPOINT_ID,
DATA_ZHA_GATEWAY, DATA_ZHA)
from .core.helpers import get_matched_clusters, async_is_bindable_target
_LOGGER = logging.getLogger(__name__)
......@@ -71,73 +72,308 @@ SERVICE_SCHEMAS = {
}),
}
WS_RECONFIGURE_NODE = 'zha/devices/reconfigure'
SCHEMA_WS_RECONFIGURE_NODE = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required(TYPE): WS_RECONFIGURE_NODE,
vol.Required(ATTR_IEEE): str
})
WS_DEVICES = 'zha/devices'
SCHEMA_WS_LIST_DEVICES = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required(TYPE): WS_DEVICES,
@websocket_api.async_response
@websocket_api.websocket_command({
vol.Required(TYPE): 'zha/devices'
})
WS_DEVICE_CLUSTERS = 'zha/devices/clusters'
SCHEMA_WS_CLUSTERS = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required(TYPE): WS_DEVICE_CLUSTERS,
async def websocket_get_devices(hass, connection, msg):
"""Get ZHA devices."""
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
devices = [
{
**device.device_info,
'entities': [{
'entity_id': entity_ref.reference_id,
NAME: entity_ref.device_info[NAME]
} for entity_ref in zha_gateway.device_registry[device.ieee]]
} for device in zha_gateway.devices.values()
]
connection.send_result(msg[ID], devices)
@websocket_api.async_response
@websocket_api.websocket_command({
vol.Required(TYPE): 'zha/devices/reconfigure',
vol.Required(ATTR_IEEE): str
})
WS_DEVICE_CLUSTER_ATTRIBUTES = 'zha/devices/clusters/attributes'
SCHEMA_WS_CLUSTER_ATTRIBUTES = \
websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required(TYPE): WS_DEVICE_CLUSTER_ATTRIBUTES,
vol.Required(ATTR_IEEE): str,
vol.Required(ATTR_ENDPOINT_ID): int,
vol.Required(ATTR_CLUSTER_ID): int,
vol.Required(ATTR_CLUSTER_TYPE): str
})
WS_READ_CLUSTER_ATTRIBUTE = 'zha/devices/clusters/attributes/value'
SCHEMA_WS_READ_CLUSTER_ATTRIBUTE = \
websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required(TYPE): WS_READ_CLUSTER_ATTRIBUTE,
vol.Required(ATTR_IEEE): str,
vol.Required(ATTR_ENDPOINT_ID): int,
vol.Required(ATTR_CLUSTER_ID): int,
vol.Required(ATTR_CLUSTER_TYPE): str,
vol.Required(ATTR_ATTRIBUTE): int,
vol.Optional(ATTR_MANUFACTURER): object,
})
WS_DEVICE_CLUSTER_COMMANDS = 'zha/devices/clusters/commands'
SCHEMA_WS_CLUSTER_COMMANDS = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required(TYPE): WS_DEVICE_CLUSTER_COMMANDS,
async def websocket_reconfigure_node(hass, connection, msg):
"""Reconfigure a ZHA nodes entities by its ieee address."""
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
ieee = msg[ATTR_IEEE]
device = zha_gateway.get_device(ieee)
_LOGGER.debug("Reconfiguring node with ieee_address: %s", ieee)
hass.async_create_task(device.async_configure())
@websocket_api.async_response
@websocket_api.websocket_command({
vol.Required(TYPE): 'zha/devices/clusters',
vol.Required(ATTR_IEEE): str
})
async def websocket_device_clusters(hass, connection, msg):
"""Return a list of device clusters."""
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
ieee = msg[ATTR_IEEE]
zha_device = zha_gateway.get_device(ieee)
response_clusters = []
if zha_device is not None:
clusters_by_endpoint = zha_device.async_get_clusters()
for ep_id, clusters in clusters_by_endpoint.items():
for c_id, cluster in clusters[IN].items():
response_clusters.append({
TYPE: IN,
ID: c_id,
NAME: cluster.__class__.__name__,
'endpoint_id': ep_id
})
for c_id, cluster in clusters[OUT].items():
response_clusters.append({
TYPE: OUT,
ID: c_id,
NAME: cluster.__class__.__name__,
'endpoint_id': ep_id
})
connection.send_result(msg[ID], response_clusters)
@websocket_api.async_response
@websocket_api.websocket_command({
vol.Required(TYPE): 'zha/devices/clusters/attributes',
vol.Required(ATTR_IEEE): str,
vol.Required(ATTR_ENDPOINT_ID): int,
vol.Required(ATTR_CLUSTER_ID): int,
vol.Required(ATTR_CLUSTER_TYPE): str
})
WS_BIND_DEVICE = 'zha/devices/bind'
SCHEMA_WS_BIND_DEVICE = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required(TYPE): WS_BIND_DEVICE,
async def websocket_device_cluster_attributes(hass, connection, msg):
"""Return a list of cluster attributes."""
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
ieee = msg[ATTR_IEEE]
endpoint_id = msg[ATTR_ENDPOINT_ID]
cluster_id = msg[ATTR_CLUSTER_ID]
cluster_type = msg[ATTR_CLUSTER_TYPE]
cluster_attributes = []
zha_device = zha_gateway.get_device(ieee)
attributes = None
if zha_device is not None:
attributes = zha_device.async_get_cluster_attributes(
endpoint_id,
cluster_id,
cluster_type)
if attributes is not None:
for attr_id in attributes:
cluster_attributes.append(
{
ID: attr_id,
NAME: attributes[attr_id][0]
}
)
_LOGGER.debug("Requested attributes for: %s %s %s %s",
"{}: [{}]".format(ATTR_CLUSTER_ID, cluster_id),
"{}: [{}]".format(ATTR_CLUSTER_TYPE, cluster_type),
"{}: [{}]".format(ATTR_ENDPOINT_ID, endpoint_id),
"{}: [{}]".format(RESPONSE, cluster_attributes)
)
connection.send_result(msg[ID], cluster_attributes)
@websocket_api.async_response
@websocket_api.websocket_command({
vol.Required(TYPE): 'zha/devices/clusters/commands',
vol.Required(ATTR_IEEE): str,
vol.Required(ATTR_ENDPOINT_ID): int,
vol.Required(ATTR_CLUSTER_ID): int,
vol.Required(ATTR_CLUSTER_TYPE): str
})
async def websocket_device_cluster_commands(hass, connection, msg):
"""Return a list of cluster commands."""
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
cluster_id = msg[ATTR_CLUSTER_ID]
cluster_type = msg[ATTR_CLUSTER_TYPE]
ieee = msg[ATTR_IEEE]
endpoint_id = msg[ATTR_ENDPOINT_ID]
zha_device = zha_gateway.get_device(ieee)
cluster_commands = []
commands = None
if zha_device is not None:
commands = zha_device.async_get_cluster_commands(
endpoint_id,
cluster_id,
cluster_type)
if commands is not None:
for cmd_id in commands[CLIENT_COMMANDS]:
cluster_commands.append(
{
TYPE: CLIENT,
ID: cmd_id,
NAME: commands[CLIENT_COMMANDS][cmd_id][0]
}
)
for cmd_id in commands[SERVER_COMMANDS]:
cluster_commands.append(
{
TYPE: SERVER,
ID: cmd_id,
NAME: commands[SERVER_COMMANDS][cmd_id][0]
}
)
_LOGGER.debug("Requested commands for: %s %s %s %s",
"{}: [{}]".format(ATTR_CLUSTER_ID, cluster_id),
"{}: [{}]".format(ATTR_CLUSTER_TYPE, cluster_type),
"{}: [{}]".format(ATTR_ENDPOINT_ID, endpoint_id),
"{}: [{}]".format(RESPONSE, cluster_commands)
)
connection.send_result(msg[ID], cluster_commands)
@websocket_api.async_response
@websocket_api.websocket_command({
vol.Required(TYPE): 'zha/devices/clusters/attributes/value',
vol.Required(ATTR_IEEE): str,
vol.Required(ATTR_ENDPOINT_ID): int,
vol.Required(ATTR_CLUSTER_ID): int,
vol.Required(ATTR_CLUSTER_TYPE): str,
vol.Required(ATTR_ATTRIBUTE): int,
vol.Optional(ATTR_MANUFACTURER): object,
})
async def websocket_read_zigbee_cluster_attributes(hass, connection, msg):
"""Read zigbee attribute for cluster on zha entity."""
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
ieee = msg[ATTR_IEEE]
endpoint_id = msg[ATTR_ENDPOINT_ID]
cluster_id = msg[ATTR_CLUSTER_ID]
cluster_type = msg[ATTR_CLUSTER_TYPE]
attribute = msg[ATTR_ATTRIBUTE]
manufacturer = msg.get(ATTR_MANUFACTURER) or None
zha_device = zha_gateway.get_device(ieee)
success = failure = None
if zha_device is not None:
cluster = zha_device.async_get_cluster(
endpoint_id, cluster_id, cluster_type=cluster_type)
success, failure = await cluster.read_attributes(
[attribute],
allow_cache=False,
only_cache=False,
manufacturer=manufacturer
)
_LOGGER.debug("Read attribute for: %s %s %s %s %s %s %s",
"{}: [{}]".format(ATTR_CLUSTER_ID, cluster_id),
"{}: [{}]".format(ATTR_CLUSTER_TYPE, cluster_type),
"{}: [{}]".format(ATTR_ENDPOINT_ID, endpoint_id),
"{}: [{}]".format(ATTR_ATTRIBUTE, attribute),
"{}: [{}]".format(ATTR_MANUFACTURER, manufacturer),
"{}: [{}]".format(RESPONSE, str(success.get(attribute))),
"{}: [{}]".format('failure', failure)
)
connection.send_result(msg[ID], str(success.get(attribute)))
@websocket_api.async_response
@websocket_api.websocket_command({
vol.Required(TYPE): 'zha/devices/bindable',
vol.Required(ATTR_IEEE): str,
})
async def websocket_get_bindable_devices(hass, connection, msg):
"""Directly bind devices."""
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
source_ieee = msg[ATTR_IEEE]
source_device = zha_gateway.get_device(source_ieee)
devices = [
{
**device.device_info
} for device in zha_gateway.devices.values() if
async_is_bindable_target(source_device, device)
]
_LOGGER.debug("Get bindable devices: %s %s",
"{}: [{}]".format(ATTR_SOURCE_IEEE, source_ieee),
"{}: [{}]".format('bindable devices:', devices)
)
connection.send_message(websocket_api.result_message(
msg[ID],
devices
))
@websocket_api.async_response
@websocket_api.websocket_command({
vol.Required(TYPE): 'zha/devices/bind',
vol.Required(ATTR_SOURCE_IEEE): str,
vol.Required(ATTR_TARGET_IEEE): str
})
WS_UNBIND_DEVICE = 'zha/devices/unbind'
SCHEMA_WS_UNBIND_DEVICE = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required(TYPE): WS_UNBIND_DEVICE,
async def websocket_bind_devices(hass, connection, msg):
"""Directly bind devices."""
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
source_ieee = msg[ATTR_SOURCE_IEEE]
target_ieee = msg[ATTR_TARGET_IEEE]
await async_binding_operation(
zha_gateway, source_ieee, target_ieee, BIND_REQUEST)
_LOGGER.info("Issue bind devices: %s %s",
"{}: [{}]".format(ATTR_SOURCE_IEEE, source_ieee),
"{}: [{}]".format(ATTR_TARGET_IEEE, target_ieee)
)
@websocket_api.async_response
@websocket_api.websocket_command({
vol.Required(TYPE): 'zha/devices/unbind',
vol.Required(ATTR_SOURCE_IEEE): str,
vol.Required(ATTR_TARGET_IEEE): str
})
WS_BINDABLE_DEVICES = 'zha/devices/bindable'
SCHEMA_WS_BINDABLE_DEVICES = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required(TYPE): WS_BINDABLE_DEVICES,
vol.Required(ATTR_IEEE): str
})
async def websocket_unbind_devices(hass, connection, msg):
"""Remove a direct binding between devices."""
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
source_ieee = msg[ATTR_SOURCE_IEEE]
target_ieee = msg[ATTR_TARGET_IEEE]
await async_binding_operation(
zha_gateway, source_ieee, target_ieee, UNBIND_REQUEST)
_LOGGER.info("Issue unbind devices: %s %s",
"{}: [{}]".format(ATTR_SOURCE_IEEE, source_ieee),
"{}: [{}]".format(ATTR_TARGET_IEEE, target_ieee)
)
async def async_binding_operation(zha_gateway, source_ieee, target_ieee,
operation):
"""Create or remove a direct zigbee binding between 2 devices."""
from zigpy.zdo import types as zdo_types
source_device = zha_gateway.get_device(source_ieee)
target_device = zha_gateway.get_device(target_ieee)
clusters_to_bind = await get_matched_clusters(source_device,
target_device)
bind_tasks = []
for cluster_pair in clusters_to_bind:
destination_address = zdo_types.MultiAddress()
destination_address.addrmode = 3
destination_address.ieee = target_device.ieee
destination_address.endpoint = \
cluster_pair.target_cluster.endpoint.endpoint_id
zdo = cluster_pair.source_cluster.endpoint.device.zdo
_LOGGER.debug("processing binding operation for: %s %s %s",
"{}: [{}]".format(ATTR_SOURCE_IEEE, source_ieee),
"{}: [{}]".format(ATTR_TARGET_IEEE, target_ieee),
"{}: {}".format(
'cluster',
cluster_pair.source_cluster.cluster_id)
)
bind_tasks.append(zdo.request(
operation,
source_device.ieee,
cluster_pair.source_cluster.endpoint.endpoint_id,
cluster_pair.source_cluster.cluster_id,
destination_address
))
await asyncio.gather(*bind_tasks)
def async_load_api(hass, application_controller, zha_gateway):
......@@ -237,301 +473,18 @@ def async_load_api(hass, application_controller, zha_gateway):
SERVICE_ISSUE_ZIGBEE_CLUSTER_COMMAND
])
@websocket_api.async_response
async def websocket_get_devices(hass, connection, msg):
"""Get ZHA devices."""
devices = [
{
**device.device_info,
'entities': [{
'entity_id': entity_ref.reference_id,
NAME: entity_ref.device_info[NAME]
} for entity_ref in zha_gateway.device_registry[device.ieee]]
} for device in zha_gateway.devices.values()
]
connection.send_message(websocket_api.result_message(
msg[ID],
devices
))
hass.components.websocket_api.async_register_command(
WS_DEVICES, websocket_get_devices,
SCHEMA_WS_LIST_DEVICES
)
@websocket_api.async_response
async def websocket_reconfigure_node(hass, connection, msg):
"""Reconfigure a ZHA nodes entities by its ieee address."""
ieee = msg[ATTR_IEEE]
device = zha_gateway.get_device(ieee)
_LOGGER.debug("Reconfiguring node with ieee_address: %s", ieee)
hass.async_create_task(device.async_configure())
hass.components.websocket_api.async_register_command(
WS_RECONFIGURE_NODE, websocket_reconfigure_node,
SCHEMA_WS_RECONFIGURE_NODE
)
@websocket_api.async_response
async def websocket_get_bindable_devices(hass, connection, msg):
"""Directly bind devices."""
source_ieee = msg[ATTR_IEEE]
source_device = zha_gateway.get_device(source_ieee)
devices = [
{
**device.device_info
} for device in zha_gateway.devices.values() if
async_is_bindable_target(source_device, device)
]
_LOGGER.debug("Get bindable devices: %s %s",
"{}: [{}]".format(ATTR_SOURCE_IEEE, source_ieee),
"{}: [{}]".format('bindable devices:', devices)
)
connection.send_message(websocket_api.result_message(
msg[ID],
devices
))
hass.components.websocket_api.async_register_command(
WS_BINDABLE_DEVICES, websocket_get_bindable_devices,
SCHEMA_WS_BINDABLE_DEVICES
)
@websocket_api.async_response
async def websocket_bind_devices(hass, connection, msg):
"""Directly bind devices."""
source_ieee = msg[ATTR_SOURCE_IEEE]
target_ieee = msg[ATTR_TARGET_IEEE]
await async_binding_operation(
source_ieee, target_ieee, BIND_REQUEST)
_LOGGER.info("Issue bind devices: %s %s",
"{}: [{}]".format(ATTR_SOURCE_IEEE, source_ieee),
"{}: [{}]".format(ATTR_TARGET_IEEE, target_ieee)
)
hass.components.websocket_api.async_register_command(
WS_BIND_DEVICE, websocket_bind_devices,
SCHEMA_WS_BIND_DEVICE
)
@websocket_api.async_response
async def websocket_unbind_devices(hass, connection, msg):
"""Remove a direct binding between devices."""
source_ieee = msg[ATTR_SOURCE_IEEE]
target_ieee = msg[ATTR_TARGET_IEEE]
await async_binding_operation(
source_ieee, target_ieee, UNBIND_REQUEST)
_LOGGER.info("Issue unbind devices: %s %s",
"{}: [{}]".format(ATTR_SOURCE_IEEE, source_ieee),
"{}: [{}]".format(ATTR_TARGET_IEEE, target_ieee)
)
hass.components.websocket_api.async_register_command(
WS_UNBIND_DEVICE, websocket_unbind_devices,
SCHEMA_WS_UNBIND_DEVICE
)
async def async_binding_operation(source_ieee, target_ieee,
operation):
"""Create or remove a direct zigbee binding between 2 devices."""
from zigpy.zdo import types as zdo_types
source_device = zha_gateway.get_device(source_ieee)
target_device = zha_gateway.get_device(target_ieee)
clusters_to_bind = await get_matched_clusters(source_device,
target_device)
bind_tasks = []
for cluster_pair in clusters_to_bind:
destination_address = zdo_types.MultiAddress()
destination_address.addrmode = 3
destination_address.ieee = target_device.ieee
destination_address.endpoint = \
cluster_pair.target_cluster.endpoint.endpoint_id
zdo = cluster_pair.source_cluster.endpoint.device.zdo
_LOGGER.debug("processing binding operation for: %s %s %s",
"{}: [{}]".format(ATTR_SOURCE_IEEE, source_ieee),
"{}: [{}]".format(ATTR_TARGET_IEEE, target_ieee),
"{}: {}".format(
'cluster',
cluster_pair.source_cluster.cluster_id)
)
bind_tasks.append(zdo.request(
operation,
source_device.ieee,
cluster_pair.source_cluster.endpoint.endpoint_id,
cluster_pair.source_cluster.cluster_id,
destination_address
))
await asyncio.gather(*bind_tasks)
@websocket_api.async_response
async def websocket_device_clusters(hass, connection, msg):
"""Return a list of device clusters."""
ieee = msg[ATTR_IEEE]
zha_device = zha_gateway.get_device(ieee)
response_clusters = []
if zha_device is not None:
clusters_by_endpoint = zha_device.async_get_clusters()
for ep_id, clusters in clusters_by_endpoint.items():
for c_id, cluster in clusters[IN].items():
response_clusters.append({
TYPE: IN,
ID: c_id,
NAME: cluster.__class__.__name__,
'endpoint_id': ep_id
})
for c_id, cluster in clusters[OUT].items():
response_clusters.append({
TYPE: OUT,
ID: c_id,
NAME: cluster.__class__.__name__,
'endpoint_id': ep_id
})
connection.send_message(websocket_api.result_message(
msg[ID],
response_clusters
))
hass.components.websocket_api.async_register_command(
WS_DEVICE_CLUSTERS, websocket_device_clusters,
SCHEMA_WS_CLUSTERS
)
@websocket_api.async_response
async def websocket_device_cluster_attributes(hass, connection, msg):
"""Return a list of cluster attributes."""
ieee = msg[ATTR_IEEE]
endpoint_id = msg[ATTR_ENDPOINT_ID]
cluster_id = msg[ATTR_CLUSTER_ID]
cluster_type = msg[ATTR_CLUSTER_TYPE]
cluster_attributes = []
zha_device = zha_gateway.get_device(ieee)
attributes = None
if zha_device is not None:
attributes = zha_device.async_get_cluster_attributes(
endpoint_id,
cluster_id,
cluster_type)
if attributes is not None:
for attr_id in attributes:
cluster_attributes.append(
{
ID: attr_id,
NAME: attributes[attr_id][0]
}
)
_LOGGER.debug("Requested attributes for: %s %s %s %s",
"{}: [{}]".format(ATTR_CLUSTER_ID, cluster_id),
"{}: [{}]".format(ATTR_CLUSTER_TYPE, cluster_type),
"{}: [{}]".format(ATTR_ENDPOINT_ID, endpoint_id),
"{}: [{}]".format(RESPONSE, cluster_attributes)
)
connection.send_message(websocket_api.result_message(
msg[ID],
cluster_attributes
))
hass.components.websocket_api.async_register_command(
WS_DEVICE_CLUSTER_ATTRIBUTES, websocket_device_cluster_attributes,
SCHEMA_WS_CLUSTER_ATTRIBUTES
)
@websocket_api.async_response
async def websocket_device_cluster_commands(hass, connection, msg):
"""Return a list of cluster commands."""
cluster_id = msg[ATTR_CLUSTER_ID]
cluster_type = msg[ATTR_CLUSTER_TYPE]
ieee = msg[ATTR_IEEE]
endpoint_id = msg[ATTR_ENDPOINT_ID]
zha_device = zha_gateway.get_device(ieee)
cluster_commands = []
commands = None
if zha_device is not None:
commands = zha_device.async_get_cluster_commands(
endpoint_id,
cluster_id,
cluster_type)
if commands is not None:
for cmd_id in commands[CLIENT_COMMANDS]:
cluster_commands.append(
{
TYPE: CLIENT,
ID: cmd_id,
NAME: commands[CLIENT_COMMANDS][cmd_id][0]
}
)
for cmd_id in commands[SERVER_COMMANDS]:
cluster_commands.append(
{
TYPE: SERVER,
ID: cmd_id,
NAME: commands[SERVER_COMMANDS][cmd_id][0]
}
)
_LOGGER.debug("Requested commands for: %s %s %s %s",
"{}: [{}]".format(ATTR_CLUSTER_ID, cluster_id),
"{}: [{}]".format(ATTR_CLUSTER_TYPE, cluster_type),
"{}: [{}]".format(ATTR_ENDPOINT_ID, endpoint_id),
"{}: [{}]".format(RESPONSE, cluster_commands)
)
connection.send_message(websocket_api.result_message(
msg[ID],
cluster_commands
))
hass.components.websocket_api.async_register_command(
WS_DEVICE_CLUSTER_COMMANDS, websocket_device_cluster_commands,
SCHEMA_WS_CLUSTER_COMMANDS
)
@websocket_api.async_response
async def websocket_read_zigbee_cluster_attributes(hass, connection, msg):
"""Read zigbee attribute for cluster on zha entity."""
ieee = msg[ATTR_IEEE]
endpoint_id = msg[ATTR_ENDPOINT_ID]
cluster_id = msg[ATTR_CLUSTER_ID]
cluster_type = msg[ATTR_CLUSTER_TYPE]
attribute = msg[ATTR_ATTRIBUTE]
manufacturer = msg.get(ATTR_MANUFACTURER) or None
zha_device = zha_gateway.get_device(ieee)
success = failure = None
if zha_device is not None:
cluster = zha_device.async_get_cluster(
endpoint_id, cluster_id, cluster_type=cluster_type)
success, failure = await cluster.read_attributes(
[attribute],
allow_cache=False,
only_cache=False,
manufacturer=manufacturer
)
_LOGGER.debug("Read attribute for: %s %s %s %s %s %s %s",
"{}: [{}]".format(ATTR_CLUSTER_ID, cluster_id),
"{}: [{}]".format(ATTR_CLUSTER_TYPE, cluster_type),
"{}: [{}]".format(ATTR_ENDPOINT_ID, endpoint_id),
"{}: [{}]".format(ATTR_ATTRIBUTE, attribute),
"{}: [{}]".format(ATTR_MANUFACTURER, manufacturer),
"{}: [{}]".format(RESPONSE, str(success.get(attribute))),
"{}: [{}]".format('failure', failure)
)
connection.send_message(websocket_api.result_message(
msg[ID],
str(success.get(attribute))
))
hass.components.websocket_api.async_register_command(
WS_READ_CLUSTER_ATTRIBUTE, websocket_read_zigbee_cluster_attributes,
SCHEMA_WS_READ_CLUSTER_ATTRIBUTE
)
websocket_api.async_register_command(hass, websocket_get_devices)
websocket_api.async_register_command(hass, websocket_reconfigure_node)
websocket_api.async_register_command(hass, websocket_device_clusters)
websocket_api.async_register_command(
hass, websocket_device_cluster_attributes)
websocket_api.async_register_command(
hass, websocket_device_cluster_commands)
websocket_api.async_register_command(
hass, websocket_read_zigbee_cluster_attributes)
websocket_api.async_register_command(hass, websocket_get_bindable_devices)
websocket_api.async_register_command(hass, websocket_bind_devices)
websocket_api.async_register_command(hass, websocket_unbind_devices)
def async_unload_api(hass):
......
......@@ -14,6 +14,7 @@ DATA_ZHA_RADIO = 'zha_radio'
DATA_ZHA_DISPATCHERS = 'zha_dispatchers'
DATA_ZHA_CORE_COMPONENT = 'zha_core_component'
DATA_ZHA_CORE_EVENTS = 'zha_core_events'
DATA_ZHA_GATEWAY = 'zha_gateway'
ZHA_DISCOVERY_NEW = 'zha_discovery_new_{}'
COMPONENTS = [
......
......@@ -22,7 +22,8 @@ from .const import (
OCCUPANCY, CLUSTER_REPORT_CONFIGS, REPORT_CONFIG_IMMEDIATE,
REPORT_CONFIG_ASAP, REPORT_CONFIG_DEFAULT, REPORT_CONFIG_MIN_INT,
REPORT_CONFIG_MAX_INT, REPORT_CONFIG_OP, SIGNAL_REMOVE,
NO_SENSOR_CLUSTERS, POWER_CONFIGURATION_CHANNEL, BINDABLE_CLUSTERS)
NO_SENSOR_CLUSTERS, POWER_CONFIGURATION_CHANNEL, BINDABLE_CLUSTERS,
DATA_ZHA_GATEWAY)
from .device import ZHADevice, DeviceStatus
from ..device_entity import ZhaDeviceEntity
from .channels import (
......@@ -52,6 +53,7 @@ class ZHAGateway:
self._devices = {}
self._device_registry = collections.defaultdict(list)
hass.data[DATA_ZHA][DATA_ZHA_CORE_COMPONENT] = self._component
hass.data[DATA_ZHA][DATA_ZHA_GATEWAY] = self
def device_joined(self, device):
"""Handle device joined.
......
......@@ -3,9 +3,7 @@ from unittest.mock import Mock
import pytest
from homeassistant.components.switch import DOMAIN
from homeassistant.components.zha.api import (
async_load_api, WS_DEVICE_CLUSTERS, ATTR_IEEE, TYPE,
ID, WS_DEVICE_CLUSTER_ATTRIBUTES, WS_DEVICE_CLUSTER_COMMANDS,
WS_DEVICES
async_load_api, ATTR_IEEE, TYPE, ID
)
from homeassistant.components.zha.core.const import (
ATTR_CLUSTER_ID, ATTR_CLUSTER_TYPE, IN, IEEE, MODEL, NAME, QUIRK_APPLIED,
......@@ -38,7 +36,7 @@ async def test_device_clusters(hass, config_entry, zha_gateway, zha_client):
"""Test getting device cluster info."""
await zha_client.send_json({
ID: 5,
TYPE: WS_DEVICE_CLUSTERS,
TYPE: 'zha/devices/clusters',
ATTR_IEEE: '00:0d:6f:00:0a:90:69:e7'
})
......@@ -64,7 +62,7 @@ async def test_device_cluster_attributes(
"""Test getting device cluster attributes."""
await zha_client.send_json({
ID: 5,
TYPE: WS_DEVICE_CLUSTER_ATTRIBUTES,
TYPE: 'zha/devices/clusters/attributes',
ATTR_ENDPOINT_ID: 1,
ATTR_IEEE: '00:0d:6f:00:0a:90:69:e7',
ATTR_CLUSTER_ID: 6,
......@@ -86,7 +84,7 @@ async def test_device_cluster_commands(
"""Test getting device cluster commands."""
await zha_client.send_json({
ID: 5,
TYPE: WS_DEVICE_CLUSTER_COMMANDS,
TYPE: 'zha/devices/clusters/commands',
ATTR_ENDPOINT_ID: 1,
ATTR_IEEE: '00:0d:6f:00:0a:90:69:e7',
ATTR_CLUSTER_ID: 6,
......@@ -109,7 +107,7 @@ async def test_list_devices(
"""Test getting entity cluster commands."""
await zha_client.send_json({
ID: 5,
TYPE: WS_DEVICES
TYPE: 'zha/devices'
})
msg = await zha_client.receive_json()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment