forked from home-assistant/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
deCONZ - support for power plugs (home-assistant#15752)
* Initial commit for deCONZ switch support * Fix hound comment * Fix martins comment; platforms shouldn't depend on another platform * Fix existing tests * New tests * Clean up unnecessary methods * Bump requirement to v43 * Added device state attributes to light
- Loading branch information
Showing
9 changed files
with
212 additions
and
10 deletions.
There are no files selected for viewing
This file contains 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 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 |
---|---|---|
|
@@ -14,3 +14,5 @@ | |
|
||
ATTR_DARK = 'dark' | ||
ATTR_ON = 'on' | ||
|
||
SWITCH_TYPES = ["On/Off plug-in unit", "Smart plug"] |
This file contains 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 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,82 @@ | ||
""" | ||
Support for deCONZ switches. | ||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/switch.deconz/ | ||
""" | ||
from homeassistant.components.deconz.const import ( | ||
DOMAIN as DATA_DECONZ, DATA_DECONZ_ID, DATA_DECONZ_UNSUB, SWITCH_TYPES) | ||
from homeassistant.components.switch import SwitchDevice | ||
from homeassistant.core import callback | ||
from homeassistant.helpers.dispatcher import async_dispatcher_connect | ||
|
||
DEPENDENCIES = ['deconz'] | ||
|
||
|
||
async def async_setup_platform(hass, config, async_add_devices, | ||
discovery_info=None): | ||
"""Old way of setting up deCONZ switches.""" | ||
pass | ||
|
||
|
||
async def async_setup_entry(hass, config_entry, async_add_devices): | ||
"""Set up switches for deCONZ component. | ||
Switches are based same device class as lights in deCONZ. | ||
""" | ||
@callback | ||
def async_add_switch(lights): | ||
"""Add switch from deCONZ.""" | ||
entities = [] | ||
for light in lights: | ||
if light.type in SWITCH_TYPES: | ||
entities.append(DeconzSwitch(light)) | ||
async_add_devices(entities, True) | ||
|
||
hass.data[DATA_DECONZ_UNSUB].append( | ||
async_dispatcher_connect(hass, 'deconz_new_light', async_add_switch)) | ||
|
||
async_add_switch(hass.data[DATA_DECONZ].lights.values()) | ||
|
||
|
||
class DeconzSwitch(SwitchDevice): | ||
"""Representation of a deCONZ switch.""" | ||
|
||
def __init__(self, switch): | ||
"""Set up switch and add update callback to get data from websocket.""" | ||
self._switch = switch | ||
|
||
async def async_added_to_hass(self): | ||
"""Subscribe to switches events.""" | ||
self._switch.register_async_callback(self.async_update_callback) | ||
self.hass.data[DATA_DECONZ_ID][self.entity_id] = self._switch.deconz_id | ||
|
||
@callback | ||
def async_update_callback(self, reason): | ||
"""Update the switch's state.""" | ||
self.async_schedule_update_ha_state() | ||
|
||
@property | ||
def is_on(self): | ||
"""Return true if switch is on.""" | ||
return self._switch.state | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the switch.""" | ||
return self._switch.name | ||
|
||
@property | ||
def unique_id(self): | ||
"""Return a unique identifier for this switch.""" | ||
return self._switch.uniqueid | ||
|
||
async def async_turn_on(self, **kwargs): | ||
"""Turn on switch.""" | ||
data = {'on': True} | ||
await self._switch.async_set_state(data) | ||
|
||
async def async_turn_off(self, **kwargs): | ||
"""Turn off switch.""" | ||
data = {'on': False} | ||
await self._switch.async_set_state(data) |
This file contains 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 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 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 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 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,90 @@ | ||
"""deCONZ switch platform tests.""" | ||
from unittest.mock import Mock, patch | ||
|
||
from homeassistant import config_entries | ||
from homeassistant.components import deconz | ||
from homeassistant.components.deconz.const import SWITCH_TYPES | ||
from homeassistant.helpers.dispatcher import async_dispatcher_send | ||
|
||
from tests.common import mock_coro | ||
|
||
SUPPORTED_SWITCHES = { | ||
"1": { | ||
"id": "Switch 1 id", | ||
"name": "Switch 1 name", | ||
"type": "On/Off plug-in unit", | ||
"state": {} | ||
}, | ||
"2": { | ||
"id": "Switch 2 id", | ||
"name": "Switch 2 name", | ||
"type": "Smart plug", | ||
"state": {} | ||
} | ||
} | ||
|
||
UNSUPPORTED_SWITCH = { | ||
"1": { | ||
"id": "Switch id", | ||
"name": "Unsupported switch", | ||
"type": "Not a smart plug", | ||
"state": {} | ||
} | ||
} | ||
|
||
|
||
async def setup_bridge(hass, data): | ||
"""Load the deCONZ switch platform.""" | ||
from pydeconz import DeconzSession | ||
loop = Mock() | ||
session = Mock() | ||
entry = Mock() | ||
entry.data = {'host': '1.2.3.4', 'port': 80, 'api_key': '1234567890ABCDEF'} | ||
bridge = DeconzSession(loop, session, **entry.data) | ||
with patch('pydeconz.DeconzSession.async_get_state', | ||
return_value=mock_coro(data)): | ||
await bridge.async_load_parameters() | ||
hass.data[deconz.DOMAIN] = bridge | ||
hass.data[deconz.DATA_DECONZ_UNSUB] = [] | ||
hass.data[deconz.DATA_DECONZ_ID] = {} | ||
config_entry = config_entries.ConfigEntry( | ||
1, deconz.DOMAIN, 'Mock Title', {'host': 'mock-host'}, 'test') | ||
await hass.config_entries.async_forward_entry_setup(config_entry, 'switch') | ||
# To flush out the service call to update the group | ||
await hass.async_block_till_done() | ||
|
||
|
||
async def test_no_switches(hass): | ||
"""Test that no switch entities are created.""" | ||
data = {} | ||
await setup_bridge(hass, data) | ||
assert len(hass.data[deconz.DATA_DECONZ_ID]) == 0 | ||
assert len(hass.states.async_all()) == 0 | ||
|
||
|
||
async def test_switch(hass): | ||
"""Test that all supported switch entities and switch group are created.""" | ||
await setup_bridge(hass, {"lights": SUPPORTED_SWITCHES}) | ||
assert "switch.switch_1_name" in hass.data[deconz.DATA_DECONZ_ID] | ||
assert "switch.switch_2_name" in hass.data[deconz.DATA_DECONZ_ID] | ||
assert len(SUPPORTED_SWITCHES) == len(SWITCH_TYPES) | ||
assert len(hass.states.async_all()) == 3 | ||
|
||
|
||
async def test_add_new_switch(hass): | ||
"""Test successful creation of switch entity.""" | ||
data = {} | ||
await setup_bridge(hass, data) | ||
switch = Mock() | ||
switch.name = 'name' | ||
switch.type = "Smart plug" | ||
switch.register_async_callback = Mock() | ||
async_dispatcher_send(hass, 'deconz_new_light', [switch]) | ||
await hass.async_block_till_done() | ||
assert "switch.name" in hass.data[deconz.DATA_DECONZ_ID] | ||
|
||
|
||
async def test_unsupported_switch(hass): | ||
"""Test that unsupported switches are not created.""" | ||
await setup_bridge(hass, {"lights": UNSUPPORTED_SWITCH}) | ||
assert len(hass.states.async_all()) == 0 |