Z-Wave Device Registry Support (#17291)
* Add device_registry support for sensor and switch domains * Add device_registry support for light * Add device registry to binary_sensor, climate, cover * Add device registry to zwave fan * Fix test for config entry loading * lint * revert erroneous modification * Revert device_registry.py change
This commit is contained in:
parent
c6d9ceca63
commit
9c52a3ce22
10 changed files with 189 additions and 31 deletions
|
@ -7,10 +7,11 @@ https://home-assistant.io/components/binary_sensor.zwave/
|
|||
import logging
|
||||
import datetime
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.event import track_point_in_time
|
||||
from homeassistant.components import zwave
|
||||
from homeassistant.components.zwave import ( # noqa pylint: disable=unused-import
|
||||
async_setup_platform, workaround)
|
||||
from homeassistant.components.zwave import workaround
|
||||
from homeassistant.components.binary_sensor import (
|
||||
DOMAIN,
|
||||
BinarySensorDevice)
|
||||
|
@ -19,6 +20,23 @@ _LOGGER = logging.getLogger(__name__)
|
|||
DEPENDENCIES = []
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities,
|
||||
discovery_info=None):
|
||||
"""Old method of setting up Z-Wave binary sensors."""
|
||||
pass
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Z-Wave binary sensors from Config Entry."""
|
||||
@callback
|
||||
def async_add_binary_sensor(binary_sensor):
|
||||
"""Add Z-Wave binary sensor."""
|
||||
async_add_entities([binary_sensor])
|
||||
|
||||
async_dispatcher_connect(hass, 'zwave_new_binary_sensor',
|
||||
async_add_binary_sensor)
|
||||
|
||||
|
||||
def get_device(values, **kwargs):
|
||||
"""Create Z-Wave entity device."""
|
||||
device_mapping = workaround.get_device_mapping(values.primary)
|
||||
|
|
|
@ -6,14 +6,15 @@ https://home-assistant.io/components/climate.zwave/
|
|||
"""
|
||||
# Because we do not compile openzwave on CI
|
||||
import logging
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.components.climate import (
|
||||
DOMAIN, ClimateDevice, STATE_AUTO, STATE_COOL, STATE_HEAT,
|
||||
SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE,
|
||||
SUPPORT_OPERATION_MODE, SUPPORT_SWING_MODE)
|
||||
from homeassistant.components.zwave import ( # noqa pylint: disable=unused-import
|
||||
ZWaveDeviceEntity, async_setup_platform)
|
||||
from homeassistant.components.zwave import ZWaveDeviceEntity
|
||||
from homeassistant.const import (
|
||||
STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_TEMPERATURE)
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -42,6 +43,22 @@ STATE_MAPPINGS = {
|
|||
}
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities,
|
||||
discovery_info=None):
|
||||
"""Old method of setting up Z-Wave climate devices."""
|
||||
pass
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Z-Wave Climate device from Config Entry."""
|
||||
@callback
|
||||
def async_add_climate(climate):
|
||||
"""Add Z-Wave Climate Device."""
|
||||
async_add_entities([climate])
|
||||
|
||||
async_dispatcher_connect(hass, 'zwave_new_climate', async_add_climate)
|
||||
|
||||
|
||||
def get_device(hass, values, **kwargs):
|
||||
"""Create Z-Wave entity device."""
|
||||
temp_unit = hass.config.units.temperature_unit
|
||||
|
|
|
@ -5,18 +5,36 @@ For more details about this platform, please refer to the documentation
|
|||
https://home-assistant.io/components/cover.zwave/
|
||||
"""
|
||||
import logging
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.components.cover import (
|
||||
DOMAIN, SUPPORT_OPEN, SUPPORT_CLOSE, ATTR_POSITION)
|
||||
from homeassistant.components import zwave
|
||||
from homeassistant.components.zwave import ( # noqa pylint: disable=unused-import
|
||||
ZWaveDeviceEntity, async_setup_platform, workaround)
|
||||
from homeassistant.components.zwave import (
|
||||
ZWaveDeviceEntity, workaround)
|
||||
from homeassistant.components.cover import CoverDevice
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SUPPORT_GARAGE = SUPPORT_OPEN | SUPPORT_CLOSE
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities,
|
||||
discovery_info=None):
|
||||
"""Old method of setting up Z-Wave covers."""
|
||||
pass
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Z-Wave Cover from Config Entry."""
|
||||
@callback
|
||||
def async_add_cover(cover):
|
||||
"""Add Z-Wave Cover."""
|
||||
async_add_entities([cover])
|
||||
|
||||
async_dispatcher_connect(hass, 'zwave_new_cover', async_add_cover)
|
||||
|
||||
|
||||
def get_device(hass, values, node_config, **kwargs):
|
||||
"""Create Z-Wave entity device."""
|
||||
invert_buttons = node_config.get(zwave.CONF_INVERT_OPENCLOSE_BUTTONS)
|
||||
|
|
|
@ -7,11 +7,12 @@ https://home-assistant.io/components/fan.zwave/
|
|||
import logging
|
||||
import math
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.components.fan import (
|
||||
DOMAIN, FanEntity, SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH,
|
||||
SUPPORT_SET_SPEED)
|
||||
from homeassistant.components import zwave
|
||||
from homeassistant.components.zwave import async_setup_platform # noqa pylint: disable=unused-import
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -35,6 +36,22 @@ SPEED_TO_VALUE = {
|
|||
}
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities,
|
||||
discovery_info=None):
|
||||
"""Old method of setting up Z-Wave fans."""
|
||||
pass
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Z-Wave Fan from Config Entry."""
|
||||
@callback
|
||||
def async_add_fan(fan):
|
||||
"""Add Z-Wave Fan."""
|
||||
async_add_entities([fan])
|
||||
|
||||
async_dispatcher_connect(hass, 'zwave_new_fan', async_add_fan)
|
||||
|
||||
|
||||
def get_device(values, **kwargs):
|
||||
"""Create Z-Wave entity device."""
|
||||
return ZwaveFan(values)
|
||||
|
|
|
@ -7,13 +7,14 @@ https://home-assistant.io/components/light.zwave/
|
|||
import logging
|
||||
|
||||
from threading import Timer
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.components.light import (
|
||||
ATTR_WHITE_VALUE, ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_HS_COLOR,
|
||||
ATTR_TRANSITION, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_COLOR,
|
||||
SUPPORT_TRANSITION, SUPPORT_WHITE_VALUE, DOMAIN, Light)
|
||||
from homeassistant.components import zwave
|
||||
from homeassistant.components.zwave import async_setup_platform # noqa pylint: disable=unused-import
|
||||
from homeassistant.const import STATE_OFF, STATE_ON
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
import homeassistant.util.color as color_util
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -43,6 +44,22 @@ TEMP_WARM_HASS = (TEMP_COLOR_MAX - TEMP_COLOR_MIN) / 3 * 2 + TEMP_COLOR_MIN
|
|||
TEMP_COLD_HASS = (TEMP_COLOR_MAX - TEMP_COLOR_MIN) / 3 + TEMP_COLOR_MIN
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities,
|
||||
discovery_info=None):
|
||||
"""Old method of setting up Z-Wave lights."""
|
||||
pass
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Z-Wave Light from Config Entry."""
|
||||
@callback
|
||||
def async_add_light(light):
|
||||
"""Add Z-Wave Light."""
|
||||
async_add_entities([light])
|
||||
|
||||
async_dispatcher_connect(hass, 'zwave_new_light', async_add_light)
|
||||
|
||||
|
||||
def get_device(node, values, node_config, **kwargs):
|
||||
"""Create Z-Wave entity device."""
|
||||
refresh = node_config.get(zwave.CONF_REFRESH_VALUE)
|
||||
|
|
|
@ -5,14 +5,31 @@ For more details about this platform, please refer to the documentation
|
|||
at https://home-assistant.io/components/sensor.zwave/
|
||||
"""
|
||||
import logging
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.components.sensor import DOMAIN
|
||||
from homeassistant.components import zwave
|
||||
from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT
|
||||
from homeassistant.components.zwave import async_setup_platform # noqa pylint: disable=unused-import
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities,
|
||||
discovery_info=None):
|
||||
"""Old method of setting up Z-Wave sensors."""
|
||||
pass
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Z-Wave Sensor from Config Entry."""
|
||||
@callback
|
||||
def async_add_sensor(sensor):
|
||||
"""Add Z-Wave Sensor."""
|
||||
async_add_entities([sensor])
|
||||
|
||||
async_dispatcher_connect(hass, 'zwave_new_sensor', async_add_sensor)
|
||||
|
||||
|
||||
def get_device(node, values, **kwargs):
|
||||
"""Create Z-Wave entity device."""
|
||||
# Generic Device mappings
|
||||
|
|
|
@ -6,13 +6,30 @@ https://home-assistant.io/components/switch.zwave/
|
|||
"""
|
||||
import logging
|
||||
import time
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.components.switch import DOMAIN, SwitchDevice
|
||||
from homeassistant.components import zwave
|
||||
from homeassistant.components.zwave import workaround, async_setup_platform # noqa pylint: disable=unused-import
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities,
|
||||
discovery_info=None):
|
||||
"""Old method of setting up Z-Wave switches."""
|
||||
pass
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Z-Wave Switch from Config Entry."""
|
||||
@callback
|
||||
def async_add_switch(switch):
|
||||
"""Add Z-Wave Switch."""
|
||||
async_add_entities([switch])
|
||||
|
||||
async_dispatcher_connect(hass, 'zwave_new_switch', async_add_switch)
|
||||
|
||||
|
||||
def get_device(values, **kwargs):
|
||||
"""Create zwave entity device."""
|
||||
return ZwaveSwitch(values)
|
||||
|
@ -25,8 +42,8 @@ class ZwaveSwitch(zwave.ZWaveDeviceEntity, SwitchDevice):
|
|||
"""Initialize the Z-Wave switch device."""
|
||||
zwave.ZWaveDeviceEntity.__init__(self, values, DOMAIN)
|
||||
self.refresh_on_update = (
|
||||
workaround.get_device_mapping(values.primary) ==
|
||||
workaround.WORKAROUND_REFRESH_NODE_ON_UPDATE)
|
||||
zwave.workaround.get_device_mapping(values.primary) ==
|
||||
zwave.workaround.WORKAROUND_REFRESH_NODE_ON_UPDATE)
|
||||
self.last_update = time.perf_counter()
|
||||
self._state = self.values.primary.data
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ DEFAULT_CONF_INVERT_OPENCLOSE_BUTTONS = False
|
|||
DEFAULT_CONF_REFRESH_VALUE = False
|
||||
DEFAULT_CONF_REFRESH_DELAY = 5
|
||||
|
||||
SUPPORTED_PLATFORMS = ['binary_sensor', 'climate', 'fan',
|
||||
'light', 'sensor', 'switch']
|
||||
|
||||
RENAME_NODE_SCHEMA = vol.Schema({
|
||||
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
|
||||
vol.Required(const.ATTR_NAME): cv.string,
|
||||
|
@ -224,7 +227,6 @@ async def async_setup_platform(hass, config, async_add_entities,
|
|||
discovery_info[const.DISCOVERY_DEVICE], None)
|
||||
if device is None:
|
||||
return False
|
||||
|
||||
async_add_entities([device])
|
||||
return True
|
||||
|
||||
|
@ -777,6 +779,10 @@ async def async_setup_entry(hass, config_entry):
|
|||
hass.services.async_register(DOMAIN, const.SERVICE_START_NETWORK,
|
||||
start_zwave)
|
||||
|
||||
for entry_component in SUPPORTED_PLATFORMS:
|
||||
hass.async_create_task(hass.config_entries.async_forward_entry_setup(
|
||||
config_entry, entry_component))
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
@ -928,9 +934,13 @@ class ZWaveDeviceEntityValues():
|
|||
async def discover_device(component, device, dict_id):
|
||||
"""Put device in a dictionary and call discovery on it."""
|
||||
self._hass.data[DATA_DEVICES][dict_id] = device
|
||||
await discovery.async_load_platform(
|
||||
self._hass, component, DOMAIN,
|
||||
{const.DISCOVERY_DEVICE: dict_id}, self._zwave_config)
|
||||
if component in SUPPORTED_PLATFORMS:
|
||||
async_dispatcher_send(
|
||||
self._hass, 'zwave_new_{}'.format(component), device)
|
||||
else:
|
||||
await discovery.async_load_platform(
|
||||
self._hass, component, DOMAIN,
|
||||
{const.DISCOVERY_DEVICE: dict_id}, self._zwave_config)
|
||||
|
||||
if device.unique_id:
|
||||
self._hass.add_job(discover_device, component, device, dict_id)
|
||||
|
@ -1010,6 +1020,18 @@ class ZWaveDeviceEntity(ZWaveBaseEntity):
|
|||
"""Return a unique ID."""
|
||||
return self._unique_id
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device information."""
|
||||
return {
|
||||
'identifiers': {
|
||||
(DOMAIN, self.node_id)
|
||||
},
|
||||
'manufacturer': self.node.manufacturer_name,
|
||||
'model': self.node.product_name,
|
||||
'name': node_name(self.node),
|
||||
}
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
|
|
|
@ -8,7 +8,7 @@ from homeassistant.helpers.entity import Entity
|
|||
from .const import (
|
||||
ATTR_NODE_ID, COMMAND_CLASS_WAKE_UP, ATTR_SCENE_ID, ATTR_SCENE_DATA,
|
||||
ATTR_BASIC_LEVEL, EVENT_NODE_EVENT, EVENT_SCENE_ACTIVATED,
|
||||
COMMAND_CLASS_CENTRAL_SCENE)
|
||||
COMMAND_CLASS_CENTRAL_SCENE, DOMAIN)
|
||||
from .util import node_name, is_node_parsed
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -110,6 +110,18 @@ class ZWaveNodeEntity(ZWaveBaseEntity):
|
|||
"""Return unique ID of Z-wave node."""
|
||||
return self._unique_id
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device information."""
|
||||
return {
|
||||
'identifiers': {
|
||||
(DOMAIN, self.node_id)
|
||||
},
|
||||
'manufacturer': self.node.manufacturer_name,
|
||||
'model': self.node.product_name,
|
||||
'name': node_name(self.node)
|
||||
}
|
||||
|
||||
def network_node_changed(self, node=None, value=None, args=None):
|
||||
"""Handle a changed node on the network."""
|
||||
if node and node.node_id != self.node_id:
|
||||
|
|
|
@ -703,21 +703,24 @@ class TestZWaveDeviceEntityValues(unittest.TestCase):
|
|||
const.COMMAND_CLASS_SWITCH_BINARY],
|
||||
}}}
|
||||
|
||||
values = zwave.ZWaveDeviceEntityValues(
|
||||
hass=self.hass,
|
||||
schema=self.mock_schema,
|
||||
primary_value=self.primary,
|
||||
zwave_config=self.zwave_config,
|
||||
device_config=self.device_config,
|
||||
registry=self.registry
|
||||
)
|
||||
values._check_entity_ready()
|
||||
self.hass.block_till_done()
|
||||
with patch.object(zwave, 'async_dispatcher_send') as \
|
||||
mock_dispatch_send:
|
||||
|
||||
assert discovery.async_load_platform.called
|
||||
assert len(discovery.async_load_platform.mock_calls) == 1
|
||||
args = discovery.async_load_platform.mock_calls[0][1]
|
||||
assert args[1] == 'binary_sensor'
|
||||
values = zwave.ZWaveDeviceEntityValues(
|
||||
hass=self.hass,
|
||||
schema=self.mock_schema,
|
||||
primary_value=self.primary,
|
||||
zwave_config=self.zwave_config,
|
||||
device_config=self.device_config,
|
||||
registry=self.registry
|
||||
)
|
||||
values._check_entity_ready()
|
||||
self.hass.block_till_done()
|
||||
|
||||
assert mock_dispatch_send.called
|
||||
assert len(mock_dispatch_send.mock_calls) == 1
|
||||
args = mock_dispatch_send.mock_calls[0][1]
|
||||
assert args[1] == 'zwave_new_binary_sensor'
|
||||
|
||||
@patch.object(zwave, 'get_platform')
|
||||
@patch.object(zwave, 'discovery')
|
||||
|
|
Loading…
Add table
Reference in a new issue