Skip to content

Instantly share code, notes, and snippets.

@dlashua
Last active July 18, 2019 13:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dlashua/b24f4b58255284f605b64270c9fa7344 to your computer and use it in GitHub Desktop.
Save dlashua/b24f4b58255284f605b64270c9fa7344 to your computer and use it in GitHub Desktop.
import appdaemon.plugins.hass.hassapi as hass
import voluptuous as vol
import time
## YAML CONFIG
# hvac_cool_switch:
# module: climateswitch
# class: ClimateSwitch
# climate: climate.hvac_cool
# switch: group.house_coolers
# mode: cool
# on_difference: -2
# off_difference: 2
# min_cycle_time: 900
class ClimateSwitch(hass.Hass):
def initialize(self):
self._ready = False
appdaemon_schema = vol.Schema({
vol.Remove(vol.Required('module')): str,
vol.Remove(vol.Required('class')): str,
vol.Remove('global_dependencies'): vol.Any(str, list),
vol.Remove('dependencies'): vol.Any(str, list),
})
schema = vol.Schema(vol.All(
appdaemon_schema.extend({
'climate': str,
'mode': vol.Any("heat", "cool"),
'on_difference': int,
'off_difference': int,
'switch': str,
vol.Optional('min_cycle_time', default=600): int,
})
))
self._config = schema(self.args)
self.last_change = 0
self._timer = None
self.listen()
self._ready = True
self.update_state()
def listen(self):
self.listen_state(
self.update_state_c, self._config['climate'], attribute="all")
self.listen_state(
self.update_state_c, self._config['switch'], attribute="all")
pass
def update_state_c(self, entity, attribute, old, new, kwargs):
if new != old:
self.update_state()
def update_state_t(self, kwargs):
self._timer = None
self.update_state()
def update_state(self):
if not self._ready:
self.log('Not Ready')
return
climate_state = self.get_state(
self._config['climate'], attribute="all")
switch_state = self.get_state(
self._config['switch'], attribute="all")
self.log('CLIMATE STATE: {}'.format(climate_state), level="DEBUG")
self.log('SWITCH STATE: {}'.format(switch_state), level="DEBUG")
if climate_state.get('attributes').get('operation_mode') != self._config['mode']:
self.log(
'Climate Entity not in mode "{}"'.format(
self._config['mode']),
level="WARNING")
return
current_temp = climate_state.get('attributes').get('current_temperature')
self.log('Current Temperature: {}'.format(current_temp), level="DEBUG")
current_setpoint = climate_state.get('attributes').get('temperature')
self.log('Current Setpoint: {}'.format(current_setpoint), level="DEBUG")
current_state = switch_state.get('state')
self.log('Current State: {}'.format(current_state), level="DEBUG")
calc_setpoint = current_temp
if current_state == "on":
calc_setpoint = current_temp + self._config['on_difference']
elif current_state == "off":
calc_setpoint = current_temp + self._config['off_difference']
self.log('Calculated Setpoint: {}'.format(calc_setpoint), level="DEBUG")
if current_setpoint != calc_setpoint:
self.set_setpoint(calc_setpoint)
return
self.log('No Change Needed', level="DEBUG")
def set_setpoint(self, setpoint):
time_since_last_change = time.time() - self.last_change
remaining_time = round(self._config['min_cycle_time'] - time_since_last_change)
if remaining_time > 0:
self.log('Min Cycle Not Elapsed. Wants {}. Wait {}s.'.format(setpoint, remaining_time))
self.cancel_timer(self._timer)
self._timer = self.run_in(self.update_state_t, remaining_time)
return
self.last_change = time.time()
self.log('Setting Setpoint to {}'.format(setpoint))
data = {
"entity_id": self._config['climate'],
"temperature": setpoint,
}
self.call_service(
'climate/set_temperature',
**data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment