Skip to content

Instantly share code, notes, and snippets.

@skylyn
Created August 3, 2020 16:47
Show Gist options
  • Save skylyn/5972d3b5ee0177a51d5835f2d22261e8 to your computer and use it in GitHub Desktop.
Save skylyn/5972d3b5ee0177a51d5835f2d22261e8 to your computer and use it in GitHub Desktop.
Open window alert with app daemon
import statistics
import time
import appdaemon.plugins.hass.hassapi as hass
import datetime
WINTER = 'winter'
SUMMER = 'summer'
MODE = SUMMER
MESSAGE_TEXT = "{action} the {room} window"
ACTION_MAP = {
SUMMER: {
'inside_hot': 'Open',
'inside_cold': 'Close'
},
WINTER: {
'inside_hot': 'Close',
'inside_cold': 'Open'
}
}
BINARY_MAP = {'Open': 'on', 'Close': 'off'}
class TempAlert(hass.Hass):
def initialize(self):
self.entity_handles = {}
self.notify_service = 'notify/{}'.format(self.args.get('notify_service', 'notify'))
self.last_notify_time = 0
self.temp_diff_req = self.args.get('temp_diff_req', '2')
self.time_between_notifications = self.args.get('time_between_notifications', '1200')
self.target_temp = int(self.args.get('target_temp'))
self.app_switch = self.args['app_switch']
self.outside_temp_sensors = self.args['outside_temp']
self.inside_temp_sensors = self.args['inside_temp']
self.room = self.args['room']
self.windows = self.args['windows']
self.window_state = 'off'
self.notifier = self.args['notifier']
if self.get_state(self.app_switch) == 'on':
for entity in (self.outside_temp_sensors + self.inside_temp_sensors):
self.entity_handles[entity] = self.listen_state(self.TempChange, entity)
for entity in self.windows:
self.entity_handles[entity] = self.listen_state(self.SetWindowState, entity)
self.SetWindowState()
self.log('successfully initialized temperature monitor.\nHandles: %s\nTarget temp: %s' % (
self.entity_handles.keys(), self.target_temp))
def TempChange(self, *args, **kwargs):
inside_temps = (float(self.get_state(sensor)) for sensor in self.inside_temp_sensors)
inside_temp = statistics.mean(inside_temps)
outside_temps = (float(self.get_state(sensor)) for sensor in self.outside_temp_sensors)
outside_temp = statistics.mean(outside_temps)
if self.TempIsOk(inside_temp) or self.get_state('input_select.home_mode') != 'Home':
return
if abs(inside_temp - outside_temp) > float(self.temp_diff_req):
if inside_temp > outside_temp:
action = ACTION_MAP[MODE]['inside_hot']
if self.window_state != BINARY_MAP[action]:
self.NotifyIfEligible(action)
elif inside_temp < outside_temp:
action = ACTION_MAP[MODE]['inside_cold']
if self.window_state != BINARY_MAP[action]:
self.NotifyIfEligible(action)
def SetWindowState(self, *args, **kwargs):
for window in self.windows:
if self.get_state(window) == 'on':
self.window_state = 'on'
return
self.window_state = 'off'
self.TempChange()
def NotifyIfEligible(self, action):
if (self.get_state(self.app_switch) == 'on' and
time.time() - self.last_notify_time > int(self.time_between_notifications) and
datetime.datetime.now() > time(10, 00)):
self.call_service('notify/{}'.format(self.notifier),
message=MESSAGE_TEXT.format(action=action, room=self.room)
)
self.last_notify_time = time.time()
def TempIsOk(self, current_temp):
if current_temp <= self.target_temp:
return True
return False
BedroomTempAlert:
module: temp_alert
notifier: hangouts_fam
class: TempAlert
app_switch: input_boolean.temp_alert
room: bedroom
windows:
- binary_sensor.bedroom_window_left
outside_temp:
- sensor.backyard_temp
inside_temp:
- sensor.master_bedroom_temp
- sensor.master_closet_temp
target_temp: 68
OfficeTempAlert:
module: temp_alert
notifier: hangouts_fam
class: TempAlert
app_switch: input_boolean.temp_alert
room: office
windows:
- binary_sensor.office_window
outside_temp:
- sensor.backyard_temp
inside_temp:
- sensor.office_temp
target_temp: 72
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment