mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 08:47:10 +00:00
Update IDs for rename node/value (#24646)
* Update IDs for rename node/value * Rename devices and entities * Improved coverage
This commit is contained in:
parent
7f90a1cab2
commit
23dd644f4a
@ -68,12 +68,14 @@ SUPPORTED_PLATFORMS = ['binary_sensor', 'climate', 'cover', 'fan',
|
|||||||
RENAME_NODE_SCHEMA = vol.Schema({
|
RENAME_NODE_SCHEMA = vol.Schema({
|
||||||
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
|
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
|
||||||
vol.Required(const.ATTR_NAME): cv.string,
|
vol.Required(const.ATTR_NAME): cv.string,
|
||||||
|
vol.Optional(const.ATTR_UPDATE_IDS, default=False): cv.boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
RENAME_VALUE_SCHEMA = vol.Schema({
|
RENAME_VALUE_SCHEMA = vol.Schema({
|
||||||
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
|
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
|
||||||
vol.Required(const.ATTR_VALUE_ID): vol.Coerce(int),
|
vol.Required(const.ATTR_VALUE_ID): vol.Coerce(int),
|
||||||
vol.Required(const.ATTR_NAME): cv.string,
|
vol.Required(const.ATTR_NAME): cv.string,
|
||||||
|
vol.Optional(const.ATTR_UPDATE_IDS, default=False): cv.boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
SET_CONFIG_PARAMETER_SCHEMA = vol.Schema({
|
SET_CONFIG_PARAMETER_SCHEMA = vol.Schema({
|
||||||
@ -389,8 +391,7 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
entity.node_id, sec)
|
entity.node_id, sec)
|
||||||
hass.async_add_job(_add_node_to_component)
|
hass.async_add_job(_add_node_to_component)
|
||||||
|
|
||||||
hass.add_job(check_has_unique_id, entity, _on_ready, _on_timeout,
|
hass.add_job(check_has_unique_id, entity, _on_ready, _on_timeout)
|
||||||
hass.loop)
|
|
||||||
|
|
||||||
def node_removed(node):
|
def node_removed(node):
|
||||||
node_id = node.node_id
|
node_id = node.node_id
|
||||||
@ -491,6 +492,7 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
if hass.state == CoreState.running:
|
if hass.state == CoreState.running:
|
||||||
hass.bus.fire(const.EVENT_NETWORK_STOP)
|
hass.bus.fire(const.EVENT_NETWORK_STOP)
|
||||||
|
|
||||||
|
@callback
|
||||||
def rename_node(service):
|
def rename_node(service):
|
||||||
"""Rename a node."""
|
"""Rename a node."""
|
||||||
node_id = service.data.get(const.ATTR_NODE_ID)
|
node_id = service.data.get(const.ATTR_NODE_ID)
|
||||||
@ -499,7 +501,19 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
node.name = name
|
node.name = name
|
||||||
_LOGGER.info(
|
_LOGGER.info(
|
||||||
"Renamed Z-Wave node %d to %s", node_id, name)
|
"Renamed Z-Wave node %d to %s", node_id, name)
|
||||||
|
update_ids = service.data.get(const.ATTR_UPDATE_IDS)
|
||||||
|
# We want to rename the device, the node entity,
|
||||||
|
# and all the contained entities
|
||||||
|
node_key = 'node-{}'.format(node_id)
|
||||||
|
entity = hass.data[DATA_DEVICES][node_key]
|
||||||
|
hass.async_create_task(entity.node_renamed(update_ids))
|
||||||
|
for key in list(hass.data[DATA_DEVICES]):
|
||||||
|
if not key.startswith('{}-'.format(node_id)):
|
||||||
|
continue
|
||||||
|
entity = hass.data[DATA_DEVICES][key]
|
||||||
|
hass.async_create_task(entity.value_renamed(update_ids))
|
||||||
|
|
||||||
|
@callback
|
||||||
def rename_value(service):
|
def rename_value(service):
|
||||||
"""Rename a node value."""
|
"""Rename a node value."""
|
||||||
node_id = service.data.get(const.ATTR_NODE_ID)
|
node_id = service.data.get(const.ATTR_NODE_ID)
|
||||||
@ -511,6 +525,10 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
_LOGGER.info(
|
_LOGGER.info(
|
||||||
"Renamed Z-Wave value (Node %d Value %d) to %s",
|
"Renamed Z-Wave value (Node %d Value %d) to %s",
|
||||||
node_id, value_id, name)
|
node_id, value_id, name)
|
||||||
|
update_ids = service.data.get(const.ATTR_UPDATE_IDS)
|
||||||
|
value_key = '{}-{}'.format(node_id, value_id)
|
||||||
|
entity = hass.data[DATA_DEVICES][value_key]
|
||||||
|
hass.async_create_task(entity.value_renamed(update_ids))
|
||||||
|
|
||||||
def set_poll_intensity(service):
|
def set_poll_intensity(service):
|
||||||
"""Set the polling intensity of a node value."""
|
"""Set the polling intensity of a node value."""
|
||||||
@ -996,7 +1014,7 @@ class ZWaveDeviceEntityValues():
|
|||||||
self._hass.add_job(discover_device, component, device)
|
self._hass.add_job(discover_device, component, device)
|
||||||
else:
|
else:
|
||||||
self._hass.add_job(check_has_unique_id, device, _on_ready,
|
self._hass.add_job(check_has_unique_id, device, _on_ready,
|
||||||
_on_timeout, self._hass.loop)
|
_on_timeout)
|
||||||
|
|
||||||
|
|
||||||
class ZWaveDeviceEntity(ZWaveBaseEntity):
|
class ZWaveDeviceEntity(ZWaveBaseEntity):
|
||||||
@ -1034,6 +1052,25 @@ class ZWaveDeviceEntity(ZWaveBaseEntity):
|
|||||||
self.update_properties()
|
self.update_properties()
|
||||||
self.maybe_schedule_update()
|
self.maybe_schedule_update()
|
||||||
|
|
||||||
|
async def value_renamed(self, update_ids=False):
|
||||||
|
"""Rename the node and update any IDs."""
|
||||||
|
self._name = _value_name(self.values.primary)
|
||||||
|
if update_ids:
|
||||||
|
# Update entity ID.
|
||||||
|
ent_reg = await async_get_registry(self.hass)
|
||||||
|
new_entity_id = ent_reg.async_generate_entity_id(
|
||||||
|
self.platform.domain,
|
||||||
|
self._name,
|
||||||
|
self.platform.entities.keys() - {self.entity_id})
|
||||||
|
if new_entity_id != self.entity_id:
|
||||||
|
# Don't change the name attribute, it will be None unless
|
||||||
|
# customised and if it's been customised, keep the
|
||||||
|
# customisation.
|
||||||
|
ent_reg.async_update_entity(
|
||||||
|
self.entity_id, new_entity_id=new_entity_id)
|
||||||
|
return
|
||||||
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Add device to dict."""
|
"""Add device to dict."""
|
||||||
async_dispatcher_connect(
|
async_dispatcher_connect(
|
||||||
|
@ -19,6 +19,7 @@ ATTR_CONFIG_VALUE = "value"
|
|||||||
ATTR_POLL_INTENSITY = "poll_intensity"
|
ATTR_POLL_INTENSITY = "poll_intensity"
|
||||||
ATTR_VALUE_INDEX = "value_index"
|
ATTR_VALUE_INDEX = "value_index"
|
||||||
ATTR_VALUE_INSTANCE = "value_instance"
|
ATTR_VALUE_INSTANCE = "value_instance"
|
||||||
|
ATTR_UPDATE_IDS = 'update_ids'
|
||||||
NETWORK_READY_WAIT_SECS = 300
|
NETWORK_READY_WAIT_SECS = 300
|
||||||
NODE_READY_WAIT_SECS = 30
|
NODE_READY_WAIT_SECS = 30
|
||||||
|
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
"""Entity class that represents Z-Wave node."""
|
"""Entity class that represents Z-Wave node."""
|
||||||
import logging
|
import logging
|
||||||
|
from itertools import count
|
||||||
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.const import ATTR_BATTERY_LEVEL, ATTR_WAKEUP, ATTR_ENTITY_ID
|
from homeassistant.const import (
|
||||||
|
ATTR_BATTERY_LEVEL, ATTR_WAKEUP, ATTR_ENTITY_ID)
|
||||||
from homeassistant.helpers.entity_registry import async_get_registry
|
from homeassistant.helpers.entity_registry import async_get_registry
|
||||||
|
from homeassistant.helpers.device_registry import (
|
||||||
|
async_get_registry as get_dev_reg)
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -192,6 +196,42 @@ class ZWaveNodeEntity(ZWaveBaseEntity):
|
|||||||
|
|
||||||
self.maybe_schedule_update()
|
self.maybe_schedule_update()
|
||||||
|
|
||||||
|
async def node_renamed(self, update_ids=False):
|
||||||
|
"""Rename the node and update any IDs."""
|
||||||
|
self._name = node_name(self.node)
|
||||||
|
# Set the name in the devices. If they're customised
|
||||||
|
# the customisation will not be stored as name and will stick.
|
||||||
|
dev_reg = await get_dev_reg(self.hass)
|
||||||
|
device = dev_reg.async_get_device(
|
||||||
|
identifiers={(DOMAIN, self.node_id), },
|
||||||
|
connections=set())
|
||||||
|
dev_reg.async_update_device(device.id, name=self._name)
|
||||||
|
# update sub-devices too
|
||||||
|
for i in count(2):
|
||||||
|
identifier = (DOMAIN, self.node_id, i)
|
||||||
|
device = dev_reg.async_get_device(
|
||||||
|
identifiers={identifier, },
|
||||||
|
connections=set())
|
||||||
|
if not device:
|
||||||
|
break
|
||||||
|
new_name = "{} ({})".format(self._name, i)
|
||||||
|
dev_reg.async_update_device(device.id, name=new_name)
|
||||||
|
|
||||||
|
# Update entity ID.
|
||||||
|
if update_ids:
|
||||||
|
ent_reg = await async_get_registry(self.hass)
|
||||||
|
new_entity_id = ent_reg.async_generate_entity_id(
|
||||||
|
DOMAIN, self._name,
|
||||||
|
self.platform.entities.keys() - {self.entity_id})
|
||||||
|
if new_entity_id != self.entity_id:
|
||||||
|
# Don't change the name attribute, it will be None unless
|
||||||
|
# customised and if it's been customised, keep the
|
||||||
|
# customisation.
|
||||||
|
ent_reg.async_update_entity(
|
||||||
|
self.entity_id, new_entity_id=new_entity_id)
|
||||||
|
return
|
||||||
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
def network_node_event(self, node, value):
|
def network_node_event(self, node, value):
|
||||||
"""Handle a node activated event on the network."""
|
"""Handle a node activated event on the network."""
|
||||||
if node.node_id == self.node.node_id:
|
if node.node_id == self.node.node_id:
|
||||||
|
@ -168,6 +168,9 @@ rename_node:
|
|||||||
node_id:
|
node_id:
|
||||||
description: ID of the node to rename.
|
description: ID of the node to rename.
|
||||||
example: 10
|
example: 10
|
||||||
|
update_ids:
|
||||||
|
description: (optional) Rename the entity IDs for entities of this node.
|
||||||
|
example: True
|
||||||
name:
|
name:
|
||||||
description: New Name
|
description: New Name
|
||||||
example: 'kitchen'
|
example: 'kitchen'
|
||||||
@ -181,6 +184,9 @@ rename_value:
|
|||||||
value_id:
|
value_id:
|
||||||
description: ID of the value to rename.
|
description: ID of the value to rename.
|
||||||
example: 72037594255792737
|
example: 72037594255792737
|
||||||
|
update_ids:
|
||||||
|
description: (optional) Update the entity ID for this value's entity.
|
||||||
|
example: True
|
||||||
name:
|
name:
|
||||||
description: New Name
|
description: New Name
|
||||||
example: 'Luminosity'
|
example: 'Luminosity'
|
||||||
|
@ -74,7 +74,7 @@ def node_name(node):
|
|||||||
return 'Unknown Node {}'.format(node.node_id)
|
return 'Unknown Node {}'.format(node.node_id)
|
||||||
|
|
||||||
|
|
||||||
async def check_has_unique_id(entity, ready_callback, timeout_callback, loop):
|
async def check_has_unique_id(entity, ready_callback, timeout_callback):
|
||||||
"""Wait for entity to have unique_id."""
|
"""Wait for entity to have unique_id."""
|
||||||
start_time = dt_util.utcnow()
|
start_time = dt_util.utcnow()
|
||||||
while True:
|
while True:
|
||||||
@ -86,7 +86,7 @@ async def check_has_unique_id(entity, ready_callback, timeout_callback, loop):
|
|||||||
# Wait up to NODE_READY_WAIT_SECS seconds for unique_id to appear.
|
# Wait up to NODE_READY_WAIT_SECS seconds for unique_id to appear.
|
||||||
timeout_callback(waited)
|
timeout_callback(waited)
|
||||||
return
|
return
|
||||||
await asyncio.sleep(1, loop=loop)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
def is_node_parsed(node):
|
def is_node_parsed(node):
|
||||||
|
@ -136,11 +136,13 @@ class DeviceRegistry:
|
|||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_update_device(
|
def async_update_device(
|
||||||
self, device_id, *, area_id=_UNDEF, name_by_user=_UNDEF,
|
self, device_id, *, area_id=_UNDEF,
|
||||||
|
name=_UNDEF, name_by_user=_UNDEF,
|
||||||
new_identifiers=_UNDEF):
|
new_identifiers=_UNDEF):
|
||||||
"""Update properties of a device."""
|
"""Update properties of a device."""
|
||||||
return self._async_update_device(
|
return self._async_update_device(
|
||||||
device_id, area_id=area_id, name_by_user=name_by_user,
|
device_id, area_id=area_id,
|
||||||
|
name=name, name_by_user=name_by_user,
|
||||||
new_identifiers=new_identifiers)
|
new_identifiers=new_identifiers)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
@ -2,26 +2,27 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
from pytz import utc
|
from pytz import utc
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
import unittest
|
|
||||||
from unittest.mock import patch, MagicMock
|
|
||||||
|
|
||||||
from homeassistant.bootstrap import async_setup_component
|
from homeassistant.bootstrap import async_setup_component
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_START
|
|
||||||
from homeassistant.components import zwave
|
from homeassistant.components import zwave
|
||||||
from homeassistant.components.zwave.binary_sensor import get_device
|
|
||||||
from homeassistant.components.zwave import (
|
from homeassistant.components.zwave import (
|
||||||
const, CONFIG_SCHEMA, CONF_DEVICE_CONFIG_GLOB, DATA_NETWORK)
|
CONF_DEVICE_CONFIG_GLOB, CONFIG_SCHEMA, DATA_NETWORK, const)
|
||||||
|
from homeassistant.components.zwave.binary_sensor import get_device
|
||||||
|
from homeassistant.const import ATTR_ENTITY_ID, EVENT_HOMEASSISTANT_START
|
||||||
|
from homeassistant.helpers.entity_registry import async_get_registry
|
||||||
|
from homeassistant.helpers.device_registry import (
|
||||||
|
async_get_registry as get_dev_reg)
|
||||||
from homeassistant.setup import setup_component
|
from homeassistant.setup import setup_component
|
||||||
from tests.common import mock_registry
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from tests.common import (
|
from tests.common import (
|
||||||
get_test_home_assistant, async_fire_time_changed, mock_coro)
|
async_fire_time_changed, get_test_home_assistant, mock_coro, mock_registry)
|
||||||
from tests.mock.zwave import MockNetwork, MockNode, MockValue, MockEntityValues
|
from tests.mock.zwave import MockEntityValues, MockNetwork, MockNode, MockValue
|
||||||
|
|
||||||
|
|
||||||
async def test_valid_device_config(hass, mock_openzwave):
|
async def test_valid_device_config(hass, mock_openzwave):
|
||||||
@ -382,6 +383,150 @@ async def test_value_discovery(hass, mock_openzwave):
|
|||||||
'binary_sensor.mock_node_mock_value').state == 'off'
|
'binary_sensor.mock_node_mock_value').state == 'off'
|
||||||
|
|
||||||
|
|
||||||
|
async def test_value_entities(hass, mock_openzwave):
|
||||||
|
"""Test discovery of a node."""
|
||||||
|
mock_receivers = {}
|
||||||
|
|
||||||
|
def mock_connect(receiver, signal, *args, **kwargs):
|
||||||
|
mock_receivers[signal] = receiver
|
||||||
|
|
||||||
|
with patch('pydispatch.dispatcher.connect', new=mock_connect):
|
||||||
|
await async_setup_component(hass, 'zwave', {'zwave': {}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
zwave_network = hass.data[DATA_NETWORK]
|
||||||
|
zwave_network.state = MockNetwork.STATE_READY
|
||||||
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_receivers
|
||||||
|
|
||||||
|
hass.async_add_job(
|
||||||
|
mock_receivers[MockNetwork.SIGNAL_ALL_NODES_QUERIED])
|
||||||
|
node = MockNode(node_id=11, generic=const.GENERIC_TYPE_SENSOR_BINARY)
|
||||||
|
zwave_network.nodes = {node.node_id: node}
|
||||||
|
value = MockValue(
|
||||||
|
data=False, node=node, index=12, instance=1,
|
||||||
|
command_class=const.COMMAND_CLASS_SENSOR_BINARY,
|
||||||
|
type=const.TYPE_BOOL, genre=const.GENRE_USER)
|
||||||
|
node.values = {'primary': value, value.value_id: value}
|
||||||
|
value2 = MockValue(
|
||||||
|
data=False, node=node, index=12, instance=2,
|
||||||
|
label="Mock Value B",
|
||||||
|
command_class=const.COMMAND_CLASS_SENSOR_BINARY,
|
||||||
|
type=const.TYPE_BOOL, genre=const.GENRE_USER)
|
||||||
|
node.values[value2.value_id] = value2
|
||||||
|
|
||||||
|
hass.async_add_job(
|
||||||
|
mock_receivers[MockNetwork.SIGNAL_NODE_ADDED], node)
|
||||||
|
hass.async_add_job(
|
||||||
|
mock_receivers[MockNetwork.SIGNAL_VALUE_ADDED], node, value)
|
||||||
|
hass.async_add_job(
|
||||||
|
mock_receivers[MockNetwork.SIGNAL_VALUE_ADDED], node, value2)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get(
|
||||||
|
'binary_sensor.mock_node_mock_value').state == 'off'
|
||||||
|
assert hass.states.get(
|
||||||
|
'binary_sensor.mock_node_mock_value_b').state == 'off'
|
||||||
|
|
||||||
|
ent_reg = await async_get_registry(hass)
|
||||||
|
dev_reg = await get_dev_reg(hass)
|
||||||
|
|
||||||
|
entry = ent_reg.async_get('zwave.mock_node')
|
||||||
|
assert entry is not None
|
||||||
|
assert entry.unique_id == 'node-{}'.format(node.node_id)
|
||||||
|
node_dev_id = entry.device_id
|
||||||
|
|
||||||
|
entry = ent_reg.async_get('binary_sensor.mock_node_mock_value')
|
||||||
|
assert entry is not None
|
||||||
|
assert entry.unique_id == '{}-{}'.format(node.node_id, value.object_id)
|
||||||
|
assert entry.name is None
|
||||||
|
assert entry.device_id == node_dev_id
|
||||||
|
|
||||||
|
entry = ent_reg.async_get('binary_sensor.mock_node_mock_value_b')
|
||||||
|
assert entry is not None
|
||||||
|
assert entry.unique_id == '{}-{}'.format(node.node_id, value2.object_id)
|
||||||
|
assert entry.name is None
|
||||||
|
assert entry.device_id != node_dev_id
|
||||||
|
device_id_b = entry.device_id
|
||||||
|
|
||||||
|
device = dev_reg.async_get(node_dev_id)
|
||||||
|
assert device is not None
|
||||||
|
assert device.name == node.name
|
||||||
|
old_device = device
|
||||||
|
|
||||||
|
device = dev_reg.async_get(device_id_b)
|
||||||
|
assert device is not None
|
||||||
|
assert device.name == "{} ({})".format(node.name, value2.instance)
|
||||||
|
|
||||||
|
# test renaming without updating
|
||||||
|
await hass.services.async_call('zwave', 'rename_node', {
|
||||||
|
const.ATTR_NODE_ID: node.node_id,
|
||||||
|
const.ATTR_NAME: "Demo Node",
|
||||||
|
})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert node.name == "Demo Node"
|
||||||
|
|
||||||
|
entry = ent_reg.async_get('zwave.mock_node')
|
||||||
|
assert entry is not None
|
||||||
|
|
||||||
|
entry = ent_reg.async_get('binary_sensor.mock_node_mock_value')
|
||||||
|
assert entry is not None
|
||||||
|
|
||||||
|
entry = ent_reg.async_get('binary_sensor.mock_node_mock_value_b')
|
||||||
|
assert entry is not None
|
||||||
|
|
||||||
|
device = dev_reg.async_get(node_dev_id)
|
||||||
|
assert device is not None
|
||||||
|
assert device.id == old_device.id
|
||||||
|
assert device.name == node.name
|
||||||
|
|
||||||
|
device = dev_reg.async_get(device_id_b)
|
||||||
|
assert device is not None
|
||||||
|
assert device.name == "{} ({})".format(node.name, value2.instance)
|
||||||
|
|
||||||
|
# test renaming
|
||||||
|
await hass.services.async_call('zwave', 'rename_node', {
|
||||||
|
const.ATTR_NODE_ID: node.node_id,
|
||||||
|
const.ATTR_UPDATE_IDS: True,
|
||||||
|
const.ATTR_NAME: "New Node",
|
||||||
|
})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert node.name == "New Node"
|
||||||
|
|
||||||
|
entry = ent_reg.async_get('zwave.new_node')
|
||||||
|
assert entry is not None
|
||||||
|
assert entry.unique_id == 'node-{}'.format(node.node_id)
|
||||||
|
|
||||||
|
entry = ent_reg.async_get('binary_sensor.new_node_mock_value')
|
||||||
|
assert entry is not None
|
||||||
|
assert entry.unique_id == '{}-{}'.format(node.node_id, value.object_id)
|
||||||
|
|
||||||
|
device = dev_reg.async_get(node_dev_id)
|
||||||
|
assert device is not None
|
||||||
|
assert device.id == old_device.id
|
||||||
|
assert device.name == node.name
|
||||||
|
|
||||||
|
device = dev_reg.async_get(device_id_b)
|
||||||
|
assert device is not None
|
||||||
|
assert device.name == "{} ({})".format(node.name, value2.instance)
|
||||||
|
|
||||||
|
await hass.services.async_call('zwave', 'rename_value', {
|
||||||
|
const.ATTR_NODE_ID: node.node_id,
|
||||||
|
const.ATTR_VALUE_ID: value.object_id,
|
||||||
|
const.ATTR_UPDATE_IDS: True,
|
||||||
|
const.ATTR_NAME: "New Label",
|
||||||
|
})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entry = ent_reg.async_get('binary_sensor.new_node_new_label')
|
||||||
|
assert entry is not None
|
||||||
|
assert entry.unique_id == '{}-{}'.format(node.node_id, value.object_id)
|
||||||
|
|
||||||
|
|
||||||
async def test_value_discovery_existing_entity(hass, mock_openzwave):
|
async def test_value_discovery_existing_entity(hass, mock_openzwave):
|
||||||
"""Test discovery of a node."""
|
"""Test discovery of a node."""
|
||||||
mock_receivers = []
|
mock_receivers = []
|
||||||
|
Loading…
x
Reference in New Issue
Block a user