mirror of
https://github.com/home-assistant/core.git
synced 2025-04-22 16:27:56 +00:00
Align switch group handling with light. (#7577)
This commit is contained in:
parent
2b70b1881a
commit
d472d81538
@ -9,8 +9,10 @@ import logging
|
||||
|
||||
from homeassistant.components.rflink import (
|
||||
CONF_ALIASSES, CONF_DEVICE_DEFAULTS, CONF_DEVICES, CONF_FIRE_EVENT,
|
||||
CONF_SIGNAL_REPETITIONS, DATA_ENTITY_LOOKUP, DEVICE_DEFAULTS_SCHEMA,
|
||||
DOMAIN, EVENT_KEY_COMMAND, SwitchableRflinkDevice, cv, vol)
|
||||
CONF_GROUP, CONF_GROUP_ALIASSES, CONF_NOGROUP_ALIASSES,
|
||||
CONF_SIGNAL_REPETITIONS, DATA_ENTITY_GROUP_LOOKUP, DATA_ENTITY_LOOKUP,
|
||||
DEVICE_DEFAULTS_SCHEMA, DOMAIN, EVENT_KEY_COMMAND, SwitchableRflinkDevice,
|
||||
cv, vol)
|
||||
from homeassistant.components.switch import SwitchDevice
|
||||
from homeassistant.const import CONF_NAME, CONF_PLATFORM
|
||||
|
||||
@ -27,8 +29,13 @@ PLATFORM_SCHEMA = vol.Schema({
|
||||
vol.Optional(CONF_NAME): cv.string,
|
||||
vol.Optional(CONF_ALIASSES, default=[]):
|
||||
vol.All(cv.ensure_list, [cv.string]),
|
||||
vol.Optional(CONF_GROUP_ALIASSES, default=[]):
|
||||
vol.All(cv.ensure_list, [cv.string]),
|
||||
vol.Optional(CONF_NOGROUP_ALIASSES, default=[]):
|
||||
vol.All(cv.ensure_list, [cv.string]),
|
||||
vol.Optional(CONF_FIRE_EVENT, default=False): cv.boolean,
|
||||
vol.Optional(CONF_SIGNAL_REPETITIONS): vol.Coerce(int),
|
||||
vol.Optional(CONF_GROUP, default=True): cv.boolean,
|
||||
},
|
||||
}),
|
||||
})
|
||||
@ -43,9 +50,26 @@ def devices_from_config(domain_config, hass=None):
|
||||
devices.append(device)
|
||||
|
||||
# Register entity (and aliasses) to listen to incoming rflink events
|
||||
for _id in config[CONF_ALIASSES] + [device_id]:
|
||||
# Device id and normal aliasses respond to normal and group command
|
||||
hass.data[DATA_ENTITY_LOOKUP][
|
||||
EVENT_KEY_COMMAND][device_id].append(device)
|
||||
if config[CONF_GROUP]:
|
||||
hass.data[DATA_ENTITY_GROUP_LOOKUP][
|
||||
EVENT_KEY_COMMAND][device_id].append(device)
|
||||
for _id in config[CONF_ALIASSES]:
|
||||
hass.data[DATA_ENTITY_LOOKUP][
|
||||
EVENT_KEY_COMMAND][_id].append(device)
|
||||
hass.data[DATA_ENTITY_GROUP_LOOKUP][
|
||||
EVENT_KEY_COMMAND][_id].append(device)
|
||||
# group_aliasses only respond to group commands
|
||||
for _id in config[CONF_GROUP_ALIASSES]:
|
||||
hass.data[DATA_ENTITY_GROUP_LOOKUP][
|
||||
EVENT_KEY_COMMAND][_id].append(device)
|
||||
# nogroup_aliasses only respond to normal commands
|
||||
for _id in config[CONF_NOGROUP_ALIASSES]:
|
||||
hass.data[DATA_ENTITY_LOOKUP][
|
||||
EVENT_KEY_COMMAND][_id].append(device)
|
||||
|
||||
return devices
|
||||
|
||||
|
||||
|
@ -53,7 +53,7 @@ def test_default_setup(hass, monkeypatch):
|
||||
assert create.call_args_list[0][1]['ignore']
|
||||
|
||||
# test default state of light loaded from config
|
||||
light_initial = hass.states.get('light.test')
|
||||
light_initial = hass.states.get(DOMAIN + '.test')
|
||||
assert light_initial.state == 'off'
|
||||
assert light_initial.attributes['assumed_state']
|
||||
|
||||
@ -67,7 +67,7 @@ def test_default_setup(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
light_after_first_command = hass.states.get('light.test')
|
||||
light_after_first_command = hass.states.get(DOMAIN + '.test')
|
||||
assert light_after_first_command.state == 'on'
|
||||
# also after receiving first command state not longer has to be assumed
|
||||
assert 'assumed_state' not in light_after_first_command.attributes
|
||||
@ -79,7 +79,7 @@ def test_default_setup(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('light.test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# should repond to group command
|
||||
event_callback({
|
||||
@ -88,7 +88,7 @@ def test_default_setup(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
light_after_first_command = hass.states.get('light.test')
|
||||
light_after_first_command = hass.states.get(DOMAIN + '.test')
|
||||
assert light_after_first_command.state == 'on'
|
||||
|
||||
# should repond to group command
|
||||
@ -98,7 +98,7 @@ def test_default_setup(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('light.test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test following aliasses
|
||||
# mock incoming command event for this device alias
|
||||
@ -108,7 +108,7 @@ def test_default_setup(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('light.test').state == 'on'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
|
||||
# test event for new unconfigured sensor
|
||||
event_callback({
|
||||
@ -117,22 +117,22 @@ def test_default_setup(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('light.protocol2_0_1').state == 'on'
|
||||
assert hass.states.get(DOMAIN + '.protocol2_0_1').state == 'on'
|
||||
|
||||
# test changing state from HA propagates to Rflink
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: 'light.test'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test'}))
|
||||
yield from hass.async_block_till_done()
|
||||
assert hass.states.get('light.test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
assert protocol.send_command_ack.call_args_list[0][0][0] == 'protocol_0_0'
|
||||
assert protocol.send_command_ack.call_args_list[0][0][1] == 'off'
|
||||
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: 'light.test'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test'}))
|
||||
yield from hass.async_block_till_done()
|
||||
assert hass.states.get('light.test').state == 'on'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
assert protocol.send_command_ack.call_args_list[1][0][1] == 'on'
|
||||
|
||||
# protocols supporting dimming and on/off should create hybrid light entity
|
||||
@ -143,7 +143,7 @@ def test_default_setup(hass, monkeypatch):
|
||||
yield from hass.async_block_till_done()
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: 'light.newkaku_0_1'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.newkaku_0_1'}))
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
# dimmable should send highest dim level when turning on
|
||||
@ -155,7 +155,7 @@ def test_default_setup(hass, monkeypatch):
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_ON,
|
||||
{
|
||||
ATTR_ENTITY_ID: 'light.newkaku_0_1',
|
||||
ATTR_ENTITY_ID: DOMAIN + '.newkaku_0_1',
|
||||
ATTR_BRIGHTNESS: 128,
|
||||
}))
|
||||
yield from hass.async_block_till_done()
|
||||
@ -165,7 +165,7 @@ def test_default_setup(hass, monkeypatch):
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_ON,
|
||||
{
|
||||
ATTR_ENTITY_ID: 'light.dim_test',
|
||||
ATTR_ENTITY_ID: DOMAIN + '.dim_test',
|
||||
ATTR_BRIGHTNESS: 128,
|
||||
}))
|
||||
yield from hass.async_block_till_done()
|
||||
@ -210,7 +210,7 @@ def test_firing_bus_event(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert calls[0].data == {'state': 'off', 'entity_id': 'light.test'}
|
||||
assert calls[0].data == {'state': 'off', 'entity_id': DOMAIN + '.test'}
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
@ -247,7 +247,7 @@ def test_signal_repetitions(hass, monkeypatch):
|
||||
# test if signal repetition is performed according to configuration
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: 'light.test'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test'}))
|
||||
|
||||
# wait for commands and repetitions to finish
|
||||
yield from hass.async_block_till_done()
|
||||
@ -257,7 +257,7 @@ def test_signal_repetitions(hass, monkeypatch):
|
||||
# test if default apply to configured devcies
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: 'light.test1'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test1'}))
|
||||
|
||||
# wait for commands and repetitions to finish
|
||||
yield from hass.async_block_till_done()
|
||||
@ -275,7 +275,7 @@ def test_signal_repetitions(hass, monkeypatch):
|
||||
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: 'light.protocol_0_2'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.protocol_0_2'}))
|
||||
|
||||
# wait for commands and repetitions to finish
|
||||
yield from hass.async_block_till_done()
|
||||
@ -311,10 +311,10 @@ def test_signal_repetitions_alternation(hass, monkeypatch):
|
||||
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: 'light.test'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test'}))
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: 'light.test1'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test1'}))
|
||||
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
@ -348,11 +348,11 @@ def test_signal_repetitions_cancelling(hass, monkeypatch):
|
||||
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: 'light.test'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test'}))
|
||||
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: 'light.test'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test'}))
|
||||
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
@ -385,7 +385,7 @@ def test_type_toggle(hass, monkeypatch):
|
||||
event_callback, _, _, _ = yield from mock_rflink(
|
||||
hass, config, DOMAIN, monkeypatch)
|
||||
|
||||
assert hass.states.get('light.toggle_test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.toggle_test').state == 'off'
|
||||
|
||||
# test sending on command to toggle alias
|
||||
event_callback({
|
||||
@ -394,7 +394,7 @@ def test_type_toggle(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('light.toggle_test').state == 'on'
|
||||
assert hass.states.get(DOMAIN + '.toggle_test').state == 'on'
|
||||
|
||||
# test sending group command to group alias
|
||||
event_callback({
|
||||
@ -403,7 +403,7 @@ def test_type_toggle(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('light.toggle_test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.toggle_test').state == 'off'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
@ -428,7 +428,7 @@ def test_group_alias(hass, monkeypatch):
|
||||
event_callback, _, _, _ = yield from mock_rflink(
|
||||
hass, config, DOMAIN, monkeypatch)
|
||||
|
||||
assert hass.states.get('light.test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to group alias
|
||||
event_callback({
|
||||
@ -437,7 +437,7 @@ def test_group_alias(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('light.test').state == 'on'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
|
||||
# test sending group command to group alias
|
||||
event_callback({
|
||||
@ -446,7 +446,7 @@ def test_group_alias(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get('light.test').state == 'on'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
@ -471,7 +471,7 @@ def test_nogroup_alias(hass, monkeypatch):
|
||||
event_callback, _, _, _ = yield from mock_rflink(
|
||||
hass, config, DOMAIN, monkeypatch)
|
||||
|
||||
assert hass.states.get('light.test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to nogroup alias
|
||||
event_callback({
|
||||
@ -480,7 +480,7 @@ def test_nogroup_alias(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
# should not affect state
|
||||
assert hass.states.get('light.test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to nogroup alias
|
||||
event_callback({
|
||||
@ -489,7 +489,7 @@ def test_nogroup_alias(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
# should affect state
|
||||
assert hass.states.get('light.test').state == 'on'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
@ -514,7 +514,7 @@ def test_nogroup_device_id(hass, monkeypatch):
|
||||
event_callback, _, _, _ = yield from mock_rflink(
|
||||
hass, config, DOMAIN, monkeypatch)
|
||||
|
||||
assert hass.states.get('light.test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to nogroup
|
||||
event_callback({
|
||||
@ -523,7 +523,7 @@ def test_nogroup_device_id(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
# should not affect state
|
||||
assert hass.states.get('light.test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to nogroup
|
||||
event_callback({
|
||||
@ -532,7 +532,7 @@ def test_nogroup_device_id(hass, monkeypatch):
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
# should affect state
|
||||
assert hass.states.get('light.test').state == 'on'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
@ -560,4 +560,4 @@ def test_disable_automatic_add(hass, monkeypatch):
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
# make sure new device is not added
|
||||
assert not hass.states.get('light.protocol_0_0')
|
||||
assert not hass.states.get(DOMAIN + '.protocol_0_0')
|
||||
|
@ -86,15 +86,144 @@ def test_default_setup(hass, monkeypatch):
|
||||
# test changing state from HA propagates to Rflink
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: 'switch.test'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test'}))
|
||||
yield from hass.async_block_till_done()
|
||||
assert hass.states.get('switch.test').state == 'off'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
assert protocol.send_command_ack.call_args_list[0][0][0] == 'protocol_0_0'
|
||||
assert protocol.send_command_ack.call_args_list[0][0][1] == 'off'
|
||||
|
||||
hass.async_add_job(
|
||||
hass.services.async_call(DOMAIN, SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: 'switch.test'}))
|
||||
{ATTR_ENTITY_ID: DOMAIN + '.test'}))
|
||||
yield from hass.async_block_till_done()
|
||||
assert hass.states.get('switch.test').state == 'on'
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
assert protocol.send_command_ack.call_args_list[1][0][1] == 'on'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_group_alias(hass, monkeypatch):
|
||||
"""Group aliases should only respond to group commands (allon/alloff)."""
|
||||
config = {
|
||||
'rflink': {
|
||||
'port': '/dev/ttyABC0',
|
||||
},
|
||||
DOMAIN: {
|
||||
'platform': 'rflink',
|
||||
'devices': {
|
||||
'protocol_0_0': {
|
||||
'name': 'test',
|
||||
'group_aliasses': ['test_group_0_0'],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# setup mocking rflink module
|
||||
event_callback, _, _, _ = yield from mock_rflink(
|
||||
hass, config, DOMAIN, monkeypatch)
|
||||
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to group alias
|
||||
event_callback({
|
||||
'id': 'test_group_0_0',
|
||||
'command': 'allon',
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
|
||||
# test sending group command to group alias
|
||||
event_callback({
|
||||
'id': 'test_group_0_0',
|
||||
'command': 'off',
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_nogroup_alias(hass, monkeypatch):
|
||||
"""Non group aliases should not respond to group commands."""
|
||||
config = {
|
||||
'rflink': {
|
||||
'port': '/dev/ttyABC0',
|
||||
},
|
||||
DOMAIN: {
|
||||
'platform': 'rflink',
|
||||
'devices': {
|
||||
'protocol_0_0': {
|
||||
'name': 'test',
|
||||
'nogroup_aliasses': ['test_nogroup_0_0'],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# setup mocking rflink module
|
||||
event_callback, _, _, _ = yield from mock_rflink(
|
||||
hass, config, DOMAIN, monkeypatch)
|
||||
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to nogroup alias
|
||||
event_callback({
|
||||
'id': 'test_nogroup_0_0',
|
||||
'command': 'allon',
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
# should not affect state
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to nogroup alias
|
||||
event_callback({
|
||||
'id': 'test_nogroup_0_0',
|
||||
'command': 'on',
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
# should affect state
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_nogroup_device_id(hass, monkeypatch):
|
||||
"""Device id that do not respond to group commands (allon/alloff)."""
|
||||
config = {
|
||||
'rflink': {
|
||||
'port': '/dev/ttyABC0',
|
||||
},
|
||||
DOMAIN: {
|
||||
'platform': 'rflink',
|
||||
'devices': {
|
||||
'test_nogroup_0_0': {
|
||||
'name': 'test',
|
||||
'group': False,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# setup mocking rflink module
|
||||
event_callback, _, _, _ = yield from mock_rflink(
|
||||
hass, config, DOMAIN, monkeypatch)
|
||||
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to nogroup
|
||||
event_callback({
|
||||
'id': 'test_nogroup_0_0',
|
||||
'command': 'allon',
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
# should not affect state
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'off'
|
||||
|
||||
# test sending group command to nogroup
|
||||
event_callback({
|
||||
'id': 'test_nogroup_0_0',
|
||||
'command': 'on',
|
||||
})
|
||||
yield from hass.async_block_till_done()
|
||||
# should affect state
|
||||
assert hass.states.get(DOMAIN + '.test').state == 'on'
|
||||
|
Loading…
x
Reference in New Issue
Block a user