From a3374b3ac2ae61592575e6f67c5633a13d451a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Fri, 28 Dec 2018 22:37:47 +0100 Subject: [PATCH] appd - Time of Day controller working --- appdaemon/apps/apps.yaml | 4 ++ appdaemon/apps/hello.py | 57 +++++++++--------- appdaemon/apps/helpers/entities.py | 16 +++-- appdaemon/apps/helpers/timers.py | 6 +- appdaemon/apps/timeofday.py | 94 +++++++++++++++++++++++++++--- packages/appd_dummies.yaml | 4 +- 6 files changed, 135 insertions(+), 46 deletions(-) create mode 100644 appdaemon/apps/apps.yaml diff --git a/appdaemon/apps/apps.yaml b/appdaemon/apps/apps.yaml new file mode 100644 index 0000000..daff739 --- /dev/null +++ b/appdaemon/apps/apps.yaml @@ -0,0 +1,4 @@ +hello_world: + module: hello + class: HelloWorld + diff --git a/appdaemon/apps/hello.py b/appdaemon/apps/hello.py index 246b205..96a6447 100644 --- a/appdaemon/apps/hello.py +++ b/appdaemon/apps/hello.py @@ -1,7 +1,6 @@ import base -import entities -class HelloWorld(entities.Entities, base.Timers): +class HelloWorld(base.Base): def initialize(self): super().initialize() @@ -9,36 +8,36 @@ class HelloWorld(entities.Entities, base.Timers): self.log("Hello from AppDaemon") self.log("You are now ready to run Apps!") - self.run_in('test1', self.after_time, 3) - self.run_in('test2', self.after_time2, 7) - # self.run_in(self.after_time2, 7) - # self.cancel_timer('test2') + # self.run_in('test1', self.after_time, 3) + # self.run_in('test2', self.after_time2, 7) + # # self.run_in(self.after_time2, 7) + # # self.cancel_timer('test2') - self.register_entity('taklampa', 'light.kontoret') - self.e['taklampa'].listen(self.light_changes) + # self.register_entity('taklampa', 'light.kontoret') + # self.e['taklampa'].listen(self.light_changes) - self.register_entity('dark', 'switch.tod2', True, "on", { - 'icon': 'mdi:lightbulb', - 'friendly_name': 'TEST'}) - self.e['dark'].listen(self.switch) + # self.register_entity('dark', 'switch.tod2', True, "on", { + # 'icon': 'mdi:lightbulb', + # 'friendly_name': 'TEST'}) + # self.e['dark'].listen(self.switch) - def switch(self, old, new, kwarg): - self.log(f"Switch switched {self.e['dark'].state}") + # def switch(self, old, new, kwarg): + # self.log(f"Switch switched {self.e['dark'].state}") - def light_changes(self, old, new, kwarg): - self.log("Light changed!") - self.log(f"State is {self.e['taklampa'].state}") + # def light_changes(self, old, new, kwarg): + # self.log("Light changed!") + # self.log(f"State is {self.e['taklampa'].state}") - def after_time(self, kwargs): - self.log("Running function") - self.e['taklampa'].attr['icon'] = "mdi:lamp" - # self.e['taklampa'].state = "off" - self.e['taklampa'].push() - self.log(f"State is {self.e['taklampa'].state}") - def after_time2(self, kwargs): - self.log("Running function2") - self.e['taklampa'].attr.pop('icon') - # self.e['taklampa'].state = "on" - self.e['taklampa'].push() + # def after_time(self, kwargs): + # self.log("Running function") + # self.e['taklampa'].attr['icon'] = "mdi:lamp" + # # self.e['taklampa'].state = "off" + # self.e['taklampa'].push() + # self.log(f"State is {self.e['taklampa'].state}") + # def after_time2(self, kwargs): + # self.log("Running function2") + # self.e['taklampa'].attr.pop('icon') + # # self.e['taklampa'].state = "on" + # self.e['taklampa'].push() - self.log(f"State is {self.e['taklampa'].state}") + # self.log(f"State is {self.e['taklampa'].state}") diff --git a/appdaemon/apps/helpers/entities.py b/appdaemon/apps/helpers/entities.py index 8028b52..b1be151 100644 --- a/appdaemon/apps/helpers/entities.py +++ b/appdaemon/apps/helpers/entities.py @@ -71,13 +71,11 @@ class Entity: self._attributes = d['attributes'] def push(self): - self._hass.set_state(self._entity, state=self._state, attributes=self._attributes) if self._state != self._laststate: - old = self._laststate - new = self._state - self._laststate = new - self.set_state(old, new) - self._callback(old, new) + self.set_state(self._laststate, self._state) + self._laststate = self._state + self._callback(self._laststate, self._state) + self._hass.set_state(self._entity, state=self._state, attributes=self._attributes) def set_state(self, old, new): pass @@ -114,6 +112,12 @@ class LightEntity(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): if data['service'] == 'turn_on': self._state = "on" diff --git a/appdaemon/apps/helpers/timers.py b/appdaemon/apps/helpers/timers.py index b8dc97b..0f62c0f 100644 --- a/appdaemon/apps/helpers/timers.py +++ b/appdaemon/apps/helpers/timers.py @@ -25,16 +25,16 @@ class Timers(base.Base): def cancel_timer(self, name, *args, **kwargs): if type(name) is str: if name in self._timers: - return super().cancel_timer(self._timers[name]) + return super(Timers, self).cancel_timer(self._timers[name]) else: - return super().cancel_timer(*args, **kwargs) + return super(Timers, self).cancel_timer(*args, **kwargs) def _override(self, f): setattr(self, f'_{f}', getattr(self, f)) def fn(name, *args, **kwargs): if type(name) is str: 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) return self._timers[name] else: diff --git a/appdaemon/apps/timeofday.py b/appdaemon/apps/timeofday.py index 77e170b..dea3037 100644 --- a/appdaemon/apps/timeofday.py +++ b/appdaemon/apps/timeofday.py @@ -1,13 +1,27 @@ -import base -import entities -class TimeOfDay(entities.Entities): +from datetime import timedelta + +from timers import Timers +from entities import Entities +class TimeOfDay(Timers, Entities): + + TOD = ['morning', 'day', 'evening', 'night'] + def initialize(self): super().initialize() self.run_in(self.setup_inputs, 1) 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: e = dict(self.args[i]) name = e['name'] @@ -15,9 +29,75 @@ class TimeOfDay(entities.Entities): del e['name'] del e['default'] 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(kwargs) + self.log(f"TOD - Time of day is {tod}, sun {'has set' if dark else 'is up'}") + + # Update outputs + self.e['dark'].state = dark + self.e['dark'].push() + self.e['tod'].state = tod + self.e['tod'].push() diff --git a/packages/appd_dummies.yaml b/packages/appd_dummies.yaml index 05906e7..6b367a7 100644 --- a/packages/appd_dummies.yaml +++ b/packages/appd_dummies.yaml @@ -16,7 +16,9 @@ input_number: min: 0 max: 10 input_datetime: - appd_dummy: {} + appd_dummy: + has_date: False + has_time: True input_select: appd_dummy: options: [1]