mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 11:47:06 +00:00
Leverage zigpy for IEEE address conversions (#27972)
* Refactor EUI64 conversions. * Update ZHA dependencies. * Update tests.
This commit is contained in:
parent
643257d911
commit
a0c50f4794
@ -4,6 +4,7 @@ import asyncio
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
from zigpy.types.named import EUI64
|
||||||
|
|
||||||
from homeassistant.components import websocket_api
|
from homeassistant.components import websocket_api
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
@ -44,7 +45,7 @@ from .core.const import (
|
|||||||
WARNING_DEVICE_STROBE_HIGH,
|
WARNING_DEVICE_STROBE_HIGH,
|
||||||
WARNING_DEVICE_STROBE_YES,
|
WARNING_DEVICE_STROBE_YES,
|
||||||
)
|
)
|
||||||
from .core.helpers import async_is_bindable_target, convert_ieee, get_matched_clusters
|
from .core.helpers import async_is_bindable_target, get_matched_clusters
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -76,16 +77,16 @@ IEEE_SERVICE = "ieee_based_service"
|
|||||||
SERVICE_SCHEMAS = {
|
SERVICE_SCHEMAS = {
|
||||||
SERVICE_PERMIT: vol.Schema(
|
SERVICE_PERMIT: vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Optional(ATTR_IEEE_ADDRESS, default=None): convert_ieee,
|
vol.Optional(ATTR_IEEE_ADDRESS, default=None): EUI64.convert,
|
||||||
vol.Optional(ATTR_DURATION, default=60): vol.All(
|
vol.Optional(ATTR_DURATION, default=60): vol.All(
|
||||||
vol.Coerce(int), vol.Range(0, 254)
|
vol.Coerce(int), vol.Range(0, 254)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
IEEE_SERVICE: vol.Schema({vol.Required(ATTR_IEEE_ADDRESS): convert_ieee}),
|
IEEE_SERVICE: vol.Schema({vol.Required(ATTR_IEEE_ADDRESS): EUI64.convert}),
|
||||||
SERVICE_SET_ZIGBEE_CLUSTER_ATTRIBUTE: vol.Schema(
|
SERVICE_SET_ZIGBEE_CLUSTER_ATTRIBUTE: vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
vol.Required(ATTR_IEEE): EUI64.convert,
|
||||||
vol.Required(ATTR_ENDPOINT_ID): cv.positive_int,
|
vol.Required(ATTR_ENDPOINT_ID): cv.positive_int,
|
||||||
vol.Required(ATTR_CLUSTER_ID): cv.positive_int,
|
vol.Required(ATTR_CLUSTER_ID): cv.positive_int,
|
||||||
vol.Optional(ATTR_CLUSTER_TYPE, default=CLUSTER_TYPE_IN): cv.string,
|
vol.Optional(ATTR_CLUSTER_TYPE, default=CLUSTER_TYPE_IN): cv.string,
|
||||||
@ -96,7 +97,7 @@ SERVICE_SCHEMAS = {
|
|||||||
),
|
),
|
||||||
SERVICE_WARNING_DEVICE_SQUAWK: vol.Schema(
|
SERVICE_WARNING_DEVICE_SQUAWK: vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
vol.Required(ATTR_IEEE): EUI64.convert,
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
ATTR_WARNING_DEVICE_MODE, default=WARNING_DEVICE_SQUAWK_MODE_ARMED
|
ATTR_WARNING_DEVICE_MODE, default=WARNING_DEVICE_SQUAWK_MODE_ARMED
|
||||||
): cv.positive_int,
|
): cv.positive_int,
|
||||||
@ -110,7 +111,7 @@ SERVICE_SCHEMAS = {
|
|||||||
),
|
),
|
||||||
SERVICE_WARNING_DEVICE_WARN: vol.Schema(
|
SERVICE_WARNING_DEVICE_WARN: vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
vol.Required(ATTR_IEEE): EUI64.convert,
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
ATTR_WARNING_DEVICE_MODE, default=WARNING_DEVICE_MODE_EMERGENCY
|
ATTR_WARNING_DEVICE_MODE, default=WARNING_DEVICE_MODE_EMERGENCY
|
||||||
): cv.positive_int,
|
): cv.positive_int,
|
||||||
@ -131,7 +132,7 @@ SERVICE_SCHEMAS = {
|
|||||||
),
|
),
|
||||||
SERVICE_ISSUE_ZIGBEE_CLUSTER_COMMAND: vol.Schema(
|
SERVICE_ISSUE_ZIGBEE_CLUSTER_COMMAND: vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
vol.Required(ATTR_IEEE): EUI64.convert,
|
||||||
vol.Required(ATTR_ENDPOINT_ID): cv.positive_int,
|
vol.Required(ATTR_ENDPOINT_ID): cv.positive_int,
|
||||||
vol.Required(ATTR_CLUSTER_ID): cv.positive_int,
|
vol.Required(ATTR_CLUSTER_ID): cv.positive_int,
|
||||||
vol.Optional(ATTR_CLUSTER_TYPE, default=CLUSTER_TYPE_IN): cv.string,
|
vol.Optional(ATTR_CLUSTER_TYPE, default=CLUSTER_TYPE_IN): cv.string,
|
||||||
@ -149,7 +150,7 @@ SERVICE_SCHEMAS = {
|
|||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{
|
{
|
||||||
vol.Required("type"): "zha/devices/permit",
|
vol.Required("type"): "zha/devices/permit",
|
||||||
vol.Optional(ATTR_IEEE, default=None): convert_ieee,
|
vol.Optional(ATTR_IEEE, default=None): EUI64.convert,
|
||||||
vol.Optional(ATTR_DURATION, default=60): vol.All(
|
vol.Optional(ATTR_DURATION, default=60): vol.All(
|
||||||
vol.Coerce(int), vol.Range(0, 254)
|
vol.Coerce(int), vol.Range(0, 254)
|
||||||
),
|
),
|
||||||
@ -200,7 +201,7 @@ async def websocket_get_devices(hass, connection, msg):
|
|||||||
@websocket_api.require_admin
|
@websocket_api.require_admin
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{vol.Required(TYPE): "zha/device", vol.Required(ATTR_IEEE): convert_ieee}
|
{vol.Required(TYPE): "zha/device", vol.Required(ATTR_IEEE): EUI64.convert}
|
||||||
)
|
)
|
||||||
async def websocket_get_device(hass, connection, msg):
|
async def websocket_get_device(hass, connection, msg):
|
||||||
"""Get ZHA devices."""
|
"""Get ZHA devices."""
|
||||||
@ -252,7 +253,7 @@ def async_get_device_info(hass, device, ha_device_registry=None):
|
|||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{
|
{
|
||||||
vol.Required(TYPE): "zha/devices/reconfigure",
|
vol.Required(TYPE): "zha/devices/reconfigure",
|
||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
vol.Required(ATTR_IEEE): EUI64.convert,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
async def websocket_reconfigure_node(hass, connection, msg):
|
async def websocket_reconfigure_node(hass, connection, msg):
|
||||||
@ -267,7 +268,7 @@ async def websocket_reconfigure_node(hass, connection, msg):
|
|||||||
@websocket_api.require_admin
|
@websocket_api.require_admin
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{vol.Required(TYPE): "zha/devices/clusters", vol.Required(ATTR_IEEE): convert_ieee}
|
{vol.Required(TYPE): "zha/devices/clusters", vol.Required(ATTR_IEEE): EUI64.convert}
|
||||||
)
|
)
|
||||||
async def websocket_device_clusters(hass, connection, msg):
|
async def websocket_device_clusters(hass, connection, msg):
|
||||||
"""Return a list of device clusters."""
|
"""Return a list of device clusters."""
|
||||||
@ -305,7 +306,7 @@ async def websocket_device_clusters(hass, connection, msg):
|
|||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{
|
{
|
||||||
vol.Required(TYPE): "zha/devices/clusters/attributes",
|
vol.Required(TYPE): "zha/devices/clusters/attributes",
|
||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
vol.Required(ATTR_IEEE): EUI64.convert,
|
||||||
vol.Required(ATTR_ENDPOINT_ID): int,
|
vol.Required(ATTR_ENDPOINT_ID): int,
|
||||||
vol.Required(ATTR_CLUSTER_ID): int,
|
vol.Required(ATTR_CLUSTER_ID): int,
|
||||||
vol.Required(ATTR_CLUSTER_TYPE): str,
|
vol.Required(ATTR_CLUSTER_TYPE): str,
|
||||||
@ -346,7 +347,7 @@ async def websocket_device_cluster_attributes(hass, connection, msg):
|
|||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{
|
{
|
||||||
vol.Required(TYPE): "zha/devices/clusters/commands",
|
vol.Required(TYPE): "zha/devices/clusters/commands",
|
||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
vol.Required(ATTR_IEEE): EUI64.convert,
|
||||||
vol.Required(ATTR_ENDPOINT_ID): int,
|
vol.Required(ATTR_ENDPOINT_ID): int,
|
||||||
vol.Required(ATTR_CLUSTER_ID): int,
|
vol.Required(ATTR_CLUSTER_ID): int,
|
||||||
vol.Required(ATTR_CLUSTER_TYPE): str,
|
vol.Required(ATTR_CLUSTER_TYPE): str,
|
||||||
@ -400,7 +401,7 @@ async def websocket_device_cluster_commands(hass, connection, msg):
|
|||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{
|
{
|
||||||
vol.Required(TYPE): "zha/devices/clusters/attributes/value",
|
vol.Required(TYPE): "zha/devices/clusters/attributes/value",
|
||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
vol.Required(ATTR_IEEE): EUI64.convert,
|
||||||
vol.Required(ATTR_ENDPOINT_ID): int,
|
vol.Required(ATTR_ENDPOINT_ID): int,
|
||||||
vol.Required(ATTR_CLUSTER_ID): int,
|
vol.Required(ATTR_CLUSTER_ID): int,
|
||||||
vol.Required(ATTR_CLUSTER_TYPE): str,
|
vol.Required(ATTR_CLUSTER_TYPE): str,
|
||||||
@ -444,7 +445,7 @@ async def websocket_read_zigbee_cluster_attributes(hass, connection, msg):
|
|||||||
@websocket_api.require_admin
|
@websocket_api.require_admin
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{vol.Required(TYPE): "zha/devices/bindable", vol.Required(ATTR_IEEE): convert_ieee}
|
{vol.Required(TYPE): "zha/devices/bindable", vol.Required(ATTR_IEEE): EUI64.convert}
|
||||||
)
|
)
|
||||||
async def websocket_get_bindable_devices(hass, connection, msg):
|
async def websocket_get_bindable_devices(hass, connection, msg):
|
||||||
"""Directly bind devices."""
|
"""Directly bind devices."""
|
||||||
@ -472,8 +473,8 @@ async def websocket_get_bindable_devices(hass, connection, msg):
|
|||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{
|
{
|
||||||
vol.Required(TYPE): "zha/devices/bind",
|
vol.Required(TYPE): "zha/devices/bind",
|
||||||
vol.Required(ATTR_SOURCE_IEEE): convert_ieee,
|
vol.Required(ATTR_SOURCE_IEEE): EUI64.convert,
|
||||||
vol.Required(ATTR_TARGET_IEEE): convert_ieee,
|
vol.Required(ATTR_TARGET_IEEE): EUI64.convert,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
async def websocket_bind_devices(hass, connection, msg):
|
async def websocket_bind_devices(hass, connection, msg):
|
||||||
@ -494,8 +495,8 @@ async def websocket_bind_devices(hass, connection, msg):
|
|||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{
|
{
|
||||||
vol.Required(TYPE): "zha/devices/unbind",
|
vol.Required(TYPE): "zha/devices/unbind",
|
||||||
vol.Required(ATTR_SOURCE_IEEE): convert_ieee,
|
vol.Required(ATTR_SOURCE_IEEE): EUI64.convert,
|
||||||
vol.Required(ATTR_TARGET_IEEE): convert_ieee,
|
vol.Required(ATTR_TARGET_IEEE): EUI64.convert,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
async def websocket_unbind_devices(hass, connection, msg):
|
async def websocket_unbind_devices(hass, connection, msg):
|
||||||
|
@ -8,6 +8,8 @@ import asyncio
|
|||||||
import collections
|
import collections
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from zigpy.types.named import EUI64
|
||||||
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -78,15 +80,6 @@ async def check_zigpy_connection(usb_path, radio_type, database_path):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def convert_ieee(ieee_str):
|
|
||||||
"""Convert given ieee string to EUI64."""
|
|
||||||
from zigpy.types import EUI64, uint8_t
|
|
||||||
|
|
||||||
if ieee_str is None:
|
|
||||||
return None
|
|
||||||
return EUI64([uint8_t(p, base=16) for p in ieee_str.split(":")])
|
|
||||||
|
|
||||||
|
|
||||||
def get_attr_id_by_name(cluster, attr_name):
|
def get_attr_id_by_name(cluster, attr_name):
|
||||||
"""Get the attribute id for a cluster attribute by its name."""
|
"""Get the attribute id for a cluster attribute by its name."""
|
||||||
return next(
|
return next(
|
||||||
@ -145,7 +138,7 @@ async def async_get_zha_device(hass, device_id):
|
|||||||
registry_device = device_registry.async_get(device_id)
|
registry_device = device_registry.async_get(device_id)
|
||||||
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
|
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
|
||||||
ieee_address = list(list(registry_device.identifiers)[0])[1]
|
ieee_address = list(list(registry_device.identifiers)[0])[1]
|
||||||
ieee = convert_ieee(ieee_address)
|
ieee = EUI64.convert(ieee_address)
|
||||||
return zha_gateway.devices[ieee]
|
return zha_gateway.devices[ieee]
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
"requirements": [
|
"requirements": [
|
||||||
"bellows-homeassistant==0.10.0",
|
"bellows-homeassistant==0.10.0",
|
||||||
"zha-quirks==0.0.26",
|
"zha-quirks==0.0.26",
|
||||||
"zigpy-deconz==0.5.0",
|
"zigpy-deconz==0.6.0",
|
||||||
"zigpy-homeassistant==0.9.0",
|
"zigpy-homeassistant==0.10.0",
|
||||||
"zigpy-xbee-homeassistant==0.5.0",
|
"zigpy-xbee-homeassistant==0.6.0",
|
||||||
"zigpy-zigate==0.4.1"
|
"zigpy-zigate==0.5.0"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": ["@dmulcahey", "@adminiuga"]
|
"codeowners": ["@dmulcahey", "@adminiuga"]
|
||||||
|
@ -2032,16 +2032,16 @@ zhong_hong_hvac==1.0.9
|
|||||||
ziggo-mediabox-xl==1.1.0
|
ziggo-mediabox-xl==1.1.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-deconz==0.5.0
|
zigpy-deconz==0.6.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-homeassistant==0.9.0
|
zigpy-homeassistant==0.10.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-xbee-homeassistant==0.5.0
|
zigpy-xbee-homeassistant==0.6.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-zigate==0.4.1
|
zigpy-zigate==0.5.0
|
||||||
|
|
||||||
# homeassistant.components.zoneminder
|
# homeassistant.components.zoneminder
|
||||||
zm-py==0.3.3
|
zm-py==0.3.3
|
||||||
|
@ -641,13 +641,13 @@ zeroconf==0.23.0
|
|||||||
zha-quirks==0.0.26
|
zha-quirks==0.0.26
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-deconz==0.5.0
|
zigpy-deconz==0.6.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-homeassistant==0.9.0
|
zigpy-homeassistant==0.10.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-xbee-homeassistant==0.5.0
|
zigpy-xbee-homeassistant==0.6.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-zigate==0.4.1
|
zigpy-zigate==0.5.0
|
||||||
|
@ -3,6 +3,8 @@ import time
|
|||||||
from unittest.mock import Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
from asynctest import CoroutineMock
|
from asynctest import CoroutineMock
|
||||||
|
from zigpy.types.named import EUI64
|
||||||
|
import zigpy.zcl.foundation as zcl_f
|
||||||
|
|
||||||
from homeassistant.components.zha.core.const import (
|
from homeassistant.components.zha.core.const import (
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
@ -10,7 +12,6 @@ from homeassistant.components.zha.core.const import (
|
|||||||
DATA_ZHA_CONFIG,
|
DATA_ZHA_CONFIG,
|
||||||
DATA_ZHA_DISPATCHERS,
|
DATA_ZHA_DISPATCHERS,
|
||||||
)
|
)
|
||||||
from homeassistant.components.zha.core.helpers import convert_ieee
|
|
||||||
from homeassistant.util import slugify
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
from tests.common import mock_coro
|
from tests.common import mock_coro
|
||||||
@ -21,7 +22,7 @@ class FakeApplication:
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Init fake application."""
|
"""Init fake application."""
|
||||||
self.ieee = convert_ieee("00:15:8d:00:02:32:4f:32")
|
self.ieee = EUI64.convert("00:15:8d:00:02:32:4f:32")
|
||||||
self.nwk = 0x087D
|
self.nwk = 0x087D
|
||||||
|
|
||||||
|
|
||||||
@ -71,7 +72,6 @@ def patch_cluster(cluster):
|
|||||||
cluster.configure_reporting = CoroutineMock(return_value=[0])
|
cluster.configure_reporting = CoroutineMock(return_value=[0])
|
||||||
cluster.deserialize = Mock()
|
cluster.deserialize = Mock()
|
||||||
cluster.handle_cluster_request = Mock()
|
cluster.handle_cluster_request = Mock()
|
||||||
cluster.handle_cluster_general_request = Mock()
|
|
||||||
cluster.read_attributes = CoroutineMock()
|
cluster.read_attributes = CoroutineMock()
|
||||||
cluster.read_attributes_raw = Mock()
|
cluster.read_attributes_raw = Mock()
|
||||||
cluster.unbind = CoroutineMock(return_value=[0])
|
cluster.unbind = CoroutineMock(return_value=[0])
|
||||||
@ -83,7 +83,7 @@ class FakeDevice:
|
|||||||
def __init__(self, ieee, manufacturer, model):
|
def __init__(self, ieee, manufacturer, model):
|
||||||
"""Init fake device."""
|
"""Init fake device."""
|
||||||
self._application = APPLICATION
|
self._application = APPLICATION
|
||||||
self.ieee = convert_ieee(ieee)
|
self.ieee = EUI64.convert(ieee)
|
||||||
self.nwk = 0xB79C
|
self.nwk = 0xB79C
|
||||||
self.zdo = Mock()
|
self.zdo = Mock()
|
||||||
self.endpoints = {0: self.zdo}
|
self.endpoints = {0: self.zdo}
|
||||||
@ -230,3 +230,12 @@ async def async_test_device_join(
|
|||||||
domain, zigpy_device, cluster, use_suffix=device_type is None
|
domain, zigpy_device, cluster, use_suffix=device_type is None
|
||||||
)
|
)
|
||||||
assert hass.states.get(entity_id) is not None
|
assert hass.states.get(entity_id) is not None
|
||||||
|
|
||||||
|
|
||||||
|
def make_zcl_header(command_id: int, global_command: bool = True) -> zcl_f.ZCLHeader:
|
||||||
|
"""Cluster.handle_message() ZCL Header helper."""
|
||||||
|
if global_command:
|
||||||
|
frc = zcl_f.FrameControl(zcl_f.FrameType.GLOBAL_COMMAND)
|
||||||
|
else:
|
||||||
|
frc = zcl_f.FrameControl(zcl_f.FrameType.CLUSTER_COMMAND)
|
||||||
|
return zcl_f.ZCLHeader(frc, tsn=1, command_id=command_id)
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
"""Test zha binary sensor."""
|
"""Test zha binary sensor."""
|
||||||
|
from zigpy.zcl.foundation import Command
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import DOMAIN
|
from homeassistant.components.binary_sensor import DOMAIN
|
||||||
from homeassistant.const import STATE_ON, STATE_OFF, STATE_UNAVAILABLE
|
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
||||||
|
|
||||||
from .common import (
|
from .common import (
|
||||||
|
async_enable_traffic,
|
||||||
async_init_zigpy_device,
|
async_init_zigpy_device,
|
||||||
|
async_test_device_join,
|
||||||
make_attribute,
|
make_attribute,
|
||||||
make_entity_id,
|
make_entity_id,
|
||||||
async_test_device_join,
|
make_zcl_header,
|
||||||
async_enable_traffic,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -74,13 +78,15 @@ async def async_test_binary_sensor_on_off(hass, cluster, entity_id):
|
|||||||
"""Test getting on and off messages for binary sensors."""
|
"""Test getting on and off messages for binary sensors."""
|
||||||
# binary sensor on
|
# binary sensor on
|
||||||
attr = make_attribute(0, 1)
|
attr = make_attribute(0, 1)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
hdr = make_zcl_header(Command.Report_Attributes)
|
||||||
|
|
||||||
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_ON
|
assert hass.states.get(entity_id).state == STATE_ON
|
||||||
|
|
||||||
# binary sensor off
|
# binary sensor off
|
||||||
attr.value.value = 0
|
attr.value.value = 0
|
||||||
cluster.handle_message(0, 0x0A, [[attr]])
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_OFF
|
assert hass.states.get(entity_id).state == STATE_OFF
|
||||||
|
|
||||||
|
@ -1,19 +1,25 @@
|
|||||||
"""Test ZHA Device Tracker."""
|
"""Test ZHA Device Tracker."""
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from zigpy.zcl.foundation import Command
|
||||||
|
|
||||||
from homeassistant.components.device_tracker import DOMAIN, SOURCE_TYPE_ROUTER
|
from homeassistant.components.device_tracker import DOMAIN, SOURCE_TYPE_ROUTER
|
||||||
from homeassistant.const import STATE_HOME, STATE_NOT_HOME, STATE_UNAVAILABLE
|
|
||||||
from homeassistant.components.zha.core.registries import (
|
from homeassistant.components.zha.core.registries import (
|
||||||
SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE,
|
SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE,
|
||||||
)
|
)
|
||||||
|
from homeassistant.const import STATE_HOME, STATE_NOT_HOME, STATE_UNAVAILABLE
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
from .common import (
|
from .common import (
|
||||||
|
async_enable_traffic,
|
||||||
async_init_zigpy_device,
|
async_init_zigpy_device,
|
||||||
|
async_test_device_join,
|
||||||
make_attribute,
|
make_attribute,
|
||||||
make_entity_id,
|
make_entity_id,
|
||||||
async_test_device_join,
|
make_zcl_header,
|
||||||
async_enable_traffic,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed
|
from tests.common import async_fire_time_changed
|
||||||
|
|
||||||
|
|
||||||
@ -67,10 +73,11 @@ async def test_device_tracker(hass, config_entry, zha_gateway):
|
|||||||
|
|
||||||
# turn state flip
|
# turn state flip
|
||||||
attr = make_attribute(0x0020, 23)
|
attr = make_attribute(0x0020, 23)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
hdr = make_zcl_header(Command.Report_Attributes)
|
||||||
|
cluster.handle_message(hdr, [[attr]])
|
||||||
|
|
||||||
attr = make_attribute(0x0021, 200)
|
attr = make_attribute(0x0021, 200)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
cluster.handle_message(hdr, [[attr]])
|
||||||
|
|
||||||
zigpy_device.last_seen = time.time() + 10
|
zigpy_device.last_seen = time.time() + 10
|
||||||
next_update = dt_util.utcnow() + timedelta(seconds=30)
|
next_update = dt_util.utcnow() + timedelta(seconds=30)
|
||||||
|
@ -1,18 +1,30 @@
|
|||||||
"""Test zha fan."""
|
"""Test zha fan."""
|
||||||
from unittest.mock import call, patch
|
from unittest.mock import call, patch
|
||||||
|
|
||||||
|
from zigpy.zcl.foundation import Command
|
||||||
|
|
||||||
from homeassistant.components import fan
|
from homeassistant.components import fan
|
||||||
from homeassistant.const import STATE_ON, STATE_OFF, STATE_UNAVAILABLE
|
|
||||||
from homeassistant.components.fan import ATTR_SPEED, DOMAIN, SERVICE_SET_SPEED
|
from homeassistant.components.fan import ATTR_SPEED, DOMAIN, SERVICE_SET_SPEED
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF
|
from homeassistant.const import (
|
||||||
from tests.common import mock_coro
|
ATTR_ENTITY_ID,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
|
)
|
||||||
|
|
||||||
from .common import (
|
from .common import (
|
||||||
|
async_enable_traffic,
|
||||||
async_init_zigpy_device,
|
async_init_zigpy_device,
|
||||||
|
async_test_device_join,
|
||||||
make_attribute,
|
make_attribute,
|
||||||
make_entity_id,
|
make_entity_id,
|
||||||
async_test_device_join,
|
make_zcl_header,
|
||||||
async_enable_traffic,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from tests.common import mock_coro
|
||||||
|
|
||||||
|
|
||||||
async def test_fan(hass, config_entry, zha_gateway):
|
async def test_fan(hass, config_entry, zha_gateway):
|
||||||
"""Test zha fan platform."""
|
"""Test zha fan platform."""
|
||||||
@ -44,13 +56,14 @@ async def test_fan(hass, config_entry, zha_gateway):
|
|||||||
|
|
||||||
# turn on at fan
|
# turn on at fan
|
||||||
attr = make_attribute(0, 1)
|
attr = make_attribute(0, 1)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
hdr = make_zcl_header(Command.Report_Attributes)
|
||||||
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_ON
|
assert hass.states.get(entity_id).state == STATE_ON
|
||||||
|
|
||||||
# turn off at fan
|
# turn off at fan
|
||||||
attr.value.value = 0
|
attr.value.value = 0
|
||||||
cluster.handle_message(0, 0x0A, [[attr]])
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_OFF
|
assert hass.states.get(entity_id).state == STATE_OFF
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import MagicMock, call, patch, sentinel
|
from unittest.mock import MagicMock, call, patch, sentinel
|
||||||
|
|
||||||
|
from zigpy.zcl.foundation import Command
|
||||||
|
|
||||||
from homeassistant.components.light import DOMAIN
|
from homeassistant.components.light import DOMAIN
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
||||||
|
|
||||||
@ -11,6 +13,7 @@ from .common import (
|
|||||||
async_test_device_join,
|
async_test_device_join,
|
||||||
make_attribute,
|
make_attribute,
|
||||||
make_entity_id,
|
make_entity_id,
|
||||||
|
make_zcl_header,
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.common import mock_coro
|
from tests.common import mock_coro
|
||||||
@ -123,13 +126,14 @@ async def async_test_on_off_from_light(hass, cluster, entity_id):
|
|||||||
"""Test on off functionality from the light."""
|
"""Test on off functionality from the light."""
|
||||||
# turn on at light
|
# turn on at light
|
||||||
attr = make_attribute(0, 1)
|
attr = make_attribute(0, 1)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
hdr = make_zcl_header(Command.Report_Attributes)
|
||||||
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_ON
|
assert hass.states.get(entity_id).state == STATE_ON
|
||||||
|
|
||||||
# turn off at light
|
# turn off at light
|
||||||
attr.value.value = 0
|
attr.value.value = 0
|
||||||
cluster.handle_message(0, 0x0A, [[attr]])
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_OFF
|
assert hass.states.get(entity_id).state == STATE_OFF
|
||||||
|
|
||||||
@ -138,7 +142,8 @@ async def async_test_on_from_light(hass, cluster, entity_id):
|
|||||||
"""Test on off functionality from the light."""
|
"""Test on off functionality from the light."""
|
||||||
# turn on at light
|
# turn on at light
|
||||||
attr = make_attribute(0, 1)
|
attr = make_attribute(0, 1)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
hdr = make_zcl_header(Command.Report_Attributes)
|
||||||
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_ON
|
assert hass.states.get(entity_id).state == STATE_ON
|
||||||
|
|
||||||
@ -243,7 +248,8 @@ async def async_test_level_on_off_from_hass(
|
|||||||
async def async_test_dimmer_from_light(hass, cluster, entity_id, level, expected_state):
|
async def async_test_dimmer_from_light(hass, cluster, entity_id, level, expected_state):
|
||||||
"""Test dimmer functionality from the light."""
|
"""Test dimmer functionality from the light."""
|
||||||
attr = make_attribute(0, level)
|
attr = make_attribute(0, level)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
hdr = make_zcl_header(Command.Report_Attributes)
|
||||||
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == expected_state
|
assert hass.states.get(entity_id).state == expected_state
|
||||||
# hass uses None for brightness of 0 in state attributes
|
# hass uses None for brightness of 0 in state attributes
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
"""Test zha lock."""
|
"""Test zha lock."""
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
from homeassistant.const import STATE_LOCKED, STATE_UNLOCKED, STATE_UNAVAILABLE
|
|
||||||
|
from zigpy.zcl.foundation import Command
|
||||||
|
|
||||||
from homeassistant.components.lock import DOMAIN
|
from homeassistant.components.lock import DOMAIN
|
||||||
from tests.common import mock_coro
|
from homeassistant.const import STATE_LOCKED, STATE_UNAVAILABLE, STATE_UNLOCKED
|
||||||
|
|
||||||
from .common import (
|
from .common import (
|
||||||
|
async_enable_traffic,
|
||||||
async_init_zigpy_device,
|
async_init_zigpy_device,
|
||||||
make_attribute,
|
make_attribute,
|
||||||
make_entity_id,
|
make_entity_id,
|
||||||
async_enable_traffic,
|
make_zcl_header,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from tests.common import mock_coro
|
||||||
|
|
||||||
LOCK_DOOR = 0
|
LOCK_DOOR = 0
|
||||||
UNLOCK_DOOR = 1
|
UNLOCK_DOOR = 1
|
||||||
|
|
||||||
@ -43,13 +49,14 @@ async def test_lock(hass, config_entry, zha_gateway):
|
|||||||
|
|
||||||
# set state to locked
|
# set state to locked
|
||||||
attr = make_attribute(0, 1)
|
attr = make_attribute(0, 1)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
hdr = make_zcl_header(Command.Report_Attributes)
|
||||||
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_LOCKED
|
assert hass.states.get(entity_id).state == STATE_LOCKED
|
||||||
|
|
||||||
# set state to unlocked
|
# set state to unlocked
|
||||||
attr.value.value = 2
|
attr.value.value = 2
|
||||||
cluster.handle_message(0, 0x0A, [[attr]])
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_UNLOCKED
|
assert hass.states.get(entity_id).state == STATE_UNLOCKED
|
||||||
|
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
"""Test zha sensor."""
|
"""Test zha sensor."""
|
||||||
|
from zigpy.zcl.foundation import Command
|
||||||
|
|
||||||
from homeassistant.components.sensor import DOMAIN
|
from homeassistant.components.sensor import DOMAIN
|
||||||
from homeassistant.const import STATE_UNKNOWN, STATE_UNAVAILABLE
|
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN
|
||||||
|
|
||||||
from .common import (
|
from .common import (
|
||||||
|
async_enable_traffic,
|
||||||
async_init_zigpy_device,
|
async_init_zigpy_device,
|
||||||
|
async_test_device_join,
|
||||||
make_attribute,
|
make_attribute,
|
||||||
make_entity_id,
|
make_entity_id,
|
||||||
async_test_device_join,
|
make_zcl_header,
|
||||||
async_enable_traffic,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -177,7 +181,8 @@ async def send_attribute_report(hass, cluster, attrid, value):
|
|||||||
device is paired to the zigbee network.
|
device is paired to the zigbee network.
|
||||||
"""
|
"""
|
||||||
attr = make_attribute(attrid, value)
|
attr = make_attribute(attrid, value)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
hdr = make_zcl_header(Command.Report_Attributes)
|
||||||
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
"""Test zha switch."""
|
"""Test zha switch."""
|
||||||
from unittest.mock import call, patch
|
from unittest.mock import call, patch
|
||||||
|
|
||||||
|
from zigpy.zcl.foundation import Command
|
||||||
|
|
||||||
from homeassistant.components.switch import DOMAIN
|
from homeassistant.components.switch import DOMAIN
|
||||||
from homeassistant.const import STATE_ON, STATE_OFF, STATE_UNAVAILABLE
|
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
||||||
from tests.common import mock_coro
|
|
||||||
from .common import (
|
from .common import (
|
||||||
|
async_enable_traffic,
|
||||||
async_init_zigpy_device,
|
async_init_zigpy_device,
|
||||||
|
async_test_device_join,
|
||||||
make_attribute,
|
make_attribute,
|
||||||
make_entity_id,
|
make_entity_id,
|
||||||
async_test_device_join,
|
make_zcl_header,
|
||||||
async_enable_traffic,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from tests.common import mock_coro
|
||||||
|
|
||||||
ON = 1
|
ON = 1
|
||||||
OFF = 0
|
OFF = 0
|
||||||
|
|
||||||
@ -44,13 +50,14 @@ async def test_switch(hass, config_entry, zha_gateway):
|
|||||||
|
|
||||||
# turn on at switch
|
# turn on at switch
|
||||||
attr = make_attribute(0, 1)
|
attr = make_attribute(0, 1)
|
||||||
cluster.handle_message(1, 0x0A, [[attr]])
|
hdr = make_zcl_header(Command.Report_Attributes)
|
||||||
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_ON
|
assert hass.states.get(entity_id).state == STATE_ON
|
||||||
|
|
||||||
# turn off at switch
|
# turn off at switch
|
||||||
attr.value.value = 0
|
attr.value.value = 0
|
||||||
cluster.handle_message(0, 0x0A, [[attr]])
|
cluster.handle_message(hdr, [[attr]])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id).state == STATE_OFF
|
assert hass.states.get(entity_id).state == STATE_OFF
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user