def orm_to_dto(orm_object): # type: (EepromModel) -> ThermostatDTO data = orm_object.serialize() kwargs = { 'name': data['name'], 'permanent_manual': data['permanent_manual'] } for i in range(6): field = 'setp{0}'.format(i) kwargs[field] = data[field] for field in [ 'sensor', 'output0', 'output1', 'pid_p', 'pid_i', 'pid_d', 'pid_int', 'room' ]: kwargs[field] = Toolbox.nonify(data[field], ThermostatMapper.BYTE_MAX) for day in ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']: field = 'auto_{0}'.format(day) kwargs[field] = ThermostatScheduleDTO(temp_night=data[field][0], start_day_1=data[field][1], end_day_1=data[field][2], temp_day_1=data[field][3], start_day_2=data[field][4], end_day_2=data[field][5], temp_day_2=data[field][6]) return ThermostatDTO(id=data['id'], **kwargs)
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)
def get_default_dto( thermostat_id, mode ): # type: (int, Literal['cooling', 'heating']) -> ThermostatDTO dto = ThermostatDTO(id=thermostat_id) # Presets dto.setp3 = Preset.DEFAULT_PRESETS[mode][Preset.Types.AWAY] dto.setp4 = Preset.DEFAULT_PRESETS[mode][Preset.Types.VACATION] dto.setp5 = Preset.DEFAULT_PRESETS[mode][Preset.Types.PARTY] # Schedules 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') ]: setattr( dto, key, ThermostatMapper._schedule_orm_to_dto(schedule_orm=DaySchedule( index=day_index, mode=mode, content='{}'), mode=mode, log_warnings=False)) return dto
def deserialize( api_data): # type: (Dict) -> Tuple[ThermostatDTO, List[str]] loaded_fields = ['id'] thermostat_dto = ThermostatDTO(api_data['id']) loaded_fields += SerializerToolbox.deserialize( dto=thermostat_dto, # Referenced api_data=api_data, mapping={ 'name': ('name', None), 'permanent_manual': ('permanent_manual', None), 'setp0': ('setp0', None), 'setp1': ('setp1', None), 'setp2': ('setp2', None), 'setp3': ('setp3', None), 'setp4': ('setp4', None), 'setp5': ('setp5', None), 'room': ('room', ThermostatSerializer.BYTE_MAX), 'sensor': ('sensor', ThermostatSerializer.BYTE_MAX), 'output0': ('output0', ThermostatSerializer.BYTE_MAX), 'output1': ('output1', ThermostatSerializer.BYTE_MAX), 'pid_p': ('pid_p', ThermostatSerializer.BYTE_MAX), 'pid_i': ('pid_i', ThermostatSerializer.BYTE_MAX), 'pid_d': ('pid_d', ThermostatSerializer.BYTE_MAX), 'pid_int': ('pid_int', ThermostatSerializer.BYTE_MAX) }) for day in ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']: field = 'auto_{0}'.format(day) if field not in api_data: continue loaded_fields.append(field) field_dto = ThermostatScheduleDTO(temp_night=api_data[field][0], start_day_1=api_data[field][1], end_day_1=api_data[field][2], temp_day_1=api_data[field][3], start_day_2=api_data[field][4], end_day_2=api_data[field][5], temp_day_2=api_data[field][6]) setattr(thermostat_dto, field, field_dto) return thermostat_dto, loaded_fields
def test_thermostat_change_events(self): events = [] def handle_event(gateway_event): events.append(gateway_event) self.pubsub.subscribe_gateway_events(PubSub.GatewayTopics.STATE, handle_event) with mock.patch.object(self.controller, 'invalidate_cache') as handle_event: status = { 'act': None, 'csetp': None, 'setpoint': None, 'output0': None, 'output1': None } self.controller._thermostats_config = {1: ThermostatDTO(1)} self.controller._thermostat_status._report_change(1, status) self.pubsub._publish_all_events() event_data = { 'id': 1, 'status': { 'preset': 'AUTO', 'current_setpoint': None, 'actual_temperature': None, 'output_0': None, 'output_1': None }, 'location': { 'room_id': 255 } } assert GatewayEvent(GatewayEvent.Types.THERMOSTAT_CHANGE, event_data) in events
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 orm_to_dto(orm_object, mode): # type: (Thermostat, str) -> ThermostatDTO dto = ThermostatDTO(id=orm_object.number, name=orm_object.name, sensor=orm_object.sensor.number if orm_object.sensor is not None else None, pid_p=getattr(orm_object, 'pid_{0}_p'.format(mode)), pid_i=getattr(orm_object, 'pid_{0}_i'.format(mode)), pid_d=getattr(orm_object, 'pid_{0}_d'.format(mode)), permanent_manual=orm_object.automatic, room=orm_object.room.number if orm_object.room is not None else None) # Outputs db_outputs = [ valve.output.number for valve in getattr(orm_object, '{0}_valves'.format(mode)) ] number_of_outputs = len(db_outputs) if number_of_outputs > 0: dto.output0 = db_outputs[0] if number_of_outputs > 1: dto.output1 = db_outputs[1] if number_of_outputs > 2: logger.warning( 'Only 2 outputs are supported in the old format. Total: {0} outputs.' .format(number_of_outputs)) # Presets for preset in orm_object.presets: setpoint = getattr(preset, '{0}_setpoint'.format(mode)) if preset.type == Preset.Types.AWAY: dto.setp3 = setpoint elif preset.type == Preset.Types.VACATION: dto.setp4 = setpoint elif preset.type == Preset.Types.PARTY: dto.setp5 = setpoint # Schedules day_schedules = { schedule.index: schedule for schedule in getattr(orm_object, '{0}_schedules'.format(mode))() } start_day_of_week = (orm_object.start / 86400 - 4) % 7 # 0: Monday, 1: Tuesday, ... 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') ]: index = int((7 - start_day_of_week + day_index) % 7) if index in day_schedules: setattr( dto, key, ThermostatMapper._schedule_orm_to_dto( day_schedules[index])) # TODO: Map missing [pid_int, setp0, setp1, setp2] return dto
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)
def load_cooling_thermostat(self, thermostat_id): # type: (int) -> ThermostatDTO return ThermostatDTO(0)