mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Targeted ZHA permit joins. (#22482)
* Targeted ZHA permit service. * Convert IEEE string to EUI64 usiv vol schema. * Update test units. * Lint. isort imports.
This commit is contained in:
parent
e26a5abb2b
commit
e670491c86
@ -7,6 +7,7 @@ https://home-assistant.io/components/zha/
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components import websocket_api
|
from homeassistant.components import websocket_api
|
||||||
@ -14,12 +15,14 @@ from homeassistant.core import callback
|
|||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.device_registry import async_get_registry
|
from homeassistant.helpers.device_registry import async_get_registry
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from .core.const import (
|
from .core.const import (
|
||||||
DOMAIN, ATTR_CLUSTER_ID, ATTR_CLUSTER_TYPE, ATTR_ATTRIBUTE, ATTR_VALUE,
|
ATTR_ARGS, ATTR_ATTRIBUTE, ATTR_CLUSTER_ID, ATTR_CLUSTER_TYPE,
|
||||||
ATTR_MANUFACTURER, ATTR_COMMAND, ATTR_COMMAND_TYPE, ATTR_ARGS, IN, OUT,
|
ATTR_COMMAND, ATTR_COMMAND_TYPE, ATTR_ENDPOINT_ID, ATTR_MANUFACTURER,
|
||||||
CLIENT_COMMANDS, SERVER_COMMANDS, SERVER, NAME, ATTR_ENDPOINT_ID,
|
ATTR_VALUE, CLIENT_COMMANDS, DATA_ZHA, DATA_ZHA_GATEWAY, DOMAIN, IN,
|
||||||
DATA_ZHA_GATEWAY, DATA_ZHA, MFG_CLUSTER_ID_START)
|
MFG_CLUSTER_ID_START, NAME, OUT, SERVER, SERVER_COMMANDS)
|
||||||
from .core.helpers import get_matched_clusters, async_is_bindable_target
|
from .core.helpers import (
|
||||||
|
async_is_bindable_target, convert_ieee, get_matched_clusters)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -48,14 +51,15 @@ 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_DURATION, default=60):
|
vol.Optional(ATTR_DURATION, default=60):
|
||||||
vol.All(vol.Coerce(int), vol.Range(1, 254)),
|
vol.All(vol.Coerce(int), vol.Range(0, 254)),
|
||||||
}),
|
}),
|
||||||
IEEE_SERVICE: vol.Schema({
|
IEEE_SERVICE: vol.Schema({
|
||||||
vol.Required(ATTR_IEEE_ADDRESS): cv.string,
|
vol.Required(ATTR_IEEE_ADDRESS): convert_ieee,
|
||||||
}),
|
}),
|
||||||
SERVICE_SET_ZIGBEE_CLUSTER_ATTRIBUTE: vol.Schema({
|
SERVICE_SET_ZIGBEE_CLUSTER_ATTRIBUTE: vol.Schema({
|
||||||
vol.Required(ATTR_IEEE): cv.string,
|
vol.Required(ATTR_IEEE): convert_ieee,
|
||||||
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=IN): cv.string,
|
vol.Optional(ATTR_CLUSTER_TYPE, default=IN): cv.string,
|
||||||
@ -64,7 +68,7 @@ SERVICE_SCHEMAS = {
|
|||||||
vol.Optional(ATTR_MANUFACTURER): cv.positive_int,
|
vol.Optional(ATTR_MANUFACTURER): cv.positive_int,
|
||||||
}),
|
}),
|
||||||
SERVICE_ISSUE_ZIGBEE_CLUSTER_COMMAND: vol.Schema({
|
SERVICE_ISSUE_ZIGBEE_CLUSTER_COMMAND: vol.Schema({
|
||||||
vol.Required(ATTR_IEEE): cv.string,
|
vol.Required(ATTR_IEEE): convert_ieee,
|
||||||
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=IN): cv.string,
|
vol.Optional(ATTR_CLUSTER_TYPE, default=IN): cv.string,
|
||||||
@ -79,11 +83,16 @@ SERVICE_SCHEMAS = {
|
|||||||
@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/permit'
|
vol.Required('type'): 'zha/devices/permit',
|
||||||
|
vol.Optional(ATTR_IEEE, default=None): convert_ieee,
|
||||||
|
vol.Optional(ATTR_DURATION, default=60): vol.All(vol.Coerce(int),
|
||||||
|
vol.Range(0, 254))
|
||||||
})
|
})
|
||||||
async def websocket_permit_devices(hass, connection, msg):
|
async def websocket_permit_devices(hass, connection, msg):
|
||||||
"""Permit ZHA zigbee devices."""
|
"""Permit ZHA zigbee devices."""
|
||||||
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
|
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
|
||||||
|
duration = msg.get(ATTR_DURATION)
|
||||||
|
ieee = msg.get(ATTR_IEEE)
|
||||||
|
|
||||||
async def forward_messages(data):
|
async def forward_messages(data):
|
||||||
"""Forward events to websocket."""
|
"""Forward events to websocket."""
|
||||||
@ -103,8 +112,8 @@ async def websocket_permit_devices(hass, connection, msg):
|
|||||||
|
|
||||||
connection.subscriptions[msg['id']] = async_cleanup
|
connection.subscriptions[msg['id']] = async_cleanup
|
||||||
zha_gateway.async_enable_debug_mode()
|
zha_gateway.async_enable_debug_mode()
|
||||||
await zha_gateway.application_controller.permit(60)
|
await zha_gateway.application_controller.permit(time_s=duration,
|
||||||
|
node=ieee)
|
||||||
connection.send_result(msg['id'])
|
connection.send_result(msg['id'])
|
||||||
|
|
||||||
|
|
||||||
@ -153,7 +162,7 @@ def async_get_device_info(hass, device, ha_device_registry=None):
|
|||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@websocket_api.websocket_command({
|
@websocket_api.websocket_command({
|
||||||
vol.Required(TYPE): 'zha/devices/reconfigure',
|
vol.Required(TYPE): 'zha/devices/reconfigure',
|
||||||
vol.Required(ATTR_IEEE): str
|
vol.Required(ATTR_IEEE): convert_ieee,
|
||||||
})
|
})
|
||||||
async def websocket_reconfigure_node(hass, connection, msg):
|
async def websocket_reconfigure_node(hass, connection, msg):
|
||||||
"""Reconfigure a ZHA nodes entities by its ieee address."""
|
"""Reconfigure a ZHA nodes entities by its ieee address."""
|
||||||
@ -168,7 +177,7 @@ async def websocket_reconfigure_node(hass, connection, msg):
|
|||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@websocket_api.websocket_command({
|
@websocket_api.websocket_command({
|
||||||
vol.Required(TYPE): 'zha/devices/clusters',
|
vol.Required(TYPE): 'zha/devices/clusters',
|
||||||
vol.Required(ATTR_IEEE): str
|
vol.Required(ATTR_IEEE): convert_ieee,
|
||||||
})
|
})
|
||||||
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."""
|
||||||
@ -201,7 +210,7 @@ async def websocket_device_clusters(hass, connection, msg):
|
|||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@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): str,
|
vol.Required(ATTR_IEEE): convert_ieee,
|
||||||
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
|
||||||
@ -243,7 +252,7 @@ async def websocket_device_cluster_attributes(hass, connection, msg):
|
|||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@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): str,
|
vol.Required(ATTR_IEEE): convert_ieee,
|
||||||
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
|
||||||
@ -295,7 +304,7 @@ async def websocket_device_cluster_commands(hass, connection, msg):
|
|||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@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): str,
|
vol.Required(ATTR_IEEE): convert_ieee,
|
||||||
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,
|
||||||
@ -340,7 +349,7 @@ async def websocket_read_zigbee_cluster_attributes(hass, connection, msg):
|
|||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@websocket_api.websocket_command({
|
@websocket_api.websocket_command({
|
||||||
vol.Required(TYPE): 'zha/devices/bindable',
|
vol.Required(TYPE): 'zha/devices/bindable',
|
||||||
vol.Required(ATTR_IEEE): str,
|
vol.Required(ATTR_IEEE): convert_ieee,
|
||||||
})
|
})
|
||||||
async def websocket_get_bindable_devices(hass, connection, msg):
|
async def websocket_get_bindable_devices(hass, connection, msg):
|
||||||
"""Directly bind devices."""
|
"""Directly bind devices."""
|
||||||
@ -369,8 +378,8 @@ async def websocket_get_bindable_devices(hass, connection, msg):
|
|||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@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): str,
|
vol.Required(ATTR_SOURCE_IEEE): convert_ieee,
|
||||||
vol.Required(ATTR_TARGET_IEEE): str
|
vol.Required(ATTR_TARGET_IEEE): convert_ieee,
|
||||||
})
|
})
|
||||||
async def websocket_bind_devices(hass, connection, msg):
|
async def websocket_bind_devices(hass, connection, msg):
|
||||||
"""Directly bind devices."""
|
"""Directly bind devices."""
|
||||||
@ -389,8 +398,8 @@ async def websocket_bind_devices(hass, connection, msg):
|
|||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@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): str,
|
vol.Required(ATTR_SOURCE_IEEE): convert_ieee,
|
||||||
vol.Required(ATTR_TARGET_IEEE): str
|
vol.Required(ATTR_TARGET_IEEE): convert_ieee,
|
||||||
})
|
})
|
||||||
async def websocket_unbind_devices(hass, connection, msg):
|
async def websocket_unbind_devices(hass, connection, msg):
|
||||||
"""Remove a direct binding between devices."""
|
"""Remove a direct binding between devices."""
|
||||||
@ -450,17 +459,20 @@ def async_load_api(hass):
|
|||||||
async def permit(service):
|
async def permit(service):
|
||||||
"""Allow devices to join this network."""
|
"""Allow devices to join this network."""
|
||||||
duration = service.data.get(ATTR_DURATION)
|
duration = service.data.get(ATTR_DURATION)
|
||||||
_LOGGER.info("Permitting joins for %ss", duration)
|
ieee = service.data.get(ATTR_IEEE_ADDRESS)
|
||||||
await application_controller.permit(duration)
|
if ieee:
|
||||||
|
_LOGGER.info("Permitting joins for %ss on %s device",
|
||||||
|
duration, ieee)
|
||||||
|
else:
|
||||||
|
_LOGGER.info("Permitting joins for %ss", duration)
|
||||||
|
await application_controller.permit(time_s=duration, node=ieee)
|
||||||
|
|
||||||
hass.helpers.service.async_register_admin_service(
|
hass.helpers.service.async_register_admin_service(
|
||||||
DOMAIN, SERVICE_PERMIT, permit, schema=SERVICE_SCHEMAS[SERVICE_PERMIT])
|
DOMAIN, SERVICE_PERMIT, permit, schema=SERVICE_SCHEMAS[SERVICE_PERMIT])
|
||||||
|
|
||||||
async def remove(service):
|
async def remove(service):
|
||||||
"""Remove a node from the network."""
|
"""Remove a node from the network."""
|
||||||
from bellows.types import EmberEUI64, uint8_t
|
|
||||||
ieee = service.data.get(ATTR_IEEE_ADDRESS)
|
ieee = service.data.get(ATTR_IEEE_ADDRESS)
|
||||||
ieee = EmberEUI64([uint8_t(p, base=16) for p in ieee.split(':')])
|
|
||||||
_LOGGER.info("Removing node %s", ieee)
|
_LOGGER.info("Removing node %s", ieee)
|
||||||
await application_controller.remove(ieee)
|
await application_controller.remove(ieee)
|
||||||
|
|
||||||
|
@ -10,35 +10,31 @@ import collections
|
|||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from homeassistant.components.system_log import LogEntry, _figure_out_source
|
from homeassistant.components.system_log import LogEntry, _figure_out_source
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
from homeassistant.helpers.entity_component import EntityComponent
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
|
|
||||||
|
from ..api import async_get_device_info
|
||||||
|
from .channels import MAINS_POWERED, ZDOChannel
|
||||||
from .const import (
|
from .const import (
|
||||||
DATA_ZHA, DATA_ZHA_CORE_COMPONENT, DOMAIN, SIGNAL_REMOVE, DATA_ZHA_GATEWAY,
|
ADD_DEVICE_RELAY_LOGGERS, ATTR_MANUFACTURER, BELLOWS, CONF_BAUDRATE,
|
||||||
CONF_USB_PATH, CONF_BAUDRATE, DEFAULT_BAUDRATE, CONF_RADIO_TYPE,
|
CONF_DATABASE, CONF_RADIO_TYPE, CONF_USB_PATH, CONTROLLER, CURRENT,
|
||||||
DATA_ZHA_RADIO, CONF_DATABASE, DEFAULT_DATABASE_NAME, DATA_ZHA_BRIDGE_ID,
|
DATA_ZHA, DATA_ZHA_BRIDGE_ID, DATA_ZHA_CORE_COMPONENT, DATA_ZHA_GATEWAY,
|
||||||
RADIO, CONTROLLER, RADIO_DESCRIPTION, BELLOWS, ZHA, ZIGPY, ZIGPY_XBEE,
|
DATA_ZHA_RADIO, DEBUG_LEVELS, DEFAULT_BAUDRATE, DEFAULT_DATABASE_NAME,
|
||||||
ZIGPY_DECONZ, ORIGINAL, CURRENT, DEBUG_LEVELS, ADD_DEVICE_RELAY_LOGGERS,
|
DEVICE_FULL_INIT, DEVICE_INFO, DEVICE_JOINED, DEVICE_REMOVED, DOMAIN, IEEE,
|
||||||
TYPE, NWK, IEEE, MODEL, SIGNATURE, ATTR_MANUFACTURER, RAW_INIT,
|
LOG_ENTRY, LOG_OUTPUT, MODEL, NWK, ORIGINAL, RADIO, RADIO_DESCRIPTION,
|
||||||
ZHA_GW_MSG, DEVICE_REMOVED, DEVICE_INFO, DEVICE_FULL_INIT, DEVICE_JOINED,
|
RAW_INIT, SIGNAL_REMOVE, SIGNATURE, TYPE, ZHA, ZHA_GW_MSG, ZIGPY,
|
||||||
LOG_OUTPUT, LOG_ENTRY
|
ZIGPY_DECONZ, ZIGPY_XBEE)
|
||||||
)
|
from .device import DeviceStatus, ZHADevice
|
||||||
from .device import ZHADevice, DeviceStatus
|
|
||||||
from .channels import (
|
|
||||||
ZDOChannel, MAINS_POWERED
|
|
||||||
)
|
|
||||||
from .helpers import convert_ieee
|
|
||||||
from .discovery import (
|
from .discovery import (
|
||||||
async_process_endpoint, async_dispatch_discovery_info,
|
async_create_device_entity, async_dispatch_discovery_info,
|
||||||
async_create_device_entity
|
async_process_endpoint)
|
||||||
)
|
|
||||||
from .store import async_get_registry
|
|
||||||
from .patches import apply_application_controller_patch
|
from .patches import apply_application_controller_patch
|
||||||
from .registries import RADIO_TYPES
|
from .registries import RADIO_TYPES
|
||||||
from ..api import async_get_device_info
|
from .store import async_get_registry
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -169,9 +165,8 @@ class ZHAGateway:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_device(self, ieee_str):
|
def get_device(self, ieee):
|
||||||
"""Return ZHADevice for given ieee."""
|
"""Return ZHADevice for given ieee."""
|
||||||
ieee = convert_ieee(ieee_str)
|
|
||||||
return self._devices.get(ieee)
|
return self._devices.get(ieee)
|
||||||
|
|
||||||
def get_entity_reference(self, entity_id):
|
def get_entity_reference(self, entity_id):
|
||||||
|
@ -148,6 +148,8 @@ async def check_zigpy_connection(usb_path, radio_type, database_path):
|
|||||||
def convert_ieee(ieee_str):
|
def convert_ieee(ieee_str):
|
||||||
"""Convert given ieee string to EUI64."""
|
"""Convert given ieee string to EUI64."""
|
||||||
from zigpy.types import EUI64, uint8_t
|
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(':')])
|
return EUI64([uint8_t(p, base=16) for p in ieee_str.split(':')])
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,9 @@ permit:
|
|||||||
duration:
|
duration:
|
||||||
description: Time to permit joins, in seconds
|
description: Time to permit joins, in seconds
|
||||||
example: 60
|
example: 60
|
||||||
|
ieee_address:
|
||||||
|
description: IEEE address of the node permitting new joins
|
||||||
|
example: "00:0d:6f:00:05:7d:2d:34"
|
||||||
|
|
||||||
remove:
|
remove:
|
||||||
description: Remove a node from the ZigBee network.
|
description: Remove a node from the ZigBee network.
|
||||||
|
@ -54,15 +54,14 @@ async def test_binary_sensor(hass, config_entry, zha_gateway):
|
|||||||
zone_cluster = zigpy_device_zone.endpoints.get(
|
zone_cluster = zigpy_device_zone.endpoints.get(
|
||||||
1).ias_zone
|
1).ias_zone
|
||||||
zone_entity_id = make_entity_id(DOMAIN, zigpy_device_zone, zone_cluster)
|
zone_entity_id = make_entity_id(DOMAIN, zigpy_device_zone, zone_cluster)
|
||||||
zone_zha_device = zha_gateway.get_device(str(zigpy_device_zone.ieee))
|
zone_zha_device = zha_gateway.get_device(zigpy_device_zone.ieee)
|
||||||
|
|
||||||
# occupancy binary_sensor
|
# occupancy binary_sensor
|
||||||
occupancy_cluster = zigpy_device_occupancy.endpoints.get(
|
occupancy_cluster = zigpy_device_occupancy.endpoints.get(
|
||||||
1).occupancy
|
1).occupancy
|
||||||
occupancy_entity_id = make_entity_id(
|
occupancy_entity_id = make_entity_id(
|
||||||
DOMAIN, zigpy_device_occupancy, occupancy_cluster)
|
DOMAIN, zigpy_device_occupancy, occupancy_cluster)
|
||||||
occupancy_zha_device = zha_gateway.get_device(
|
occupancy_zha_device = zha_gateway.get_device(zigpy_device_occupancy.ieee)
|
||||||
str(zigpy_device_occupancy.ieee))
|
|
||||||
|
|
||||||
# dimmable binary_sensor
|
# dimmable binary_sensor
|
||||||
remote_on_off_cluster = zigpy_device_remote.endpoints.get(
|
remote_on_off_cluster = zigpy_device_remote.endpoints.get(
|
||||||
@ -72,7 +71,7 @@ async def test_binary_sensor(hass, config_entry, zha_gateway):
|
|||||||
remote_entity_id = make_entity_id(DOMAIN, zigpy_device_remote,
|
remote_entity_id = make_entity_id(DOMAIN, zigpy_device_remote,
|
||||||
remote_on_off_cluster,
|
remote_on_off_cluster,
|
||||||
use_suffix=False)
|
use_suffix=False)
|
||||||
remote_zha_device = zha_gateway.get_device(str(zigpy_device_remote.ieee))
|
remote_zha_device = zha_gateway.get_device(zigpy_device_remote.ieee)
|
||||||
|
|
||||||
# test that the sensors exist and are in the unavailable state
|
# test that the sensors exist and are in the unavailable state
|
||||||
assert hass.states.get(zone_entity_id).state == STATE_UNAVAILABLE
|
assert hass.states.get(zone_entity_id).state == STATE_UNAVAILABLE
|
||||||
|
@ -31,7 +31,7 @@ async def test_fan(hass, config_entry, zha_gateway):
|
|||||||
|
|
||||||
cluster = zigpy_device.endpoints.get(1).fan
|
cluster = zigpy_device.endpoints.get(1).fan
|
||||||
entity_id = make_entity_id(DOMAIN, zigpy_device, cluster)
|
entity_id = make_entity_id(DOMAIN, zigpy_device, cluster)
|
||||||
zha_device = zha_gateway.get_device(str(zigpy_device.ieee))
|
zha_device = zha_gateway.get_device(zigpy_device.ieee)
|
||||||
|
|
||||||
# test that the fan was created and that it is unavailable
|
# test that the fan was created and that it is unavailable
|
||||||
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
|
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
|
||||||
|
@ -51,7 +51,7 @@ async def test_light(hass, config_entry, zha_gateway, monkeypatch):
|
|||||||
on_off_entity_id = make_entity_id(DOMAIN, zigpy_device_on_off,
|
on_off_entity_id = make_entity_id(DOMAIN, zigpy_device_on_off,
|
||||||
on_off_device_on_off_cluster,
|
on_off_device_on_off_cluster,
|
||||||
use_suffix=False)
|
use_suffix=False)
|
||||||
on_off_zha_device = zha_gateway.get_device(str(zigpy_device_on_off.ieee))
|
on_off_zha_device = zha_gateway.get_device(zigpy_device_on_off.ieee)
|
||||||
|
|
||||||
# dimmable light
|
# dimmable light
|
||||||
level_device_on_off_cluster = zigpy_device_level.endpoints.get(1).on_off
|
level_device_on_off_cluster = zigpy_device_level.endpoints.get(1).on_off
|
||||||
@ -65,7 +65,7 @@ async def test_light(hass, config_entry, zha_gateway, monkeypatch):
|
|||||||
level_entity_id = make_entity_id(DOMAIN, zigpy_device_level,
|
level_entity_id = make_entity_id(DOMAIN, zigpy_device_level,
|
||||||
level_device_on_off_cluster,
|
level_device_on_off_cluster,
|
||||||
use_suffix=False)
|
use_suffix=False)
|
||||||
level_zha_device = zha_gateway.get_device(str(zigpy_device_level.ieee))
|
level_zha_device = zha_gateway.get_device(zigpy_device_level.ieee)
|
||||||
|
|
||||||
# test that the lights were created and that they are unavailable
|
# test that the lights were created and that they are unavailable
|
||||||
assert hass.states.get(on_off_entity_id).state == STATE_UNAVAILABLE
|
assert hass.states.get(on_off_entity_id).state == STATE_UNAVAILABLE
|
||||||
|
@ -114,8 +114,7 @@ async def async_build_devices(hass, zha_gateway, config_entry, cluster_ids):
|
|||||||
1).in_clusters[cluster_id]
|
1).in_clusters[cluster_id]
|
||||||
device_info["entity_id"] = make_entity_id(
|
device_info["entity_id"] = make_entity_id(
|
||||||
DOMAIN, zigpy_device, device_info["cluster"])
|
DOMAIN, zigpy_device, device_info["cluster"])
|
||||||
device_info["zha_device"] = zha_gateway.get_device(
|
device_info["zha_device"] = zha_gateway.get_device(zigpy_device.ieee)
|
||||||
str(zigpy_device.ieee))
|
|
||||||
return device_infos
|
return device_infos
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ async def test_switch(hass, config_entry, zha_gateway):
|
|||||||
|
|
||||||
cluster = zigpy_device.endpoints.get(1).on_off
|
cluster = zigpy_device.endpoints.get(1).on_off
|
||||||
entity_id = make_entity_id(DOMAIN, zigpy_device, cluster)
|
entity_id = make_entity_id(DOMAIN, zigpy_device, cluster)
|
||||||
zha_device = zha_gateway.get_device(str(zigpy_device.ieee))
|
zha_device = zha_gateway.get_device(zigpy_device.ieee)
|
||||||
|
|
||||||
# test that the switch was created and that its state is unavailable
|
# test that the switch was created and that its state is unavailable
|
||||||
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
|
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user