mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 11:47:06 +00:00
ZHA code cleanup. (#25644)
* isort ZHA imports. * Sort zha channel registry. * Sort ZHA core registry. * Sort ZHA core consts.
This commit is contained in:
parent
39257164a9
commit
77e4ff94fd
@ -26,7 +26,7 @@ from .core.const import (
|
|||||||
DEFAULT_BAUDRATE,
|
DEFAULT_BAUDRATE,
|
||||||
DEFAULT_RADIO_TYPE,
|
DEFAULT_RADIO_TYPE,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
ENABLE_QUIRKS,
|
CONF_ENABLE_QUIRKS,
|
||||||
RadioType,
|
RadioType,
|
||||||
)
|
)
|
||||||
from .core.registries import establish_device_mappings
|
from .core.registries import establish_device_mappings
|
||||||
@ -46,7 +46,7 @@ CONFIG_SCHEMA = vol.Schema(
|
|||||||
vol.Optional(CONF_DEVICE_CONFIG, default={}): vol.Schema(
|
vol.Optional(CONF_DEVICE_CONFIG, default={}): vol.Schema(
|
||||||
{cv.string: DEVICE_CONFIG_SCHEMA_ENTRY}
|
{cv.string: DEVICE_CONFIG_SCHEMA_ENTRY}
|
||||||
),
|
),
|
||||||
vol.Optional(ENABLE_QUIRKS, default=True): cv.boolean,
|
vol.Optional(CONF_ENABLE_QUIRKS, default=True): cv.boolean,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -99,7 +99,7 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
hass.data[DATA_ZHA][DATA_ZHA_DISPATCHERS] = []
|
hass.data[DATA_ZHA][DATA_ZHA_DISPATCHERS] = []
|
||||||
config = hass.data[DATA_ZHA].get(DATA_ZHA_CONFIG, {})
|
config = hass.data[DATA_ZHA].get(DATA_ZHA_CONFIG, {})
|
||||||
|
|
||||||
if config.get(ENABLE_QUIRKS, True):
|
if config.get(CONF_ENABLE_QUIRKS, True):
|
||||||
# needs to be done here so that the ZHA module is finished loading
|
# needs to be done here so that the ZHA module is finished loading
|
||||||
# before zhaquirks is imported
|
# before zhaquirks is imported
|
||||||
# pylint: disable=W0611, W0612
|
# pylint: disable=W0611, W0612
|
||||||
|
@ -21,16 +21,16 @@ from .core.const import (
|
|||||||
ATTR_ENDPOINT_ID,
|
ATTR_ENDPOINT_ID,
|
||||||
ATTR_MANUFACTURER,
|
ATTR_MANUFACTURER,
|
||||||
ATTR_VALUE,
|
ATTR_VALUE,
|
||||||
CLIENT_COMMANDS,
|
CLUSTER_COMMANDS_CLIENT,
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_GATEWAY,
|
DATA_ZHA_GATEWAY,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
IN,
|
CLUSTER_TYPE_IN,
|
||||||
MFG_CLUSTER_ID_START,
|
MFG_CLUSTER_ID_START,
|
||||||
NAME,
|
ATTR_NAME,
|
||||||
OUT,
|
CLUSTER_TYPE_OUT,
|
||||||
SERVER,
|
CLUSTER_COMMAND_SERVER,
|
||||||
SERVER_COMMANDS,
|
CLUSTER_COMMANDS_SERVER,
|
||||||
)
|
)
|
||||||
from .core.helpers import async_is_bindable_target, convert_ieee, get_matched_clusters
|
from .core.helpers import async_is_bindable_target, convert_ieee, get_matched_clusters
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ SERVICE_SCHEMAS = {
|
|||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
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=CLUSTER_TYPE_IN): cv.string,
|
||||||
vol.Required(ATTR_ATTRIBUTE): cv.positive_int,
|
vol.Required(ATTR_ATTRIBUTE): cv.positive_int,
|
||||||
vol.Required(ATTR_VALUE): cv.string,
|
vol.Required(ATTR_VALUE): cv.string,
|
||||||
vol.Optional(ATTR_MANUFACTURER): cv.positive_int,
|
vol.Optional(ATTR_MANUFACTURER): cv.positive_int,
|
||||||
@ -85,7 +85,7 @@ SERVICE_SCHEMAS = {
|
|||||||
vol.Required(ATTR_IEEE): convert_ieee,
|
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=CLUSTER_TYPE_IN): cv.string,
|
||||||
vol.Required(ATTR_COMMAND): cv.positive_int,
|
vol.Required(ATTR_COMMAND): cv.positive_int,
|
||||||
vol.Required(ATTR_COMMAND_TYPE): cv.string,
|
vol.Required(ATTR_COMMAND_TYPE): cv.string,
|
||||||
vol.Optional(ATTR_ARGS, default=""): cv.string,
|
vol.Optional(ATTR_ARGS, default=""): cv.string,
|
||||||
@ -155,7 +155,10 @@ def async_get_device_info(hass, device, ha_device_registry=None):
|
|||||||
ret_device = {}
|
ret_device = {}
|
||||||
ret_device.update(device.device_info)
|
ret_device.update(device.device_info)
|
||||||
ret_device["entities"] = [
|
ret_device["entities"] = [
|
||||||
{"entity_id": entity_ref.reference_id, NAME: entity_ref.device_info[NAME]}
|
{
|
||||||
|
"entity_id": entity_ref.reference_id,
|
||||||
|
ATTR_NAME: entity_ref.device_info[ATTR_NAME],
|
||||||
|
}
|
||||||
for entity_ref in zha_gateway.device_registry[device.ieee]
|
for entity_ref in zha_gateway.device_registry[device.ieee]
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -201,21 +204,21 @@ async def websocket_device_clusters(hass, connection, msg):
|
|||||||
if zha_device is not None:
|
if zha_device is not None:
|
||||||
clusters_by_endpoint = zha_device.async_get_clusters()
|
clusters_by_endpoint = zha_device.async_get_clusters()
|
||||||
for ep_id, clusters in clusters_by_endpoint.items():
|
for ep_id, clusters in clusters_by_endpoint.items():
|
||||||
for c_id, cluster in clusters[IN].items():
|
for c_id, cluster in clusters[CLUSTER_TYPE_IN].items():
|
||||||
response_clusters.append(
|
response_clusters.append(
|
||||||
{
|
{
|
||||||
TYPE: IN,
|
TYPE: CLUSTER_TYPE_IN,
|
||||||
ID: c_id,
|
ID: c_id,
|
||||||
NAME: cluster.__class__.__name__,
|
ATTR_NAME: cluster.__class__.__name__,
|
||||||
"endpoint_id": ep_id,
|
"endpoint_id": ep_id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
for c_id, cluster in clusters[OUT].items():
|
for c_id, cluster in clusters[CLUSTER_TYPE_OUT].items():
|
||||||
response_clusters.append(
|
response_clusters.append(
|
||||||
{
|
{
|
||||||
TYPE: OUT,
|
TYPE: CLUSTER_TYPE_OUT,
|
||||||
ID: c_id,
|
ID: c_id,
|
||||||
NAME: cluster.__class__.__name__,
|
ATTR_NAME: cluster.__class__.__name__,
|
||||||
"endpoint_id": ep_id,
|
"endpoint_id": ep_id,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -250,7 +253,9 @@ async def websocket_device_cluster_attributes(hass, connection, msg):
|
|||||||
)
|
)
|
||||||
if attributes is not None:
|
if attributes is not None:
|
||||||
for attr_id in attributes:
|
for attr_id in attributes:
|
||||||
cluster_attributes.append({ID: attr_id, NAME: attributes[attr_id][0]})
|
cluster_attributes.append(
|
||||||
|
{ID: attr_id, ATTR_NAME: attributes[attr_id][0]}
|
||||||
|
)
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Requested attributes for: %s %s %s %s",
|
"Requested attributes for: %s %s %s %s",
|
||||||
"{}: [{}]".format(ATTR_CLUSTER_ID, cluster_id),
|
"{}: [{}]".format(ATTR_CLUSTER_ID, cluster_id),
|
||||||
@ -289,20 +294,20 @@ async def websocket_device_cluster_commands(hass, connection, msg):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if commands is not None:
|
if commands is not None:
|
||||||
for cmd_id in commands[CLIENT_COMMANDS]:
|
for cmd_id in commands[CLUSTER_COMMANDS_CLIENT]:
|
||||||
cluster_commands.append(
|
cluster_commands.append(
|
||||||
{
|
{
|
||||||
TYPE: CLIENT,
|
TYPE: CLIENT,
|
||||||
ID: cmd_id,
|
ID: cmd_id,
|
||||||
NAME: commands[CLIENT_COMMANDS][cmd_id][0],
|
ATTR_NAME: commands[CLUSTER_COMMANDS_CLIENT][cmd_id][0],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
for cmd_id in commands[SERVER_COMMANDS]:
|
for cmd_id in commands[CLUSTER_COMMANDS_SERVER]:
|
||||||
cluster_commands.append(
|
cluster_commands.append(
|
||||||
{
|
{
|
||||||
TYPE: SERVER,
|
TYPE: CLUSTER_COMMAND_SERVER,
|
||||||
ID: cmd_id,
|
ID: cmd_id,
|
||||||
NAME: commands[SERVER_COMMANDS][cmd_id][0],
|
ATTR_NAME: commands[CLUSTER_COMMANDS_SERVER][cmd_id][0],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
|
@ -2,34 +2,35 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import (
|
from homeassistant.components.binary_sensor import (
|
||||||
|
DEVICE_CLASS_GAS,
|
||||||
|
DEVICE_CLASS_MOISTURE,
|
||||||
|
DEVICE_CLASS_MOTION,
|
||||||
|
DEVICE_CLASS_MOVING,
|
||||||
|
DEVICE_CLASS_OCCUPANCY,
|
||||||
|
DEVICE_CLASS_OPENING,
|
||||||
|
DEVICE_CLASS_SMOKE,
|
||||||
|
DEVICE_CLASS_VIBRATION,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
BinarySensorDevice,
|
BinarySensorDevice,
|
||||||
DEVICE_CLASS_MOVING,
|
|
||||||
DEVICE_CLASS_MOTION,
|
|
||||||
DEVICE_CLASS_OPENING,
|
|
||||||
DEVICE_CLASS_MOISTURE,
|
|
||||||
DEVICE_CLASS_SMOKE,
|
|
||||||
DEVICE_CLASS_GAS,
|
|
||||||
DEVICE_CLASS_VIBRATION,
|
|
||||||
DEVICE_CLASS_OCCUPANCY,
|
|
||||||
)
|
)
|
||||||
from homeassistant.const import STATE_ON
|
from homeassistant.const import STATE_ON
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from .core.const import (
|
from .core.const import (
|
||||||
|
SENSOR_ACCELERATION,
|
||||||
|
CHANNEL_ATTRIBUTE,
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_DISPATCHERS,
|
DATA_ZHA_DISPATCHERS,
|
||||||
ZHA_DISCOVERY_NEW,
|
SENSOR_OCCUPANCY,
|
||||||
ON_OFF_CHANNEL,
|
CHANNEL_ON_OFF,
|
||||||
ZONE_CHANNEL,
|
SENSOR_OPENING,
|
||||||
SIGNAL_ATTR_UPDATED,
|
|
||||||
ATTRIBUTE_CHANNEL,
|
|
||||||
UNKNOWN,
|
|
||||||
OPENING,
|
|
||||||
ZONE,
|
|
||||||
OCCUPANCY,
|
|
||||||
SENSOR_TYPE,
|
SENSOR_TYPE,
|
||||||
ACCELERATION,
|
SIGNAL_ATTR_UPDATED,
|
||||||
|
UNKNOWN,
|
||||||
|
ZHA_DISCOVERY_NEW,
|
||||||
|
ZONE,
|
||||||
|
CHANNEL_ZONE,
|
||||||
)
|
)
|
||||||
from .entity import ZhaEntity
|
from .entity import ZhaEntity
|
||||||
|
|
||||||
@ -54,10 +55,10 @@ async def get_ias_device_class(channel):
|
|||||||
|
|
||||||
DEVICE_CLASS_REGISTRY = {
|
DEVICE_CLASS_REGISTRY = {
|
||||||
UNKNOWN: None,
|
UNKNOWN: None,
|
||||||
OPENING: DEVICE_CLASS_OPENING,
|
SENSOR_OPENING: DEVICE_CLASS_OPENING,
|
||||||
ZONE: get_ias_device_class,
|
ZONE: get_ias_device_class,
|
||||||
OCCUPANCY: DEVICE_CLASS_OCCUPANCY,
|
SENSOR_OCCUPANCY: DEVICE_CLASS_OCCUPANCY,
|
||||||
ACCELERATION: DEVICE_CLASS_MOVING,
|
SENSOR_ACCELERATION: DEVICE_CLASS_MOVING,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -108,9 +109,9 @@ class BinarySensor(ZhaEntity, BinarySensorDevice):
|
|||||||
"""Initialize the ZHA binary sensor."""
|
"""Initialize the ZHA binary sensor."""
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self._device_state_attributes = {}
|
self._device_state_attributes = {}
|
||||||
self._zone_channel = self.cluster_channels.get(ZONE_CHANNEL)
|
self._zone_channel = self.cluster_channels.get(CHANNEL_ZONE)
|
||||||
self._on_off_channel = self.cluster_channels.get(ON_OFF_CHANNEL)
|
self._on_off_channel = self.cluster_channels.get(CHANNEL_ON_OFF)
|
||||||
self._attr_channel = self.cluster_channels.get(ATTRIBUTE_CHANNEL)
|
self._attr_channel = self.cluster_channels.get(CHANNEL_ATTRIBUTE)
|
||||||
self._zha_sensor_type = kwargs[SENSOR_TYPE]
|
self._zha_sensor_type = kwargs[SENSOR_TYPE]
|
||||||
|
|
||||||
async def _determine_device_class(self):
|
async def _determine_device_class(self):
|
||||||
|
@ -13,20 +13,21 @@ from random import uniform
|
|||||||
|
|
||||||
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 ..helpers import (
|
|
||||||
configure_reporting,
|
|
||||||
construct_unique_id,
|
|
||||||
safe_read,
|
|
||||||
get_attr_id_by_name,
|
|
||||||
bind_cluster,
|
|
||||||
LogMixin,
|
|
||||||
)
|
|
||||||
from ..const import (
|
from ..const import (
|
||||||
|
CHANNEL_ATTRIBUTE,
|
||||||
|
CHANNEL_EVENT_RELAY,
|
||||||
REPORT_CONFIG_DEFAULT,
|
REPORT_CONFIG_DEFAULT,
|
||||||
SIGNAL_ATTR_UPDATED,
|
SIGNAL_ATTR_UPDATED,
|
||||||
ATTRIBUTE_CHANNEL,
|
CHANNEL_ZDO,
|
||||||
EVENT_RELAY_CHANNEL,
|
)
|
||||||
ZDO_CHANNEL,
|
from ..helpers import (
|
||||||
|
LogMixin,
|
||||||
|
bind_cluster,
|
||||||
|
configure_reporting,
|
||||||
|
construct_unique_id,
|
||||||
|
get_attr_id_by_name,
|
||||||
|
safe_read,
|
||||||
)
|
)
|
||||||
from ..registries import CLUSTER_REPORT_CONFIGS
|
from ..registries import CLUSTER_REPORT_CONFIGS
|
||||||
|
|
||||||
@ -232,7 +233,7 @@ class ZigbeeChannel(LogMixin):
|
|||||||
class AttributeListeningChannel(ZigbeeChannel):
|
class AttributeListeningChannel(ZigbeeChannel):
|
||||||
"""Channel for attribute reports from the cluster."""
|
"""Channel for attribute reports from the cluster."""
|
||||||
|
|
||||||
CHANNEL_NAME = ATTRIBUTE_CHANNEL
|
CHANNEL_NAME = CHANNEL_ATTRIBUTE
|
||||||
|
|
||||||
def __init__(self, cluster, device):
|
def __init__(self, cluster, device):
|
||||||
"""Initialize AttributeListeningChannel."""
|
"""Initialize AttributeListeningChannel."""
|
||||||
@ -266,7 +267,7 @@ class ZDOChannel(LogMixin):
|
|||||||
|
|
||||||
def __init__(self, cluster, device):
|
def __init__(self, cluster, device):
|
||||||
"""Initialize ZDOChannel."""
|
"""Initialize ZDOChannel."""
|
||||||
self.name = ZDO_CHANNEL
|
self.name = CHANNEL_ZDO
|
||||||
self._cluster = cluster
|
self._cluster = cluster
|
||||||
self._zha_device = device
|
self._zha_device = device
|
||||||
self._status = ChannelStatus.CREATED
|
self._status = ChannelStatus.CREATED
|
||||||
@ -320,7 +321,7 @@ class ZDOChannel(LogMixin):
|
|||||||
class EventRelayChannel(ZigbeeChannel):
|
class EventRelayChannel(ZigbeeChannel):
|
||||||
"""Event relay that can be attached to zigbee clusters."""
|
"""Event relay that can be attached to zigbee clusters."""
|
||||||
|
|
||||||
CHANNEL_NAME = EVENT_RELAY_CHANNEL
|
CHANNEL_NAME = CHANNEL_EVENT_RELAY
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def attribute_updated(self, attrid, value):
|
def attribute_updated(self, attrid, value):
|
||||||
|
@ -5,8 +5,10 @@ For more details about this component, please refer to the documentation at
|
|||||||
https://home-assistant.io/components/zha/
|
https://home-assistant.io/components/zha/
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
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 . import ZigbeeChannel
|
from . import ZigbeeChannel
|
||||||
from ..const import SIGNAL_ATTR_UPDATED
|
from ..const import SIGNAL_ATTR_UPDATED
|
||||||
|
|
||||||
|
@ -5,12 +5,14 @@ For more details about this component, please refer to the documentation at
|
|||||||
https://home-assistant.io/components/zha/
|
https://home-assistant.io/components/zha/
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
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.event import async_call_later
|
from homeassistant.helpers.event import async_call_later
|
||||||
|
|
||||||
from . import ZigbeeChannel, parse_and_log_command
|
from . import ZigbeeChannel, parse_and_log_command
|
||||||
from ..helpers import get_attr_id_by_name
|
|
||||||
from ..const import SIGNAL_ATTR_UPDATED, SIGNAL_MOVE_LEVEL, SIGNAL_SET_LEVEL
|
from ..const import SIGNAL_ATTR_UPDATED, SIGNAL_MOVE_LEVEL, SIGNAL_SET_LEVEL
|
||||||
|
from ..helpers import get_attr_id_by_name
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -5,9 +5,11 @@ For more details about this component, please refer to the documentation at
|
|||||||
https://home-assistant.io/components/zha/
|
https://home-assistant.io/components/zha/
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
|
|
||||||
from . import AttributeListeningChannel
|
from . import AttributeListeningChannel
|
||||||
from ..const import SIGNAL_ATTR_UPDATED, ELECTRICAL_MEASUREMENT_CHANNEL
|
from ..const import CHANNEL_ELECTRICAL_MEASUREMENT, SIGNAL_ATTR_UPDATED
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
class ElectricalMeasurementChannel(AttributeListeningChannel):
|
class ElectricalMeasurementChannel(AttributeListeningChannel):
|
||||||
"""Channel that polls active power level."""
|
"""Channel that polls active power level."""
|
||||||
|
|
||||||
CHANNEL_NAME = ELECTRICAL_MEASUREMENT_CHANNEL
|
CHANNEL_NAME = CHANNEL_ELECTRICAL_MEASUREMENT
|
||||||
|
|
||||||
async def async_update(self):
|
async def async_update(self):
|
||||||
"""Retrieve latest state."""
|
"""Retrieve latest state."""
|
||||||
|
@ -5,8 +5,10 @@ For more details about this component, please refer to the documentation at
|
|||||||
https://home-assistant.io/components/zha/
|
https://home-assistant.io/components/zha/
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
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 . import ZigbeeChannel
|
from . import ZigbeeChannel
|
||||||
from ..const import SIGNAL_ATTR_UPDATED
|
from ..const import SIGNAL_ATTR_UPDATED
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ For more details about this component, please refer to the documentation at
|
|||||||
https://home-assistant.io/components/zha/
|
https://home-assistant.io/components/zha/
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from . import ZigbeeChannel
|
from . import ZigbeeChannel
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -5,13 +5,12 @@ For more details about this component, please refer to the documentation at
|
|||||||
https://home-assistant.io/components/zha/
|
https://home-assistant.io/components/zha/
|
||||||
"""
|
"""
|
||||||
from . import ZigbeeChannel
|
from . import ZigbeeChannel
|
||||||
|
|
||||||
from .closures import DoorLockChannel
|
from .closures import DoorLockChannel
|
||||||
from .general import (
|
from .general import (
|
||||||
OnOffChannel,
|
|
||||||
LevelControlChannel,
|
|
||||||
PowerConfigurationChannel,
|
|
||||||
BasicChannel,
|
BasicChannel,
|
||||||
|
LevelControlChannel,
|
||||||
|
OnOffChannel,
|
||||||
|
PowerConfigurationChannel,
|
||||||
)
|
)
|
||||||
from .homeautomation import ElectricalMeasurementChannel
|
from .homeautomation import ElectricalMeasurementChannel
|
||||||
from .hvac import FanChannel
|
from .hvac import FanChannel
|
||||||
@ -27,27 +26,27 @@ def populate_channel_registry():
|
|||||||
|
|
||||||
ZIGBEE_CHANNEL_REGISTRY.update(
|
ZIGBEE_CHANNEL_REGISTRY.update(
|
||||||
{
|
{
|
||||||
zcl.clusters.general.Alarms.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.Commissioning.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.Identify.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.Groups.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.Scenes.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.Partition.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.Ota.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.PowerProfile.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.ApplianceControl.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.PollControl.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.GreenPowerProxy.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.OnOffConfiguration.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.general.OnOff.cluster_id: OnOffChannel,
|
|
||||||
zcl.clusters.general.LevelControl.cluster_id: LevelControlChannel,
|
|
||||||
zcl.clusters.lighting.Color.cluster_id: ColorChannel,
|
|
||||||
zcl.clusters.homeautomation.ElectricalMeasurement.cluster_id: ElectricalMeasurementChannel,
|
|
||||||
zcl.clusters.general.PowerConfiguration.cluster_id: PowerConfigurationChannel,
|
|
||||||
zcl.clusters.general.Basic.cluster_id: BasicChannel,
|
|
||||||
zcl.clusters.security.IasZone.cluster_id: IASZoneChannel,
|
|
||||||
zcl.clusters.hvac.Fan.cluster_id: FanChannel,
|
|
||||||
zcl.clusters.lightlink.LightLink.cluster_id: ZigbeeChannel,
|
|
||||||
zcl.clusters.closures.DoorLock.cluster_id: DoorLockChannel,
|
zcl.clusters.closures.DoorLock.cluster_id: DoorLockChannel,
|
||||||
|
zcl.clusters.general.Alarms.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.ApplianceControl.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.Basic.cluster_id: BasicChannel,
|
||||||
|
zcl.clusters.general.Commissioning.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.GreenPowerProxy.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.Groups.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.Identify.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.LevelControl.cluster_id: LevelControlChannel,
|
||||||
|
zcl.clusters.general.OnOff.cluster_id: OnOffChannel,
|
||||||
|
zcl.clusters.general.OnOffConfiguration.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.Ota.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.Partition.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.PollControl.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.PowerConfiguration.cluster_id: PowerConfigurationChannel,
|
||||||
|
zcl.clusters.general.PowerProfile.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.general.Scenes.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.homeautomation.ElectricalMeasurement.cluster_id: ElectricalMeasurementChannel,
|
||||||
|
zcl.clusters.hvac.Fan.cluster_id: FanChannel,
|
||||||
|
zcl.clusters.lighting.Color.cluster_id: ColorChannel,
|
||||||
|
zcl.clusters.lightlink.LightLink.cluster_id: ZigbeeChannel,
|
||||||
|
zcl.clusters.security.IasZone.cluster_id: IASZoneChannel,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -5,11 +5,13 @@ For more details about this component, please refer to the documentation at
|
|||||||
https://home-assistant.io/components/zha/
|
https://home-assistant.io/components/zha/
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
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 . import ZigbeeChannel
|
from . import ZigbeeChannel
|
||||||
from ..helpers import bind_cluster
|
|
||||||
from ..const import SIGNAL_ATTR_UPDATED
|
from ..const import SIGNAL_ATTR_UPDATED
|
||||||
|
from ..helpers import bind_cluster
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -10,132 +10,98 @@ from homeassistant.components.lock import DOMAIN as LOCK
|
|||||||
from homeassistant.components.sensor import DOMAIN as SENSOR
|
from homeassistant.components.sensor import DOMAIN as SENSOR
|
||||||
from homeassistant.components.switch import DOMAIN as SWITCH
|
from homeassistant.components.switch import DOMAIN as SWITCH
|
||||||
|
|
||||||
DOMAIN = "zha"
|
ATTR_ARGS = "args"
|
||||||
|
ATTR_ATTRIBUTE = "attribute"
|
||||||
|
ATTR_AVAILABLE = "available"
|
||||||
|
ATTR_CLUSTER_ID = "cluster_id"
|
||||||
|
ATTR_CLUSTER_TYPE = "cluster_type"
|
||||||
|
ATTR_COMMAND = "command"
|
||||||
|
ATTR_COMMAND_TYPE = "command_type"
|
||||||
|
ATTR_ENDPOINT_ID = "endpoint_id"
|
||||||
|
ATTR_IEEE = "ieee"
|
||||||
|
ATTR_LAST_SEEN = "last_seen"
|
||||||
|
ATTR_LEVEL = "level"
|
||||||
|
ATTR_LQI = "lqi"
|
||||||
|
ATTR_MANUFACTURER = "manufacturer"
|
||||||
|
ATTR_MANUFACTURER_CODE = "manufacturer_code"
|
||||||
|
ATTR_MODEL = "model"
|
||||||
|
ATTR_NAME = "name"
|
||||||
|
ATTR_NWK = "nwk"
|
||||||
|
ATTR_POWER_SOURCE = "power_source"
|
||||||
|
ATTR_QUIRK_APPLIED = "quirk_applied"
|
||||||
|
ATTR_QUIRK_CLASS = "quirk_class"
|
||||||
|
ATTR_RSSI = "rssi"
|
||||||
|
ATTR_SIGNATURE = "signature"
|
||||||
|
ATTR_TYPE = "type"
|
||||||
|
ATTR_VALUE = "value"
|
||||||
|
|
||||||
BAUD_RATES = [2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 128000, 256000]
|
BAUD_RATES = [2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 128000, 256000]
|
||||||
|
|
||||||
DATA_ZHA = "zha"
|
CHANNEL_ATTRIBUTE = "attribute"
|
||||||
DATA_ZHA_CONFIG = "config"
|
CHANNEL_BASIC = "basic"
|
||||||
DATA_ZHA_BRIDGE_ID = "zha_bridge_id"
|
CHANNEL_COLOR = "light_color"
|
||||||
DATA_ZHA_DISPATCHERS = "zha_dispatchers"
|
CHANNEL_DOORLOCK = "door_lock"
|
||||||
DATA_ZHA_CORE_EVENTS = "zha_core_events"
|
CHANNEL_ELECTRICAL_MEASUREMENT = "electrical_measurement"
|
||||||
DATA_ZHA_GATEWAY = "zha_gateway"
|
CHANNEL_EVENT_RELAY = "event_relay"
|
||||||
ZHA_DISCOVERY_NEW = "zha_discovery_new_{}"
|
CHANNEL_FAN = "fan"
|
||||||
|
CHANNEL_LEVEL = ATTR_LEVEL
|
||||||
|
CHANNEL_ON_OFF = "on_off"
|
||||||
|
CHANNEL_POWER_CONFIGURATION = "power"
|
||||||
|
CHANNEL_ZDO = "zdo"
|
||||||
|
CHANNEL_ZONE = ZONE = "ias_zone"
|
||||||
|
|
||||||
|
CLUSTER_COMMAND_SERVER = "server"
|
||||||
|
CLUSTER_COMMANDS_CLIENT = "client_commands"
|
||||||
|
CLUSTER_COMMANDS_SERVER = "server_commands"
|
||||||
|
CLUSTER_TYPE_IN = "in"
|
||||||
|
CLUSTER_TYPE_OUT = "out"
|
||||||
|
|
||||||
COMPONENTS = (BINARY_SENSOR, DEVICE_TRACKER, FAN, LIGHT, LOCK, SENSOR, SWITCH)
|
COMPONENTS = (BINARY_SENSOR, DEVICE_TRACKER, FAN, LIGHT, LOCK, SENSOR, SWITCH)
|
||||||
|
|
||||||
CONF_BAUDRATE = "baudrate"
|
CONF_BAUDRATE = "baudrate"
|
||||||
CONF_DATABASE = "database_path"
|
CONF_DATABASE = "database_path"
|
||||||
CONF_DEVICE_CONFIG = "device_config"
|
CONF_DEVICE_CONFIG = "device_config"
|
||||||
|
CONF_ENABLE_QUIRKS = "enable_quirks"
|
||||||
CONF_RADIO_TYPE = "radio_type"
|
CONF_RADIO_TYPE = "radio_type"
|
||||||
CONF_USB_PATH = "usb_path"
|
CONF_USB_PATH = "usb_path"
|
||||||
DATA_DEVICE_CONFIG = "zha_device_config"
|
|
||||||
ENABLE_QUIRKS = "enable_quirks"
|
|
||||||
|
|
||||||
RADIO = "radio"
|
|
||||||
RADIO_DESCRIPTION = "radio_description"
|
|
||||||
CONTROLLER = "controller"
|
CONTROLLER = "controller"
|
||||||
|
|
||||||
|
DATA_DEVICE_CONFIG = "zha_device_config"
|
||||||
|
DATA_ZHA = "zha"
|
||||||
|
DATA_ZHA_CONFIG = "config"
|
||||||
|
DATA_ZHA_BRIDGE_ID = "zha_bridge_id"
|
||||||
|
DATA_ZHA_CORE_EVENTS = "zha_core_events"
|
||||||
|
DATA_ZHA_DISPATCHERS = "zha_dispatchers"
|
||||||
|
DATA_ZHA_GATEWAY = "zha_gateway"
|
||||||
|
|
||||||
|
DEBUG_COMP_BELLOWS = "bellows"
|
||||||
|
DEBUG_COMP_ZHA = "homeassistant.components.zha"
|
||||||
|
DEBUG_COMP_ZIGPY = "zigpy"
|
||||||
|
DEBUG_COMP_ZIGPY_DECONZ = "zigpy_deconz"
|
||||||
|
DEBUG_COMP_ZIGPY_XBEE = "zigpy_xbee"
|
||||||
|
DEBUG_LEVEL_CURRENT = "current"
|
||||||
|
DEBUG_LEVEL_ORIGINAL = "original"
|
||||||
|
DEBUG_LEVELS = {
|
||||||
|
DEBUG_COMP_BELLOWS: logging.DEBUG,
|
||||||
|
DEBUG_COMP_ZHA: logging.DEBUG,
|
||||||
|
DEBUG_COMP_ZIGPY: logging.DEBUG,
|
||||||
|
DEBUG_COMP_ZIGPY_XBEE: logging.DEBUG,
|
||||||
|
DEBUG_COMP_ZIGPY_DECONZ: logging.DEBUG,
|
||||||
|
}
|
||||||
|
DEBUG_RELAY_LOGGERS = [DEBUG_COMP_ZHA, DEBUG_COMP_ZIGPY]
|
||||||
|
|
||||||
DEFAULT_RADIO_TYPE = "ezsp"
|
DEFAULT_RADIO_TYPE = "ezsp"
|
||||||
DEFAULT_BAUDRATE = 57600
|
DEFAULT_BAUDRATE = 57600
|
||||||
DEFAULT_DATABASE_NAME = "zigbee.db"
|
DEFAULT_DATABASE_NAME = "zigbee.db"
|
||||||
|
DISCOVERY_KEY = "zha_discovery_info"
|
||||||
|
|
||||||
ATTR_CLUSTER_ID = "cluster_id"
|
DOMAIN = "zha"
|
||||||
ATTR_CLUSTER_TYPE = "cluster_type"
|
|
||||||
ATTR_ATTRIBUTE = "attribute"
|
|
||||||
ATTR_VALUE = "value"
|
|
||||||
ATTR_MANUFACTURER = "manufacturer"
|
|
||||||
ATTR_COMMAND = "command"
|
|
||||||
ATTR_COMMAND_TYPE = "command_type"
|
|
||||||
ATTR_ARGS = "args"
|
|
||||||
ATTR_ENDPOINT_ID = "endpoint_id"
|
|
||||||
ATTR_AVAILABLE = "available"
|
|
||||||
|
|
||||||
IN = "in"
|
|
||||||
OUT = "out"
|
|
||||||
CLIENT_COMMANDS = "client_commands"
|
|
||||||
SERVER_COMMANDS = "server_commands"
|
|
||||||
SERVER = "server"
|
|
||||||
IEEE = "ieee"
|
|
||||||
MODEL = "model"
|
|
||||||
NAME = "name"
|
|
||||||
LQI = "lqi"
|
|
||||||
RSSI = "rssi"
|
|
||||||
LAST_SEEN = "last_seen"
|
|
||||||
|
|
||||||
SENSOR_TYPE = "sensor_type"
|
|
||||||
HUMIDITY = "humidity"
|
|
||||||
TEMPERATURE = "temperature"
|
|
||||||
ILLUMINANCE = "illuminance"
|
|
||||||
PRESSURE = "pressure"
|
|
||||||
METERING = "metering"
|
|
||||||
ELECTRICAL_MEASUREMENT = "electrical_measurement"
|
|
||||||
GENERIC = "generic"
|
|
||||||
BATTERY = "battery"
|
|
||||||
UNKNOWN = "unknown"
|
|
||||||
UNKNOWN_MANUFACTURER = "unk_manufacturer"
|
|
||||||
UNKNOWN_MODEL = "unk_model"
|
|
||||||
OPENING = "opening"
|
|
||||||
OCCUPANCY = "occupancy"
|
|
||||||
ACCELERATION = "acceleration"
|
|
||||||
|
|
||||||
ATTR_LEVEL = "level"
|
|
||||||
|
|
||||||
ZDO_CHANNEL = "zdo"
|
|
||||||
ON_OFF_CHANNEL = "on_off"
|
|
||||||
ATTRIBUTE_CHANNEL = "attribute"
|
|
||||||
BASIC_CHANNEL = "basic"
|
|
||||||
COLOR_CHANNEL = "light_color"
|
|
||||||
FAN_CHANNEL = "fan"
|
|
||||||
LEVEL_CHANNEL = ATTR_LEVEL
|
|
||||||
ZONE_CHANNEL = ZONE = "ias_zone"
|
|
||||||
ELECTRICAL_MEASUREMENT_CHANNEL = "electrical_measurement"
|
|
||||||
POWER_CONFIGURATION_CHANNEL = "power"
|
|
||||||
EVENT_RELAY_CHANNEL = "event_relay"
|
|
||||||
DOORLOCK_CHANNEL = "door_lock"
|
|
||||||
|
|
||||||
SIGNAL_ATTR_UPDATED = "attribute_updated"
|
|
||||||
SIGNAL_MOVE_LEVEL = "move_level"
|
|
||||||
SIGNAL_SET_LEVEL = "set_level"
|
|
||||||
SIGNAL_STATE_ATTR = "update_state_attribute"
|
|
||||||
SIGNAL_AVAILABLE = "available"
|
|
||||||
SIGNAL_REMOVE = "remove"
|
|
||||||
|
|
||||||
QUIRK_APPLIED = "quirk_applied"
|
|
||||||
QUIRK_CLASS = "quirk_class"
|
|
||||||
MANUFACTURER_CODE = "manufacturer_code"
|
|
||||||
POWER_SOURCE = "power_source"
|
|
||||||
MAINS_POWERED = "Mains"
|
|
||||||
BATTERY_OR_UNKNOWN = "Battery or Unknown"
|
|
||||||
|
|
||||||
BELLOWS = "bellows"
|
|
||||||
ZHA = "homeassistant.components.zha"
|
|
||||||
ZIGPY = "zigpy"
|
|
||||||
ZIGPY_XBEE = "zigpy_xbee"
|
|
||||||
ZIGPY_DECONZ = "zigpy_deconz"
|
|
||||||
ORIGINAL = "original"
|
|
||||||
CURRENT = "current"
|
|
||||||
DEBUG_LEVELS = {
|
|
||||||
BELLOWS: logging.DEBUG,
|
|
||||||
ZHA: logging.DEBUG,
|
|
||||||
ZIGPY: logging.DEBUG,
|
|
||||||
ZIGPY_XBEE: logging.DEBUG,
|
|
||||||
ZIGPY_DECONZ: logging.DEBUG,
|
|
||||||
}
|
|
||||||
ADD_DEVICE_RELAY_LOGGERS = [ZHA, ZIGPY]
|
|
||||||
TYPE = "type"
|
|
||||||
NWK = "nwk"
|
|
||||||
SIGNATURE = "signature"
|
|
||||||
RAW_INIT = "raw_device_initialized"
|
|
||||||
ZHA_GW_MSG = "zha_gateway_message"
|
|
||||||
DEVICE_REMOVED = "device_removed"
|
|
||||||
DEVICE_INFO = "device_info"
|
|
||||||
DEVICE_FULL_INIT = "device_fully_initialized"
|
|
||||||
DEVICE_JOINED = "device_joined"
|
|
||||||
LOG_OUTPUT = "log_output"
|
|
||||||
LOG_ENTRY = "log_entry"
|
|
||||||
MFG_CLUSTER_ID_START = 0xFC00
|
MFG_CLUSTER_ID_START = 0xFC00
|
||||||
|
|
||||||
|
POWER_MAINS_POWERED = "Mains"
|
||||||
|
POWER_BATTERY_OR_UNKNOWN = "Battery or Unknown"
|
||||||
|
|
||||||
|
|
||||||
class RadioType(enum.Enum):
|
class RadioType(enum.Enum):
|
||||||
"""Possible options for radio type."""
|
"""Possible options for radio type."""
|
||||||
@ -150,8 +116,6 @@ class RadioType(enum.Enum):
|
|||||||
return [e.value for e in RadioType]
|
return [e.value for e in RadioType]
|
||||||
|
|
||||||
|
|
||||||
DISCOVERY_KEY = "zha_discovery_info"
|
|
||||||
|
|
||||||
REPORT_CONFIG_MAX_INT = 900
|
REPORT_CONFIG_MAX_INT = 900
|
||||||
REPORT_CONFIG_MAX_INT_BATTERY_SAVE = 10800
|
REPORT_CONFIG_MAX_INT_BATTERY_SAVE = 10800
|
||||||
REPORT_CONFIG_MIN_INT = 30
|
REPORT_CONFIG_MIN_INT = 30
|
||||||
@ -185,3 +149,39 @@ REPORT_CONFIG_OP = (
|
|||||||
REPORT_CONFIG_MAX_INT,
|
REPORT_CONFIG_MAX_INT,
|
||||||
REPORT_CONFIG_RPT_CHANGE,
|
REPORT_CONFIG_RPT_CHANGE,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SENSOR_ACCELERATION = "acceleration"
|
||||||
|
SENSOR_BATTERY = "battery"
|
||||||
|
SENSOR_ELECTRICAL_MEASUREMENT = "electrical_measurement"
|
||||||
|
SENSOR_GENERIC = "generic"
|
||||||
|
SENSOR_HUMIDITY = "humidity"
|
||||||
|
SENSOR_ILLUMINANCE = "illuminance"
|
||||||
|
SENSOR_METERING = "metering"
|
||||||
|
SENSOR_OCCUPANCY = "occupancy"
|
||||||
|
SENSOR_OPENING = "opening"
|
||||||
|
SENSOR_PRESSURE = "pressure"
|
||||||
|
SENSOR_TEMPERATURE = "temperature"
|
||||||
|
SENSOR_TYPE = "sensor_type"
|
||||||
|
|
||||||
|
SIGNAL_ATTR_UPDATED = "attribute_updated"
|
||||||
|
SIGNAL_AVAILABLE = "available"
|
||||||
|
SIGNAL_MOVE_LEVEL = "move_level"
|
||||||
|
SIGNAL_REMOVE = "remove"
|
||||||
|
SIGNAL_SET_LEVEL = "set_level"
|
||||||
|
SIGNAL_STATE_ATTR = "update_state_attribute"
|
||||||
|
|
||||||
|
UNKNOWN = "unknown"
|
||||||
|
UNKNOWN_MANUFACTURER = "unk_manufacturer"
|
||||||
|
UNKNOWN_MODEL = "unk_model"
|
||||||
|
|
||||||
|
ZHA_DISCOVERY_NEW = "zha_discovery_new_{}"
|
||||||
|
ZHA_GW_MSG_RAW_INIT = "raw_device_initialized"
|
||||||
|
ZHA_GW_MSG = "zha_gateway_message"
|
||||||
|
ZHA_GW_MSG_DEVICE_REMOVED = "device_removed"
|
||||||
|
ZHA_GW_MSG_DEVICE_INFO = "device_info"
|
||||||
|
ZHA_GW_MSG_DEVICE_FULL_INIT = "device_fully_initialized"
|
||||||
|
ZHA_GW_MSG_DEVICE_JOINED = "device_joined"
|
||||||
|
ZHA_GW_MSG_LOG_OUTPUT = "log_output"
|
||||||
|
ZHA_GW_MSG_LOG_ENTRY = "log_entry"
|
||||||
|
ZHA_GW_RADIO = "radio"
|
||||||
|
ZHA_GW_RADIO_DESCRIPTION = "radio_description"
|
||||||
|
@ -21,36 +21,36 @@ from .channels import EventRelayChannel
|
|||||||
from .const import (
|
from .const import (
|
||||||
ATTR_ARGS,
|
ATTR_ARGS,
|
||||||
ATTR_ATTRIBUTE,
|
ATTR_ATTRIBUTE,
|
||||||
|
ATTR_AVAILABLE,
|
||||||
ATTR_CLUSTER_ID,
|
ATTR_CLUSTER_ID,
|
||||||
ATTR_COMMAND,
|
ATTR_COMMAND,
|
||||||
ATTR_COMMAND_TYPE,
|
ATTR_COMMAND_TYPE,
|
||||||
ATTR_ENDPOINT_ID,
|
ATTR_ENDPOINT_ID,
|
||||||
ATTR_MANUFACTURER,
|
ATTR_MANUFACTURER,
|
||||||
ATTR_VALUE,
|
ATTR_VALUE,
|
||||||
BATTERY_OR_UNKNOWN,
|
POWER_BATTERY_OR_UNKNOWN,
|
||||||
CLIENT_COMMANDS,
|
CLUSTER_COMMANDS_CLIENT,
|
||||||
IEEE,
|
ATTR_IEEE,
|
||||||
IN,
|
CLUSTER_TYPE_IN,
|
||||||
MAINS_POWERED,
|
ATTR_LAST_SEEN,
|
||||||
MANUFACTURER_CODE,
|
ATTR_LQI,
|
||||||
MODEL,
|
POWER_MAINS_POWERED,
|
||||||
NAME,
|
ATTR_MANUFACTURER_CODE,
|
||||||
NWK,
|
ATTR_MODEL,
|
||||||
OUT,
|
ATTR_NAME,
|
||||||
POWER_CONFIGURATION_CHANNEL,
|
ATTR_NWK,
|
||||||
POWER_SOURCE,
|
CLUSTER_TYPE_OUT,
|
||||||
QUIRK_APPLIED,
|
CHANNEL_POWER_CONFIGURATION,
|
||||||
QUIRK_CLASS,
|
ATTR_POWER_SOURCE,
|
||||||
SERVER,
|
ATTR_QUIRK_APPLIED,
|
||||||
SERVER_COMMANDS,
|
ATTR_QUIRK_CLASS,
|
||||||
|
ATTR_RSSI,
|
||||||
|
CLUSTER_COMMAND_SERVER,
|
||||||
|
CLUSTER_COMMANDS_SERVER,
|
||||||
SIGNAL_AVAILABLE,
|
SIGNAL_AVAILABLE,
|
||||||
UNKNOWN_MANUFACTURER,
|
UNKNOWN_MANUFACTURER,
|
||||||
UNKNOWN_MODEL,
|
UNKNOWN_MODEL,
|
||||||
ZDO_CHANNEL,
|
CHANNEL_ZDO,
|
||||||
LQI,
|
|
||||||
RSSI,
|
|
||||||
LAST_SEEN,
|
|
||||||
ATTR_AVAILABLE,
|
|
||||||
)
|
)
|
||||||
from .helpers import LogMixin
|
from .helpers import LogMixin
|
||||||
|
|
||||||
@ -155,7 +155,9 @@ class ZHADevice(LogMixin):
|
|||||||
@property
|
@property
|
||||||
def power_source(self):
|
def power_source(self):
|
||||||
"""Return the power source for the device."""
|
"""Return the power source for the device."""
|
||||||
return MAINS_POWERED if self.is_mains_powered else BATTERY_OR_UNKNOWN
|
return (
|
||||||
|
POWER_MAINS_POWERED if self.is_mains_powered else POWER_BATTERY_OR_UNKNOWN
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_router(self):
|
def is_router(self):
|
||||||
@ -223,18 +225,18 @@ class ZHADevice(LogMixin):
|
|||||||
time_struct = time.localtime(self.last_seen)
|
time_struct = time.localtime(self.last_seen)
|
||||||
update_time = time.strftime("%Y-%m-%dT%H:%M:%S", time_struct)
|
update_time = time.strftime("%Y-%m-%dT%H:%M:%S", time_struct)
|
||||||
return {
|
return {
|
||||||
IEEE: ieee,
|
ATTR_IEEE: ieee,
|
||||||
NWK: self.nwk,
|
ATTR_NWK: self.nwk,
|
||||||
ATTR_MANUFACTURER: self.manufacturer,
|
ATTR_MANUFACTURER: self.manufacturer,
|
||||||
MODEL: self.model,
|
ATTR_MODEL: self.model,
|
||||||
NAME: self.name or ieee,
|
ATTR_NAME: self.name or ieee,
|
||||||
QUIRK_APPLIED: self.quirk_applied,
|
ATTR_QUIRK_APPLIED: self.quirk_applied,
|
||||||
QUIRK_CLASS: self.quirk_class,
|
ATTR_QUIRK_CLASS: self.quirk_class,
|
||||||
MANUFACTURER_CODE: self.manufacturer_code,
|
ATTR_MANUFACTURER_CODE: self.manufacturer_code,
|
||||||
POWER_SOURCE: self.power_source,
|
ATTR_POWER_SOURCE: self.power_source,
|
||||||
LQI: self.lqi,
|
ATTR_LQI: self.lqi,
|
||||||
RSSI: self.rssi,
|
ATTR_RSSI: self.rssi,
|
||||||
LAST_SEEN: update_time,
|
ATTR_LAST_SEEN: update_time,
|
||||||
ATTR_AVAILABLE: self.available,
|
ATTR_AVAILABLE: self.available,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,8 +244,8 @@ class ZHADevice(LogMixin):
|
|||||||
"""Add cluster channel to device."""
|
"""Add cluster channel to device."""
|
||||||
# only keep 1 power configuration channel
|
# only keep 1 power configuration channel
|
||||||
if (
|
if (
|
||||||
cluster_channel.name is POWER_CONFIGURATION_CHANNEL
|
cluster_channel.name is CHANNEL_POWER_CONFIGURATION
|
||||||
and POWER_CONFIGURATION_CHANNEL in self.cluster_channels
|
and CHANNEL_POWER_CONFIGURATION in self.cluster_channels
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -318,7 +320,7 @@ class ZHADevice(LogMixin):
|
|||||||
semaphore = asyncio.Semaphore(3)
|
semaphore = asyncio.Semaphore(3)
|
||||||
zdo_task = None
|
zdo_task = None
|
||||||
for channel in channels:
|
for channel in channels:
|
||||||
if channel.name == ZDO_CHANNEL:
|
if channel.name == CHANNEL_ZDO:
|
||||||
# pylint: disable=E1111
|
# pylint: disable=E1111
|
||||||
if zdo_task is None: # We only want to do this once
|
if zdo_task is None: # We only want to do this once
|
||||||
zdo_task = self._async_create_task(
|
zdo_task = self._async_create_task(
|
||||||
@ -356,7 +358,10 @@ class ZHADevice(LogMixin):
|
|||||||
def async_get_clusters(self):
|
def async_get_clusters(self):
|
||||||
"""Get all clusters for this device."""
|
"""Get all clusters for this device."""
|
||||||
return {
|
return {
|
||||||
ep_id: {IN: endpoint.in_clusters, OUT: endpoint.out_clusters}
|
ep_id: {
|
||||||
|
CLUSTER_TYPE_IN: endpoint.in_clusters,
|
||||||
|
CLUSTER_TYPE_OUT: endpoint.out_clusters,
|
||||||
|
}
|
||||||
for (ep_id, endpoint) in self._zigpy_device.endpoints.items()
|
for (ep_id, endpoint) in self._zigpy_device.endpoints.items()
|
||||||
if ep_id != 0
|
if ep_id != 0
|
||||||
}
|
}
|
||||||
@ -367,19 +372,24 @@ class ZHADevice(LogMixin):
|
|||||||
from zigpy.profiles import zha, zll
|
from zigpy.profiles import zha, zll
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ep_id: {IN: endpoint.in_clusters, OUT: endpoint.out_clusters}
|
ep_id: {
|
||||||
|
CLUSTER_TYPE_IN: endpoint.in_clusters,
|
||||||
|
CLUSTER_TYPE_OUT: endpoint.out_clusters,
|
||||||
|
}
|
||||||
for (ep_id, endpoint) in self._zigpy_device.endpoints.items()
|
for (ep_id, endpoint) in self._zigpy_device.endpoints.items()
|
||||||
if ep_id != 0 and endpoint.profile_id in (zha.PROFILE_ID, zll.PROFILE_ID)
|
if ep_id != 0 and endpoint.profile_id in (zha.PROFILE_ID, zll.PROFILE_ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_get_cluster(self, endpoint_id, cluster_id, cluster_type=IN):
|
def async_get_cluster(self, endpoint_id, cluster_id, cluster_type=CLUSTER_TYPE_IN):
|
||||||
"""Get zigbee cluster from this entity."""
|
"""Get zigbee cluster from this entity."""
|
||||||
clusters = self.async_get_clusters()
|
clusters = self.async_get_clusters()
|
||||||
return clusters[endpoint_id][cluster_type][cluster_id]
|
return clusters[endpoint_id][cluster_type][cluster_id]
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_get_cluster_attributes(self, endpoint_id, cluster_id, cluster_type=IN):
|
def async_get_cluster_attributes(
|
||||||
|
self, endpoint_id, cluster_id, cluster_type=CLUSTER_TYPE_IN
|
||||||
|
):
|
||||||
"""Get zigbee attributes for specified cluster."""
|
"""Get zigbee attributes for specified cluster."""
|
||||||
cluster = self.async_get_cluster(endpoint_id, cluster_id, cluster_type)
|
cluster = self.async_get_cluster(endpoint_id, cluster_id, cluster_type)
|
||||||
if cluster is None:
|
if cluster is None:
|
||||||
@ -387,14 +397,16 @@ class ZHADevice(LogMixin):
|
|||||||
return cluster.attributes
|
return cluster.attributes
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_get_cluster_commands(self, endpoint_id, cluster_id, cluster_type=IN):
|
def async_get_cluster_commands(
|
||||||
|
self, endpoint_id, cluster_id, cluster_type=CLUSTER_TYPE_IN
|
||||||
|
):
|
||||||
"""Get zigbee commands for specified cluster."""
|
"""Get zigbee commands for specified cluster."""
|
||||||
cluster = self.async_get_cluster(endpoint_id, cluster_id, cluster_type)
|
cluster = self.async_get_cluster(endpoint_id, cluster_id, cluster_type)
|
||||||
if cluster is None:
|
if cluster is None:
|
||||||
return None
|
return None
|
||||||
return {
|
return {
|
||||||
CLIENT_COMMANDS: cluster.client_commands,
|
CLUSTER_COMMANDS_CLIENT: cluster.client_commands,
|
||||||
SERVER_COMMANDS: cluster.server_commands,
|
CLUSTER_COMMANDS_SERVER: cluster.server_commands,
|
||||||
}
|
}
|
||||||
|
|
||||||
async def write_zigbee_attribute(
|
async def write_zigbee_attribute(
|
||||||
@ -403,7 +415,7 @@ class ZHADevice(LogMixin):
|
|||||||
cluster_id,
|
cluster_id,
|
||||||
attribute,
|
attribute,
|
||||||
value,
|
value,
|
||||||
cluster_type=IN,
|
cluster_type=CLUSTER_TYPE_IN,
|
||||||
manufacturer=None,
|
manufacturer=None,
|
||||||
):
|
):
|
||||||
"""Write a value to a zigbee attribute for a cluster in this entity."""
|
"""Write a value to a zigbee attribute for a cluster in this entity."""
|
||||||
@ -444,7 +456,7 @@ class ZHADevice(LogMixin):
|
|||||||
command,
|
command,
|
||||||
command_type,
|
command_type,
|
||||||
args,
|
args,
|
||||||
cluster_type=IN,
|
cluster_type=CLUSTER_TYPE_IN,
|
||||||
manufacturer=None,
|
manufacturer=None,
|
||||||
):
|
):
|
||||||
"""Issue a command against specified zigbee cluster on this entity."""
|
"""Issue a command against specified zigbee cluster on this entity."""
|
||||||
@ -452,7 +464,7 @@ class ZHADevice(LogMixin):
|
|||||||
if cluster is None:
|
if cluster is None:
|
||||||
return None
|
return None
|
||||||
response = None
|
response = None
|
||||||
if command_type == SERVER:
|
if command_type == CLUSTER_COMMAND_SERVER:
|
||||||
response = await cluster.command(
|
response = await cluster.command(
|
||||||
command, *args, manufacturer=manufacturer, expect_reply=True
|
command, *args, manufacturer=manufacturer, expect_reply=True
|
||||||
)
|
)
|
||||||
|
@ -12,28 +12,29 @@ from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR
|
|||||||
from homeassistant.components.sensor import DOMAIN as SENSOR
|
from homeassistant.components.sensor import DOMAIN as SENSOR
|
||||||
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 .channels import AttributeListeningChannel, EventRelayChannel, ZDOChannel
|
from .channels import AttributeListeningChannel, EventRelayChannel, ZDOChannel
|
||||||
from .channels.registry import ZIGBEE_CHANNEL_REGISTRY
|
from .channels.registry import ZIGBEE_CHANNEL_REGISTRY
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_DEVICE_CONFIG,
|
|
||||||
COMPONENTS,
|
COMPONENTS,
|
||||||
ZHA_DISCOVERY_NEW,
|
CONF_DEVICE_CONFIG,
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
|
SENSOR_GENERIC,
|
||||||
SENSOR_TYPE,
|
SENSOR_TYPE,
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
GENERIC,
|
ZHA_DISCOVERY_NEW,
|
||||||
)
|
)
|
||||||
from .registries import (
|
from .registries import (
|
||||||
BINARY_SENSOR_TYPES,
|
BINARY_SENSOR_TYPES,
|
||||||
CHANNEL_ONLY_CLUSTERS,
|
CHANNEL_ONLY_CLUSTERS,
|
||||||
EVENT_RELAY_CLUSTERS,
|
|
||||||
SENSOR_TYPES,
|
|
||||||
DEVICE_CLASS,
|
|
||||||
COMPONENT_CLUSTERS,
|
COMPONENT_CLUSTERS,
|
||||||
SINGLE_INPUT_CLUSTER_DEVICE_CLASS,
|
DEVICE_CLASS,
|
||||||
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS,
|
EVENT_RELAY_CLUSTERS,
|
||||||
OUTPUT_CHANNEL_ONLY_CLUSTERS,
|
OUTPUT_CHANNEL_ONLY_CLUSTERS,
|
||||||
REMOTE_DEVICE_TYPES,
|
REMOTE_DEVICE_TYPES,
|
||||||
|
SENSOR_TYPES,
|
||||||
|
SINGLE_INPUT_CLUSTER_DEVICE_CLASS,
|
||||||
|
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -291,7 +292,7 @@ def _async_handle_single_cluster_match(
|
|||||||
|
|
||||||
if component == SENSOR:
|
if component == SENSOR:
|
||||||
discovery_info.update(
|
discovery_info.update(
|
||||||
{SENSOR_TYPE: SENSOR_TYPES.get(cluster.cluster_id, GENERIC)}
|
{SENSOR_TYPE: SENSOR_TYPES.get(cluster.cluster_id, SENSOR_GENERIC)}
|
||||||
)
|
)
|
||||||
if component == BINARY_SENSOR:
|
if component == BINARY_SENSOR:
|
||||||
discovery_info.update(
|
discovery_info.update(
|
||||||
|
@ -22,45 +22,45 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send
|
|||||||
|
|
||||||
from ..api import async_get_device_info
|
from ..api import async_get_device_info
|
||||||
from .const import (
|
from .const import (
|
||||||
ADD_DEVICE_RELAY_LOGGERS,
|
DEBUG_RELAY_LOGGERS,
|
||||||
ATTR_MANUFACTURER,
|
ATTR_MANUFACTURER,
|
||||||
BELLOWS,
|
DEBUG_COMP_BELLOWS,
|
||||||
CONF_BAUDRATE,
|
CONF_BAUDRATE,
|
||||||
CONF_DATABASE,
|
CONF_DATABASE,
|
||||||
CONF_RADIO_TYPE,
|
CONF_RADIO_TYPE,
|
||||||
CONF_USB_PATH,
|
CONF_USB_PATH,
|
||||||
CONTROLLER,
|
CONTROLLER,
|
||||||
CURRENT,
|
DEBUG_LEVEL_CURRENT,
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_BRIDGE_ID,
|
DATA_ZHA_BRIDGE_ID,
|
||||||
DATA_ZHA_GATEWAY,
|
DATA_ZHA_GATEWAY,
|
||||||
DEBUG_LEVELS,
|
DEBUG_LEVELS,
|
||||||
DEFAULT_BAUDRATE,
|
DEFAULT_BAUDRATE,
|
||||||
DEFAULT_DATABASE_NAME,
|
DEFAULT_DATABASE_NAME,
|
||||||
DEVICE_FULL_INIT,
|
ZHA_GW_MSG_DEVICE_FULL_INIT,
|
||||||
DEVICE_INFO,
|
ZHA_GW_MSG_DEVICE_INFO,
|
||||||
DEVICE_JOINED,
|
ZHA_GW_MSG_DEVICE_JOINED,
|
||||||
DEVICE_REMOVED,
|
ZHA_GW_MSG_DEVICE_REMOVED,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
IEEE,
|
ATTR_IEEE,
|
||||||
LOG_ENTRY,
|
ZHA_GW_MSG_LOG_ENTRY,
|
||||||
LOG_OUTPUT,
|
ZHA_GW_MSG_LOG_OUTPUT,
|
||||||
MODEL,
|
ATTR_MODEL,
|
||||||
NWK,
|
ATTR_NWK,
|
||||||
ORIGINAL,
|
DEBUG_LEVEL_ORIGINAL,
|
||||||
RADIO,
|
ZHA_GW_RADIO,
|
||||||
RADIO_DESCRIPTION,
|
ZHA_GW_RADIO_DESCRIPTION,
|
||||||
RAW_INIT,
|
ZHA_GW_MSG_RAW_INIT,
|
||||||
SIGNAL_REMOVE,
|
SIGNAL_REMOVE,
|
||||||
SIGNATURE,
|
ATTR_SIGNATURE,
|
||||||
TYPE,
|
ATTR_TYPE,
|
||||||
UNKNOWN_MANUFACTURER,
|
UNKNOWN_MANUFACTURER,
|
||||||
UNKNOWN_MODEL,
|
UNKNOWN_MODEL,
|
||||||
ZHA,
|
DEBUG_COMP_ZHA,
|
||||||
ZHA_GW_MSG,
|
ZHA_GW_MSG,
|
||||||
ZIGPY,
|
DEBUG_COMP_ZIGPY,
|
||||||
ZIGPY_DECONZ,
|
DEBUG_COMP_ZIGPY_DECONZ,
|
||||||
ZIGPY_XBEE,
|
DEBUG_COMP_ZIGPY_XBEE,
|
||||||
)
|
)
|
||||||
from .device import DeviceStatus, ZHADevice
|
from .device import DeviceStatus, ZHADevice
|
||||||
from .discovery import async_dispatch_discovery_info, async_process_endpoint
|
from .discovery import async_dispatch_discovery_info, async_process_endpoint
|
||||||
@ -91,8 +91,8 @@ class ZHAGateway:
|
|||||||
self.radio_description = None
|
self.radio_description = None
|
||||||
hass.data[DATA_ZHA][DATA_ZHA_GATEWAY] = self
|
hass.data[DATA_ZHA][DATA_ZHA_GATEWAY] = self
|
||||||
self._log_levels = {
|
self._log_levels = {
|
||||||
ORIGINAL: async_capture_log_levels(),
|
DEBUG_LEVEL_ORIGINAL: async_capture_log_levels(),
|
||||||
CURRENT: async_capture_log_levels(),
|
DEBUG_LEVEL_CURRENT: async_capture_log_levels(),
|
||||||
}
|
}
|
||||||
self.debug_enabled = False
|
self.debug_enabled = False
|
||||||
self._log_relay_handler = LogRelayHandler(hass, self)
|
self._log_relay_handler = LogRelayHandler(hass, self)
|
||||||
@ -107,9 +107,9 @@ class ZHAGateway:
|
|||||||
baudrate = self._config.get(CONF_BAUDRATE, DEFAULT_BAUDRATE)
|
baudrate = self._config.get(CONF_BAUDRATE, DEFAULT_BAUDRATE)
|
||||||
radio_type = self._config_entry.data.get(CONF_RADIO_TYPE)
|
radio_type = self._config_entry.data.get(CONF_RADIO_TYPE)
|
||||||
|
|
||||||
radio_details = RADIO_TYPES[radio_type][RADIO]()
|
radio_details = RADIO_TYPES[radio_type][ZHA_GW_RADIO]()
|
||||||
radio = radio_details[RADIO]
|
radio = radio_details[ZHA_GW_RADIO]
|
||||||
self.radio_description = RADIO_TYPES[radio_type][RADIO_DESCRIPTION]
|
self.radio_description = RADIO_TYPES[radio_type][ZHA_GW_RADIO_DESCRIPTION]
|
||||||
await radio.connect(usb_path, baudrate)
|
await radio.connect(usb_path, baudrate)
|
||||||
|
|
||||||
if CONF_DATABASE in self._config:
|
if CONF_DATABASE in self._config:
|
||||||
@ -141,7 +141,11 @@ class ZHAGateway:
|
|||||||
async_dispatcher_send(
|
async_dispatcher_send(
|
||||||
self._hass,
|
self._hass,
|
||||||
ZHA_GW_MSG,
|
ZHA_GW_MSG,
|
||||||
{TYPE: DEVICE_JOINED, NWK: device.nwk, IEEE: str(device.ieee)},
|
{
|
||||||
|
ATTR_TYPE: ZHA_GW_MSG_DEVICE_JOINED,
|
||||||
|
ATTR_NWK: device.nwk,
|
||||||
|
ATTR_IEEE: str(device.ieee),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def raw_device_initialized(self, device):
|
def raw_device_initialized(self, device):
|
||||||
@ -154,12 +158,12 @@ class ZHAGateway:
|
|||||||
self._hass,
|
self._hass,
|
||||||
ZHA_GW_MSG,
|
ZHA_GW_MSG,
|
||||||
{
|
{
|
||||||
TYPE: RAW_INIT,
|
ATTR_TYPE: ZHA_GW_MSG_RAW_INIT,
|
||||||
NWK: device.nwk,
|
ATTR_NWK: device.nwk,
|
||||||
IEEE: str(device.ieee),
|
ATTR_IEEE: str(device.ieee),
|
||||||
MODEL: device.model if device.model else UNKNOWN_MODEL,
|
ATTR_MODEL: device.model if device.model else UNKNOWN_MODEL,
|
||||||
ATTR_MANUFACTURER: manuf if manuf else UNKNOWN_MANUFACTURER,
|
ATTR_MANUFACTURER: manuf if manuf else UNKNOWN_MANUFACTURER,
|
||||||
SIGNATURE: device.get_signature(),
|
ATTR_SIGNATURE: device.get_signature(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -198,7 +202,10 @@ class ZHAGateway:
|
|||||||
async_dispatcher_send(
|
async_dispatcher_send(
|
||||||
self._hass,
|
self._hass,
|
||||||
ZHA_GW_MSG,
|
ZHA_GW_MSG,
|
||||||
{TYPE: DEVICE_REMOVED, DEVICE_INFO: device_info},
|
{
|
||||||
|
ATTR_TYPE: ZHA_GW_MSG_DEVICE_REMOVED,
|
||||||
|
ZHA_GW_MSG_DEVICE_INFO: device_info,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_device(self, ieee):
|
def get_device(self, ieee):
|
||||||
@ -254,11 +261,11 @@ class ZHAGateway:
|
|||||||
@callback
|
@callback
|
||||||
def async_enable_debug_mode(self):
|
def async_enable_debug_mode(self):
|
||||||
"""Enable debug mode for ZHA."""
|
"""Enable debug mode for ZHA."""
|
||||||
self._log_levels[ORIGINAL] = async_capture_log_levels()
|
self._log_levels[DEBUG_LEVEL_ORIGINAL] = async_capture_log_levels()
|
||||||
async_set_logger_levels(DEBUG_LEVELS)
|
async_set_logger_levels(DEBUG_LEVELS)
|
||||||
self._log_levels[CURRENT] = async_capture_log_levels()
|
self._log_levels[DEBUG_LEVEL_CURRENT] = async_capture_log_levels()
|
||||||
|
|
||||||
for logger_name in ADD_DEVICE_RELAY_LOGGERS:
|
for logger_name in DEBUG_RELAY_LOGGERS:
|
||||||
logging.getLogger(logger_name).addHandler(self._log_relay_handler)
|
logging.getLogger(logger_name).addHandler(self._log_relay_handler)
|
||||||
|
|
||||||
self.debug_enabled = True
|
self.debug_enabled = True
|
||||||
@ -266,9 +273,9 @@ class ZHAGateway:
|
|||||||
@callback
|
@callback
|
||||||
def async_disable_debug_mode(self):
|
def async_disable_debug_mode(self):
|
||||||
"""Disable debug mode for ZHA."""
|
"""Disable debug mode for ZHA."""
|
||||||
async_set_logger_levels(self._log_levels[ORIGINAL])
|
async_set_logger_levels(self._log_levels[DEBUG_LEVEL_ORIGINAL])
|
||||||
self._log_levels[CURRENT] = async_capture_log_levels()
|
self._log_levels[DEBUG_LEVEL_CURRENT] = async_capture_log_levels()
|
||||||
for logger_name in ADD_DEVICE_RELAY_LOGGERS:
|
for logger_name in DEBUG_RELAY_LOGGERS:
|
||||||
logging.getLogger(logger_name).removeHandler(self._log_relay_handler)
|
logging.getLogger(logger_name).removeHandler(self._log_relay_handler)
|
||||||
self.debug_enabled = False
|
self.debug_enabled = False
|
||||||
|
|
||||||
@ -377,7 +384,10 @@ class ZHAGateway:
|
|||||||
async_dispatcher_send(
|
async_dispatcher_send(
|
||||||
self._hass,
|
self._hass,
|
||||||
ZHA_GW_MSG,
|
ZHA_GW_MSG,
|
||||||
{TYPE: DEVICE_FULL_INIT, DEVICE_INFO: device_info},
|
{
|
||||||
|
ATTR_TYPE: ZHA_GW_MSG_DEVICE_FULL_INIT,
|
||||||
|
ZHA_GW_MSG_DEVICE_INFO: device_info,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
async def shutdown(self):
|
async def shutdown(self):
|
||||||
@ -390,22 +400,26 @@ class ZHAGateway:
|
|||||||
def async_capture_log_levels():
|
def async_capture_log_levels():
|
||||||
"""Capture current logger levels for ZHA."""
|
"""Capture current logger levels for ZHA."""
|
||||||
return {
|
return {
|
||||||
BELLOWS: logging.getLogger(BELLOWS).getEffectiveLevel(),
|
DEBUG_COMP_BELLOWS: logging.getLogger(DEBUG_COMP_BELLOWS).getEffectiveLevel(),
|
||||||
ZHA: logging.getLogger(ZHA).getEffectiveLevel(),
|
DEBUG_COMP_ZHA: logging.getLogger(DEBUG_COMP_ZHA).getEffectiveLevel(),
|
||||||
ZIGPY: logging.getLogger(ZIGPY).getEffectiveLevel(),
|
DEBUG_COMP_ZIGPY: logging.getLogger(DEBUG_COMP_ZIGPY).getEffectiveLevel(),
|
||||||
ZIGPY_XBEE: logging.getLogger(ZIGPY_XBEE).getEffectiveLevel(),
|
DEBUG_COMP_ZIGPY_XBEE: logging.getLogger(
|
||||||
ZIGPY_DECONZ: logging.getLogger(ZIGPY_DECONZ).getEffectiveLevel(),
|
DEBUG_COMP_ZIGPY_XBEE
|
||||||
|
).getEffectiveLevel(),
|
||||||
|
DEBUG_COMP_ZIGPY_DECONZ: logging.getLogger(
|
||||||
|
DEBUG_COMP_ZIGPY_DECONZ
|
||||||
|
).getEffectiveLevel(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_set_logger_levels(levels):
|
def async_set_logger_levels(levels):
|
||||||
"""Set logger levels for ZHA."""
|
"""Set logger levels for ZHA."""
|
||||||
logging.getLogger(BELLOWS).setLevel(levels[BELLOWS])
|
logging.getLogger(DEBUG_COMP_BELLOWS).setLevel(levels[DEBUG_COMP_BELLOWS])
|
||||||
logging.getLogger(ZHA).setLevel(levels[ZHA])
|
logging.getLogger(DEBUG_COMP_ZHA).setLevel(levels[DEBUG_COMP_ZHA])
|
||||||
logging.getLogger(ZIGPY).setLevel(levels[ZIGPY])
|
logging.getLogger(DEBUG_COMP_ZIGPY).setLevel(levels[DEBUG_COMP_ZIGPY])
|
||||||
logging.getLogger(ZIGPY_XBEE).setLevel(levels[ZIGPY_XBEE])
|
logging.getLogger(DEBUG_COMP_ZIGPY_XBEE).setLevel(levels[DEBUG_COMP_ZIGPY_XBEE])
|
||||||
logging.getLogger(ZIGPY_DECONZ).setLevel(levels[ZIGPY_DECONZ])
|
logging.getLogger(DEBUG_COMP_ZIGPY_DECONZ).setLevel(levels[DEBUG_COMP_ZIGPY_DECONZ])
|
||||||
|
|
||||||
|
|
||||||
class LogRelayHandler(logging.Handler):
|
class LogRelayHandler(logging.Handler):
|
||||||
@ -426,5 +440,7 @@ class LogRelayHandler(logging.Handler):
|
|||||||
|
|
||||||
entry = LogEntry(record, stack, _figure_out_source(record, stack, self.hass))
|
entry = LogEntry(record, stack, _figure_out_source(record, stack, self.hass))
|
||||||
async_dispatcher_send(
|
async_dispatcher_send(
|
||||||
self.hass, ZHA_GW_MSG, {TYPE: LOG_OUTPUT, LOG_ENTRY: entry.to_dict()}
|
self.hass,
|
||||||
|
ZHA_GW_MSG,
|
||||||
|
{ATTR_TYPE: ZHA_GW_MSG_LOG_OUTPUT, ZHA_GW_MSG_LOG_ENTRY: entry.to_dict()},
|
||||||
)
|
)
|
||||||
|
@ -6,17 +6,19 @@ https://home-assistant.io/components/zha/
|
|||||||
"""
|
"""
|
||||||
import asyncio
|
import asyncio
|
||||||
import collections
|
import collections
|
||||||
import logging
|
|
||||||
from concurrent.futures import TimeoutError as Timeout
|
from concurrent.futures import TimeoutError as Timeout
|
||||||
|
import logging
|
||||||
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
DEFAULT_BAUDRATE,
|
DEFAULT_BAUDRATE,
|
||||||
|
CLUSTER_TYPE_IN,
|
||||||
|
CLUSTER_TYPE_OUT,
|
||||||
REPORT_CONFIG_MAX_INT,
|
REPORT_CONFIG_MAX_INT,
|
||||||
REPORT_CONFIG_MIN_INT,
|
REPORT_CONFIG_MIN_INT,
|
||||||
REPORT_CONFIG_RPT_CHANGE,
|
REPORT_CONFIG_RPT_CHANGE,
|
||||||
RadioType,
|
RadioType,
|
||||||
IN,
|
|
||||||
OUT,
|
|
||||||
)
|
)
|
||||||
from .registries import BINDABLE_CLUSTERS
|
from .registries import BINDABLE_CLUSTERS
|
||||||
|
|
||||||
@ -206,14 +208,18 @@ async def get_matched_clusters(source_zha_device, target_zha_device):
|
|||||||
clusters_to_bind = []
|
clusters_to_bind = []
|
||||||
|
|
||||||
for endpoint_id in source_clusters:
|
for endpoint_id in source_clusters:
|
||||||
for cluster_id in source_clusters[endpoint_id][OUT]:
|
for cluster_id in source_clusters[endpoint_id][CLUSTER_TYPE_OUT]:
|
||||||
if cluster_id not in BINDABLE_CLUSTERS:
|
if cluster_id not in BINDABLE_CLUSTERS:
|
||||||
continue
|
continue
|
||||||
for t_endpoint_id in target_clusters:
|
for t_endpoint_id in target_clusters:
|
||||||
if cluster_id in target_clusters[t_endpoint_id][IN]:
|
if cluster_id in target_clusters[t_endpoint_id][CLUSTER_TYPE_IN]:
|
||||||
cluster_pair = ClusterPair(
|
cluster_pair = ClusterPair(
|
||||||
source_cluster=source_clusters[endpoint_id][OUT][cluster_id],
|
source_cluster=source_clusters[endpoint_id][CLUSTER_TYPE_OUT][
|
||||||
target_cluster=target_clusters[t_endpoint_id][IN][cluster_id],
|
cluster_id
|
||||||
|
],
|
||||||
|
target_cluster=target_clusters[t_endpoint_id][CLUSTER_TYPE_IN][
|
||||||
|
cluster_id
|
||||||
|
],
|
||||||
)
|
)
|
||||||
clusters_to_bind.append(cluster_pair)
|
clusters_to_bind.append(cluster_pair)
|
||||||
return clusters_to_bind
|
return clusters_to_bind
|
||||||
@ -228,9 +234,9 @@ def async_is_bindable_target(source_zha_device, target_zha_device):
|
|||||||
bindables = set(BINDABLE_CLUSTERS)
|
bindables = set(BINDABLE_CLUSTERS)
|
||||||
for endpoint_id in source_clusters:
|
for endpoint_id in source_clusters:
|
||||||
for t_endpoint_id in target_clusters:
|
for t_endpoint_id in target_clusters:
|
||||||
matches = set(source_clusters[endpoint_id][OUT].keys()).intersection(
|
matches = set(
|
||||||
target_clusters[t_endpoint_id][IN].keys()
|
source_clusters[endpoint_id][CLUSTER_TYPE_OUT].keys()
|
||||||
)
|
).intersection(target_clusters[t_endpoint_id][CLUSTER_TYPE_IN].keys())
|
||||||
if any(bindable in bindables for bindable in matches):
|
if any(bindable in bindables for bindable in matches):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -14,56 +14,56 @@ from homeassistant.components.sensor import DOMAIN as SENSOR
|
|||||||
from homeassistant.components.switch import DOMAIN as SWITCH
|
from homeassistant.components.switch import DOMAIN as SWITCH
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
HUMIDITY,
|
SENSOR_ACCELERATION,
|
||||||
TEMPERATURE,
|
SENSOR_BATTERY,
|
||||||
ILLUMINANCE,
|
CONTROLLER,
|
||||||
PRESSURE,
|
SENSOR_ELECTRICAL_MEASUREMENT,
|
||||||
METERING,
|
SENSOR_HUMIDITY,
|
||||||
ELECTRICAL_MEASUREMENT,
|
SENSOR_ILLUMINANCE,
|
||||||
OCCUPANCY,
|
SENSOR_METERING,
|
||||||
REPORT_CONFIG_IMMEDIATE,
|
SENSOR_OCCUPANCY,
|
||||||
OPENING,
|
SENSOR_OPENING,
|
||||||
ZONE,
|
SENSOR_PRESSURE,
|
||||||
RADIO_DESCRIPTION,
|
ZHA_GW_RADIO,
|
||||||
|
ZHA_GW_RADIO_DESCRIPTION,
|
||||||
REPORT_CONFIG_ASAP,
|
REPORT_CONFIG_ASAP,
|
||||||
REPORT_CONFIG_DEFAULT,
|
REPORT_CONFIG_DEFAULT,
|
||||||
REPORT_CONFIG_MIN_INT,
|
REPORT_CONFIG_IMMEDIATE,
|
||||||
REPORT_CONFIG_MAX_INT,
|
REPORT_CONFIG_MAX_INT,
|
||||||
|
REPORT_CONFIG_MIN_INT,
|
||||||
REPORT_CONFIG_OP,
|
REPORT_CONFIG_OP,
|
||||||
ACCELERATION,
|
SENSOR_TEMPERATURE,
|
||||||
|
ZONE,
|
||||||
RadioType,
|
RadioType,
|
||||||
RADIO,
|
|
||||||
CONTROLLER,
|
|
||||||
BATTERY,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SMARTTHINGS_HUMIDITY_CLUSTER = 0xFC45
|
BINARY_SENSOR_CLUSTERS = set()
|
||||||
SMARTTHINGS_ACCELERATION_CLUSTER = 0xFC02
|
|
||||||
SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE = 0x8000
|
|
||||||
|
|
||||||
DEVICE_CLASS = {}
|
|
||||||
SINGLE_INPUT_CLUSTER_DEVICE_CLASS = {}
|
|
||||||
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS = {}
|
|
||||||
SENSOR_TYPES = {}
|
|
||||||
RADIO_TYPES = {}
|
|
||||||
BINARY_SENSOR_TYPES = {}
|
BINARY_SENSOR_TYPES = {}
|
||||||
REMOTE_DEVICE_TYPES = {}
|
BINDABLE_CLUSTERS = []
|
||||||
|
CHANNEL_ONLY_CLUSTERS = []
|
||||||
CLUSTER_REPORT_CONFIGS = {}
|
CLUSTER_REPORT_CONFIGS = {}
|
||||||
CUSTOM_CLUSTER_MAPPINGS = {}
|
CUSTOM_CLUSTER_MAPPINGS = {}
|
||||||
EVENT_RELAY_CLUSTERS = []
|
DEVICE_CLASS = {}
|
||||||
CHANNEL_ONLY_CLUSTERS = []
|
|
||||||
OUTPUT_CHANNEL_ONLY_CLUSTERS = []
|
|
||||||
BINDABLE_CLUSTERS = []
|
|
||||||
INPUT_BIND_ONLY_CLUSTERS = []
|
|
||||||
BINARY_SENSOR_CLUSTERS = set()
|
|
||||||
DEVICE_TRACKER_CLUSTERS = set()
|
DEVICE_TRACKER_CLUSTERS = set()
|
||||||
|
EVENT_RELAY_CLUSTERS = []
|
||||||
|
INPUT_BIND_ONLY_CLUSTERS = []
|
||||||
LIGHT_CLUSTERS = set()
|
LIGHT_CLUSTERS = set()
|
||||||
|
OUTPUT_CHANNEL_ONLY_CLUSTERS = []
|
||||||
|
RADIO_TYPES = {}
|
||||||
|
REMOTE_DEVICE_TYPES = {}
|
||||||
|
SENSOR_TYPES = {}
|
||||||
|
SINGLE_INPUT_CLUSTER_DEVICE_CLASS = {}
|
||||||
|
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS = {}
|
||||||
SWITCH_CLUSTERS = set()
|
SWITCH_CLUSTERS = set()
|
||||||
|
SMARTTHINGS_ACCELERATION_CLUSTER = 0xFC02
|
||||||
|
SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE = 0x8000
|
||||||
|
SMARTTHINGS_HUMIDITY_CLUSTER = 0xFC45
|
||||||
|
|
||||||
COMPONENT_CLUSTERS = {
|
COMPONENT_CLUSTERS = {
|
||||||
BINARY_SENSOR: BINARY_SENSOR_CLUSTERS,
|
BINARY_SENSOR: BINARY_SENSOR_CLUSTERS,
|
||||||
|
DEVICE_TRACKER: DEVICE_TRACKER_CLUSTERS,
|
||||||
LIGHT: LIGHT_CLUSTERS,
|
LIGHT: LIGHT_CLUSTERS,
|
||||||
SWITCH: SWITCH_CLUSTERS,
|
SWITCH: SWITCH_CLUSTERS,
|
||||||
DEVICE_TRACKER: DEVICE_TRACKER_CLUSTERS,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -90,144 +90,58 @@ def establish_device_mappings():
|
|||||||
import bellows.ezsp
|
import bellows.ezsp
|
||||||
from bellows.zigbee.application import ControllerApplication
|
from bellows.zigbee.application import ControllerApplication
|
||||||
|
|
||||||
return {RADIO: bellows.ezsp.EZSP(), CONTROLLER: ControllerApplication}
|
return {ZHA_GW_RADIO: bellows.ezsp.EZSP(), CONTROLLER: ControllerApplication}
|
||||||
|
|
||||||
RADIO_TYPES[RadioType.ezsp.name] = {
|
RADIO_TYPES[RadioType.ezsp.name] = {
|
||||||
RADIO: get_ezsp_radio,
|
ZHA_GW_RADIO: get_ezsp_radio,
|
||||||
RADIO_DESCRIPTION: "EZSP",
|
ZHA_GW_RADIO_DESCRIPTION: "EZSP",
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_xbee_radio():
|
def get_xbee_radio():
|
||||||
import zigpy_xbee.api
|
import zigpy_xbee.api
|
||||||
from zigpy_xbee.zigbee.application import ControllerApplication
|
from zigpy_xbee.zigbee.application import ControllerApplication
|
||||||
|
|
||||||
return {RADIO: zigpy_xbee.api.XBee(), CONTROLLER: ControllerApplication}
|
return {ZHA_GW_RADIO: zigpy_xbee.api.XBee(), CONTROLLER: ControllerApplication}
|
||||||
|
|
||||||
RADIO_TYPES[RadioType.xbee.name] = {
|
RADIO_TYPES[RadioType.xbee.name] = {
|
||||||
RADIO: get_xbee_radio,
|
ZHA_GW_RADIO: get_xbee_radio,
|
||||||
RADIO_DESCRIPTION: "XBee",
|
ZHA_GW_RADIO_DESCRIPTION: "XBee",
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_deconz_radio():
|
def get_deconz_radio():
|
||||||
import zigpy_deconz.api
|
import zigpy_deconz.api
|
||||||
from zigpy_deconz.zigbee.application import ControllerApplication
|
from zigpy_deconz.zigbee.application import ControllerApplication
|
||||||
|
|
||||||
return {RADIO: zigpy_deconz.api.Deconz(), CONTROLLER: ControllerApplication}
|
return {
|
||||||
|
ZHA_GW_RADIO: zigpy_deconz.api.Deconz(),
|
||||||
|
CONTROLLER: ControllerApplication,
|
||||||
|
}
|
||||||
|
|
||||||
RADIO_TYPES[RadioType.deconz.name] = {
|
RADIO_TYPES[RadioType.deconz.name] = {
|
||||||
RADIO: get_deconz_radio,
|
ZHA_GW_RADIO: get_deconz_radio,
|
||||||
RADIO_DESCRIPTION: "Deconz",
|
ZHA_GW_RADIO_DESCRIPTION: "Deconz",
|
||||||
}
|
}
|
||||||
|
|
||||||
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
|
BINARY_SENSOR_CLUSTERS.add(SMARTTHINGS_ACCELERATION_CLUSTER)
|
||||||
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
|
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
|
||||||
|
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.measurement.OccupancySensing.cluster_id)
|
||||||
|
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.security.IasZone.cluster_id)
|
||||||
|
|
||||||
CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.general.Basic.cluster_id)
|
BINARY_SENSOR_TYPES.update(
|
||||||
CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.lightlink.LightLink.cluster_id)
|
{
|
||||||
|
SMARTTHINGS_ACCELERATION_CLUSTER: SENSOR_ACCELERATION,
|
||||||
OUTPUT_CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.general.Scenes.cluster_id)
|
zcl.clusters.general.OnOff.cluster_id: SENSOR_OPENING,
|
||||||
|
zcl.clusters.measurement.OccupancySensing.cluster_id: SENSOR_OCCUPANCY,
|
||||||
|
zcl.clusters.security.IasZone.cluster_id: ZONE,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
BINDABLE_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
|
BINDABLE_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
|
||||||
BINDABLE_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
|
BINDABLE_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
|
||||||
BINDABLE_CLUSTERS.append(zcl.clusters.lighting.Color.cluster_id)
|
BINDABLE_CLUSTERS.append(zcl.clusters.lighting.Color.cluster_id)
|
||||||
|
|
||||||
INPUT_BIND_ONLY_CLUSTERS.append(zcl.clusters.lightlink.LightLink.cluster_id)
|
CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.general.Basic.cluster_id)
|
||||||
|
CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.lightlink.LightLink.cluster_id)
|
||||||
DEVICE_CLASS[zha.PROFILE_ID].update(
|
|
||||||
{
|
|
||||||
zha.DeviceType.SMART_PLUG: SWITCH,
|
|
||||||
zha.DeviceType.LEVEL_CONTROLLABLE_OUTPUT: LIGHT,
|
|
||||||
zha.DeviceType.ON_OFF_LIGHT: LIGHT,
|
|
||||||
zha.DeviceType.DIMMABLE_LIGHT: LIGHT,
|
|
||||||
zha.DeviceType.COLOR_DIMMABLE_LIGHT: LIGHT,
|
|
||||||
zha.DeviceType.ON_OFF_LIGHT_SWITCH: SWITCH,
|
|
||||||
zha.DeviceType.ON_OFF_BALLAST: SWITCH,
|
|
||||||
zha.DeviceType.DIMMABLE_BALLAST: LIGHT,
|
|
||||||
zha.DeviceType.ON_OFF_PLUG_IN_UNIT: SWITCH,
|
|
||||||
zha.DeviceType.DIMMABLE_PLUG_IN_UNIT: LIGHT,
|
|
||||||
zha.DeviceType.COLOR_TEMPERATURE_LIGHT: LIGHT,
|
|
||||||
zha.DeviceType.EXTENDED_COLOR_LIGHT: LIGHT,
|
|
||||||
SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE: DEVICE_TRACKER,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
DEVICE_CLASS[zll.PROFILE_ID].update(
|
|
||||||
{
|
|
||||||
zll.DeviceType.ON_OFF_LIGHT: LIGHT,
|
|
||||||
zll.DeviceType.ON_OFF_PLUGIN_UNIT: SWITCH,
|
|
||||||
zll.DeviceType.DIMMABLE_LIGHT: LIGHT,
|
|
||||||
zll.DeviceType.DIMMABLE_PLUGIN_UNIT: LIGHT,
|
|
||||||
zll.DeviceType.COLOR_LIGHT: LIGHT,
|
|
||||||
zll.DeviceType.EXTENDED_COLOR_LIGHT: LIGHT,
|
|
||||||
zll.DeviceType.COLOR_TEMPERATURE_LIGHT: LIGHT,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
SINGLE_INPUT_CLUSTER_DEVICE_CLASS.update(
|
|
||||||
{
|
|
||||||
zcl.clusters.general.OnOff: SWITCH,
|
|
||||||
zcl.clusters.measurement.RelativeHumidity: SENSOR,
|
|
||||||
# this works for now but if we hit conflicts we can break it out to
|
|
||||||
# a different dict that is keyed by manufacturer
|
|
||||||
SMARTTHINGS_HUMIDITY_CLUSTER: SENSOR,
|
|
||||||
zcl.clusters.measurement.TemperatureMeasurement: SENSOR,
|
|
||||||
zcl.clusters.measurement.PressureMeasurement: SENSOR,
|
|
||||||
zcl.clusters.measurement.IlluminanceMeasurement: SENSOR,
|
|
||||||
zcl.clusters.smartenergy.Metering: SENSOR,
|
|
||||||
zcl.clusters.homeautomation.ElectricalMeasurement: SENSOR,
|
|
||||||
zcl.clusters.security.IasZone: BINARY_SENSOR,
|
|
||||||
zcl.clusters.measurement.OccupancySensing: BINARY_SENSOR,
|
|
||||||
zcl.clusters.hvac.Fan: FAN,
|
|
||||||
SMARTTHINGS_ACCELERATION_CLUSTER: BINARY_SENSOR,
|
|
||||||
zcl.clusters.general.MultistateInput.cluster_id: SENSOR,
|
|
||||||
zcl.clusters.general.AnalogInput.cluster_id: SENSOR,
|
|
||||||
zcl.clusters.closures.DoorLock: LOCK,
|
|
||||||
zcl.clusters.general.PowerConfiguration: SENSOR,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS.update(
|
|
||||||
{zcl.clusters.general.OnOff: BINARY_SENSOR}
|
|
||||||
)
|
|
||||||
|
|
||||||
SENSOR_TYPES.update(
|
|
||||||
{
|
|
||||||
zcl.clusters.measurement.RelativeHumidity.cluster_id: HUMIDITY,
|
|
||||||
SMARTTHINGS_HUMIDITY_CLUSTER: HUMIDITY,
|
|
||||||
zcl.clusters.measurement.TemperatureMeasurement.cluster_id: TEMPERATURE,
|
|
||||||
zcl.clusters.measurement.PressureMeasurement.cluster_id: PRESSURE,
|
|
||||||
zcl.clusters.measurement.IlluminanceMeasurement.cluster_id: ILLUMINANCE,
|
|
||||||
zcl.clusters.smartenergy.Metering.cluster_id: METERING,
|
|
||||||
zcl.clusters.homeautomation.ElectricalMeasurement.cluster_id: ELECTRICAL_MEASUREMENT,
|
|
||||||
zcl.clusters.general.PowerConfiguration.cluster_id: BATTERY,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
BINARY_SENSOR_TYPES.update(
|
|
||||||
{
|
|
||||||
zcl.clusters.measurement.OccupancySensing.cluster_id: OCCUPANCY,
|
|
||||||
zcl.clusters.security.IasZone.cluster_id: ZONE,
|
|
||||||
zcl.clusters.general.OnOff.cluster_id: OPENING,
|
|
||||||
SMARTTHINGS_ACCELERATION_CLUSTER: ACCELERATION,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
zhap = zha.PROFILE_ID
|
|
||||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.NON_COLOR_SCENE_CONTROLLER)
|
|
||||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.NON_COLOR_CONTROLLER)
|
|
||||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_SCENE_CONTROLLER)
|
|
||||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_CONTROLLER)
|
|
||||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.REMOTE_CONTROL)
|
|
||||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.SCENE_SELECTOR)
|
|
||||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.DIMMER_SWITCH)
|
|
||||||
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_DIMMER_SWITCH)
|
|
||||||
|
|
||||||
zllp = zll.PROFILE_ID
|
|
||||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.COLOR_CONTROLLER)
|
|
||||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.COLOR_SCENE_CONTROLLER)
|
|
||||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.CONTROLLER)
|
|
||||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.SCENE_CONTROLLER)
|
|
||||||
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.CONTROL_BRIDGE)
|
|
||||||
|
|
||||||
CLUSTER_REPORT_CONFIGS.update(
|
CLUSTER_REPORT_CONFIGS.update(
|
||||||
{
|
{
|
||||||
@ -311,15 +225,104 @@ def establish_device_mappings():
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
|
DEVICE_CLASS[zha.PROFILE_ID].update(
|
||||||
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.security.IasZone.cluster_id)
|
{
|
||||||
BINARY_SENSOR_CLUSTERS.add(zcl.clusters.measurement.OccupancySensing.cluster_id)
|
SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE: DEVICE_TRACKER,
|
||||||
BINARY_SENSOR_CLUSTERS.add(SMARTTHINGS_ACCELERATION_CLUSTER)
|
zha.DeviceType.COLOR_DIMMABLE_LIGHT: LIGHT,
|
||||||
|
zha.DeviceType.COLOR_TEMPERATURE_LIGHT: LIGHT,
|
||||||
|
zha.DeviceType.DIMMABLE_BALLAST: LIGHT,
|
||||||
|
zha.DeviceType.DIMMABLE_LIGHT: LIGHT,
|
||||||
|
zha.DeviceType.DIMMABLE_PLUG_IN_UNIT: LIGHT,
|
||||||
|
zha.DeviceType.EXTENDED_COLOR_LIGHT: LIGHT,
|
||||||
|
zha.DeviceType.LEVEL_CONTROLLABLE_OUTPUT: LIGHT,
|
||||||
|
zha.DeviceType.ON_OFF_BALLAST: SWITCH,
|
||||||
|
zha.DeviceType.ON_OFF_LIGHT: LIGHT,
|
||||||
|
zha.DeviceType.ON_OFF_LIGHT_SWITCH: SWITCH,
|
||||||
|
zha.DeviceType.ON_OFF_PLUG_IN_UNIT: SWITCH,
|
||||||
|
zha.DeviceType.SMART_PLUG: SWITCH,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
DEVICE_CLASS[zll.PROFILE_ID].update(
|
||||||
|
{
|
||||||
|
zll.DeviceType.COLOR_LIGHT: LIGHT,
|
||||||
|
zll.DeviceType.COLOR_TEMPERATURE_LIGHT: LIGHT,
|
||||||
|
zll.DeviceType.DIMMABLE_LIGHT: LIGHT,
|
||||||
|
zll.DeviceType.DIMMABLE_PLUGIN_UNIT: LIGHT,
|
||||||
|
zll.DeviceType.EXTENDED_COLOR_LIGHT: LIGHT,
|
||||||
|
zll.DeviceType.ON_OFF_LIGHT: LIGHT,
|
||||||
|
zll.DeviceType.ON_OFF_PLUGIN_UNIT: SWITCH,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
DEVICE_TRACKER_CLUSTERS.add(zcl.clusters.general.PowerConfiguration.cluster_id)
|
DEVICE_TRACKER_CLUSTERS.add(zcl.clusters.general.PowerConfiguration.cluster_id)
|
||||||
|
|
||||||
LIGHT_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
|
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
|
||||||
|
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
|
||||||
|
|
||||||
|
INPUT_BIND_ONLY_CLUSTERS.append(zcl.clusters.lightlink.LightLink.cluster_id)
|
||||||
|
|
||||||
|
OUTPUT_CHANNEL_ONLY_CLUSTERS.append(zcl.clusters.general.Scenes.cluster_id)
|
||||||
|
|
||||||
LIGHT_CLUSTERS.add(zcl.clusters.general.LevelControl.cluster_id)
|
LIGHT_CLUSTERS.add(zcl.clusters.general.LevelControl.cluster_id)
|
||||||
|
LIGHT_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
|
||||||
LIGHT_CLUSTERS.add(zcl.clusters.lighting.Color.cluster_id)
|
LIGHT_CLUSTERS.add(zcl.clusters.lighting.Color.cluster_id)
|
||||||
|
|
||||||
|
SINGLE_INPUT_CLUSTER_DEVICE_CLASS.update(
|
||||||
|
{
|
||||||
|
# this works for now but if we hit conflicts we can break it out to
|
||||||
|
# a different dict that is keyed by manufacturer
|
||||||
|
SMARTTHINGS_ACCELERATION_CLUSTER: BINARY_SENSOR,
|
||||||
|
SMARTTHINGS_HUMIDITY_CLUSTER: SENSOR,
|
||||||
|
zcl.clusters.closures.DoorLock: LOCK,
|
||||||
|
zcl.clusters.general.AnalogInput.cluster_id: SENSOR,
|
||||||
|
zcl.clusters.general.MultistateInput.cluster_id: SENSOR,
|
||||||
|
zcl.clusters.general.OnOff: SWITCH,
|
||||||
|
zcl.clusters.general.PowerConfiguration: SENSOR,
|
||||||
|
zcl.clusters.homeautomation.ElectricalMeasurement: SENSOR,
|
||||||
|
zcl.clusters.hvac.Fan: FAN,
|
||||||
|
zcl.clusters.measurement.IlluminanceMeasurement: SENSOR,
|
||||||
|
zcl.clusters.measurement.OccupancySensing: BINARY_SENSOR,
|
||||||
|
zcl.clusters.measurement.PressureMeasurement: SENSOR,
|
||||||
|
zcl.clusters.measurement.RelativeHumidity: SENSOR,
|
||||||
|
zcl.clusters.measurement.TemperatureMeasurement: SENSOR,
|
||||||
|
zcl.clusters.security.IasZone: BINARY_SENSOR,
|
||||||
|
zcl.clusters.smartenergy.Metering: SENSOR,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS.update(
|
||||||
|
{zcl.clusters.general.OnOff: BINARY_SENSOR}
|
||||||
|
)
|
||||||
|
|
||||||
|
SENSOR_TYPES.update(
|
||||||
|
{
|
||||||
|
SMARTTHINGS_HUMIDITY_CLUSTER: SENSOR_HUMIDITY,
|
||||||
|
zcl.clusters.general.PowerConfiguration.cluster_id: SENSOR_BATTERY,
|
||||||
|
zcl.clusters.homeautomation.ElectricalMeasurement.cluster_id: SENSOR_ELECTRICAL_MEASUREMENT,
|
||||||
|
zcl.clusters.measurement.IlluminanceMeasurement.cluster_id: SENSOR_ILLUMINANCE,
|
||||||
|
zcl.clusters.measurement.PressureMeasurement.cluster_id: SENSOR_PRESSURE,
|
||||||
|
zcl.clusters.measurement.RelativeHumidity.cluster_id: SENSOR_HUMIDITY,
|
||||||
|
zcl.clusters.measurement.TemperatureMeasurement.cluster_id: SENSOR_TEMPERATURE,
|
||||||
|
zcl.clusters.smartenergy.Metering.cluster_id: SENSOR_METERING,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
SWITCH_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
|
SWITCH_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id)
|
||||||
|
|
||||||
|
zhap = zha.PROFILE_ID
|
||||||
|
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_CONTROLLER)
|
||||||
|
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_DIMMER_SWITCH)
|
||||||
|
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.COLOR_SCENE_CONTROLLER)
|
||||||
|
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.DIMMER_SWITCH)
|
||||||
|
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.NON_COLOR_CONTROLLER)
|
||||||
|
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.NON_COLOR_SCENE_CONTROLLER)
|
||||||
|
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.REMOTE_CONTROL)
|
||||||
|
REMOTE_DEVICE_TYPES[zhap].append(zha.DeviceType.SCENE_SELECTOR)
|
||||||
|
|
||||||
|
zllp = zll.PROFILE_ID
|
||||||
|
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.COLOR_CONTROLLER)
|
||||||
|
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.COLOR_SCENE_CONTROLLER)
|
||||||
|
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.CONTROL_BRIDGE)
|
||||||
|
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.CONTROLLER)
|
||||||
|
REMOTE_DEVICE_TYPES[zllp].append(zll.DeviceType.SCENE_CONTROLLER)
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
"""Data storage helper for ZHA."""
|
"""Data storage helper for ZHA."""
|
||||||
import logging
|
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
# pylint: disable=W0611
|
# pylint: disable=W0611
|
||||||
|
from collections import OrderedDict
|
||||||
|
import logging
|
||||||
from typing import MutableMapping # noqa: F401
|
from typing import MutableMapping # noqa: F401
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.loader import bind_hass
|
|
||||||
from homeassistant.helpers.typing import HomeAssistantType
|
from homeassistant.helpers.typing import HomeAssistantType
|
||||||
|
from homeassistant.loader import bind_hass
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
"""Support for the ZHA platform."""
|
"""Support for the ZHA platform."""
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
from homeassistant.components.device_tracker import SOURCE_TYPE_ROUTER, DOMAIN
|
|
||||||
|
from homeassistant.components.device_tracker import DOMAIN, SOURCE_TYPE_ROUTER
|
||||||
from homeassistant.components.device_tracker.config_entry import ScannerEntity
|
from homeassistant.components.device_tracker.config_entry import ScannerEntity
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from .core.const import (
|
from .core.const import (
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_DISPATCHERS,
|
DATA_ZHA_DISPATCHERS,
|
||||||
ZHA_DISCOVERY_NEW,
|
CHANNEL_POWER_CONFIGURATION,
|
||||||
POWER_CONFIGURATION_CHANNEL,
|
|
||||||
SIGNAL_ATTR_UPDATED,
|
SIGNAL_ATTR_UPDATED,
|
||||||
|
ZHA_DISCOVERY_NEW,
|
||||||
)
|
)
|
||||||
from .entity import ZhaEntity
|
from .entity import ZhaEntity
|
||||||
from .sensor import battery_percentage_remaining_formatter
|
from .sensor import battery_percentage_remaining_formatter
|
||||||
@ -56,7 +58,7 @@ class ZHADeviceScannerEntity(ScannerEntity, ZhaEntity):
|
|||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
"""Initialize the ZHA device tracker."""
|
"""Initialize the ZHA device tracker."""
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self._battery_channel = self.cluster_channels.get(POWER_CONFIGURATION_CHANNEL)
|
self._battery_channel = self.cluster_channels.get(CHANNEL_POWER_CONFIGURATION)
|
||||||
self._connected = False
|
self._connected = False
|
||||||
self._keepalive_interval = 60
|
self._keepalive_interval = 60
|
||||||
self._should_poll = True
|
self._should_poll = True
|
||||||
|
@ -16,8 +16,8 @@ from .core.const import (
|
|||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_BRIDGE_ID,
|
DATA_ZHA_BRIDGE_ID,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
MODEL,
|
ATTR_MODEL,
|
||||||
NAME,
|
ATTR_NAME,
|
||||||
SIGNAL_REMOVE,
|
SIGNAL_REMOVE,
|
||||||
)
|
)
|
||||||
from .core.helpers import LogMixin
|
from .core.helpers import LogMixin
|
||||||
@ -99,8 +99,8 @@ class ZhaEntity(RestoreEntity, LogMixin, entity.Entity):
|
|||||||
"connections": {(CONNECTION_ZIGBEE, ieee)},
|
"connections": {(CONNECTION_ZIGBEE, ieee)},
|
||||||
"identifiers": {(DOMAIN, ieee)},
|
"identifiers": {(DOMAIN, ieee)},
|
||||||
ATTR_MANUFACTURER: zha_device_info[ATTR_MANUFACTURER],
|
ATTR_MANUFACTURER: zha_device_info[ATTR_MANUFACTURER],
|
||||||
MODEL: zha_device_info[MODEL],
|
ATTR_MODEL: zha_device_info[ATTR_MODEL],
|
||||||
NAME: zha_device_info[NAME],
|
ATTR_NAME: zha_device_info[ATTR_NAME],
|
||||||
"via_device": (DOMAIN, self.hass.data[DATA_ZHA][DATA_ZHA_BRIDGE_ID]),
|
"via_device": (DOMAIN, self.hass.data[DATA_ZHA][DATA_ZHA_BRIDGE_ID]),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
"""Fans on Zigbee Home Automation networks."""
|
"""Fans on Zigbee Home Automation networks."""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from homeassistant.core import callback
|
|
||||||
from homeassistant.components.fan import (
|
from homeassistant.components.fan import (
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SPEED_HIGH,
|
SPEED_HIGH,
|
||||||
@ -11,13 +10,15 @@ from homeassistant.components.fan import (
|
|||||||
SUPPORT_SET_SPEED,
|
SUPPORT_SET_SPEED,
|
||||||
FanEntity,
|
FanEntity,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from .core.const import (
|
from .core.const import (
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_DISPATCHERS,
|
DATA_ZHA_DISPATCHERS,
|
||||||
ZHA_DISCOVERY_NEW,
|
CHANNEL_FAN,
|
||||||
FAN_CHANNEL,
|
|
||||||
SIGNAL_ATTR_UPDATED,
|
SIGNAL_ATTR_UPDATED,
|
||||||
|
ZHA_DISCOVERY_NEW,
|
||||||
)
|
)
|
||||||
from .entity import ZhaEntity
|
from .entity import ZhaEntity
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ class ZhaFan(ZhaEntity, FanEntity):
|
|||||||
def __init__(self, unique_id, zha_device, channels, **kwargs):
|
def __init__(self, unique_id, zha_device, channels, **kwargs):
|
||||||
"""Init this sensor."""
|
"""Init this sensor."""
|
||||||
super().__init__(unique_id, zha_device, channels, **kwargs)
|
super().__init__(unique_id, zha_device, channels, **kwargs)
|
||||||
self._fan_channel = self.cluster_channels.get(FAN_CHANNEL)
|
self._fan_channel = self.cluster_channels.get(CHANNEL_FAN)
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Run when about to be added to hass."""
|
"""Run when about to be added to hass."""
|
||||||
|
@ -3,21 +3,23 @@ from datetime import timedelta
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from zigpy.zcl.foundation import Status
|
from zigpy.zcl.foundation import Status
|
||||||
|
|
||||||
from homeassistant.components import light
|
from homeassistant.components import light
|
||||||
from homeassistant.const import STATE_ON
|
from homeassistant.const import STATE_ON
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
from homeassistant.helpers.event import async_track_time_interval
|
from homeassistant.helpers.event import async_track_time_interval
|
||||||
import homeassistant.util.color as color_util
|
import homeassistant.util.color as color_util
|
||||||
|
|
||||||
from .core.const import (
|
from .core.const import (
|
||||||
|
CHANNEL_COLOR,
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_DISPATCHERS,
|
DATA_ZHA_DISPATCHERS,
|
||||||
ZHA_DISCOVERY_NEW,
|
CHANNEL_LEVEL,
|
||||||
COLOR_CHANNEL,
|
CHANNEL_ON_OFF,
|
||||||
ON_OFF_CHANNEL,
|
|
||||||
LEVEL_CHANNEL,
|
|
||||||
SIGNAL_ATTR_UPDATED,
|
SIGNAL_ATTR_UPDATED,
|
||||||
SIGNAL_SET_LEVEL,
|
SIGNAL_SET_LEVEL,
|
||||||
|
ZHA_DISCOVERY_NEW,
|
||||||
)
|
)
|
||||||
from .entity import ZhaEntity
|
from .entity import ZhaEntity
|
||||||
|
|
||||||
@ -83,9 +85,9 @@ class Light(ZhaEntity, light.Light):
|
|||||||
self._color_temp = None
|
self._color_temp = None
|
||||||
self._hs_color = None
|
self._hs_color = None
|
||||||
self._brightness = None
|
self._brightness = None
|
||||||
self._on_off_channel = self.cluster_channels.get(ON_OFF_CHANNEL)
|
self._on_off_channel = self.cluster_channels.get(CHANNEL_ON_OFF)
|
||||||
self._level_channel = self.cluster_channels.get(LEVEL_CHANNEL)
|
self._level_channel = self.cluster_channels.get(CHANNEL_LEVEL)
|
||||||
self._color_channel = self.cluster_channels.get(COLOR_CHANNEL)
|
self._color_channel = self.cluster_channels.get(CHANNEL_COLOR)
|
||||||
|
|
||||||
if self._level_channel:
|
if self._level_channel:
|
||||||
self._supported_features |= light.SUPPORT_BRIGHTNESS
|
self._supported_features |= light.SUPPORT_BRIGHTNESS
|
||||||
|
@ -2,20 +2,22 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from zigpy.zcl.foundation import Status
|
from zigpy.zcl.foundation import Status
|
||||||
from homeassistant.core import callback
|
|
||||||
from homeassistant.components.lock import (
|
from homeassistant.components.lock import (
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
STATE_UNLOCKED,
|
|
||||||
STATE_LOCKED,
|
STATE_LOCKED,
|
||||||
|
STATE_UNLOCKED,
|
||||||
LockDevice,
|
LockDevice,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from .core.const import (
|
from .core.const import (
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_DISPATCHERS,
|
DATA_ZHA_DISPATCHERS,
|
||||||
ZHA_DISCOVERY_NEW,
|
CHANNEL_DOORLOCK,
|
||||||
DOORLOCK_CHANNEL,
|
|
||||||
SIGNAL_ATTR_UPDATED,
|
SIGNAL_ATTR_UPDATED,
|
||||||
|
ZHA_DISCOVERY_NEW,
|
||||||
)
|
)
|
||||||
from .entity import ZhaEntity
|
from .entity import ZhaEntity
|
||||||
|
|
||||||
@ -73,7 +75,7 @@ class ZhaDoorLock(ZhaEntity, LockDevice):
|
|||||||
def __init__(self, unique_id, zha_device, channels, **kwargs):
|
def __init__(self, unique_id, zha_device, channels, **kwargs):
|
||||||
"""Init this sensor."""
|
"""Init this sensor."""
|
||||||
super().__init__(unique_id, zha_device, channels, **kwargs)
|
super().__init__(unique_id, zha_device, channels, **kwargs)
|
||||||
self._doorlock_channel = self.cluster_channels.get(DOORLOCK_CHANNEL)
|
self._doorlock_channel = self.cluster_channels.get(CHANNEL_DOORLOCK)
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Run when about to be added to hass."""
|
"""Run when about to be added to hass."""
|
||||||
|
@ -2,37 +2,38 @@
|
|||||||
import logging
|
import logging
|
||||||
import numbers
|
import numbers
|
||||||
|
|
||||||
from homeassistant.core import callback
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
DOMAIN,
|
DEVICE_CLASS_BATTERY,
|
||||||
DEVICE_CLASS_HUMIDITY,
|
DEVICE_CLASS_HUMIDITY,
|
||||||
DEVICE_CLASS_ILLUMINANCE,
|
DEVICE_CLASS_ILLUMINANCE,
|
||||||
DEVICE_CLASS_TEMPERATURE,
|
|
||||||
DEVICE_CLASS_PRESSURE,
|
|
||||||
DEVICE_CLASS_POWER,
|
DEVICE_CLASS_POWER,
|
||||||
DEVICE_CLASS_BATTERY,
|
DEVICE_CLASS_PRESSURE,
|
||||||
|
DEVICE_CLASS_TEMPERATURE,
|
||||||
|
DOMAIN,
|
||||||
)
|
)
|
||||||
from homeassistant.const import TEMP_CELSIUS, POWER_WATT, ATTR_UNIT_OF_MEASUREMENT
|
from homeassistant.const import ATTR_UNIT_OF_MEASUREMENT, POWER_WATT, TEMP_CELSIUS
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from .core.const import (
|
from .core.const import (
|
||||||
|
CHANNEL_ATTRIBUTE,
|
||||||
|
SENSOR_BATTERY,
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_DISPATCHERS,
|
DATA_ZHA_DISPATCHERS,
|
||||||
ZHA_DISCOVERY_NEW,
|
SENSOR_ELECTRICAL_MEASUREMENT,
|
||||||
HUMIDITY,
|
CHANNEL_ELECTRICAL_MEASUREMENT,
|
||||||
TEMPERATURE,
|
SENSOR_GENERIC,
|
||||||
ILLUMINANCE,
|
SENSOR_HUMIDITY,
|
||||||
PRESSURE,
|
SENSOR_ILLUMINANCE,
|
||||||
METERING,
|
SENSOR_METERING,
|
||||||
ELECTRICAL_MEASUREMENT,
|
CHANNEL_POWER_CONFIGURATION,
|
||||||
GENERIC,
|
SENSOR_PRESSURE,
|
||||||
SENSOR_TYPE,
|
SENSOR_TYPE,
|
||||||
ATTRIBUTE_CHANNEL,
|
|
||||||
ELECTRICAL_MEASUREMENT_CHANNEL,
|
|
||||||
SIGNAL_ATTR_UPDATED,
|
SIGNAL_ATTR_UPDATED,
|
||||||
SIGNAL_STATE_ATTR,
|
SIGNAL_STATE_ATTR,
|
||||||
|
SENSOR_TEMPERATURE,
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
BATTERY,
|
ZHA_DISCOVERY_NEW,
|
||||||
POWER_CONFIGURATION_CHANNEL,
|
|
||||||
)
|
)
|
||||||
from .entity import ZhaEntity
|
from .entity import ZhaEntity
|
||||||
|
|
||||||
@ -121,49 +122,49 @@ async def async_battery_device_state_attr_provider(channel):
|
|||||||
|
|
||||||
|
|
||||||
FORMATTER_FUNC_REGISTRY = {
|
FORMATTER_FUNC_REGISTRY = {
|
||||||
HUMIDITY: humidity_formatter,
|
SENSOR_HUMIDITY: humidity_formatter,
|
||||||
TEMPERATURE: temperature_formatter,
|
SENSOR_TEMPERATURE: temperature_formatter,
|
||||||
PRESSURE: pressure_formatter,
|
SENSOR_PRESSURE: pressure_formatter,
|
||||||
ELECTRICAL_MEASUREMENT: active_power_formatter,
|
SENSOR_ELECTRICAL_MEASUREMENT: active_power_formatter,
|
||||||
ILLUMINANCE: illuminance_formatter,
|
SENSOR_ILLUMINANCE: illuminance_formatter,
|
||||||
GENERIC: pass_through_formatter,
|
SENSOR_GENERIC: pass_through_formatter,
|
||||||
BATTERY: battery_percentage_remaining_formatter,
|
SENSOR_BATTERY: battery_percentage_remaining_formatter,
|
||||||
}
|
}
|
||||||
|
|
||||||
UNIT_REGISTRY = {
|
UNIT_REGISTRY = {
|
||||||
HUMIDITY: "%",
|
SENSOR_HUMIDITY: "%",
|
||||||
TEMPERATURE: TEMP_CELSIUS,
|
SENSOR_TEMPERATURE: TEMP_CELSIUS,
|
||||||
PRESSURE: "hPa",
|
SENSOR_PRESSURE: "hPa",
|
||||||
ILLUMINANCE: "lx",
|
SENSOR_ILLUMINANCE: "lx",
|
||||||
METERING: POWER_WATT,
|
SENSOR_METERING: POWER_WATT,
|
||||||
ELECTRICAL_MEASUREMENT: POWER_WATT,
|
SENSOR_ELECTRICAL_MEASUREMENT: POWER_WATT,
|
||||||
GENERIC: None,
|
SENSOR_GENERIC: None,
|
||||||
BATTERY: "%",
|
SENSOR_BATTERY: "%",
|
||||||
}
|
}
|
||||||
|
|
||||||
CHANNEL_REGISTRY = {
|
CHANNEL_REGISTRY = {
|
||||||
ELECTRICAL_MEASUREMENT: ELECTRICAL_MEASUREMENT_CHANNEL,
|
SENSOR_ELECTRICAL_MEASUREMENT: CHANNEL_ELECTRICAL_MEASUREMENT,
|
||||||
BATTERY: POWER_CONFIGURATION_CHANNEL,
|
SENSOR_BATTERY: CHANNEL_POWER_CONFIGURATION,
|
||||||
}
|
}
|
||||||
|
|
||||||
POLLING_REGISTRY = {ELECTRICAL_MEASUREMENT: True}
|
POLLING_REGISTRY = {SENSOR_ELECTRICAL_MEASUREMENT: True}
|
||||||
|
|
||||||
FORCE_UPDATE_REGISTRY = {ELECTRICAL_MEASUREMENT: False}
|
FORCE_UPDATE_REGISTRY = {SENSOR_ELECTRICAL_MEASUREMENT: False}
|
||||||
|
|
||||||
DEVICE_CLASS_REGISTRY = {
|
DEVICE_CLASS_REGISTRY = {
|
||||||
UNKNOWN: None,
|
UNKNOWN: None,
|
||||||
HUMIDITY: DEVICE_CLASS_HUMIDITY,
|
SENSOR_HUMIDITY: DEVICE_CLASS_HUMIDITY,
|
||||||
TEMPERATURE: DEVICE_CLASS_TEMPERATURE,
|
SENSOR_TEMPERATURE: DEVICE_CLASS_TEMPERATURE,
|
||||||
PRESSURE: DEVICE_CLASS_PRESSURE,
|
SENSOR_PRESSURE: DEVICE_CLASS_PRESSURE,
|
||||||
ILLUMINANCE: DEVICE_CLASS_ILLUMINANCE,
|
SENSOR_ILLUMINANCE: DEVICE_CLASS_ILLUMINANCE,
|
||||||
METERING: DEVICE_CLASS_POWER,
|
SENSOR_METERING: DEVICE_CLASS_POWER,
|
||||||
ELECTRICAL_MEASUREMENT: DEVICE_CLASS_POWER,
|
SENSOR_ELECTRICAL_MEASUREMENT: DEVICE_CLASS_POWER,
|
||||||
BATTERY: DEVICE_CLASS_BATTERY,
|
SENSOR_BATTERY: DEVICE_CLASS_BATTERY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DEVICE_STATE_ATTR_PROVIDER_REGISTRY = {
|
DEVICE_STATE_ATTR_PROVIDER_REGISTRY = {
|
||||||
BATTERY: async_battery_device_state_attr_provider
|
SENSOR_BATTERY: async_battery_device_state_attr_provider
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -217,7 +218,7 @@ class Sensor(ZhaEntity):
|
|||||||
def __init__(self, unique_id, zha_device, channels, **kwargs):
|
def __init__(self, unique_id, zha_device, channels, **kwargs):
|
||||||
"""Init this sensor."""
|
"""Init this sensor."""
|
||||||
super().__init__(unique_id, zha_device, channels, **kwargs)
|
super().__init__(unique_id, zha_device, channels, **kwargs)
|
||||||
self._sensor_type = kwargs.get(SENSOR_TYPE, GENERIC)
|
self._sensor_type = kwargs.get(SENSOR_TYPE, SENSOR_GENERIC)
|
||||||
self._unit = UNIT_REGISTRY.get(self._sensor_type)
|
self._unit = UNIT_REGISTRY.get(self._sensor_type)
|
||||||
self._formatter_function = FORMATTER_FUNC_REGISTRY.get(
|
self._formatter_function = FORMATTER_FUNC_REGISTRY.get(
|
||||||
self._sensor_type, pass_through_formatter
|
self._sensor_type, pass_through_formatter
|
||||||
@ -225,7 +226,7 @@ class Sensor(ZhaEntity):
|
|||||||
self._force_update = FORCE_UPDATE_REGISTRY.get(self._sensor_type, False)
|
self._force_update = FORCE_UPDATE_REGISTRY.get(self._sensor_type, False)
|
||||||
self._should_poll = POLLING_REGISTRY.get(self._sensor_type, False)
|
self._should_poll = POLLING_REGISTRY.get(self._sensor_type, False)
|
||||||
self._channel = self.cluster_channels.get(
|
self._channel = self.cluster_channels.get(
|
||||||
CHANNEL_REGISTRY.get(self._sensor_type, ATTRIBUTE_CHANNEL)
|
CHANNEL_REGISTRY.get(self._sensor_type, CHANNEL_ATTRIBUTE)
|
||||||
)
|
)
|
||||||
self._device_class = DEVICE_CLASS_REGISTRY.get(self._sensor_type, None)
|
self._device_class = DEVICE_CLASS_REGISTRY.get(self._sensor_type, None)
|
||||||
self.state_attr_provider = DEVICE_STATE_ATTR_PROVIDER_REGISTRY.get(
|
self.state_attr_provider = DEVICE_STATE_ATTR_PROVIDER_REGISTRY.get(
|
||||||
|
@ -2,16 +2,18 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from zigpy.zcl.foundation import Status
|
from zigpy.zcl.foundation import Status
|
||||||
|
|
||||||
from homeassistant.components.switch import DOMAIN, SwitchDevice
|
from homeassistant.components.switch import DOMAIN, SwitchDevice
|
||||||
from homeassistant.const import STATE_ON
|
from homeassistant.const import STATE_ON
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from .core.const import (
|
from .core.const import (
|
||||||
DATA_ZHA,
|
DATA_ZHA,
|
||||||
DATA_ZHA_DISPATCHERS,
|
DATA_ZHA_DISPATCHERS,
|
||||||
ZHA_DISCOVERY_NEW,
|
CHANNEL_ON_OFF,
|
||||||
ON_OFF_CHANNEL,
|
|
||||||
SIGNAL_ATTR_UPDATED,
|
SIGNAL_ATTR_UPDATED,
|
||||||
|
ZHA_DISCOVERY_NEW,
|
||||||
)
|
)
|
||||||
from .entity import ZhaEntity
|
from .entity import ZhaEntity
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ class Switch(ZhaEntity, SwitchDevice):
|
|||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
"""Initialize the ZHA switch."""
|
"""Initialize the ZHA switch."""
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self._on_off_channel = self.cluster_channels.get(ON_OFF_CHANNEL)
|
self._on_off_channel = self.cluster_channels.get(CHANNEL_ON_OFF)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
"""Test ZHA API."""
|
"""Test ZHA API."""
|
||||||
import pytest
|
import pytest
|
||||||
from homeassistant.components.switch import DOMAIN
|
from homeassistant.components.switch import DOMAIN
|
||||||
from homeassistant.components.zha.api import async_load_api, ATTR_IEEE, TYPE, ID
|
from homeassistant.components.zha.api import async_load_api, TYPE, ID
|
||||||
from homeassistant.components.zha.core.const import (
|
from homeassistant.components.zha.core.const import (
|
||||||
ATTR_CLUSTER_ID,
|
ATTR_CLUSTER_ID,
|
||||||
ATTR_CLUSTER_TYPE,
|
ATTR_CLUSTER_TYPE,
|
||||||
IN,
|
CLUSTER_TYPE_IN,
|
||||||
IEEE,
|
ATTR_IEEE,
|
||||||
MODEL,
|
ATTR_MODEL,
|
||||||
NAME,
|
ATTR_NAME,
|
||||||
QUIRK_APPLIED,
|
ATTR_QUIRK_APPLIED,
|
||||||
ATTR_MANUFACTURER,
|
ATTR_MANUFACTURER,
|
||||||
ATTR_ENDPOINT_ID,
|
ATTR_ENDPOINT_ID,
|
||||||
)
|
)
|
||||||
@ -49,14 +49,14 @@ async def test_device_clusters(hass, config_entry, zha_gateway, zha_client):
|
|||||||
cluster_infos = sorted(msg["result"], key=lambda k: k[ID])
|
cluster_infos = sorted(msg["result"], key=lambda k: k[ID])
|
||||||
|
|
||||||
cluster_info = cluster_infos[0]
|
cluster_info = cluster_infos[0]
|
||||||
assert cluster_info[TYPE] == IN
|
assert cluster_info[TYPE] == CLUSTER_TYPE_IN
|
||||||
assert cluster_info[ID] == 0
|
assert cluster_info[ID] == 0
|
||||||
assert cluster_info[NAME] == "Basic"
|
assert cluster_info[ATTR_NAME] == "Basic"
|
||||||
|
|
||||||
cluster_info = cluster_infos[1]
|
cluster_info = cluster_infos[1]
|
||||||
assert cluster_info[TYPE] == IN
|
assert cluster_info[TYPE] == CLUSTER_TYPE_IN
|
||||||
assert cluster_info[ID] == 6
|
assert cluster_info[ID] == 6
|
||||||
assert cluster_info[NAME] == "OnOff"
|
assert cluster_info[ATTR_NAME] == "OnOff"
|
||||||
|
|
||||||
|
|
||||||
async def test_device_cluster_attributes(hass, config_entry, zha_gateway, zha_client):
|
async def test_device_cluster_attributes(hass, config_entry, zha_gateway, zha_client):
|
||||||
@ -68,7 +68,7 @@ async def test_device_cluster_attributes(hass, config_entry, zha_gateway, zha_cl
|
|||||||
ATTR_ENDPOINT_ID: 1,
|
ATTR_ENDPOINT_ID: 1,
|
||||||
ATTR_IEEE: "00:0d:6f:00:0a:90:69:e7",
|
ATTR_IEEE: "00:0d:6f:00:0a:90:69:e7",
|
||||||
ATTR_CLUSTER_ID: 6,
|
ATTR_CLUSTER_ID: 6,
|
||||||
ATTR_CLUSTER_TYPE: IN,
|
ATTR_CLUSTER_TYPE: CLUSTER_TYPE_IN,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ async def test_device_cluster_attributes(hass, config_entry, zha_gateway, zha_cl
|
|||||||
|
|
||||||
for attribute in attributes:
|
for attribute in attributes:
|
||||||
assert attribute[ID] is not None
|
assert attribute[ID] is not None
|
||||||
assert attribute[NAME] is not None
|
assert attribute[ATTR_NAME] is not None
|
||||||
|
|
||||||
|
|
||||||
async def test_device_cluster_commands(hass, config_entry, zha_gateway, zha_client):
|
async def test_device_cluster_commands(hass, config_entry, zha_gateway, zha_client):
|
||||||
@ -91,7 +91,7 @@ async def test_device_cluster_commands(hass, config_entry, zha_gateway, zha_clie
|
|||||||
ATTR_ENDPOINT_ID: 1,
|
ATTR_ENDPOINT_ID: 1,
|
||||||
ATTR_IEEE: "00:0d:6f:00:0a:90:69:e7",
|
ATTR_IEEE: "00:0d:6f:00:0a:90:69:e7",
|
||||||
ATTR_CLUSTER_ID: 6,
|
ATTR_CLUSTER_ID: 6,
|
||||||
ATTR_CLUSTER_TYPE: IN,
|
ATTR_CLUSTER_TYPE: CLUSTER_TYPE_IN,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ async def test_device_cluster_commands(hass, config_entry, zha_gateway, zha_clie
|
|||||||
|
|
||||||
for command in commands:
|
for command in commands:
|
||||||
assert command[ID] is not None
|
assert command[ID] is not None
|
||||||
assert command[NAME] is not None
|
assert command[ATTR_NAME] is not None
|
||||||
assert command[TYPE] is not None
|
assert command[TYPE] is not None
|
||||||
|
|
||||||
|
|
||||||
@ -116,13 +116,13 @@ async def test_list_devices(hass, config_entry, zha_gateway, zha_client):
|
|||||||
assert len(devices) == 1
|
assert len(devices) == 1
|
||||||
|
|
||||||
for device in devices:
|
for device in devices:
|
||||||
assert device[IEEE] is not None
|
assert device[ATTR_IEEE] is not None
|
||||||
assert device[ATTR_MANUFACTURER] is not None
|
assert device[ATTR_MANUFACTURER] is not None
|
||||||
assert device[MODEL] is not None
|
assert device[ATTR_MODEL] is not None
|
||||||
assert device[NAME] is not None
|
assert device[ATTR_NAME] is not None
|
||||||
assert device[QUIRK_APPLIED] is not None
|
assert device[ATTR_QUIRK_APPLIED] is not None
|
||||||
assert device["entities"] is not None
|
assert device["entities"] is not None
|
||||||
|
|
||||||
for entity_reference in device["entities"]:
|
for entity_reference in device["entities"]:
|
||||||
assert entity_reference[NAME] is not None
|
assert entity_reference[ATTR_NAME] is not None
|
||||||
assert entity_reference["entity_id"] is not None
|
assert entity_reference["entity_id"] is not None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user