def control_thermostat(): now = datetime.now() therm = Thermostat.objects.all()[0] client = ThermostatClient(therm.ip_address) cur_state = client.get("/tstat") cur_temp = cur_state.get('temp', None) cur_operating_mode = cur_state.get('tmode', 0) cur_hvac_state = cur_state.get('tstate', 0) is_override = False if cur_state.get('override', 0) == 0 else True is_hold = False if cur_state.get('hold', 0) == 0 else True heat_setpoint = cur_state.get('t_heat', None) cool_setpoint = cur_state.get('t_cool', None) if cur_state.get('error', None) or not cur_temp or cur_temp == -1: print cur_state return cur_running_setpoint = heat_setpoint if cur_operating_mode == 1 else cool_setpoint # Save data as signals tempsensor = ThermostatTemperatureSensor.objects.filter(thermostat=therm)[0] indoor_temp_signal = _get_signal(sensor=tempsensor, value_type='real') heat_on_signal = _get_signal(name='Heat On', value_type='bool') cool_on_signal = _get_signal(name='Cool On', value_type='bool') setpoint_signal = _get_signal(name='Temperature Setpoint', value_type='real') _save_datapoint(indoor_temp_signal, cur_temp) _save_datapoint(heat_on_signal, cur_hvac_state == 1) _save_datapoint(cool_on_signal, cur_hvac_state == 2) # Look up latest weekly recurring setpoint to use recurring_setpoints = RecurringWeeklySetpoint.objects.all() sorted_recurring = sorted(recurring_setpoints, key=attrgetter('day_of_week', 'hour', 'minute')) recurring_setpoint = None for s in sorted_recurring: date_this_week = _get_date_this_week(s, now=now) if date_this_week < now: recurring_setpoint = s # See if we have any scheduled hold setpoints # Doesn't make sense to have overlapping hold setpoints, so pick the first one we find hold_setpoints = ScheduledHoldSetpoint.objects.filter(start__lte=now, end__gte=now) hold_setpoint = hold_setpoints[0] if hold_setpoints else None # Figure out which setpoint to use # Scheduled hold setpoints trump recurring weekly setpoints, # and manual override (from thermostat panel or web interface) trump all if recurring_setpoint: last_recurring_setpoint = therm.last_recurring_setpoint if not last_recurring_setpoint: switch_periods = True else: if _get_date_this_week(recurring_setpoint, now=now) > _get_date_this_week(last_recurring_setpoint, now=now): switch_periods = True else: switch_periods = False if hold_setpoint: last_hold_setpoint = therm.last_scheduled_setpoint if last_hold_setpoint != hold_setpoint: switch_periods = True therm.last_recurring_setpoint = recurring_setpoint therm.last_scheduled_setpoint = hold_setpoint therm.save() temp_to_set = None if recurring_setpoint: temp_to_set = recurring_setpoint.setpoint new_mode = recurring_setpoint.mode if hold_setpoint: temp_to_set = hold_setpoint.setpoint new_mode = hold_setpoint.mode if is_override and not switch_periods: temp_to_set = None if temp_to_set and temp_to_set != cur_running_setpoint: if new_mode == 'auto': new_mode = therm.mode if new_mode == 'heat': params = {'a_heat': temp_to_set, 'hold': 1, 'a_mode': 1} elif new_mode == 'cool': params = {'a_cool': temp_to_set, 'hold': 1, 'a_mode': 1} if new_mode != therm.mode: params.update({'tmode': 1 if new_mode == 'heat' else 2}) client.send("/tstat", params) # TODO: Handle auto mode _save_datapoint(setpoint_signal, temp_to_set) else: if cur_running_setpoint: _save_datapoint(setpoint_signal, cur_running_setpoint)