def __flood_fade(self, setpoint): """Flood fade generator. Args: setpoint (float): Setpoint for the hardware. Returns: list: Output voltages for the two analog outputs. """ # Negative limit. if setpoint < 0: setpoint = 0 # Positive limit. if setpoint > 100: setpoint = 100 voltage_1 = 0 voltage_2 = 0 # The model. if setpoint <= 50: voltage_1 = l_scale(setpoint, [0, 50], [0, 100]) voltage_2 = 0 else: voltage_1 = 100 voltage_2 = l_scale(setpoint, [50, 100], [0, 100]) # Return the voltages. return (voltage_1, voltage_2)
def analog_read(self, pin): """Write the analog input pin. Parameters ---------- pin : str Pin index. value : int Value for the output pin. Returns ------- int State of the pin. """ if self.is_gpio_off(pin): return False if self.is_gpio_nothing(pin): raise ValueError("Pin can not be None or empty string.") value = 0.0 state = {"value": value, "min": 0.0, "max": 10.0} # Local GPIO. if self.is_gpio_local(pin): # Read device analog inputs. request = self.__black_island.generate_request("GetAnalogInputs") irr_response = self.__modbus_rtu_clients[0].execute(request) if irr_response is not None: if not irr_response.isError(): self.__AI = irr_response.registers else: GlobalErrorHandler.log_hardware_malfunction( self.__logger, "GPIO: {} @ {} malfunctioning, check modbus cables and connections." .format(pin, self)) else: GlobalErrorHandler.log_hardware_malfunction( self.__logger, "GPIO: {} @ {} malfunctioning, check modbus cables and connections." .format(pin, self)) value = self.__AI[self._gpio_map[pin]] value = l_scale(value, [0, 50000], [0, 10]) state["value"] = value # self.__logger.debug("analog_read({}, {})".format(self.model, pin)) else: raise ValueError("Pin does not exists in pin map.") return state
def analog_write(self, pin, value): """Write the analog input pin. Parameters ---------- pin : str Pin index. value : int Value for the output pin. Returns ------- int State of the pin. """ if self.is_gpio_off(pin): return False if self.is_gpio_nothing(pin): raise ValueError("Pin can not be None or empty string.") response = False # Local GPIO. if self.is_gpio_local(pin): value = l_scale(value, [0, 10], [0, 50000]) value = int(value) self.__AO[self._gpio_map[pin]] = value # Write device analog outputs. request = self.__black_island\ .generate_request("SetAnalogOutputs", SetAnalogOutputs=self.__AO) hrw_response = self.__modbus_rtu_clients[0].execute(request) if hrw_response is not None: if not hrw_response.isError(): response = True else: GlobalErrorHandler.log_hardware_malfunction( self.__logger, "GPIO: {} @ {} malfunctioning, check modbus cables and connections." .format(pin, self)) else: GlobalErrorHandler.log_hardware_malfunction( self.__logger, "GPIO: {} @ {} malfunctioning, check modbus cables and connections." .format(pin, self)) # self.__logger.debug("analog_write({}, {}, {})".format(self.model, pin, value)) else: raise ValueError("Pin does not exists in pin map.") return response
def __set_thermal_force(self, thermal_force): """ Apply thermal force to the devices. """ # 6. Ако модула на пределната термална сила е по-малък от модула на термалната сила, # тогава Термалата сила = Пределната термала сила if thermal_force > abs(self.__thermal_force_limit): thermal_force = self.__thermal_force_limit elif thermal_force < -abs(self.__thermal_force_limit): thermal_force = -abs(self.__thermal_force_limit) # 7. Лимитираме Термалната сила в интервала -100 : + 100: if thermal_force < -100: thermal_force = -100 if thermal_force > 100: thermal_force = 100 self.__logger.debug("Mode: {}; TForce: {:3.3f}"\ .format(self.__thermal_mode.get_state(), thermal_force)) if self.__thermal_mode.is_state(ThermalMode.ColdSeason): if thermal_force > 0: self.__loop1_valve_dev.target_position = 0 self.__loop2_valve_dev.target_position = 0 elif thermal_force <= 0: self.__loop1_valve_dev.target_position = 100 self.__loop2_valve_dev.target_position = 100 elif self.__thermal_mode.is_state(ThermalMode.TransisionSeason): if thermal_force < 0: self.__loop1_valve_dev.target_position = 100 self.__loop2_valve_dev.target_position = 0 elif thermal_force > 0: self.__loop1_valve_dev.target_position = 0 self.__loop2_valve_dev.target_position = 100 else: self.__loop1_valve_dev.target_position = 0 self.__loop2_valve_dev.target_position = 0 elif self.__thermal_mode.is_state(ThermalMode.WarmSeason): if thermal_force < 0: self.__loop1_valve_dev.target_position = 100 self.__loop2_valve_dev.target_position = 100 elif thermal_force > 0: self.__loop1_valve_dev.target_position = 0 self.__loop2_valve_dev.target_position = 0 # If thermal mode set properly apply thermal force if not self.__thermal_mode.is_state(ThermalMode.NONE): self.__set_ventilation(thermal_force) # Set convector fan. conv_tf = l_scale(thermal_force, [0, 100], [0, 3]) conv_tf = abs(conv_tf) conv_tf = int(conv_tf) self.__convector_dev.set_state(conv_tf)
def get_value(self): """Get value. """ raw = 0.0 if bool(self.__state): raw = l_scale(self.__state["value"], [self.__state["min"], self.__state["max"]], [self.__min_measured, self.__max_measured]) return raw
def debit(self, debit): """Set debit. Args: debit (float): Debit of the pump. """ if self.__fw_pumps is not None: for pump in self.__fw_pumps: pump.debit = debit if self.__rev_pumps is not None: for pump in self.__rev_pumps: pump.debit = float(l_scale(debit, [0, 100], [100, 0]))
def __calculate(self): """ Apply thermal force to the devices. """ current_illumination = 0 target_illumination = 0 delta = 0 error = 0 # If there is no one at the zone, just turn off the lights. is_empty = self.__is_empty() # Scale t target_illumination = l_scale(self.__target_illumination, [0.0, self.__output_limit], [0.0, 100.0]) # Read sensor. if self.__light_sensor is not None: current_illumination = self.__light_sensor.get_value() current_illumination = l_scale(current_illumination, [0.0, self.__output_limit], [0.0, 100.0]) # Limits lower_limit = 0.0 mid_1 = 20.0 mid_2 = 80.0 upper_limit = 100.0 # Check the limits. if lower_limit <= target_illumination <= mid_1: self.__tmp_output = (target_illumination / mid_1) * 20.0 elif mid_1 < target_illumination < mid_2: # Apply the formula. first = current_illumination second = (1 + ((50.0 - target_illumination) / 100.0)) calculated_value = first * second # Calculate the target error. error = calculated_value - current_illumination # Integrate the delta to temporal output. delta = error * self.__error_gain self.__tmp_output += delta elif mid_2 <= target_illumination <= upper_limit: self.__tmp_output = (target_illumination / upper_limit) * 100. # Limitate the output by target value. if self.__tmp_output > abs(self.__output_limit): self.__tmp_output = self.__output_limit # Limitate by absolute maximum and minimum. if self.__tmp_output < 0: self.__tmp_output = 0 if self.__tmp_output > 100: self.__tmp_output = 100 # Apply the output if it is different. self.__output = self.__tmp_output # Convert to volgate. to_voltage_scale = 0.1 # Magic number!!! voltage_1, voltage_2 = self.__flood_fade(self.__output) out_to_v1 = voltage_1 * to_voltage_scale out_to_v2 = voltage_2 * to_voltage_scale # If the zone is empty, turn the lights off. if is_empty: pass # set the voltage. self.__set_voltages(out_to_v1, out_to_v2) self.__logger.debug("TRG {:3.3f}\tINP {:3.3f}\tERR: {:3.3f}\tOUT1: {:3.3f}\tOUT2: {:3.3f}"\ .format(target_illumination, current_illumination, delta, out_to_v1, out_to_v2))
def target_position(self, position): """Set the position of the valve control group. Args: position (int): Position of the valves. """ # In this mode we controll proportional all the forward vales. # And invers proportional all revers valves. if self.mode == ValveControlGroupMode.Proportional: if position > 100.0: position = 100.0 if position < 0.0: position = 0.0 if self.__fw_valves is not None: for valve in self.__fw_valves: valve.target_position = position if self.__rev_valves is not None: for valve in self.__rev_valves: valve.target_position = float( l_scale(position, [0, 100], [100, 0])) # In this mode we controll proportional all the forward vales. # And invers proportional all revers valves. # But when the value of the elif self.mode == ValveControlGroupMode.DualSide: if position > 100.0: position = 100.0 if position < -100.0: position = -100.0 if position > 0: if self.__fw_valves is not None: for valve in self.__fw_valves: valve.target_position = position if self.__rev_valves is not None: for valve in self.__rev_valves: valve.target_position = 0 elif position < 0: if self.__rev_valves is not None: for valve in self.__rev_valves: valve.target_position = float( l_scale(position, [0, -100], [0, 100])) if self.__fw_valves is not None: for valve in self.__fw_valves: valve.target_position = 0 else: if self.__fw_valves is not None: for valve in self.__fw_valves: valve.target_position = 0 if self.__rev_valves is not None: for valve in self.__rev_valves: valve.target_position = 0