Created
November 1, 2022 12:54
-
-
Save deviantintegral/84c5755be907b2c1cd8343141ce63375 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import datetime | |
import appdaemon.plugins.hass.hassapi as hass | |
# app arguments: | |
# - hygrometer - a sensor entity ID registering humidity in percent. | |
# - switch - a switch entity ID to turn the humidifier on and off. | |
# - start_at - an ISO time like 18:30:00 for the earliest time the humidifer can turn on. | |
# - end_at - an ISO time like 18:30:00 for the latest time the humidifer can turn off. | |
# - target_number - a number input helper set up in HA to control desired humidity. | |
# - enable_switch - an switch input helper set up in HA to turn automatic humidity on or off. | |
# Hardcoded - group.adults entity tracking if people entities are home. | |
class Humidifier(hass.Hass): | |
# noinspection PyAttributeOutsideInit | |
def initialize(self): | |
self.log("Starting Humidifier " + self.name) | |
self._hygrometer = self.args['hygrometer'] | |
self._switch = self.args['switch'] | |
self._start_at = datetime.datetime.strptime(dict.get(self.args, "start_at", "18:30:00"), "%H:%M:%S").time() | |
self._end_at = datetime.datetime.strptime(dict.get(self.args, "end_at", "08:00:00"), "%H:%M:%S").time() | |
self._target_number = dict.get(self.args, "target_number", None) | |
# Create an input boolean to enable or disable this app. | |
self._enable_switch = dict.get(self.args, "enable_switch", None) | |
# Only activate when people are home, with no proximity considerations. | |
self.listen_state(self.enable, "group.adults", new="home") | |
self.listen_state(self.disable, "group.adults", new="not_home", immediate=True) | |
if self._enable_switch: | |
self.listen_state(self.enable, self._enable_switch, new="on") | |
self.listen_state(self.disable, self._enable_switch, new="off") | |
self._target = 50 | |
if self._target_number: | |
self._target = float(self.get_state(entity_id=self._target_number)) | |
self.listen_state(self.set_target, self._target_number, immediate=True) | |
self._register_callbacks() | |
def enable(self, entity, attribute, old, new, kwargs): | |
self.log("Enabling humidifiers") | |
self._register_callbacks() | |
def _register_callbacks(self): | |
self._humidity_handle = self.listen_state(self.on_change, entity_id=self._hygrometer) | |
self._on_handle = self.run_daily(self.turn_on_start, start=self._start_at) | |
self._off_handle = self.run_daily(self.turn_off_end, start=self._end_at) | |
def disable(self, entity, attribute, old, new, kwargs): | |
self.log("Disabling humidifier") | |
if self._humidity_handle is not None: | |
self.cancel_listen_state(self._humidity_handle) | |
if self._on_handle is not None: | |
self.cancel_timer(self._on_handle) | |
if self._off_handle is not None: | |
self.cancel_timer(self._off_handle) | |
def set_target(self, entity, attribute, old, new, kwargs): | |
self._target = float(new) | |
self.log("Set target to " + str(self._target)) | |
def turn_on_start(self, kwargs): | |
humidity = float(self.get_state(entity_id=self._hygrometer)) | |
if humidity < self._target: | |
self.log("Turning on humidifier attached to " + self._switch) | |
self.turn_on(self._switch) | |
def turn_off_end(self, kwargs): | |
self.log("Turning off humidifier attached to " + self._switch) | |
self.turn_off(self._switch) | |
def on_change(self, entity, attribute, old, new, kwargs): | |
if new == "unavailable": | |
return | |
self.log("New humidity for " + self._hygrometer + " is " + new + ", target is " + str(self._target)) | |
new = float(new) | |
now = self.datetime().time() | |
if self._start_at < self._end_at: | |
# Times do not overlap a calendar day. | |
active = self._start_at <= now < self._end_at | |
else: | |
# Times are within a calendar day. | |
active = self._start_at <= now or now < self._end_at | |
state = self.get_state(entity_id=self._switch) | |
if active: | |
if new <= (self._target - 1) and state == "off": | |
self.log("Turning on humidifier attached to " + self._switch) | |
self.turn_on(self._switch) | |
if new >= (self._target + 1) and state == "on": | |
self.log("Turning off humidifier attached to " + self._switch) | |
self.turn_off(self._switch) | |
elif state == "on": | |
self.log("Turning off humidifier attached to " + self._switch) | |
self.turn_off(self._switch) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment