appd - Time of Day controller working

This commit is contained in:
Thomas Lovén 2018-12-28 22:37:47 +01:00
parent a070dc679f
commit a3374b3ac2
6 changed files with 135 additions and 46 deletions

4
appdaemon/apps/apps.yaml Normal file
View File

@ -0,0 +1,4 @@
hello_world:
module: hello
class: HelloWorld

View File

@ -1,7 +1,6 @@
import base import base
import entities
class HelloWorld(entities.Entities, base.Timers): class HelloWorld(base.Base):
def initialize(self): def initialize(self):
super().initialize() super().initialize()
@ -9,36 +8,36 @@ class HelloWorld(entities.Entities, base.Timers):
self.log("Hello from AppDaemon") self.log("Hello from AppDaemon")
self.log("You are now ready to run Apps!") self.log("You are now ready to run Apps!")
self.run_in('test1', self.after_time, 3) # self.run_in('test1', self.after_time, 3)
self.run_in('test2', self.after_time2, 7) # self.run_in('test2', self.after_time2, 7)
# self.run_in(self.after_time2, 7) # # self.run_in(self.after_time2, 7)
# self.cancel_timer('test2') # # self.cancel_timer('test2')
self.register_entity('taklampa', 'light.kontoret') # self.register_entity('taklampa', 'light.kontoret')
self.e['taklampa'].listen(self.light_changes) # self.e['taklampa'].listen(self.light_changes)
self.register_entity('dark', 'switch.tod2', True, "on", { # self.register_entity('dark', 'switch.tod2', True, "on", {
'icon': 'mdi:lightbulb', # 'icon': 'mdi:lightbulb',
'friendly_name': 'TEST'}) # 'friendly_name': 'TEST'})
self.e['dark'].listen(self.switch) # self.e['dark'].listen(self.switch)
def switch(self, old, new, kwarg): # def switch(self, old, new, kwarg):
self.log(f"Switch switched {self.e['dark'].state}") # self.log(f"Switch switched {self.e['dark'].state}")
def light_changes(self, old, new, kwarg): # def light_changes(self, old, new, kwarg):
self.log("Light changed!") # self.log("Light changed!")
self.log(f"State is {self.e['taklampa'].state}") # self.log(f"State is {self.e['taklampa'].state}")
def after_time(self, kwargs): # def after_time(self, kwargs):
self.log("Running function") # self.log("Running function")
self.e['taklampa'].attr['icon'] = "mdi:lamp" # self.e['taklampa'].attr['icon'] = "mdi:lamp"
# self.e['taklampa'].state = "off" # # self.e['taklampa'].state = "off"
self.e['taklampa'].push() # self.e['taklampa'].push()
self.log(f"State is {self.e['taklampa'].state}") # self.log(f"State is {self.e['taklampa'].state}")
def after_time2(self, kwargs): # def after_time2(self, kwargs):
self.log("Running function2") # self.log("Running function2")
self.e['taklampa'].attr.pop('icon') # self.e['taklampa'].attr.pop('icon')
# self.e['taklampa'].state = "on" # # self.e['taklampa'].state = "on"
self.e['taklampa'].push() # self.e['taklampa'].push()
self.log(f"State is {self.e['taklampa'].state}") # self.log(f"State is {self.e['taklampa'].state}")

View File

@ -71,13 +71,11 @@ class Entity:
self._attributes = d['attributes'] self._attributes = d['attributes']
def push(self): def push(self):
self._hass.set_state(self._entity, state=self._state, attributes=self._attributes)
if self._state != self._laststate: if self._state != self._laststate:
old = self._laststate self.set_state(self._laststate, self._state)
new = self._state self._laststate = self._state
self._laststate = new self._callback(self._laststate, self._state)
self.set_state(old, new) self._hass.set_state(self._entity, state=self._state, attributes=self._attributes)
self._callback(old, new)
def set_state(self, old, new): def set_state(self, old, new):
pass pass
@ -114,6 +112,12 @@ class LightEntity(Entity):
class SwitchEntity(Entity): class SwitchEntity(Entity):
def set_state(self, old, new):
if new == True:
self._state = "on"
if new == False:
self._state = "off"
def service_callback(self, data): def service_callback(self, data):
if data['service'] == 'turn_on': if data['service'] == 'turn_on':
self._state = "on" self._state = "on"

View File

@ -25,16 +25,16 @@ class Timers(base.Base):
def cancel_timer(self, name, *args, **kwargs): def cancel_timer(self, name, *args, **kwargs):
if type(name) is str: if type(name) is str:
if name in self._timers: if name in self._timers:
return super().cancel_timer(self._timers[name]) return super(Timers, self).cancel_timer(self._timers[name])
else: else:
return super().cancel_timer(*args, **kwargs) return super(Timers, self).cancel_timer(*args, **kwargs)
def _override(self, f): def _override(self, f):
setattr(self, f'_{f}', getattr(self, f)) setattr(self, f'_{f}', getattr(self, f))
def fn(name, *args, **kwargs): def fn(name, *args, **kwargs):
if type(name) is str: if type(name) is str:
if name in self._timers: if name in self._timers:
super().cancel_timer(self._timers[name]) super(Timers, self).cancel_timer(self._timers[name])
self._timers[name] = getattr(self, f'_{f}')(*args, **kwargs) self._timers[name] = getattr(self, f'_{f}')(*args, **kwargs)
return self._timers[name] return self._timers[name]
else: else:

View File

@ -1,13 +1,27 @@
import base from datetime import timedelta
import entities
class TimeOfDay(entities.Entities): from timers import Timers
from entities import Entities
class TimeOfDay(Timers, Entities):
TOD = ['morning', 'day', 'evening', 'night']
def initialize(self): def initialize(self):
super().initialize() super().initialize()
self.run_in(self.setup_inputs, 1) self.run_in(self.setup_inputs, 1)
def setup_inputs(self, kwargs): def setup_inputs(self, kwargs):
inputs = ['morning', 'day', 'evening', 'night', 'sunrise', 'sunset', 'tod', 'dark'] inputs = [
'morning',
'day',
'evening',
'night',
'sunrise',
'sunset',
'tod',
'dark',
]
for i in inputs: for i in inputs:
e = dict(self.args[i]) e = dict(self.args[i])
name = e['name'] name = e['name']
@ -15,9 +29,75 @@ class TimeOfDay(entities.Entities):
del e['name'] del e['name']
del e['default'] del e['default']
self.register_entity(i, name, True, default, e) self.register_entity(i, name, True, default, e)
self.e[i].listen(self.update, {'trigger': 'setting', 'entity': i})
self.e['sunrise'].listen(self.input_listener, {'changed': "sunrise"}) self.update(None, None, {'trigger': 'init'})
def update(self, old, new, kwarg):
trigger = kwarg.get('trigger', None)
if kwarg.get('entity', None) in ['tod', 'dark']:
return
self.log(f"TOD - updated by {trigger}")
# Set up triggers for each TOD
for t in self.TOD:
if not trigger == t:
self.run_once(
t,
self.update,
self.parse_time(self.e[t].state),
trigger=t
)
# Set up triggers for sunrise and sunset
if trigger != 'sunrise':
sunrise = float(self.e['sunrise'].state)
sunrise = timedelta(minutes=sunrise)
sunrise = (self.sunrise() + sunrise).time()
self.run_once(
'sunrise',
self.update,
sunrise,
trigger='sunrise'
)
if trigger != 'sunset':
sunset = float(self.e['sunset'].state)
sunset = timedelta(minutes=sunset)
sunset = (self.sunset() + sunset).time()
self.run_once(
'sunset',
self.update,
sunset,
trigger='sunset'
)
# Determine current time of day
if trigger in self.TOD:
tod = trigger
else:
tod = 'night'
for t in self.TOD:
if self.time() >= self.parse_time(self.e[t].state):
tod = t
# Determine if sun is down
if trigger == 'sunrise':
dark = False
elif trigger == 'sunset':
dark = True
elif sunrise <= self.time() <= sunset:
dark = False
else:
dark = True
def input_listener(self, old, new, kwargs): self.log(f"TOD - Time of day is {tod}, sun {'has set' if dark else 'is up'}")
self.log(kwargs)
# Update outputs
self.e['dark'].state = dark
self.e['dark'].push()
self.e['tod'].state = tod
self.e['tod'].push()

View File

@ -16,7 +16,9 @@ input_number:
min: 0 min: 0
max: 10 max: 10
input_datetime: input_datetime:
appd_dummy: {} appd_dummy:
has_date: False
has_time: True
input_select: input_select:
appd_dummy: appd_dummy:
options: [1] options: [1]