Skip to content

Commit

Permalink
Update IDs for rename node/value (#24646)
Browse files Browse the repository at this point in the history
* Update IDs for rename node/value

* Rename devices and entities

* Improved coverage
  • Loading branch information
Swamp-Ig authored and balloob committed Jul 1, 2019
1 parent 7f90a1c commit 23dd644
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 19 deletions.
43 changes: 40 additions & 3 deletions homeassistant/components/zwave/__init__.py
Expand Up @@ -68,12 +68,14 @@
RENAME_NODE_SCHEMA = vol.Schema({
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
vol.Required(const.ATTR_NAME): cv.string,
vol.Optional(const.ATTR_UPDATE_IDS, default=False): cv.boolean,
})

RENAME_VALUE_SCHEMA = vol.Schema({
vol.Required(const.ATTR_NODE_ID): vol.Coerce(int),
vol.Required(const.ATTR_VALUE_ID): vol.Coerce(int),
vol.Required(const.ATTR_NAME): cv.string,
vol.Optional(const.ATTR_UPDATE_IDS, default=False): cv.boolean,
})

SET_CONFIG_PARAMETER_SCHEMA = vol.Schema({
Expand Down Expand Up @@ -389,8 +391,7 @@ def _on_timeout(sec):
entity.node_id, sec)
hass.async_add_job(_add_node_to_component)

hass.add_job(check_has_unique_id, entity, _on_ready, _on_timeout,
hass.loop)
hass.add_job(check_has_unique_id, entity, _on_ready, _on_timeout)

def node_removed(node):
node_id = node.node_id
Expand Down Expand Up @@ -491,6 +492,7 @@ def stop_network(_service_or_event):
if hass.state == CoreState.running:
hass.bus.fire(const.EVENT_NETWORK_STOP)

@callback
def rename_node(service):
"""Rename a node."""
node_id = service.data.get(const.ATTR_NODE_ID)
Expand All @@ -499,7 +501,19 @@ def rename_node(service):
node.name = name
_LOGGER.info(
"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):
"""Rename a node value."""
node_id = service.data.get(const.ATTR_NODE_ID)
Expand All @@ -511,6 +525,10 @@ def rename_value(service):
_LOGGER.info(
"Renamed Z-Wave value (Node %d Value %d) to %s",
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):
"""Set the polling intensity of a node value."""
Expand Down Expand Up @@ -996,7 +1014,7 @@ async def discover_device(component, device):
self._hass.add_job(discover_device, component, device)
else:
self._hass.add_job(check_has_unique_id, device, _on_ready,
_on_timeout, self._hass.loop)
_on_timeout)


class ZWaveDeviceEntity(ZWaveBaseEntity):
Expand Down Expand Up @@ -1034,6 +1052,25 @@ def value_changed(self):
self.update_properties()
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):
"""Add device to dict."""
async_dispatcher_connect(
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/zwave/const.py
Expand Up @@ -19,6 +19,7 @@
ATTR_POLL_INTENSITY = "poll_intensity"
ATTR_VALUE_INDEX = "value_index"
ATTR_VALUE_INSTANCE = "value_instance"
ATTR_UPDATE_IDS = 'update_ids'
NETWORK_READY_WAIT_SECS = 300
NODE_READY_WAIT_SECS = 30

Expand Down
42 changes: 41 additions & 1 deletion homeassistant/components/zwave/node_entity.py
@@ -1,9 +1,13 @@
"""Entity class that represents Z-Wave node."""
import logging
from itertools import count

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.device_registry import (
async_get_registry as get_dev_reg)
from homeassistant.helpers.entity import Entity

from .const import (
Expand Down Expand Up @@ -192,6 +196,42 @@ def node_changed(self):

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):
"""Handle a node activated event on the network."""
if node.node_id == self.node.node_id:
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/zwave/services.yaml
Expand Up @@ -168,6 +168,9 @@ rename_node:
node_id:
description: ID of the node to rename.
example: 10
update_ids:
description: (optional) Rename the entity IDs for entities of this node.
example: True
name:
description: New Name
example: 'kitchen'
Expand All @@ -181,6 +184,9 @@ rename_value:
value_id:
description: ID of the value to rename.
example: 72037594255792737
update_ids:
description: (optional) Update the entity ID for this value's entity.
example: True
name:
description: New Name
example: 'Luminosity'
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/zwave/util.py
Expand Up @@ -74,7 +74,7 @@ def node_name(node):
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."""
start_time = dt_util.utcnow()
while True:
Expand All @@ -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.
timeout_callback(waited)
return
await asyncio.sleep(1, loop=loop)
await asyncio.sleep(1)


def is_node_parsed(node):
Expand Down
6 changes: 4 additions & 2 deletions homeassistant/helpers/device_registry.py
Expand Up @@ -136,11 +136,13 @@ def async_get_or_create(self, *, config_entry_id, connections=None,

@callback
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):
"""Update properties of a 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)

@callback
Expand Down

0 comments on commit 23dd644

Please sign in to comment.