Scene bugfixes and UI improvements

This commit is contained in:
Paulus Schoutsen 2015-03-16 23:32:18 -07:00
parent b459a29947
commit 1245af356b
10 changed files with 69 additions and 37 deletions

View file

@ -459,6 +459,11 @@ class State(object):
self.last_changed = util.strip_microseconds( self.last_changed = util.strip_microseconds(
last_changed or self.last_updated) last_changed or self.last_updated)
@property
def domain(self):
""" Returns domain of this state. """
return util.split_entity_id(self.entity_id)[0]
def copy(self): def copy(self):
""" Creates a copy of itself. """ """ Creates a copy of itself. """
return State(self.entity_id, self.state, return State(self.entity_id, self.state,

View file

@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """ """ DO NOT MODIFY. Auto-generated by build_frontend script """
VERSION = "1d8b14c387123a4b42fec6b8f9346675" VERSION = "c47a52ae084d870c0c306eea8c27f507"

File diff suppressed because one or more lines are too long

View file

@ -1,23 +1,11 @@
<link rel="import" href="../bower_components/polymer/polymer.html"> <link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="./state-card-display.html">
<link rel="import" href="../components/state-info.html"> <link rel="import" href="../components/state-info.html">
<polymer-element name="state-card-configurator" attributes="stateObj" noscript> <polymer-element name="state-card-configurator" attributes="stateObj" noscript>
<template> <template>
<style> <state-card-display stateObj="{{stateObj}}"></state-card-display>
.state {
margin-left: 16px;
text-transform: capitalize;
font-weight: 300;
font-size: 1.3rem;
text-align: right;
}
</style>
<div horizontal justified layout>
<state-info stateObj="{{stateObj}}"></state-info>
<div class='state'>{{stateObj.stateDisplay}}</div>
</div>
<!-- pre load the image so the dialog is rendered the proper size --> <!-- pre load the image so the dialog is rendered the proper size -->
<template if="{{stateObj.attributes.description_image}}"> <template if="{{stateObj.attributes.description_image}}">

View file

@ -4,6 +4,7 @@
<link rel="import" href="state-card-toggle.html"> <link rel="import" href="state-card-toggle.html">
<link rel="import" href="state-card-thermostat.html"> <link rel="import" href="state-card-thermostat.html">
<link rel="import" href="state-card-configurator.html"> <link rel="import" href="state-card-configurator.html">
<link rel="import" href="state-card-scene.html">
<polymer-element name="state-card-content" attributes="stateObj"> <polymer-element name="state-card-content" attributes="stateObj">
<template> <template>

View file

@ -0,0 +1,27 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="./state-card-display.html">
<link rel="import" href="./state-card-toggle.html">
<polymer-element name="state-card-scene" attributes="stateObj">
<template>
<template if={{allowToggle}}>
<state-card-toggle stateObj="{{stateObj}}"></state-card-toggle>
</template>
<template if={{!allowToggle}}>
<state-card-display stateObj="{{stateObj}}"></state-card-display>
</template>
</template>
<script>
(function() {
Polymer({
allowToggle: false,
stateObjChanged: function(oldVal, newVal) {
this.allowToggle = newVal.state === 'off' ||
newVal.attributes.active_requested;
},
});
})();
</script>
</polymer-element>

View file

@ -134,7 +134,6 @@
if (this.filter) { if (this.filter) {
var filter = this.filter; var filter = this.filter;
states = stateStore.all.filter(function(state) { states = stateStore.all.filter(function(state) {
console.log(state, state.domain, filter);
return state.domain === filter; return state.domain === filter;
}); });

View file

@ -2,7 +2,7 @@
<script> <script>
(function() { (function() {
var DOMAINS_WITH_CARD = ['thermostat', 'configurator']; var DOMAINS_WITH_CARD = ['thermostat', 'configurator', 'scene'];
var DOMAINS_WITH_MORE_INFO = [ var DOMAINS_WITH_MORE_INFO = [
'light', 'group', 'sun', 'configurator', 'thermostat', 'script' 'light', 'group', 'sun', 'configurator', 'thermostat', 'script'
]; ];

View file

@ -61,8 +61,6 @@ def setup(hass, config):
else: else:
scene.turn_off() scene.turn_off()
scene.update_ha_state(True)
hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_scene_service) hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_scene_service)
hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_scene_service) hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_scene_service)
@ -104,6 +102,7 @@ class Scene(ToggleDevice):
self.is_active = False self.is_active = False
self.prev_states = None self.prev_states = None
self.ignore_updates = False
self.hass.states.track_change( self.hass.states.track_change(
self.entity_ids, self.entity_state_changed) self.entity_ids, self.entity_state_changed)
@ -140,23 +139,27 @@ class Scene(ToggleDevice):
self.prev_states = tuple(self.hass.states.get(entity_id) self.prev_states = tuple(self.hass.states.get(entity_id)
for entity_id in self.entity_ids) for entity_id in self.entity_ids)
reproduce_state(self.hass, self.scene_config.states.values()) self._reproduce_state(self.scene_config.states.values())
def turn_off(self): def turn_off(self):
""" Deactivates scene and restores old states. """ """ Deactivates scene and restores old states. """
if self.prev_states: if self.prev_states:
reproduce_state(self.hass, self.prev_states) self._reproduce_state(self.prev_states)
self.prev_states = None self.prev_states = None
def entity_state_changed(self, entity_id, old_state, new_state): def entity_state_changed(self, entity_id, old_state, new_state):
""" Called when an entity part of this scene changes state. """ """ Called when an entity part of this scene changes state. """
if self.ignore_updates:
return
# If new state is not what we expect, it can never be active # If new state is not what we expect, it can never be active
if self._state_as_requested(new_state): if self._state_as_requested(new_state):
self.update() self.update()
else: else:
self.is_active = False self.is_active = False
self.prev_states = None
self.update_ha_state(True) self.update_ha_state()
def update(self): def update(self):
""" """
@ -170,9 +173,6 @@ class Scene(ToggleDevice):
self._state_as_requested(self.hass.states.get(entity_id)) self._state_as_requested(self.hass.states.get(entity_id))
for entity_id in self.entity_ids) 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): def _state_as_requested(self, cur_state):
""" Returns if given state is as requested. """ """ Returns if given state is as requested. """
state = self.scene_config.states.get(cur_state and cur_state.entity_id) state = self.scene_config.states.get(cur_state and cur_state.entity_id)
@ -180,3 +180,11 @@ class Scene(ToggleDevice):
return (cur_state is not None and state.state == cur_state.state and return (cur_state is not None and state.state == cur_state.state and
all(value == cur_state.attributes.get(key) all(value == cur_state.attributes.get(key)
for key, value in state.attributes.items())) for key, value in state.attributes.items()))
def _reproduce_state(self, states):
""" Wraps reproduce state with Scence specific logic. """
self.ignore_updates = True
reproduce_state(self.hass, states, True)
self.ignore_updates = False
self.update_ha_state(True)

View file

@ -8,8 +8,8 @@ import logging
from datetime import datetime from datetime import datetime
from homeassistant import State from homeassistant import State
from homeassistant.const import STATE_ON, STATE_OFF from homeassistant.const import (
import homeassistant.components as core_components STATE_ON, STATE_OFF, SERVICE_TURN_ON, SERVICE_TURN_OFF, ATTR_ENTITY_ID)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -33,7 +33,7 @@ class TrackStates(object):
self.states.extend(self.hass.states.get_since(self.now)) self.states.extend(self.hass.states.get_since(self.now))
def reproduce_state(hass, states): def reproduce_state(hass, states, blocking=False):
""" Takes in a state and will try to have the entity reproduce it. """ """ Takes in a state and will try to have the entity reproduce it. """
if isinstance(states, State): if isinstance(states, State):
states = [states] states = [states]
@ -45,8 +45,14 @@ def reproduce_state(hass, states):
continue continue
if state.state == STATE_ON: if state.state == STATE_ON:
core_components.turn_on(hass, state.entity_id, **state.attributes) service = SERVICE_TURN_ON
elif state.state == STATE_OFF: elif state.state == STATE_OFF:
core_components.turn_off(hass, state.entity_id, **state.attributes) service = SERVICE_TURN_OFF
else: else:
_LOGGER.warning("Unable to reproduce state for %s", state) _LOGGER.warning("Unable to reproduce state for %s", state)
continue
service_data = dict(state.attributes)
service_data[ATTR_ENTITY_ID] = state.entity_id
hass.services.call(state.domain, service, service_data, blocking)