Example #1
0
    def set_thermostat_mode(self,
                            thermostat_on,
                            cooling_mode=False,
                            cooling_on=False,
                            automatic=None,
                            setpoint=None):
        # type: (bool, bool, bool, Optional[bool], Optional[int]) -> None
        mode = ThermostatMode.COOLING if cooling_mode else ThermostatMode.HEATING  # type: Literal['cooling', 'heating']
        global_thermosat = ThermostatGroup.get(number=0)
        global_thermosat.on = thermostat_on
        global_thermosat.mode = mode
        global_thermosat.save()

        for thermostat_number, thermostat_pid in self.thermostat_pids.items():
            thermostat = Thermostat.get(number=thermostat_number)
            if thermostat is not None:
                if automatic is False and setpoint is not None and 3 <= setpoint <= 5:
                    preset = thermostat.get_preset(
                        preset_type=Preset.SETPOINT_TO_TYPE.get(
                            setpoint, Preset.Types.SCHEDULE))
                    thermostat.active_preset = preset
                else:
                    thermostat.active_preset = thermostat.get_preset(
                        preset_type=Preset.Types.SCHEDULE)
                thermostat_pid.update_thermostat(thermostat)
                thermostat_pid.tick()
Example #2
0
    def test_orm_to_dto_mapping(self):
        controller = GatewayThermostatMappingTests._create_controller()

        group, _ = ThermostatGroup.get_or_create(
            number=0,
            name='Default',
            on=True,
            mode=ThermostatGroup.Modes.HEATING)
        thermostat = Thermostat(
            number=10,
            start=0,  # 0 is on a thursday
            name='thermostat',
            thermostat_group=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

        self.assertEqual(
            ThermostatDTO(id=10,
                          name='thermostat',
                          setp3=14.0,
                          setp4=14.0,
                          setp5=14.0,
                          sensor=None,
                          pid_p=120.0,
                          pid_i=0.0,
                          pid_d=0.0,
                          room=None,
                          permanent_manual=True), dto)

        day_schedule = thermostat.heating_schedules()[0]  # type: DaySchedule
        day_schedule.schedule_data = {
            0: 5.0,
            120: 5.5,  # 120 and 1200 are selected because 120 < 1200,
            1200: 6.0,  # but str(120) > str(1200)
            3600: 6.5,
            7500: 7.0
        }
        day_schedule.save()
        heating_thermostats = controller.load_heating_thermostats()
        self.assertEqual(1, len(heating_thermostats))
        dto = heating_thermostats[0]  # type: ThermostatDTO

        self.assertEqual(
            ThermostatScheduleDTO(temp_night=5.0,
                                  temp_day_1=5.5,
                                  temp_day_2=6.5,
                                  start_day_1='00:02',
                                  end_day_1='00:20',
                                  start_day_2='01:00',
                                  end_day_2='02:05'), dto.auto_thu)
Example #3
0
    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()
Example #4
0
 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')
Example #5
0
    def test_load(self):
        controller = GatewayThermostatMappingTests._create_controller()

        group, _ = ThermostatGroup.get_or_create(
            number=0,
            name='Default',
            on=True,
            mode=ThermostatGroup.Modes.HEATING)
        thermostat = Thermostat(number=10,
                                start=0,
                                name='thermostat',
                                thermostat_group=group)
        thermostat.save()

        for i in range(7):
            day_schedule = DaySchedule(index=i, content='{}', mode='heating')
            day_schedule.thermostat = thermostat
            day_schedule.save()
            day_schedule = DaySchedule(index=i, content='{}', mode='cooling')
            day_schedule.thermostat = thermostat
            day_schedule.save()

        # Validate load calls
        heating_thermostats = controller.load_heating_thermostats()
        self.assertEqual(1, len(heating_thermostats))
        cooling_thermostats = controller.load_cooling_thermostats()
        self.assertEqual(1, len(cooling_thermostats))
        heating_thermostat_dto = heating_thermostats[0]
        cooling_thermostat_dto = cooling_thermostats[0]
        self.assertEqual(heating_thermostat_dto,
                         controller.load_heating_thermostat(10))
        self.assertEqual(cooling_thermostat_dto,
                         controller.load_cooling_thermostat(10))

        # Validate contents
        # Presets have a different default value for cooling vs heating
        heating_thermostat_dto.setp3 = cooling_thermostat_dto.setp3
        heating_thermostat_dto.setp4 = cooling_thermostat_dto.setp4
        heating_thermostat_dto.setp5 = cooling_thermostat_dto.setp5
        self.assertEqual(heating_thermostat_dto, cooling_thermostat_dto)
        self.assertEqual('thermostat', heating_thermostat_dto.name)
        self.assertEqual(thermostat.number, heating_thermostat_dto.id)
 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')
Example #7
0
 def load_thermostat_group(self):
     # type: () -> ThermostatGroupDTO
     thermostat_group = ThermostatGroup.get(number=0)
     pump_delay = None
     for thermostat in thermostat_group.thermostats:
         for valve in thermostat.valves:
             pump_delay = valve.delay
             break
     sensor_number = None if thermostat_group.sensor is None else thermostat_group.sensor.number
     thermostat_group_dto = ThermostatGroupDTO(
         id=0,
         outside_sensor_id=sensor_number,
         threshold_temperature=thermostat_group.threshold_temperature,
         pump_delay=pump_delay)
     for link in OutputToThermostatGroup.select(OutputToThermostatGroup, Output) \
                                        .join_from(OutputToThermostatGroup, Output) \
                                        .where(OutputToThermostatGroup.thermostat_group == thermostat_group):
         if link.index > 3 or link.output is None:
             continue
         field = 'switch_to_{0}_{1}'.format(link.mode, link.index)
         setattr(thermostat_group_dto, field,
                 (link.output.number, link.value))
     return thermostat_group_dto
Example #8
0
    def test_load(self):
        controller = GatewayThermostatMappingTests._create_controller()

        group, _ = ThermostatGroup.get_or_create(
            number=0,
            name='Default',
            on=True,
            mode=ThermostatGroup.Modes.HEATING)
        thermostat = Thermostat(number=10,
                                start=0,
                                name='thermostat',
                                thermostat_group=group)
        thermostat.save()

        # Validate load calls
        heating_thermostats = controller.load_heating_thermostats()
        self.assertEqual(1, len(heating_thermostats))
        cooling_thermostats = controller.load_cooling_thermostats()
        self.assertEqual(1, len(cooling_thermostats))
        heating_thermostat_dto = heating_thermostats[0]
        cooling_thermostat_dto = cooling_thermostats[0]
        self.assertEqual(heating_thermostat_dto,
                         controller.load_heating_thermostat(10))
        self.assertEqual(cooling_thermostat_dto,
                         controller.load_cooling_thermostat(10))

        # Validate contents
        # Presets & schedules have a different default value for cooling vs heating
        heating_thermostat_dto.setp3 = cooling_thermostat_dto.setp3
        heating_thermostat_dto.setp4 = cooling_thermostat_dto.setp4
        heating_thermostat_dto.setp5 = cooling_thermostat_dto.setp5
        for day in ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']:
            setattr(heating_thermostat_dto, 'auto_{0}'.format(day),
                    getattr(cooling_thermostat_dto, 'auto_{0}'.format(day)))
        self.assertEqual(heating_thermostat_dto, cooling_thermostat_dto)
        self.assertEqual('thermostat', heating_thermostat_dto.name)
        self.assertEqual(thermostat.number, heating_thermostat_dto.id)
Example #9
0
    def get_thermostat_status(self):  # type: () -> ThermostatGroupStatusDTO
        def get_output_level(output_number):
            if output_number is None:
                return 0  # we are returning 0 if outputs are not configured
            try:
                output = self._output_controller.get_output_status(
                    output_number)
            except ValueError:
                logger.info(
                    'Output {0} state not yet available'.format(output_number))
                return 0  # Output state is not yet cached (during startup)
            if output.dimmer is None:
                status_ = output.status
                output_level = 0 if status_ is None else int(status_) * 100
            else:
                output_level = output.dimmer
            return output_level

        global_thermostat = ThermostatGroup.get(number=0)
        if global_thermostat is None:
            raise RuntimeError('Global thermostat not found!')
        group_status = ThermostatGroupStatusDTO(
            id=0,
            on=global_thermostat.on,
            automatic=True,  # Default, will be updated below
            setpoint=0,  # Default, will be updated below
            cooling=global_thermostat.mode == ThermostatMode.COOLING)

        for thermostat in global_thermostat.thermostats:
            valves = thermostat.cooling_valves if global_thermostat.mode == 'cooling' else thermostat.heating_valves
            db_outputs = [valve.output.number for valve in valves]

            number_of_outputs = len(db_outputs)
            if number_of_outputs > 2:
                logger.warning(
                    'Only 2 outputs are supported in the old format. Total: {0} outputs.'
                    .format(number_of_outputs))

            output0 = db_outputs[0] if number_of_outputs > 0 else None
            output1 = db_outputs[1] if number_of_outputs > 1 else None

            active_preset = thermostat.active_preset
            if global_thermostat.mode == ThermostatMode.COOLING:
                setpoint_temperature = active_preset.cooling_setpoint
            else:
                setpoint_temperature = active_preset.heating_setpoint

            group_status.statusses.append(
                ThermostatStatusDTO(
                    id=thermostat.number,
                    actual_temperature=self._gateway_api.
                    get_sensor_temperature_status(thermostat.sensor),
                    setpoint_temperature=setpoint_temperature,
                    outside_temperature=self._gateway_api.
                    get_sensor_temperature_status(global_thermostat.sensor),
                    mode=0,  # TODO: Need to be fixed
                    automatic=active_preset.type == Preset.Types.SCHEDULE,
                    setpoint=Preset.TYPE_TO_SETPOINT.get(
                        active_preset.type, 0),
                    name=thermostat.name,
                    sensor_id=thermostat.sensor.number,
                    airco=0,  # TODO: Check if still used
                    output_0_level=get_output_level(output0),
                    output_1_level=get_output_level(output1)))

        # Update global references
        group_status.automatic = all(status.automatic
                                     for status in group_status.statusses)
        used_setpoints = set(status.setpoint
                             for status in group_status.statusses)
        group_status.setpoint = next(iter(used_setpoints)) if len(
            used_setpoints) == 1 else 0  # 0 is a fallback

        return group_status
Example #10
0
    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)
Example #11
0
    def dto_to_orm(
            thermostat_dto, fields,
            mode):  # type: (ThermostatDTO, List[str], str) -> Thermostat
        # TODO: A mapper should not alter the database, but instead give an in-memory
        #       structure back to the caller to process
        objects = {}  # type: Dict[str, Dict[int, Any]]

        def _load_object(orm_type, number):
            if number is None:
                return None
            return objects.setdefault(orm_type.__name__, {}).setdefault(
                number, orm_type.get(number=number))

        # We don't get a start date, calculate last monday night to map the schedules
        now = int(time.time())
        day_of_week = (now / 86400 - 4) % 7  # 0: Monday, 1: Tuesday, ...
        last_monday_night = now - now % 86400 - day_of_week * 86400

        # Update/save thermostat configuration
        try:
            thermostat = Thermostat.get(number=thermostat_dto.id)
        except Thermostat.DoesNotExist:
            thermostat_group = ThermostatGroup.get(number=0)
            thermostat = Thermostat(number=thermostat_dto.id)
            thermostat.thermostat_group = thermostat_group
        for orm_field, (dto_field, mapping) in {
                'name': ('name', None),
                'sensor': ('sensor', lambda n: _load_object(Sensor, n)),
                'room': ('room', lambda n: _load_object(Room, n)),
                'pid_{0}_p'.format(mode): ('pid_p', float),
                'pid_{0}_i'.format(mode): ('pid_i', float),
                'pid_{0}_d'.format(mode): ('pid_d', float)
        }.items():
            if dto_field not in fields:
                continue
            value = getattr(thermostat_dto, dto_field)
            if value is None:
                continue
            if mapping is not None:
                value = mapping(value)
            setattr(thermostat, orm_field, value)

        thermostat.start = last_monday_night
        thermostat.save()

        # Update/save output configuration
        output_config_present = 'output0' in fields or 'output1' in fields
        if output_config_present:
            # Unlink all previously linked valve_ids, we are resetting this with the new outputs we got from the API
            deleted = ValveToThermostat \
                .delete() \
                .where(ValveToThermostat.thermostat == thermostat) \
                .where(ValveToThermostat.mode == mode) \
                .execute()
            logger.info('Unlinked {0} valve_ids from thermostat {1}'.format(
                deleted, thermostat.name))

            for field in ['output0', 'output1']:
                dto_data = getattr(thermostat_dto, field)
                if dto_data is None:
                    continue

                # 1. Get or create output, creation also saves to db
                output_number = int(dto_data)
                output, output_created = Output.get_or_create(
                    number=output_number)

                # 2. Get or create the valve and link to this output
                try:
                    valve = Valve.get(output=output)
                except DoesNotExist:
                    valve = Valve(output=output)
                valve.name = 'Valve (output {0})'.format(output_number)
                valve.save()

                # 3. Link the valve to the thermostat, set properties
                try:
                    valve_to_thermostat = ValveToThermostat.get(
                        valve=valve, thermostat=thermostat, mode=mode)
                except DoesNotExist:
                    valve_to_thermostat = ValveToThermostat(
                        valve=valve, thermostat=thermostat, mode=mode)

                # TODO: Decide if this is a cooling thermostat or heating thermostat
                valve_to_thermostat.priority = 0 if field == 'output0' else 1
                valve_to_thermostat.save()

        # Update/save scheduling configuration
        for day_index, key in [
            (0, 'auto_mon'), (1, 'auto_tue'), (2, 'auto_wed'), (3, 'auto_thu'),
            (4, 'auto_fri'), (5, 'auto_sat'), (6, 'auto_sun')
        ]:
            if key not in fields:
                continue
            dto_data = getattr(thermostat_dto, key)
            if dto_data is None:
                continue
            try:
                day_schedule = DaySchedule.get(thermostat=thermostat,
                                               index=day_index,
                                               mode=mode)
            except DoesNotExist:
                day_schedule = DaySchedule(thermostat=thermostat,
                                           index=day_index,
                                           mode=mode)
            day_schedule.schedule_data = ThermostatMapper._schedule_dto_to_orm(
                dto_data)
            day_schedule.save()

        # Presets
        for field, preset_type in [('setp3', Preset.Types.AWAY),
                                   ('setp4', Preset.Types.VACATION),
                                   ('setp5', Preset.Types.PARTY)]:
            if field not in fields:
                continue
            dto_data = getattr(thermostat_dto, field)
            if dto_data is None:
                continue
            try:
                preset = Preset.get(type=preset_type, thermostat=thermostat)
            except DoesNotExist:
                preset = Preset(type=preset_type, thermostat=thermostat)
            setattr(preset, '{0}_setpoint'.format(mode), float(dto_data))
            preset.active = False
            preset.save()

        # TODO: Map missing [permanent_manual, setp0, setp1, setp2, pid_int]
        return thermostat
    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())
Example #13
0
    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)