Template switch change flow / add restore (#6356)

* Template switch change flow / add restore

* fix tests

* fix binary_sensor template
This commit is contained in:
Pascal Vizeli 2017-03-02 14:09:53 +01:00 committed by GitHub
parent 597ae2e716
commit 55dc483c91
4 changed files with 128 additions and 12 deletions

View file

@ -16,7 +16,7 @@ from homeassistant.components.binary_sensor import (
from homeassistant.const import (
ATTR_FRIENDLY_NAME, ATTR_ENTITY_ID, CONF_VALUE_TEMPLATE,
CONF_SENSOR_CLASS, CONF_SENSORS, CONF_DEVICE_CLASS,
EVENT_HOMEASSISTANT_START)
EVENT_HOMEASSISTANT_START, STATE_ON)
from homeassistant.exceptions import TemplateError
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import get_deprecated
@ -92,7 +92,7 @@ class BinarySensorTemplate(BinarySensorDevice):
"""Register callbacks."""
state = yield from async_get_last_state(self.hass, self.entity_id)
if state:
self._state = state.state
self._state = state.state == STATE_ON
@callback
def template_bsensor_state_listener(entity, old_state, new_state):

View file

@ -14,12 +14,13 @@ from homeassistant.components.switch import (
ENTITY_ID_FORMAT, SwitchDevice, PLATFORM_SCHEMA)
from homeassistant.const import (
ATTR_FRIENDLY_NAME, CONF_VALUE_TEMPLATE, STATE_OFF, STATE_ON,
ATTR_ENTITY_ID, CONF_SWITCHES)
ATTR_ENTITY_ID, CONF_SWITCHES, EVENT_HOMEASSISTANT_START)
from homeassistant.exceptions import TemplateError
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.event import async_track_state_change
from homeassistant.helpers.restore_state import async_get_last_state
from homeassistant.helpers.script import Script
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
_VALID_STATES = [STATE_ON, STATE_OFF, 'true', 'false']
@ -88,14 +89,30 @@ class SwitchTemplate(SwitchDevice):
self._on_script = Script(hass, on_action)
self._off_script = Script(hass, off_action)
self._state = False
self._entities = entity_ids
@asyncio.coroutine
def async_added_to_hass(self):
"""Register callbacks."""
state = yield from async_get_last_state(self.hass, self.entity_id)
if state:
self._state = state.state == STATE_ON
@callback
def template_switch_state_listener(entity, old_state, new_state):
"""Called when the target device changes state."""
hass.async_add_job(self.async_update_ha_state(True))
self.hass.async_add_job(self.async_update_ha_state(True))
@callback
def template_switch_startup(event):
"""Update template on startup."""
async_track_state_change(
hass, entity_ids, template_switch_state_listener)
self.hass, self._entities, template_switch_state_listener)
self.hass.async_add_job(self.async_update_ha_state(True))
self.hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_START, template_switch_startup)
@property
def name(self):

View file

@ -39,6 +39,7 @@ class TestTemplateSensor:
})
self.hass.start()
self.hass.block_till_done()
state = self.hass.states.get('sensor.test_template_sensor')
assert state.state == 'It .'
@ -68,6 +69,7 @@ class TestTemplateSensor:
})
self.hass.start()
self.hass.block_till_done()
state = self.hass.states.get('sensor.test_template_sensor')
assert 'icon' not in state.attributes
@ -93,6 +95,7 @@ class TestTemplateSensor:
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_template_attribute_missing(self):
@ -111,6 +114,7 @@ class TestTemplateSensor:
})
self.hass.start()
self.hass.block_till_done()
state = self.hass.states.get('sensor.test_template_sensor')
assert state.state == 'unknown'
@ -131,6 +135,8 @@ class TestTemplateSensor:
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_invalid_sensor_does_not_create(self):
@ -146,6 +152,7 @@ class TestTemplateSensor:
})
self.hass.start()
assert self.hass.states.all() == []
def test_no_sensors_does_not_create(self):
@ -158,6 +165,8 @@ class TestTemplateSensor:
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_missing_template_does_not_create(self):
@ -176,6 +185,8 @@ class TestTemplateSensor:
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []

View file

@ -1,12 +1,14 @@
"""The tests for the Template switch platform."""
from homeassistant.core import callback
import asyncio
from homeassistant.core import callback, State, CoreState
import homeassistant.bootstrap as bootstrap
import homeassistant.components as core
from homeassistant.const import (
STATE_ON,
STATE_OFF)
from homeassistant.const import STATE_ON, STATE_OFF
from homeassistant.helpers.restore_state import DATA_RESTORE_CACHE
from tests.common import get_test_home_assistant, assert_setup_component
from tests.common import (
get_test_home_assistant, assert_setup_component, mock_component)
class TestTemplateSwitch:
@ -55,6 +57,9 @@ class TestTemplateSwitch:
}
})
self.hass.start()
self.hass.block_till_done()
state = self.hass.states.set('switch.test_state', STATE_ON)
self.hass.block_till_done()
@ -90,6 +95,9 @@ class TestTemplateSwitch:
}
})
self.hass.start()
self.hass.block_till_done()
state = self.hass.states.get('switch.test_template_switch')
assert state.state == STATE_ON
@ -116,6 +124,9 @@ class TestTemplateSwitch:
}
})
self.hass.start()
self.hass.block_till_done()
state = self.hass.states.get('switch.test_template_switch')
assert state.state == STATE_OFF
@ -141,6 +152,10 @@ class TestTemplateSwitch:
}
}
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_invalid_name_does_not_create(self):
@ -165,6 +180,10 @@ class TestTemplateSwitch:
}
}
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_invalid_switch_does_not_create(self):
@ -178,6 +197,10 @@ class TestTemplateSwitch:
}
}
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_no_switches_does_not_create(self):
@ -188,6 +211,10 @@ class TestTemplateSwitch:
'platform': 'template'
}
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_missing_template_does_not_create(self):
@ -212,6 +239,10 @@ class TestTemplateSwitch:
}
}
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_missing_on_does_not_create(self):
@ -236,6 +267,10 @@ class TestTemplateSwitch:
}
}
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_missing_off_does_not_create(self):
@ -260,6 +295,10 @@ class TestTemplateSwitch:
}
}
})
self.hass.start()
self.hass.block_till_done()
assert self.hass.states.all() == []
def test_on_action(self):
@ -282,6 +321,10 @@ class TestTemplateSwitch:
}
}
})
self.hass.start()
self.hass.block_till_done()
self.hass.states.set('switch.test_state', STATE_OFF)
self.hass.block_till_done()
@ -314,6 +357,10 @@ class TestTemplateSwitch:
}
}
})
self.hass.start()
self.hass.block_till_done()
self.hass.states.set('switch.test_state', STATE_ON)
self.hass.block_till_done()
@ -324,3 +371,44 @@ class TestTemplateSwitch:
self.hass.block_till_done()
assert len(self.calls) == 1
@asyncio.coroutine
def test_restore_state(hass):
"""Ensure states are restored on startup."""
hass.data[DATA_RESTORE_CACHE] = {
'switch.test_template_switch':
State('switch.test_template_switch', 'on'),
}
hass.state = CoreState.starting
mock_component(hass, 'recorder')
yield from bootstrap.async_setup_component(hass, 'switch', {
'switch': {
'platform': 'template',
'switches': {
'test_template_switch': {
'value_template':
"{{ states.switch.test_state.state }}",
'turn_on': {
'service': 'switch.turn_on',
'entity_id': 'switch.test_state'
},
'turn_off': {
'service': 'switch.turn_off',
'entity_id': 'switch.test_state'
},
}
}
}
})
state = hass.states.get('switch.test_template_switch')
assert state.state == 'on'
yield from hass.async_start()
yield from hass.async_block_till_done()
state = hass.states.get('switch.test_template_switch')
assert state.state == 'unavailable'