def load_sensor(self, sensor_id): # type: (int) -> SensorDTO sensor = Sensor.select(Room) \ .join_from(Sensor, Room, join_type=JOIN.LEFT_OUTER) \ .where(Sensor.number == sensor_id) \ .get() # type: Sensor # TODO: Load dict sensor_dto = self._master_controller.load_sensor(sensor_id=sensor_id) sensor_dto.room = sensor.room.number if sensor.room is not None else None return sensor_dto
def load_sensors(self): # type: () -> List[SensorDTO] sensor_dtos = [] for sensor_ in list( Sensor.select(Sensor, Room).join_from( Sensor, Room, join_type=JOIN.LEFT_OUTER)): # TODO: Load dicts sensor_dto = self._master_controller.load_sensor( sensor_id=sensor_.number) sensor_dto.room = sensor_.room.number if sensor_.room is not None else None sensor_dtos.append(sensor_dto) return sensor_dtos
def save_thermostat_group(self, thermostat_group): # type: (Tuple[ThermostatGroupDTO, List[str]]) -> None thermostat_group_dto, fields = thermostat_group # Update thermostat group configuration orm_object = ThermostatGroup.get(number=0) # type: ThermostatGroup if 'outside_sensor_id' in fields: orm_object.sensor = Sensor.get( number=thermostat_group_dto.outside_sensor_id) if 'threshold_temperature' in fields: orm_object.threshold_temperature = thermostat_group_dto.threshold_temperature # type: ignore orm_object.save() # Link configuration outputs to global thermostat config for mode in ['cooling', 'heating']: links = { link.index: link for link in OutputToThermostatGroup.select().where( (OutputToThermostatGroup.thermostat_group == orm_object) & (OutputToThermostatGroup.mode == mode)) } for i in range(4): field = 'switch_to_{0}_{1}'.format(mode, i) if field not in fields: continue link = links.get(i) data = getattr(thermostat_group_dto, field) if data is None: if link is not None: link.delete_instance() else: output_number, value = data output = Output.get(number=output_number) if link is None: OutputToThermostatGroup.create( output=output, thermostat_group=orm_object, mode=mode, index=i, value=value) else: link.output = output link.value = value link.save() if 'pump_delay' in fields: # Set valve delay for all valves in this group for thermostat in orm_object.thermostats: for valve in thermostat.valves: valve.delay = thermostat_group_dto.pump_delay # type: ignore valve.save()
def setUp(self): self.test_db = SqliteDatabase(':memory:') self.test_db.bind(MODELS) self.test_db.connect() self.test_db.create_tables(MODELS) self._gateway_api = mock.Mock(GatewayApi) self._gateway_api.get_sensor_temperature_status.return_value = 0.0 self._pump_valve_controller = mock.Mock(PumpValveController) SetUpTestInjections(gateway_api=self._gateway_api) self._thermostat_group = ThermostatGroup.create( number=0, name='thermostat group', on=True, threshold_temperature=10.0, sensor=Sensor.create(number=1), mode='heating')
def save_sensors( self, sensors): # type: (List[Tuple[SensorDTO, List[str]]]) -> None sensors_to_save = [] for sensor_dto, fields in sensors: sensor_ = Sensor.get_or_none(number=sensor_dto.id) # type: Sensor if sensor_ is None: logger.info('Ignored saving non-existing Sensor {0}'.format( sensor_dto.id)) if 'room' in fields: if sensor_dto.room is None: sensor_.room = None elif 0 <= sensor_dto.room <= 100: sensor_.room, _ = Room.get_or_create( number=sensor_dto.room) sensor_.save() sensors_to_save.append((sensor_dto, fields)) self._master_controller.save_sensors(sensors_to_save)
def setUp(self): self.test_db = SqliteDatabase(':memory:') self.test_db.bind(MODELS) self.test_db.connect() self.test_db.create_tables(MODELS) self._gateway_api = mock.Mock(GatewayApi) self._gateway_api.get_timezone.return_value = 'Europe/Brussels' self._gateway_api.get_sensor_temperature_status.return_value = 10.0 output_controller = mock.Mock(OutputController) output_controller.get_output_status.return_value = OutputStateDTO(id=0, status=False) SetUpTestInjections(gateway_api=self._gateway_api, output_controller=output_controller, pubsub=mock.Mock()) self._thermostat_controller = ThermostatControllerGateway() SetUpTestInjections(thermostat_controller=self._thermostat_controller) self._thermostat_group = ThermostatGroup.create(number=0, name='thermostat group', on=True, threshold_temperature=10.0, sensor=Sensor.create(number=1), mode='heating')
def _get_thermostat_pid(self): thermostat = Thermostat.create(number=1, name='thermostat 1', sensor=Sensor.create(number=10), pid_heating_p=200, pid_heating_i=100, pid_heating_d=50, pid_cooling_p=200, pid_cooling_i=100, pid_cooling_d=50, automatic=True, room=None, start=0, valve_config='equal', thermostat_group=self._thermostat_group) ValveToThermostat.create(thermostat=thermostat, valve=Valve.create( number=1, name='valve 1', output=Output.create(number=1)), mode=ThermostatGroup.Modes.HEATING, priority=0) ValveToThermostat.create(thermostat=thermostat, valve=Valve.create( number=2, name='valve 2', output=Output.create(number=2)), mode=ThermostatGroup.Modes.COOLING, priority=0) Preset.create(type=Preset.Types.SCHEDULE, heating_setpoint=20.0, cooling_setpoint=25.0, active=True, thermostat=thermostat) return ThermostatPid(thermostat=thermostat, pump_valve_controller=self._pump_valve_controller)
def test_save(self): temperatures = {} def _get_temperature(sensor_id): return temperatures[sensor_id] controller = GatewayThermostatMappingTests._create_controller( get_sensor_temperature_status=_get_temperature) room = Room(number=5) room.save() thermostat_group = ThermostatGroup(number=0, name='global') thermostat_group.save() thermostat = Thermostat( number=10, start=0, # 0 is on a thursday name='thermostat', thermostat_group=thermostat_group) thermostat.save() heating_thermostats = controller.load_heating_thermostats() self.assertEqual(1, len(heating_thermostats)) dto = heating_thermostats[0] # type: ThermostatDTO default_schedule_dto = ThermostatScheduleDTO(temp_day_1=20.0, start_day_1='07:00', end_day_1='09:00', temp_day_2=21.0, start_day_2='17:00', end_day_2='22:00', temp_night=16.0) Sensor.create(number=15) dto.room = 5 dto.sensor = 15 dto.output0 = 5 dto.name = 'changed' dto.auto_thu = ThermostatScheduleDTO(temp_night=10, temp_day_1=15, temp_day_2=30, start_day_1='08:00', end_day_1='10:30', start_day_2='16:00', end_day_2='18:45') temperatures[15] = 5.0 controller.save_heating_thermostats([dto]) heating_thermostats = controller.load_heating_thermostats() self.assertEqual(1, len(heating_thermostats)) dto = heating_thermostats[0] # type: ThermostatDTO self.assertEqual( ThermostatDTO(id=10, name='changed', setp3=16.0, setp4=15.0, setp5=22.0, sensor=15, pid_p=120.0, pid_i=0.0, pid_d=0.0, room=5, output0=5, permanent_manual=True, auto_mon=default_schedule_dto, auto_tue=default_schedule_dto, auto_wed=default_schedule_dto, auto_thu=ThermostatScheduleDTO(temp_night=10.0, temp_day_1=15.0, temp_day_2=30.0, start_day_1='08:00', end_day_1='10:30', start_day_2='16:00', end_day_2='18:45'), auto_fri=default_schedule_dto, auto_sat=default_schedule_dto, auto_sun=default_schedule_dto), dto)
def test_save_pumpgroups(self): thermostat = Thermostat.create(number=1, name='thermostat 1', sensor=Sensor.create(number=10), pid_heating_p=200, pid_heating_i=100, pid_heating_d=50, pid_cooling_p=200, pid_cooling_i=100, pid_cooling_d=50, automatic=True, room=None, start=0, valve_config='equal', thermostat_group=self._thermostat_group) valve_1_output = Output.create(number=1) valve_1 = Valve.create(number=1, name='valve 1', output=valve_1_output) valve_2_output = Output.create(number=2) valve_2 = Valve.create(number=2, name='valve 2', output=valve_2_output) valve_3_output = Output.create(number=3) valve_3 = Valve.create(number=3, name='valve 3', output=valve_3_output) ValveToThermostat.create(thermostat=thermostat, valve=valve_1, mode=ThermostatGroup.Modes.HEATING, priority=0) ValveToThermostat.create(thermostat=thermostat, valve=valve_2, mode=ThermostatGroup.Modes.COOLING, priority=0) ValveToThermostat.create(thermostat=thermostat, valve=valve_3, mode=ThermostatGroup.Modes.HEATING, priority=0) Preset.create(type=Preset.Types.SCHEDULE, heating_setpoint=20.0, cooling_setpoint=25.0, active=True, thermostat=thermostat) pump_output = Output.create(number=4) pump = Pump.create(name='pump 1', output=pump_output) heating_pump_groups = self._thermostat_controller.load_heating_pump_groups() self.assertEqual([PumpGroupDTO(id=pump.id, pump_output_id=pump_output.id, valve_output_ids=[], room_id=None)], heating_pump_groups) PumpToValve.create(pump=pump, valve=valve_1) PumpToValve.create(pump=pump, valve=valve_2) pump_groups = self._thermostat_controller.load_heating_pump_groups() self.assertEqual([PumpGroupDTO(id=pump.id, pump_output_id=pump_output.id, valve_output_ids=[valve_1_output.id], room_id=None)], pump_groups) pump_groups = self._thermostat_controller.load_cooling_pump_groups() self.assertEqual([PumpGroupDTO(id=pump.id, pump_output_id=pump_output.id, valve_output_ids=[valve_2_output.id], room_id=None)], pump_groups) self._thermostat_controller._save_pump_groups(ThermostatGroup.Modes.HEATING, [(PumpGroupDTO(id=pump.id, pump_output_id=pump_output.id, valve_output_ids=[valve_1_output.id, valve_3_output.id]), ['pump_output_id', 'valve_output_ids'])]) pump_groups = self._thermostat_controller.load_heating_pump_groups() self.assertEqual([PumpGroupDTO(id=pump.id, pump_output_id=pump_output.id, valve_output_ids=[valve_1_output.id, valve_3_output.id], room_id=None)], pump_groups) pump_groups = self._thermostat_controller.load_cooling_pump_groups() self.assertEqual([PumpGroupDTO(id=pump.id, pump_output_id=pump_output.id, valve_output_ids=[valve_2_output.id], room_id=None)], pump_groups)
def test_thermostat_control(self): thermostat = Thermostat.create(number=1, name='thermostat 1', sensor=Sensor.create(number=10), pid_heating_p=200, pid_heating_i=100, pid_heating_d=50, pid_cooling_p=200, pid_cooling_i=100, pid_cooling_d=50, automatic=True, room=None, start=0, valve_config='equal', thermostat_group=self._thermostat_group) Output.create(number=1) Output.create(number=2) Output.create(number=3) valve_output = Output.create(number=4) valve = Valve.create(number=1, name='valve 1', output=valve_output) ValveToThermostat.create(thermostat=thermostat, valve=valve, mode=ThermostatGroup.Modes.HEATING, priority=0) self._thermostat_controller.refresh_config_from_db() expected = ThermostatGroupStatusDTO(id=0, on=True, setpoint=0, cooling=False, automatic=True, statusses=[ThermostatStatusDTO(id=1, name='thermostat 1', automatic=True, setpoint=0, sensor_id=10, actual_temperature=10.0, setpoint_temperature=14.0, outside_temperature=10.0, output_0_level=0, output_1_level=0, mode=0, airco=0)]) self.assertEqual(expected, self._thermostat_controller.get_thermostat_status()) self._thermostat_controller.set_current_setpoint(thermostat_number=1, heating_temperature=15.0) expected.statusses[0].setpoint_temperature = 15.0 self.assertEqual(expected, self._thermostat_controller.get_thermostat_status()) self._thermostat_controller.set_per_thermostat_mode(thermostat_number=1, automatic=True, setpoint=16.0) expected.statusses[0].setpoint_temperature = 16.0 self.assertEqual(expected, self._thermostat_controller.get_thermostat_status()) preset = self._thermostat_controller.get_current_preset(thermostat_number=1) self.assertTrue(preset.active) self.assertEqual(30.0, preset.cooling_setpoint) self.assertEqual(16.0, preset.heating_setpoint) self.assertEqual(Preset.Types.SCHEDULE, preset.type) self._thermostat_controller.set_current_preset(thermostat_number=1, preset_type=Preset.Types.PARTY) expected.statusses[0].setpoint_temperature = 14.0 expected.statusses[0].setpoint = expected.setpoint = 5 # PARTY = legacy `5` setpoint expected.statusses[0].automatic = expected.automatic = False self.assertEqual(expected, self._thermostat_controller.get_thermostat_status()) self._thermostat_controller.set_thermostat_mode(thermostat_on=True, cooling_mode=True, cooling_on=True, automatic=False, setpoint=4) expected.statusses[0].setpoint_temperature = 30.0 expected.statusses[0].setpoint = expected.setpoint = 4 # VACATION = legacy `4` setpoint expected.cooling = True self.assertEqual(expected, self._thermostat_controller.get_thermostat_status()) self._thermostat_controller.set_thermostat_mode(thermostat_on=True, cooling_mode=False, cooling_on=True, automatic=True) expected.statusses[0].setpoint_temperature = 16.0 expected.statusses[0].setpoint = expected.setpoint = 0 # AUTO = legacy `0/1/2` setpoint expected.statusses[0].automatic = expected.automatic = True expected.cooling = False self.assertEqual(expected, self._thermostat_controller.get_thermostat_status())
def test_thermostat_group_crud(self): thermostat = Thermostat.create(number=1, name='thermostat 1', sensor=Sensor.create(number=10), pid_heating_p=200, pid_heating_i=100, pid_heating_d=50, pid_cooling_p=200, pid_cooling_i=100, pid_cooling_d=50, automatic=True, room=None, start=0, valve_config='equal', thermostat_group=self._thermostat_group) Output.create(number=1) Output.create(number=2) Output.create(number=3) valve_output = Output.create(number=4) valve = Valve.create(number=1, name='valve 1', output=valve_output) ValveToThermostat.create(thermostat=thermostat, valve=valve, mode=ThermostatGroup.Modes.HEATING, priority=0) thermostat_group = ThermostatGroup.get(number=0) # type: ThermostatGroup self.assertEqual(10.0, thermostat_group.threshold_temperature) self.assertEqual(0, OutputToThermostatGroup.select() .where(OutputToThermostatGroup.thermostat_group == thermostat_group) .count()) self._thermostat_controller.save_thermostat_group((ThermostatGroupDTO(id=0, outside_sensor_id=1, pump_delay=30, threshold_temperature=15, switch_to_heating_0=(1, 0), switch_to_heating_1=(2, 100), switch_to_cooling_0=(1, 100)), ['outside_sensor_id', 'pump_delay', 'threshold_temperature', 'switch_to_heating_0', 'switch_to_heating_1', 'switch_to_cooling_0'])) thermostat_group = ThermostatGroup.get(number=0) self.assertEqual(15.0, thermostat_group.threshold_temperature) links = [{'index': link.index, 'value': link.value, 'mode': link.mode, 'output': link.output_id} for link in (OutputToThermostatGroup.select() .where(OutputToThermostatGroup.thermostat_group == thermostat_group))] self.assertEqual(3, len(links)) self.assertIn({'index': 0, 'value': 0, 'mode': 'heating', 'output': 1}, links) self.assertIn({'index': 1, 'value': 100, 'mode': 'heating', 'output': 2}, links) self.assertIn({'index': 0, 'value': 100, 'mode': 'cooling', 'output': 1}, links) new_thermostat_group_dto = ThermostatGroupDTO(id=0, outside_sensor_id=1, pump_delay=60, threshold_temperature=10, switch_to_heating_0=(1, 50), switch_to_cooling_0=(2, 0)) self._thermostat_controller.save_thermostat_group((new_thermostat_group_dto, ['outside_sensor_id', 'pump_delay', 'threshold_temperature', 'switch_to_heating_0', 'switch_to_heating_1', 'switch_to_cooling_0'])) thermostat_group = ThermostatGroup.get(number=0) self.assertEqual(10.0, thermostat_group.threshold_temperature) links = [{'index': link.index, 'value': link.value, 'mode': link.mode, 'output': link.output_id} for link in (OutputToThermostatGroup.select() .where(OutputToThermostatGroup.thermostat_group == thermostat_group))] self.assertEqual(2, len(links)) self.assertIn({'index': 0, 'value': 50, 'mode': 'heating', 'output': 1}, links) self.assertIn({'index': 0, 'value': 0, 'mode': 'cooling', 'output': 2}, links) self.assertEqual(new_thermostat_group_dto, self._thermostat_controller.load_thermostat_group())
def test_save(self): temperatures = {} def _get_temperature(sensor_id): return temperatures[sensor_id] controller = GatewayThermostatMappingTests._create_controller( get_sensor_temperature_status=_get_temperature) thermostat_group = ThermostatGroup(number=0, name='global') thermostat_group.save() thermostat = Thermostat( number=10, start=0, # 0 is on a thursday name='thermostat', thermostat_group=thermostat_group) thermostat.save() for i in range(7): day_schedule = DaySchedule(index=i, content='{}', mode='heating') day_schedule.thermostat = thermostat day_schedule.save() heating_thermostats = controller.load_heating_thermostats() self.assertEqual(1, len(heating_thermostats)) dto = heating_thermostats[0] # type: ThermostatDTO Sensor.create(number=15) dto.room = 5 # This field won't be saved dto.sensor = 15 dto.output0 = 5 dto.name = 'changed' dto.auto_thu = ThermostatScheduleDTO(temp_night=10, temp_day_1=15, temp_day_2=30, start_day_1='08:00', end_day_1='10:30', start_day_2='16:00', end_day_2='18:45') temperatures[15] = 5.0 controller.save_heating_thermostats([ (dto, ['sensor', 'output0', 'name', 'auto_thu']) ]) heating_thermostats = controller.load_heating_thermostats() self.assertEqual(1, len(heating_thermostats)) dto = heating_thermostats[0] # type: ThermostatDTO self.assertEqual( ThermostatDTO( id=10, name='changed', setp3=14.0, setp4=14.0, setp5=14.0, sensor=15, pid_p=120.0, pid_i=0.0, pid_d=0.0, room=None, # Unchanged output0=5, permanent_manual=True, auto_thu=ThermostatScheduleDTO(temp_night=10.0, temp_day_1=15.0, temp_day_2=30.0, start_day_1='08:00', end_day_1='10:30', start_day_2='16:00', end_day_2='18:45')), dto)