Esempio n. 1
0
 def refresh_from_db(self):  # type: () -> None
     with self._config_change_lock:
         # Collect valve drivers
         current_ids = []
         for item in Valve.select():
             if item.id in self._valve_drivers:
                 self._valve_drivers[item.id].update(item)
             else:
                 self._valve_drivers[item.id] = ValveDriver(item)
             current_ids.append(item.id)
         for item_id in list(self._valve_drivers.keys()):
             if item_id not in current_ids:
                 del self._valve_drivers[item_id]
         # Collect pump drivers
         current_ids = []
         pump_drivers_per_valve = {}  # type: Dict[int, Set[PumpDriver]]
         for item in Pump.select():
             if item.id in self._pump_drivers:
                 pump_driver = self._pump_drivers[item.id]
                 pump_driver.update(item)
             else:
                 pump_driver = PumpDriver(item)
                 self._pump_drivers[item.id] = pump_driver
             current_ids.append(item.id)
             for valve_id in pump_driver.valve_ids:
                 if valve_id not in pump_drivers_per_valve:
                     pump_drivers_per_valve[valve_id] = set()
                 pump_drivers_per_valve[valve_id].add(pump_driver)
         for item_id in list(self._pump_drivers.keys()):
             if item_id not in current_ids:
                 del self._pump_drivers[item_id]
         self._pump_drivers_per_valve = pump_drivers_per_valve
Esempio n. 2
0
    def _save_pump_groups(
        mode, pump_groups
    ):  # type: (str, List[Tuple[PumpGroupDTO, List[str]]]) -> None
        for pump_group_dto, fields in pump_groups:
            if 'pump_output_id' in fields and 'valve_output_ids' in fields:
                valve_output_ids = pump_group_dto.valve_output_ids
                pump = Pump.get(id=pump_group_dto.id)  # type: Pump
                pump.output = Output.get(number=pump_group_dto.pump_output_id)

                links = {
                    pump_to_valve.valve.output.number: pump_to_valve
                    for pump_to_valve in PumpToValve.select(
                        PumpToValve, Pump, Valve, Output).join_from(
                            PumpToValve, Valve).join_from(
                                PumpToValve, Pump).join_from(Valve, Output).
                    join_from(Valve, ValveToThermostat).where((
                        ValveToThermostat.mode == mode) & (Pump.id == pump.id))
                }
                for output_id in list(links.keys()):
                    if output_id not in valve_output_ids:
                        pump_to_valve = links.pop(
                            output_id)  # type: PumpToValve
                        pump_to_valve.delete_instance()
                    else:
                        valve_output_ids.remove(output_id)
                for output_id in valve_output_ids:
                    output = Output.get(number=output_id)
                    valve = Valve.get_or_none(output=output)
                    if valve is None:
                        valve = Valve(name=output.name, output=output)
                        valve.save()
                    PumpToValve.create(pump=pump, valve=valve)
Esempio n. 3
0
 def load_cooling_pump_group(self,
                             pump_group_id):  # type: (int) -> PumpGroupDTO
     pump = Pump.get(number=pump_group_id)
     return PumpGroupDTO(id=pump_group_id,
                         pump_output_id=pump.output.number,
                         valve_output_ids=[
                             valve.output.number
                             for valve in pump.cooling_valves
                         ],
                         room_id=None)
Esempio n. 4
0
 def load_cooling_pump_groups(self):  # type: () -> List[PumpGroupDTO]
     pump_groups = []
     for pump in Pump.select():
         pump_groups.append(
             PumpGroupDTO(id=pump.id,
                          pump_output_id=pump.output.number,
                          valve_output_ids=[
                              valve.output.number
                              for valve in pump.cooling_valves
                          ],
                          room_id=None))
     return pump_groups
Esempio n. 5
0
    def test_pump_driver(self):
        output = Output.create(number=0)
        pump = Pump.create(number=1,
                           name='pump',
                           output=output)

        SetUpTestInjections(output_controller=mock.Mock(OutputController))
        driver = PumpDriver(pump)
        self.assertIsNone(driver.state)
        self.assertFalse(driver.error)
        self.assertEqual(pump.id, driver.id)

        driver.turn_on()
        self.assertTrue(driver.state)
        self.assertFalse(driver.error)

        driver.turn_off()
        self.assertFalse(driver.state)
        self.assertFalse(driver.error)

        driver._output_controller.set_output_status.side_effect = RuntimeError()
        with self.assertRaises(RuntimeError):
            driver.turn_on()
        self.assertFalse(driver.state)
        self.assertTrue(driver.error)

        driver._output_controller.set_output_status.side_effect = None
        driver.turn_on()
        self.assertTrue(driver.state)
        self.assertFalse(driver.error)

        driver._output_controller.set_output_status.side_effect = RuntimeError()
        with self.assertRaises(RuntimeError):
            driver.turn_off()
        self.assertTrue(driver.state)
        self.assertTrue(driver.error)

        driver._output_controller.set_output_status.side_effect = None
        driver.turn_off()
        self.assertFalse(driver.state)
        self.assertFalse(driver.error)
    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)
Esempio n. 7
0
    def test_transitions(self):
        pump_1 = Pump.create(number=1,
                             name='pump 1',
                             output=Output.create(number=1))
        pump_2 = Pump.create(number=2,
                             name='pump 2',
                             output=Output.create(number=2))
        valve_1 = Valve.create(number=1,
                               name='valve 1',
                               delay=30,
                               output=Output.create(number=11))
        valve_2 = Valve.create(number=2,
                               name='valve 2',
                               delay=15,
                               output=Output.create(number=12))
        valve_3 = Valve.create(number=3,
                               name='valve 3',
                               delay=15,
                               output=Output.create(number=13))
        PumpToValve.create(pump=pump_1, valve=valve_1)
        PumpToValve.create(pump=pump_1, valve=valve_2)
        PumpToValve.create(pump=pump_2, valve=valve_3)

        SetUpTestInjections(output_controller=mock.Mock(OutputController))
        controller = PumpValveController()
        controller.refresh_from_db()

        valve_driver_1 = controller.get_valve_driver(1)
        valve_driver_2 = controller.get_valve_driver(2)
        valve_driver_3 = controller.get_valve_driver(3)
        pump_driver_1 = controller._pump_drivers[1]
        pump_driver_2 = controller._pump_drivers[2]

        # Initial state, everything is off
        self.assertFalse(pump_driver_1.state)
        self.assertEqual(0, valve_driver_1.percentage)
        self.assertEqual(0, valve_driver_2.percentage)
        self.assertFalse(pump_driver_2.state)
        self.assertEqual(0, valve_driver_3.percentage)

        # Set the second valve to 50%
        # The pump should only be turned on after 15s
        valve_driver_2.set(50)
        controller.steer()
        self.assertFalse(pump_driver_1.state)
        self.assertEqual(0, valve_driver_1.percentage)
        self.assertEqual(50, valve_driver_2.percentage)
        self.assertFalse(pump_driver_2.state)
        self.assertEqual(0, valve_driver_3.percentage)

        # Pump still off after 10s
        time.sleep(10)
        controller.steer()
        self.assertFalse(pump_driver_1.state)
        self.assertEqual(0, valve_driver_1.percentage)
        self.assertEqual(50, valve_driver_2.percentage)
        self.assertFalse(pump_driver_2.state)
        self.assertEqual(0, valve_driver_3.percentage)

        # Pump is on after 10s
        time.sleep(10)
        controller.steer()
        self.assertTrue(pump_driver_1.state)
        self.assertEqual(0, valve_driver_1.percentage)
        self.assertEqual(50, valve_driver_2.percentage)
        self.assertFalse(pump_driver_2.state)
        self.assertEqual(0, valve_driver_3.percentage)

        # Other valves are also opened
        valve_driver_1.set(100)
        valve_driver_3.set(100)
        controller.steer()
        self.assertTrue(pump_driver_1.state)
        self.assertEqual(100, valve_driver_1.percentage)
        self.assertEqual(50, valve_driver_2.percentage)
        self.assertFalse(pump_driver_2.state)
        self.assertEqual(100, valve_driver_3.percentage)

        # After a time, both valves are fully open
        time.sleep(40)
        controller.steer()
        self.assertTrue(pump_driver_1.state)
        self.assertEqual(100, valve_driver_1.percentage)
        self.assertEqual(50, valve_driver_2.percentage)
        self.assertTrue(pump_driver_2.state)
        self.assertEqual(100, valve_driver_3.percentage)

        # Two valves are closed again
        # When valves are closed, the pumps are stopped immediately
        valve_driver_2.set(0)
        valve_driver_3.set(0)
        time.sleep(10)
        controller.steer()
        self.assertTrue(pump_driver_1.state)
        self.assertEqual(100, valve_driver_1.percentage)
        self.assertEqual(0, valve_driver_2.percentage)
        self.assertFalse(pump_driver_2.state)
        self.assertEqual(0, valve_driver_3.percentage)