mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +00:00
commit
18f27d2e45
@ -139,3 +139,12 @@ script:
|
||||
execute_service: light.turn_on
|
||||
service_data:
|
||||
entity_id: group.living_room
|
||||
|
||||
scene:
|
||||
- name: Romantic
|
||||
entities:
|
||||
light.tv_back_light: on
|
||||
light.ceiling:
|
||||
state: on
|
||||
color: [0.33, 0.66]
|
||||
brightness: 200
|
||||
|
@ -10,7 +10,7 @@ import threading
|
||||
import json
|
||||
|
||||
import homeassistant as ha
|
||||
from homeassistant.helpers import TrackStates
|
||||
from homeassistant.helpers.state import TrackStates
|
||||
import homeassistant.remote as rem
|
||||
from homeassistant.const import (
|
||||
URL_API, URL_API_STATES, URL_API_EVENTS, URL_API_SERVICES, URL_API_STREAM,
|
||||
|
@ -1,2 +1,2 @@
|
||||
""" DO NOT MODIFY. Auto-generated by build_frontend script """
|
||||
VERSION = "da527496648e2c85d7a5f8c261c18466"
|
||||
VERSION = "1d8b14c387123a4b42fec6b8f9346675"
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
Subproject commit 642a83e437fed356db3e13d5a5b0c28d4b3fb713
|
||||
Subproject commit e048bf6ece91983b9f03aafeb414ae5c535288a2
|
@ -81,10 +81,13 @@
|
||||
<core-icon icon="apps"></core-icon>
|
||||
States
|
||||
</paper-item>
|
||||
<paper-item data-panel="group">
|
||||
<core-icon icon="homeassistant-24:group"></core-icon>
|
||||
Groups
|
||||
</paper-item>
|
||||
|
||||
<template repeat="{{activeFilters as filter}}">
|
||||
<paper-item data-panel="states_{{filter}}">
|
||||
<core-icon icon="{{filter | filterIcon}}"></core-icon>
|
||||
{{filter | filterName}}
|
||||
</paper-item>
|
||||
</template>
|
||||
|
||||
<template if="{{hasHistoryComponent}}">
|
||||
<paper-item data-panel="history">
|
||||
@ -93,13 +96,6 @@
|
||||
</paper-item>
|
||||
</template>
|
||||
|
||||
<template if="{{hasScriptComponent}}">
|
||||
<paper-item data-panel="script">
|
||||
<core-icon icon="description"></core-icon>
|
||||
Scripts
|
||||
</paper-item>
|
||||
</template>
|
||||
|
||||
<div flex></div>
|
||||
|
||||
<paper-item on-click="{{handleLogOutClick}}">
|
||||
@ -134,7 +130,7 @@
|
||||
<partial-states hidden?="{{hideStates}}"
|
||||
main narrow="{{narrow}}"
|
||||
togglePanel="{{togglePanel}}"
|
||||
filter="{{selected}}">
|
||||
filter="{{stateFilter}}">
|
||||
</partial-states>
|
||||
|
||||
<template if="{{selected == 'history'}}">
|
||||
@ -153,14 +149,18 @@
|
||||
|
||||
</template>
|
||||
<script>
|
||||
(function() {
|
||||
var storeListenerMixIn = window.hass.storeListenerMixIn;
|
||||
var authActions = window.hass.authActions;
|
||||
var uiUtil = window.hass.uiUtil;
|
||||
var uiConstants = window.hass.uiConstants;
|
||||
|
||||
Polymer(Polymer.mixin({
|
||||
selected: "states",
|
||||
stateFilter: null,
|
||||
narrow: false,
|
||||
activeFilters: [],
|
||||
hasHistoryComponent: false,
|
||||
hasScriptComponent: false,
|
||||
|
||||
isStreaming: false,
|
||||
hasStreamError: false,
|
||||
@ -177,6 +177,12 @@ Polymer(Polymer.mixin({
|
||||
this.stopListeningToStores();
|
||||
},
|
||||
|
||||
stateStoreChanged: function(stateStore) {
|
||||
this.activeFilters = stateStore.domains.filter(function(domain) {
|
||||
return domain in uiConstants.STATE_FILTERS;
|
||||
}).toArray();
|
||||
},
|
||||
|
||||
componentStoreChanged: function(componentStore) {
|
||||
this.hasHistoryComponent = componentStore.isLoaded('history');
|
||||
this.hasScriptComponent = componentStore.isLoaded('script');
|
||||
@ -205,14 +211,13 @@ Polymer(Polymer.mixin({
|
||||
this.togglePanel();
|
||||
this.selected = newChoice;
|
||||
}
|
||||
switch(this.selected) {
|
||||
case 'states':
|
||||
case 'group':
|
||||
case 'script':
|
||||
hideStates = false;
|
||||
break;
|
||||
default:
|
||||
hideStates = true;
|
||||
|
||||
if (this.selected.substr(0, 7) === 'states_') {
|
||||
this.hideStates = false;
|
||||
this.stateFilter = this.selected.substr(7);
|
||||
} else {
|
||||
this.hideStates = this.selected !== 'states';
|
||||
this.stateFilter = null;
|
||||
}
|
||||
},
|
||||
|
||||
@ -227,6 +232,15 @@ Polymer(Polymer.mixin({
|
||||
handleLogOutClick: function() {
|
||||
authActions.logOut();
|
||||
},
|
||||
|
||||
filterIcon: function(filter) {
|
||||
return uiUtil.domainIcon(filter);
|
||||
},
|
||||
|
||||
filterName: function(filter) {
|
||||
return uiConstants.STATE_FILTERS[filter];
|
||||
},
|
||||
}, storeListenerMixIn));
|
||||
})();
|
||||
</script>
|
||||
</polymer-element>
|
||||
|
@ -64,16 +64,12 @@
|
||||
</partial-base>
|
||||
</template>
|
||||
<script>
|
||||
(function(){
|
||||
var storeListenerMixIn = window.hass.storeListenerMixIn;
|
||||
var syncActions = window.hass.syncActions;
|
||||
var voiceActions = window.hass.voiceActions;
|
||||
var stateStore = window.hass.stateStore;
|
||||
|
||||
var stateGroupFilter = function(state) { return state.domain === 'group'; };
|
||||
var stateScriptFilter = function(state) { return state.domain === 'script'; };
|
||||
var stateFilter = function(state) {
|
||||
return !stateGroupFilter(state) && !stateScriptFilter(state);
|
||||
};
|
||||
var uiConstants = window.hass.uiConstants;
|
||||
|
||||
Polymer(Polymer.mixin({
|
||||
headerTitle: "States",
|
||||
@ -123,36 +119,30 @@
|
||||
this.isTransmitting = voiceStore.isTransmitting;
|
||||
this.finalTranscript = voiceStore.finalTranscript;
|
||||
this.interimTranscript = voiceStore.interimTranscript.slice(
|
||||
this.finalTranscript.length)
|
||||
this.finalTranscript.length);
|
||||
},
|
||||
|
||||
filterChanged: function() {
|
||||
this.refreshStates();
|
||||
|
||||
switch (this.filter) {
|
||||
case "group":
|
||||
this.headerTitle = "Groups";
|
||||
break;
|
||||
|
||||
case "script":
|
||||
this.headerTitle = "Scripts";
|
||||
break;
|
||||
|
||||
default:
|
||||
this.headerTitle = "States";
|
||||
break;
|
||||
}
|
||||
this.headerTitle = uiConstants.STATE_FILTERS[this.filter] || 'States';
|
||||
},
|
||||
|
||||
refreshStates: function() {
|
||||
var states = stateStore.all;
|
||||
var states;
|
||||
|
||||
if (this.filter) {
|
||||
var filter = this.filter;
|
||||
states = stateStore.all.filter(function(state) {
|
||||
console.log(state, state.domain, filter);
|
||||
return state.domain === filter;
|
||||
});
|
||||
|
||||
if (this.filter == 'group') {
|
||||
states = states.filter(stateGroupFilter);
|
||||
} else if (this.filter == 'script') {
|
||||
states = states.filter(stateScriptFilter);
|
||||
} else {
|
||||
states = states.filter(stateFilter);
|
||||
// all but the STATE_FILTER keys
|
||||
states = stateStore.all.filter(function(state) {
|
||||
return !(state.domain in uiConstants.STATE_FILTERS);
|
||||
});
|
||||
}
|
||||
|
||||
this.states = states.toArray();
|
||||
@ -170,5 +160,6 @@
|
||||
}
|
||||
},
|
||||
}, storeListenerMixIn));
|
||||
})();
|
||||
</script>
|
||||
</polymer>
|
||||
|
@ -84,6 +84,9 @@ window.hass.uiUtil.domainIcon = function(domain, state) {
|
||||
case "script":
|
||||
return "description";
|
||||
|
||||
case 'scene':
|
||||
return 'social:pages';
|
||||
|
||||
default:
|
||||
return "bookmark-outline";
|
||||
}
|
||||
|
@ -51,9 +51,17 @@
|
||||
preferenceStore = window.hass.preferenceStore,
|
||||
authActions = window.hass.authActions;
|
||||
|
||||
window.hass.uiActions = {
|
||||
window.hass.uiConstants = {
|
||||
ACTION_SHOW_DIALOG_MORE_INFO: 'ACTION_SHOW_DIALOG_MORE_INFO',
|
||||
|
||||
STATE_FILTERS: {
|
||||
'group': 'Groups',
|
||||
'script': 'Scripts',
|
||||
'scene': 'Scenes',
|
||||
},
|
||||
};
|
||||
|
||||
window.hass.uiActions = {
|
||||
showMoreInfoDialog: function(entityId) {
|
||||
dispatcher.dispatch({
|
||||
actionType: this.ACTION_SHOW_DIALOG_MORE_INFO,
|
||||
@ -70,6 +78,6 @@
|
||||
};
|
||||
|
||||
// UI specific util methods
|
||||
window.hass.uiUtil = {}
|
||||
window.hass.uiUtil = {};
|
||||
})();
|
||||
</script>
|
||||
|
183
homeassistant/components/scene.py
Normal file
183
homeassistant/components/scene.py
Normal file
@ -0,0 +1,183 @@
|
||||
"""
|
||||
homeassistant.components.scene
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Allows users to set and activate scenes within Home Assistant.
|
||||
|
||||
A scene is a set of states that describe how you want certain entities to be.
|
||||
For example, light A should be red with 100 brightness. Light B should be on.
|
||||
|
||||
A scene is active if all states of the scene match the real states.
|
||||
|
||||
If a scene is manually activated it will store the previous state of the
|
||||
entities. These will be restored when the state is deactivated manually.
|
||||
|
||||
If one of the enties that are being tracked change state on its own, the
|
||||
old state will not be restored when it is being deactivated.
|
||||
"""
|
||||
import logging
|
||||
from collections import namedtuple
|
||||
|
||||
from homeassistant import State
|
||||
from homeassistant.helpers.device import ToggleDevice
|
||||
from homeassistant.helpers.device_component import DeviceComponent
|
||||
from homeassistant.helpers.state import reproduce_state
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID, STATE_OFF, STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF)
|
||||
|
||||
DOMAIN = 'scene'
|
||||
DEPENDENCIES = ['group']
|
||||
|
||||
ATTR_ACTIVE_REQUESTED = "active_requested"
|
||||
|
||||
CONF_ENTITIES = "entities"
|
||||
|
||||
SceneConfig = namedtuple('SceneConfig', ['name', 'states'])
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
""" Sets up scenes. """
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
scene_configs = config.get(DOMAIN)
|
||||
|
||||
if not isinstance(scene_configs, list):
|
||||
logger.error('Scene config should be a list of scenes')
|
||||
return False
|
||||
|
||||
component = DeviceComponent(logger, DOMAIN, hass)
|
||||
|
||||
component.add_devices(Scene(hass, _process_config(scene_config))
|
||||
for scene_config in scene_configs)
|
||||
|
||||
def handle_scene_service(service):
|
||||
""" Handles calls to the switch services. """
|
||||
target_scenes = component.extract_from_service(service)
|
||||
|
||||
for scene in target_scenes:
|
||||
if service.service == SERVICE_TURN_ON:
|
||||
scene.turn_on()
|
||||
else:
|
||||
scene.turn_off()
|
||||
|
||||
scene.update_ha_state(True)
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_scene_service)
|
||||
hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_scene_service)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _process_config(scene_config):
|
||||
""" Process passed in config into a format to work with. """
|
||||
name = scene_config.get('name')
|
||||
states = {}
|
||||
c_entities = dict(scene_config.get(CONF_ENTITIES, {}))
|
||||
|
||||
for entity_id in c_entities:
|
||||
if isinstance(c_entities[entity_id], dict):
|
||||
state = c_entities[entity_id].pop('state', None)
|
||||
attributes = c_entities[entity_id]
|
||||
else:
|
||||
state = c_entities[entity_id]
|
||||
attributes = {}
|
||||
|
||||
# YAML translates 'on' to a boolean
|
||||
# http://yaml.org/type/bool.html
|
||||
if isinstance(state, bool):
|
||||
state = STATE_ON if state else STATE_OFF
|
||||
else:
|
||||
state = str(state)
|
||||
|
||||
states[entity_id.lower()] = State(entity_id, state, attributes)
|
||||
|
||||
return SceneConfig(name, states)
|
||||
|
||||
|
||||
class Scene(ToggleDevice):
|
||||
""" A scene is a group of entities and the states we want them to be. """
|
||||
|
||||
def __init__(self, hass, scene_config):
|
||||
self.hass = hass
|
||||
self.scene_config = scene_config
|
||||
|
||||
self.is_active = False
|
||||
self.active_requested = False
|
||||
self.prev_states = None
|
||||
|
||||
self.hass.states.track_change(
|
||||
self.entity_ids, self.entity_state_changed)
|
||||
|
||||
self.update()
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
return False
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.scene_config.name
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
return self.is_active
|
||||
|
||||
@property
|
||||
def entity_ids(self):
|
||||
""" Entity IDs part of this scene. """
|
||||
return self.scene_config.states.keys()
|
||||
|
||||
@property
|
||||
def state_attributes(self):
|
||||
""" Scene state attributes. """
|
||||
return {
|
||||
ATTR_ENTITY_ID: list(self.entity_ids),
|
||||
ATTR_ACTIVE_REQUESTED: self.prev_states is not None,
|
||||
}
|
||||
|
||||
def turn_on(self):
|
||||
""" Activates scene. Tries to get entities into requested state. """
|
||||
self.prev_states = tuple(self.hass.states.get(entity_id)
|
||||
for entity_id in self.entity_ids)
|
||||
|
||||
reproduce_state(self.hass, self.scene_config.states.values())
|
||||
|
||||
def turn_off(self):
|
||||
""" Deactivates scene and restores old states. """
|
||||
if self.prev_states:
|
||||
reproduce_state(self.hass, self.prev_states)
|
||||
self.prev_states = None
|
||||
|
||||
def entity_state_changed(self, entity_id, old_state, new_state):
|
||||
""" Called when an entity part of this scene changes state. """
|
||||
# If new state is not what we expect, it can never be active
|
||||
if self._state_as_requested(new_state):
|
||||
self.update()
|
||||
else:
|
||||
self.is_active = False
|
||||
|
||||
self.update_ha_state(True)
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
Update if the scene is active.
|
||||
|
||||
Will look at each requested state and see if the current entity
|
||||
has the same state and has at least the same attributes with the
|
||||
same values. The real state can have more attributes.
|
||||
"""
|
||||
self.is_active = all(
|
||||
self._state_as_requested(self.hass.states.get(entity_id))
|
||||
for entity_id in self.entity_ids)
|
||||
|
||||
if not self.is_active and self.prev_states:
|
||||
self.prev_states = None
|
||||
|
||||
def _state_as_requested(self, cur_state):
|
||||
""" Returns if given state is as requested. """
|
||||
state = self.scene_config.states.get(cur_state and cur_state.entity_id)
|
||||
|
||||
return (cur_state is not None and state.state == cur_state.state and
|
||||
all(value == cur_state.attributes.get(key)
|
||||
for key, value in state.attributes.items()))
|
@ -1,8 +1,6 @@
|
||||
"""
|
||||
Helper methods for components within Home Assistant.
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
from homeassistant.loader import get_component
|
||||
from homeassistant.const import ATTR_ENTITY_ID, CONF_PLATFORM
|
||||
from homeassistant.util import ensure_unique_string, slugify
|
||||
@ -43,25 +41,6 @@ def extract_entity_ids(hass, service):
|
||||
return [ent_id for ent_id in group.expand_entity_ids(hass, service_ent_id)]
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods, attribute-defined-outside-init
|
||||
class TrackStates(object):
|
||||
"""
|
||||
Records the time when the with-block is entered. Will add all states
|
||||
that have changed since the start time to the return list when with-block
|
||||
is exited.
|
||||
"""
|
||||
def __init__(self, hass):
|
||||
self.hass = hass
|
||||
self.states = []
|
||||
|
||||
def __enter__(self):
|
||||
self.now = datetime.now()
|
||||
return self.states
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.states.extend(self.hass.states.get_since(self.now))
|
||||
|
||||
|
||||
def validate_config(config, items, logger):
|
||||
"""
|
||||
Validates if all items are available in the configuration.
|
||||
|
@ -7,6 +7,8 @@ from homeassistant.helpers import (
|
||||
from homeassistant.components import group, discovery
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
|
||||
DEFAULT_SCAN_INTERVAL = 15
|
||||
|
||||
|
||||
class DeviceComponent(object):
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
@ -14,7 +16,8 @@ class DeviceComponent(object):
|
||||
"""
|
||||
Helper class that will help a device component manage its devices.
|
||||
"""
|
||||
def __init__(self, logger, domain, hass, scan_interval,
|
||||
def __init__(self, logger, domain, hass,
|
||||
scan_interval=DEFAULT_SCAN_INTERVAL,
|
||||
discovery_platforms=None, group_name=None):
|
||||
self.logger = logger
|
||||
self.hass = hass
|
||||
@ -33,17 +36,8 @@ class DeviceComponent(object):
|
||||
"""
|
||||
Sets up a full device component:
|
||||
- Loads the platforms from the config
|
||||
- Will update devices on an interval
|
||||
- Will listen for supported discovered platforms
|
||||
"""
|
||||
|
||||
# only setup group if name is given
|
||||
if self.group_name is None:
|
||||
self.group = None
|
||||
else:
|
||||
self.group = group.Group(self.hass, self.group_name,
|
||||
user_defined=False)
|
||||
|
||||
# Look in config for Domain, Domain 2, Domain 3 etc and load them
|
||||
for p_type, p_config in \
|
||||
config_per_platform(config, self.domain, self.logger):
|
||||
@ -54,6 +48,31 @@ class DeviceComponent(object):
|
||||
discovery.listen(self.hass, self.discovery_platforms.keys(),
|
||||
self._device_discovered)
|
||||
|
||||
def add_devices(self, new_devices):
|
||||
"""
|
||||
Takes in a list of new devices. For each device will see if it already
|
||||
exists. If not, will add it, set it up and push the first state.
|
||||
"""
|
||||
for device in new_devices:
|
||||
if device is not None and device not in self.devices.values():
|
||||
device.hass = self.hass
|
||||
|
||||
device.entity_id = generate_entity_id(
|
||||
self.entity_id_format, device.name, self.devices.keys())
|
||||
|
||||
self.devices[device.entity_id] = device
|
||||
|
||||
device.update_ha_state()
|
||||
|
||||
if self.group is None and self.group_name is not None:
|
||||
self.group = group.Group(self.hass, self.group_name,
|
||||
user_defined=False)
|
||||
|
||||
if self.group is not None:
|
||||
self.group.update_tracked_entity_ids(self.devices.keys())
|
||||
|
||||
self._start_polling()
|
||||
|
||||
def extract_from_service(self, service):
|
||||
"""
|
||||
Takes a service and extracts all known devices.
|
||||
@ -81,27 +100,6 @@ class DeviceComponent(object):
|
||||
|
||||
self._setup_platform(self.discovery_platforms[service], {}, info)
|
||||
|
||||
def _add_devices(self, new_devices):
|
||||
"""
|
||||
Takes in a list of new devices. For each device will see if it already
|
||||
exists. If not, will add it, set it up and push the first state.
|
||||
"""
|
||||
for device in new_devices:
|
||||
if device is not None and device not in self.devices.values():
|
||||
device.hass = self.hass
|
||||
|
||||
device.entity_id = generate_entity_id(
|
||||
self.entity_id_format, device.name, self.devices.keys())
|
||||
|
||||
self.devices[device.entity_id] = device
|
||||
|
||||
device.update_ha_state()
|
||||
|
||||
if self.group is not None:
|
||||
self.group.update_tracked_entity_ids(self.devices.keys())
|
||||
|
||||
self._start_polling()
|
||||
|
||||
def _start_polling(self):
|
||||
""" Start polling device states if necessary. """
|
||||
if self.is_polling or \
|
||||
@ -125,7 +123,7 @@ class DeviceComponent(object):
|
||||
|
||||
try:
|
||||
platform.setup_platform(
|
||||
self.hass, config, self._add_devices, discovery_info)
|
||||
self.hass, config, self.add_devices, discovery_info)
|
||||
except AttributeError:
|
||||
# Support old deprecated method for now - 3/1/2015
|
||||
if hasattr(platform, 'get_devices'):
|
||||
@ -133,7 +131,7 @@ class DeviceComponent(object):
|
||||
"Please upgrade %s to return new devices using "
|
||||
"setup_platform. See %s/demo.py for an example.",
|
||||
platform_name, self.domain)
|
||||
self._add_devices(platform.get_devices(self.hass, config))
|
||||
self.add_devices(platform.get_devices(self.hass, config))
|
||||
|
||||
else:
|
||||
# AttributeError if setup_platform does not exist
|
||||
|
52
homeassistant/helpers/state.py
Normal file
52
homeassistant/helpers/state.py
Normal file
@ -0,0 +1,52 @@
|
||||
"""
|
||||
homeassistant.helpers.state
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Helpers that help with state related things.
|
||||
"""
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from homeassistant import State
|
||||
from homeassistant.const import STATE_ON, STATE_OFF
|
||||
import homeassistant.components as core_components
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods, attribute-defined-outside-init
|
||||
class TrackStates(object):
|
||||
"""
|
||||
Records the time when the with-block is entered. Will add all states
|
||||
that have changed since the start time to the return list when with-block
|
||||
is exited.
|
||||
"""
|
||||
def __init__(self, hass):
|
||||
self.hass = hass
|
||||
self.states = []
|
||||
|
||||
def __enter__(self):
|
||||
self.now = datetime.now()
|
||||
return self.states
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.states.extend(self.hass.states.get_since(self.now))
|
||||
|
||||
|
||||
def reproduce_state(hass, states):
|
||||
""" Takes in a state and will try to have the entity reproduce it. """
|
||||
if isinstance(states, State):
|
||||
states = [states]
|
||||
|
||||
for state in states:
|
||||
current_state = hass.states.get(state.entity_id)
|
||||
|
||||
if current_state is None:
|
||||
continue
|
||||
|
||||
if state.state == STATE_ON:
|
||||
core_components.turn_on(hass, state.entity_id, **state.attributes)
|
||||
elif state.state == STATE_OFF:
|
||||
core_components.turn_off(hass, state.entity_id, **state.attributes)
|
||||
else:
|
||||
_LOGGER.warning("Unable to reproduce state for %s", state)
|
Loading…
x
Reference in New Issue
Block a user