Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zha: Add remove service #11683

Merged
merged 2 commits into from
Feb 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions homeassistant/components/zha/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
https://home-assistant.io/components/zha/
"""
import asyncio
import collections
import enum
import logging

Expand Down Expand Up @@ -55,13 +56,18 @@ class RadioType(enum.Enum):
}, extra=vol.ALLOW_EXTRA)

ATTR_DURATION = 'duration'
ATTR_IEEE = 'ieee_address'

SERVICE_PERMIT = 'permit'
SERVICE_REMOVE = 'remove'
SERVICE_SCHEMAS = {
SERVICE_PERMIT: vol.Schema({
vol.Optional(ATTR_DURATION, default=60):
vol.All(vol.Coerce(int), vol.Range(1, 254)),
}),
SERVICE_REMOVE: vol.Schema({
vol.Required(ATTR_IEEE): cv.string,
}),
}


Expand Down Expand Up @@ -116,6 +122,18 @@ def permit(service):
hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit,
schema=SERVICE_SCHEMAS[SERVICE_PERMIT])

@asyncio.coroutine
def remove(service):
"""Remove a node from the network."""
from bellows.types import EmberEUI64, uint8_t
ieee = service.data.get(ATTR_IEEE)
ieee = EmberEUI64([uint8_t(p, base=16) for p in ieee.split(':')])
_LOGGER.info("Removing node %s", ieee)
yield from APPLICATION_CONTROLLER.remove(ieee)

hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove,
schema=SERVICE_SCHEMAS[SERVICE_REMOVE])

return True


Expand All @@ -126,6 +144,7 @@ def __init__(self, hass, config):
"""Initialize the listener."""
self._hass = hass
self._config = config
self._device_registry = collections.defaultdict(list)
hass.data[DISCOVERY_KEY] = hass.data.get(DISCOVERY_KEY, {})

def device_joined(self, device):
Expand All @@ -147,7 +166,8 @@ def device_left(self, device):

def device_removed(self, device):
"""Handle device being removed from the network."""
pass
for device_entity in self._device_registry[device.ieee]:
self._hass.async_add_job(device_entity.async_remove())

@asyncio.coroutine
def async_device_initialized(self, device, join):
Expand Down Expand Up @@ -189,6 +209,7 @@ def async_device_initialized(self, device, join):
for c in profile_clusters[1]
if c in endpoint.out_clusters]
discovery_info = {
'application_listener': self,
'endpoint': endpoint,
'in_clusters': {c.cluster_id: c for c in in_clusters},
'out_clusters': {c.cluster_id: c for c in out_clusters},
Expand All @@ -214,6 +235,7 @@ def async_device_initialized(self, device, join):

component = zha_const.SINGLE_CLUSTER_DEVICE_CLASS[cluster_type]
discovery_info = {
'application_listener': self,
'endpoint': endpoint,
'in_clusters': {cluster.cluster_id: cluster},
'out_clusters': {},
Expand All @@ -231,19 +253,22 @@ def async_device_initialized(self, device, join):
self._config,
)

def register_entity(self, ieee, entity_obj):
"""Record the creation of a hass entity associated with ieee."""
self._device_registry[ieee].append(entity_obj)


class Entity(entity.Entity):
"""A base class for ZHA entities."""

_domain = None # Must be overridden by subclasses

def __init__(self, endpoint, in_clusters, out_clusters, manufacturer,
model, **kwargs):
model, application_listener, **kwargs):
"""Init ZHA entity."""
self._device_state_attributes = {}
ieeetail = ''.join([
'%02x' % (o, ) for o in endpoint.device.ieee[-4:]
])
ieee = endpoint.device.ieee
ieeetail = ''.join(['%02x' % (o, ) for o in ieee[-4:]])
if manufacturer and model is not None:
self.entity_id = '%s.%s_%s_%s_%s' % (
self._domain,
Expand Down Expand Up @@ -271,6 +296,8 @@ def __init__(self, endpoint, in_clusters, out_clusters, manufacturer,
self._out_clusters = out_clusters
self._state = ha_const.STATE_UNKNOWN

application_listener.register_entity(ieee, self)

def attribute_updated(self, attribute, value):
"""Handle an attribute updated on this cluster."""
pass
Expand Down
7 changes: 7 additions & 0 deletions homeassistant/components/zha/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@ permit:
duration:
description: Time to permit joins, in seconds
example: 60

remove:
description: Remove a node from the ZigBee network.
fields:
ieee_address:
description: IEEE address of the node to remove
example: "00:0d:6f:00:05:7d:2d:34"