-
-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Add support for ZHA door locks #2 #24344
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
Merged
Adminiuga
merged 9 commits into
home-assistant:dev
from
presslab-us:zha-implement-closure
Jun 7, 2019
Merged
Changes from 6 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
2be4bd7
Add support for DoorLock cluster
presslab-us 0268fe0
Add test for zha lock
presslab-us 33506ed
Change lock_state report to REPORT_CONFIG_IMMEDIATE
presslab-us 6ac908b
Update channel command wrapper to return the entire result
presslab-us 7dbc056
Fix tests
presslab-us 5986c99
Fix lint
presslab-us 93377a9
Update DoorLock test to work with updated zigpy schema
presslab-us 4d388bd
Fix lint
presslab-us 66579d8
Fix unlock test
presslab-us File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| """Locks on Zigbee Home Automation networks.""" | ||
| import logging | ||
|
|
||
| from zigpy.zcl.foundation import Status | ||
| from homeassistant.core import callback | ||
| from homeassistant.components.lock import ( | ||
| DOMAIN, STATE_UNLOCKED, STATE_LOCKED, LockDevice) | ||
| from homeassistant.helpers.dispatcher import async_dispatcher_connect | ||
| from .core.const import ( | ||
| DATA_ZHA, DATA_ZHA_DISPATCHERS, ZHA_DISCOVERY_NEW, DOORLOCK_CHANNEL, | ||
| SIGNAL_ATTR_UPDATED | ||
| ) | ||
| from .entity import ZhaEntity | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
| """ The first state is Zigbee 'Not fully locked' """ | ||
|
|
||
| STATE_LIST = [ | ||
| STATE_UNLOCKED, | ||
| STATE_LOCKED, | ||
| STATE_UNLOCKED | ||
| ] | ||
|
|
||
| VALUE_TO_STATE = {i: state for i, state in enumerate(STATE_LIST)} | ||
|
|
||
|
|
||
| async def async_setup_platform(hass, config, async_add_entities, | ||
| discovery_info=None): | ||
| """Old way of setting up Zigbee Home Automation locks.""" | ||
| pass | ||
|
|
||
|
|
||
| async def async_setup_entry(hass, config_entry, async_add_entities): | ||
| """Set up the Zigbee Home Automation Door Lock from config entry.""" | ||
| async def async_discover(discovery_info): | ||
| await _async_setup_entities(hass, config_entry, async_add_entities, | ||
| [discovery_info]) | ||
|
|
||
| unsub = async_dispatcher_connect( | ||
| hass, ZHA_DISCOVERY_NEW.format(DOMAIN), async_discover) | ||
| hass.data[DATA_ZHA][DATA_ZHA_DISPATCHERS].append(unsub) | ||
|
|
||
| locks = hass.data.get(DATA_ZHA, {}).get(DOMAIN) | ||
| if locks is not None: | ||
| await _async_setup_entities(hass, config_entry, async_add_entities, | ||
| locks.values()) | ||
| del hass.data[DATA_ZHA][DOMAIN] | ||
|
|
||
|
|
||
| async def _async_setup_entities(hass, config_entry, async_add_entities, | ||
| discovery_infos): | ||
| """Set up the ZHA locks.""" | ||
| entities = [] | ||
| for discovery_info in discovery_infos: | ||
| entities.append(ZhaDoorLock(**discovery_info)) | ||
|
|
||
| async_add_entities(entities, update_before_add=True) | ||
|
|
||
|
|
||
| class ZhaDoorLock(ZhaEntity, LockDevice): | ||
| """Representation of a ZHA lock.""" | ||
|
|
||
| _domain = DOMAIN | ||
|
|
||
| def __init__(self, unique_id, zha_device, channels, **kwargs): | ||
| """Init this sensor.""" | ||
| super().__init__(unique_id, zha_device, channels, **kwargs) | ||
| self._doorlock_channel = self.cluster_channels.get(DOORLOCK_CHANNEL) | ||
|
|
||
| async def async_added_to_hass(self): | ||
| """Run when about to be added to hass.""" | ||
| await super().async_added_to_hass() | ||
| await self.async_accept_signal( | ||
| self._doorlock_channel, SIGNAL_ATTR_UPDATED, self.async_set_state) | ||
|
|
||
| @callback | ||
| def async_restore_last_state(self, last_state): | ||
| """Restore previous state.""" | ||
| self._state = VALUE_TO_STATE.get(last_state.state, last_state.state) | ||
|
|
||
| @property | ||
| def is_locked(self) -> bool: | ||
| """Return true if entity is locked.""" | ||
| if self._state is None: | ||
| return False | ||
| return self._state == STATE_LOCKED | ||
|
|
||
| @property | ||
| def device_state_attributes(self): | ||
| """Return state attributes.""" | ||
| return self.state_attributes | ||
|
|
||
| async def async_lock(self, **kwargs): | ||
| """Lock the lock.""" | ||
| result = await self._doorlock_channel.lock_door() | ||
| if not isinstance(result, list) or result[0] is not Status.SUCCESS: | ||
| _LOGGER.error("Error with lock_door: %s", result) | ||
| return | ||
| self.async_schedule_update_ha_state() | ||
|
|
||
| async def async_unlock(self, **kwargs): | ||
| """Unlock the lock.""" | ||
| result = await self._doorlock_channel.unlock_door() | ||
| if not isinstance(result, list) or result[0] is not Status.SUCCESS: | ||
| _LOGGER.error("Error with unlock_door: %s", result) | ||
| return | ||
| self.async_schedule_update_ha_state() | ||
|
|
||
| async def async_update(self): | ||
| """Attempt to retrieve state from the lock.""" | ||
| await super().async_update() | ||
| await self.async_get_state() | ||
|
|
||
| def async_set_state(self, state): | ||
| """Handle state update from channel.""" | ||
| self._state = VALUE_TO_STATE.get(state, self._state) | ||
| self.async_schedule_update_ha_state() | ||
|
|
||
| async def async_get_state(self, from_cache=True): | ||
| """Attempt to retrieve state from the lock.""" | ||
| if self._doorlock_channel: | ||
| state = await self._doorlock_channel.get_attribute_value( | ||
| 'lock_state', from_cache=from_cache) | ||
| if state is not None: | ||
| self._state = VALUE_TO_STATE.get(state, self._state) | ||
|
|
||
| async def refresh(self, time): | ||
| """Call async_get_state at an interval.""" | ||
| await self.async_get_state(from_cache=False) | ||
|
|
||
| def debug(self, msg, *args): | ||
| """Log debug message.""" | ||
| _LOGGER.debug('%s: ' + msg, self.entity_id, *args) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.