Skip to content

Instantly share code, notes, and snippets.

@matt2005
Created August 9, 2017 22:49
Show Gist options
  • Save matt2005/e2c853251808b9a3bc7c98fa25cc59ca to your computer and use it in GitHub Desktop.
Save matt2005/e2c853251808b9a3bc7c98fa25cc59ca to your computer and use it in GitHub Desktop.
test_sensors:
module: testsensors
class: TestSensors
heating_test:
module: heatinglogic
class: HeatingLogic
sensor_temperature_flow_actual: sensor.heating_flow_temp
sensor_temperature_outside_actual: sensor.heating_outside_temp
input_temperature_inside_setpoint: input_slider.heating_setpoint_temp
switch_heating: switch.heating
adjustment: 3
gain: 1.2
temperature_flow_max: 70 # C
temperature_flow_min: 25 # C
temperature_flow_tolerance_above: 5 # C
temperature_flow_tolerance_below: 5 # C
switch_heating_max_on: 150 # Minutes
import appdaemon.appapi as appapi
class HeatingLogic(appapi.AppDaemon):
def initialize(self):
self.log("Starting HeatingLogic ...")
self.gain = float(self.args['gain'])
self.adjustment = float(self.args['adjustment'])
self.temperature_flow_min = float(self.args['temperature_flow_min'])
self.temperature_flow_max = float(self.args['temperature_flow_max'])
self.temperature_flow_tolerance_above = float(self.args['temperature_flow_tolerance_above'])
self.temperature_flow_tolerance_below = float(self.args['temperature_flow_tolerance_below'])
self.switch_heating = self.args['switch_heating']
self.switch_heating_max_on = float(self.args['switch_heating_max_on']) # Minutes
# Get current temperature information
self.get_sensor_temperatures()
# Register for sensor status updates
self.listen_state(self.temperature_change, entity=self.args['sensor_temperature_outside_actual'])
self.listen_state(self.temperature_change, entity=self.args['sensor_temperature_flow_actual'])
self.listen_state(self.temperature_change, entity=self.args['input_temperature_inside_setpoint'])
# Set inital power state
self.action_heating()
def get_sensor_temperatures(self, update_entity="", update_value=0.0):
# Get values from HA
if not update_entity:
self.temperature_outside_actual = float(self.get_state(self.args['sensor_temperature_outside_actual']))
self.temperature_flow_actual = float(self.get_state(self.args['sensor_temperature_flow_actual']))
self.temperature_inside_setpoint = float(self.get_state(self.args['input_temperature_inside_setpoint']))
elif update_entity == self.args['sensor_temperature_outside_actual']:
self.temperature_outside_actual = update_value
elif update_entity == self.args['sensor_temperature_flow_actual']:
self.temperature_flow_actual = update_value
elif update_entity == self.args['input_temperature_inside_setpoint']:
self.temperature_inside_setpoint = update_value
def calculate_temperature_flow_setpoint(self):
"""
Calculate best vorlauftemperatur
"""
temperature_flow_setpoint = float(min(max(0.55*self.gain*(self.temperature_inside_setpoint**(self.temperature_outside_actual/(320-self.temperature_outside_actual*4)))*((-self.temperature_outside_actual+20)*2)+self.temperature_inside_setpoint+self.adjustment, self.temperature_flow_min), self.temperature_flow_max))
return temperature_flow_setpoint
def calculate_heating_action(self):
"""
Decide wether to turn heating on, off or to leave it in its current state
"""
temperature_flow_setpoint = self.calculate_temperature_flow_setpoint()
self.log("T-flow-setpoint: "+str(temperature_flow_setpoint) +" => ")
if self.temperature_flow_actual < (temperature_flow_setpoint-self.temperature_flow_tolerance_below):
return "on"
elif self.temperature_flow_actual >= (temperature_flow_setpoint+self.temperature_flow_tolerance_above):
return "off"
else:
return ""
def temperature_change(self, entity, attribute, old, new, kwargs):
"""
Callback function
called if any temperature changes
"""
self.get_sensor_temperatures(update_entity=entity, update_value=float(new))
self.action_heating()
def action_heating(self):
"""
Action: Turn heating on or off
"""
# Decide to turn heating on or off
calculated_action = self.calculate_heating_action()
# Execute action
if calculated_action == "on":
self.action_heating_on({})
elif calculated_action == "off":
self.action_heating_off({})
else:
self.log("Leaving heating in its current state (T-flow-actual: %f; T-outside-actual: %f; T-inside-setpoint: %f)" % (self.temperature_flow_actual, self.temperature_outside_actual, self.temperature_inside_setpoint))
def action_heating_on(self, kwargs):
self.log("Turning heating on (T-flow-actual: %f; T-outside-actual: %f; T-inside-setpoint: %f)" % (self.temperature_flow_actual, self.temperature_outside_actual, self.temperature_inside_setpoint))
self.call_service("switch/turn_on", entity_id=self.switch_heating)
# Set timer for auto turn off to prevent damage
self.turn_off_timer = self.run_in(self.action_heating_off, int(60*self.switch_heating_max_on), timer=True)
def action_heating_off(self, kwargs):
if 'timer' in kwargs and kwargs['timer']==True:
self.log("Timeout reached for heating in state 'on'. Going to turn it off =>")
self.log("Turning heating off (T-flow-actual: %f; T-outside-actual: %f; T-inside-setpoint: %f)" % (self.temperature_flow_actual, self.temperature_outside_actual, self.temperature_inside_setpoint))
self.call_service("switch/turn_off", entity_id=self.switch_heating)
# cancel timer for auto turn off
if hasattr(self, 'turn_off_timer'):
self.cancel_timer(self.turn_off_timer)
self.log("Canceled turn_off timer")
import appdaemon.appapi as appapi
import datetime
# Declare Class
class TestSensors(appapi.AppDaemon):
#initialize() function which will be called at startup and reload
def initialize(self):
# Call to Home Assistant to turn the porch light on
self.log("Setting flow temp ...")
self.set_state("sensor.heating_flow_temp", state = 20, attributes={"unit_of_measurement": "°C", "friendly_name": "FlowTemp"})
self.log("Setting outside temp ...")
self.set_state("sensor.heating_outside_temp", state = 10, attributes={"unit_of_measurement": "°C", "friendly_name": "OutsideTemp"})
self.log("Setting set point ...")
self.set_state("input_slider.heating_setpoint_temp", state = 20, attributes={"initial": 0, "min": 0, "max": 35, "step": 1, "friendly_name": "SetPoint"})
self.log("Setting switch heating ...")
self.set_state("switch.heating", state = "off", attributes={"assumed_state": True, "friendly_name": "Switch"})
self.log("Setting group ...")
self.set_state("group.heating", state = "off", attributes={"assumed_state": False, "friendly_name": "HeatingLogicTest", "entity_id": ["sensor.heating_flow_temp","sensor.heating_outside_temp","input_slider.heating_setpoint_temp","switch.heating"]})
@matt2005
Copy link
Author

matt2005 commented Aug 9, 2017

Testsensors creates the components in Home assistant

@matt2005
Copy link
Author

matt2005 commented Aug 9, 2017

AppDaemon.yaml contains the additions required

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment