Skip to content
Snippets Groups Projects
climate_chamber_dummy.py 6.01 KiB
#!/usr/bin/python3
import shared_simulated_state

chamber_dummy_instance = None


def get_climate_chamber_dummy(target_accuracy):
    global chamber_dummy_instance
    if chamber_dummy_instance is None:
        chamber_dummy_instance = ClimateChamberDummy(target_accuracy)
    return chamber_dummy_instance


class ClimateChamberDummy:
    def __init__(self, target_accuracy):
        """
                Implements the basic operation of the climate chamber

        """
        # open connection here

        # store the credentials so that methods can access them
        self.target_accuracy = target_accuracy
        self.simulated_state = shared_simulated_state.get_simulated_state()
        self.last_simulation_time = self.simulated_state.simulated_time.value
        self.simulated_mode = 'OFF'
        self.target_temperature = self.simulated_state.simulated_temperature.value
        self.target_humidity = self.simulated_state.simulated_humidity.value
        self.temperature_slope = 0.1  # 0.1 degrees/second
        self.humidity_slope = 0.5  # degrees/second
        self.communication_delay = 0.3

    def run_simulation(self):
        self.simulate_temp()
        self.simulate_hum()
        self.last_simulation_time = self.simulated_state.simulated_time.value

    def simulate_temp(self):
        max_delta_temp = self.target_temperature - self.simulated_state.simulated_temperature.value
        if max_delta_temp < 0:
            direction = -1
        else:
            direction = 1
        new_time = self.simulated_state.simulated_time.value
        delta_time = new_time - self.last_simulation_time

        max_temp_change_in_delta_time = self.temperature_slope * delta_time

        if abs(max_delta_temp) < max_temp_change_in_delta_time:
            self.simulated_state.simulated_temperature.value = self.target_temperature
        else:
            self.simulated_state.simulated_temperature.value = self.simulated_state.simulated_temperature.value + direction * \
                                                         self.temperature_slope * delta_time

    def simulate_hum(self):
        max_delta_hum = self.target_humidity - self.simulated_state.simulated_humidity.value
        if max_delta_hum < 0:
            direction = -1
        else:
            direction = 1
        new_time = self.simulated_state.simulated_time.value
        delta_time = new_time - self.last_simulation_time

        max_hum_change_in_delta_time = self.humidity_slope * delta_time

        if abs(max_delta_hum) < max_hum_change_in_delta_time:
            self.simulated_state.simulated_humidity.value = self.target_humidity
        else:
            self.simulated_state.simulated_humidity.value = self.simulated_state.simulated_humidity.value + direction * \
                                                      self.humidity_slope * delta_time

    # the communication section

    def read_temperature(self):

        self.simulated_state.simulated_time.value += self.communication_delay
        # data format: [current temp, set temp, upper limit, lower limit]
        return [self.simulated_state.simulated_temperature.value, self.target_temperature, 0., 100.]

    def read_humidity(self):

        self.simulated_state.simulated_time.value += self.communication_delay
        # data format: [current temp, set temp, upper limit, lower limit]
        return [self.simulated_state.simulated_humidity.value, self.target_humidity, 0., 100.]

    def set_temperature(self, temperature):
        # simulate everything that has happened until now, before we store the new setpoint
        # sets the temp of the chamber(float)
        self.target_temperature = temperature
        print('ChamberDummy: target temperature now is ' + str(self.target_temperature))
        response = 'OK: TEMP, S30\r\n'
        self.simulated_state.simulated_time.value += self.communication_delay
        return response

    def set_humidity(self, humidity):
        # simulate everything that has happened until now, before we store the new setpoint

        # sets the humidity of the chamber(float)
        self.target_humidity = humidity
        print('ChamberDummy: target humidity now is ' + str(self.target_humidity))
        response = 'OK: HUMI, S30\r\n'
        self.simulated_state.simulated_time.value += self.communication_delay
        return response

    def close(self):
        pass

    # additional functionality

    def set_mode(self, mode):
        self.simulated_mode = mode
        response = 'FIXME!!!'
        self.simulated_state.simulated_time.value += self.communication_delay
        return response

    def get_const(self):
        """
        combination of read_temperature() and read_humidity()
        """
        temp = self.read_temperature()
        hum = self.read_humidity()
        return [temp, hum]

    def set_const(self, setPoint):
        """

        Parameters
        ----------
        setPoint : tuple(float,float)
            A tuple of temperature and humidity as setpoint

        Returns
        -------
        None.

        """
        # setPoint = (temp,hum)
        self.set_temperature(setPoint[0])
        self.set_humidity(setPoint[1])

    def read_mode(self):
        self.simulated_state.simulated_time.value += self.communication_delay
        return self.simulated_mode

    # deprecated. Use read_humidity etc. instead
    def read_monitor(self):
        # output data format: [temp, humid, op-state, num. of alarms]
        return str(self.read_temperature()[0]) + ', ' + str(self.read_humidity()[0]) + ', ' + self.simulated_mode + ',0'

    def is_temperature_reached(self):
        if abs(self.simulated_state.simulated_temperature.value - self.target_temperature) < self.target_accuracy[0]:
            return True
        else:
            return False

    def is_humidity_reached(self):
        if abs(self.simulated_state.simulated_humidity.value - self.target_humidity) < self.target_accuracy[1]:
            return True
        else:
            return False

    def __del__(self):
        self.close()

    def get_heater_percentage(self):
        return 0.0, 0.0