def __erp_update(self): """Sync registers. """ # Update periodically bgERP. self.__erp_service_update_timer.update() if self.__erp_service_update_timer.expired: self.__erp_service_update_timer.clear() ztm_regs = self.__registers.by_scope(Scope.Device) ztm_regs = ztm_regs.new_then(60) ztm_regs_dict = ztm_regs.to_dict() update_state = self.__erp.sync(ztm_regs_dict) if update_state is not None: # is not None if self.__registers is not None: self.__registers.update(update_state) # Clear the last atendies. (Eml6287) self.__registers.write("ac.last_update_attendees", str([])) # (Eml6287) # (Request to stop the queue from MG @ 15.01.2021) # not_send_len = self.__registers_snapshot.qsize() # if not_send_len > 0: # Get from the queue. # snapshot = self.__registers_snapshot.get() # Send the firs from the queue. # self.__erp.sync(snapshot) else: GlobalErrorHandler.log_no_connection_erp(self.__logger) self.__erp_state_machine.set_state(ERPState.Login)
def __air_temp_upper_settings_cb(self, register): # Check data type. if not register.data_type == "json": GlobalErrorHandler.log_bad_register_value(self.__logger, register) return if register.value != {} and self.__air_temp_upper_dev is None: self.__air_temp_upper_dev = ThermometersFactory.create( controller=self._controller, name="Air temperature upper", vendor=register.value['vendor'], model=register.value['model'], options=register.value['options']) if self.__air_temp_upper_dev is not None: self.__air_temp_upper_dev.init() self.__temp_proc.add(self.__air_temp_upper_dev) elif register.value == {} and self.__air_temp_upper_dev is not None: self.__temp_proc.remove(self.__air_temp_upper_dev) self.__air_temp_upper_dev.shutdown() del self.__air_temp_upper_dev
def __exit_reader_cb(self, register): # Check data type. if not register.data_type == "json": GlobalErrorHandler.log_bad_register_value(self.__logger, register) return # Create if register.value != {} and self.__exit_reader is None: self.__exit_reader = CardReaderFactory.create( controller=self._controller, name="Exit Reader", vendor=register.value['vendor'], model=register.value['model'], options=register.value['options']) if self.__exit_reader is not None: if self.__exit_reader.reader_state == CardReaderState.NONE: self.__exit_reader.cb_read_card(self.__cb_read_card) self.__exit_reader.init() # Delete elif register.value == {} and self.__exit_reader is not None: self.__delete_reader(self.__exit_reader)
def __loop2_flowmeter_settings_cb(self, register): # Check data type. if not register.data_type == "json": GlobalErrorHandler.log_bad_register_data_type(self.__logger, register) return if register.value != {} and self.__loop2_flowmeter is None: self.__loop2_flowmeter = FlowmetersFactory.create( name="Loop 2 flowmeter", controller=self._controller, vendor=register.value['vendor'], model=register.value['model'], options=register.value['options']) if self.__loop2_flowmeter is not None: self.__loop2_flowmeter.init() self.__loop2_leak_teat = LeakTest(self.__loop2_flowmeter, 20) self.__loop2_leak_teat.on_result(self.__loop2_leaktest_result) elif register.value == {} and self.__loop2_flowmeter is not None: self.__loop2_flowmeter.shutdown() del self.__loop2_flowmeter del self.__loop2_leak_teat
def __convectors_east_enable_cb(self, register: Register): if not register.data_type == "bool": GlobalErrorHandler.log_bad_register_data_type( self.__logger, register) return if register.value and self.__vcg_convectors_east is None: # Consumers (RED) self.__vcg_convectors_east = ValveControlGroup( name="VCG Convectors east", key="{}.convectors_east".format(self.key), controller=self._controller, registers=self._registers, fw_valves=["cold_in", "cold_out"], rev_valves=["hot_in", "hot_out"], fw_pumps=["pump"]) self.__vcg_convectors_east.mode = ValveControlGroupMode.Proportional if self.__vcg_convectors_east is not None: self.__vcg_convectors_east.init() elif register.value == False and self.__vcg_convectors_east is not None: self.__vcg_convectors_east.shutdown() del self.__vcg_convectors_east
def __vcg_pool_heating_enable_cb(self, register: Register): # Check data type. if not register.data_type == "bool": GlobalErrorHandler.log_bad_register_data_type( self.__logger, register) return if register.value and self.__vcg_pool_heating is None: # Consumers (RED) self.__vcg_pool_heating = ValveControlGroup( name="VCG Pool Heating", key="{}.vcg_pool_heating".format(self.key), controller=self._controller, registers=self._registers, fw_valves=["valve"], fw_pumps=["pump"]) self.__vcg_pool_heating.mode = ValveControlGroupMode.Proportional if self.__vcg_pool_heating is not None: self.__vcg_pool_heating.init() elif register.value == False and self.__vcg_pool_heating is not None: self.__vcg_pool_heating.shutdown() del self.__vcg_pool_heating
def __tva_roof_floor_enable_cb(self, register: Register): if not register.data_type == "bool": GlobalErrorHandler.log_bad_register_data_type( self.__logger, register) return if register.value and self.__vcg_tva_roof_floor is None: # Floor East (RED and BLUE) self.__vcg_tva_roof_floor = ValveControlGroup(\ name="VCG tva roof floor", key="{}.tva_roof_floor".format(self.key), controller=self._controller, registers=self._registers, fw_valves=["cold_in", "cold_out"], rev_valves=["hot_in", "hot_out"], fw_pumps=["pump"]) self.__vcg_tva_roof_floor.mode = ValveControlGroupMode.DualSide if self.__vcg_tva_roof_floor is not None: self.__vcg_tva_roof_floor.init() elif not register.value and self.__vcg_tva_roof_floor is not None: self.__vcg_tva_roof_floor.shutdown() del self.__vcg_tva_roof_floor
def __adjust_temp_cb(self, register): # Check data type. if not (register.data_type == "float" or register.data_type == "int"): GlobalErrorHandler.log_bad_register_data_type(self.__logger, register) return if self.__adjust_temp == register.value: return # @see https://experta.bg/L/S/122745/m/Fwntindd min_temp = 2.5 max_temp = -2.5 min_temp_reg = self._registers.by_name("{}.temp_{}.min".format(self.key, self.__identifier)) if min_temp_reg is not None: min_temp = min_temp_reg.value max_temp_reg = self._registers.by_name("{}.temp_{}.max".format(self.key, self.__identifier)) if max_temp_reg is not None: max_temp = max_temp_reg.value actual_temp = register.value if actual_temp < min_temp: actual_temp = min_temp if actual_temp > max_temp: actual_temp = max_temp self.__adjust_temp = actual_temp
def update(self, registers): """Update registers content. Args: registers (dict): Dictionary of registers. Raises: ValueError: None register values. """ if registers is None: raise ValueError("Registers can not be None.") if len(registers) <= 0: return # Go through registers. for name in registers: register = None # Update registers. if name in self.names(): register = self.by_name(name) register.value = self.__preprocess_value(registers[name]) # Add missing register. else: register = Register(name) register.value = self.__preprocess_value(registers[name]) self.append(register) GlobalErrorHandler.log_unexpected_register( self.__logger, register)
def __update_exit_reader(self): """Update exit reader state.""" if self.__exit_reader is not None: # Update card reader. self.__exit_reader.update() if self.__exit_reader.reader_state == CardReaderState.STOP: message = "Card reader {}; State {}; Port {}."\ .format(self.__exit_reader.serial_number, \ self.__exit_reader.reader_state, \ self.__exit_reader.port_name) GlobalErrorHandler.log_hardware_malfunction( self.__logger, message) self.__exit_reader.init() if self.__exit_reader.reader_state == CardReaderState.NONE: message = "Card reader {}; State {}."\ .format(self.__exit_reader.serial_number, self.__entry_reader.reader_state) GlobalErrorHandler.log_hardware_malfunction( self.__logger, message) self.__exit_reader.init()
def __time_to_open_cb(self, register): if not register.data_type == "int": GlobalErrorHandler.log_bad_register_value(self.__logger, register) return self.__open_timer.expiration_time = register.value
def __blink_time_cb(self, register): # Check data type. if not (register.data_type == "int" or register.data_type == "float"): GlobalErrorHandler.log_bad_register_data_type(self.__logger, register) return self.__blink_timer.expiration_time = register.value
def __enable_err_msg_cb(self, register): # Check data type. if not register.data_type == "bool": GlobalErrorHandler.log_bad_register_data_type(self.__logger, register) return self.__enable_err_msg = register.value
def __window_closed_input_cb(self, register): # Check data type. if not register.data_type == "str": GlobalErrorHandler.log_bad_register_data_type(self.__logger, register) return self.__window_closed_input = register.value
def __door_window_blind_value_cb(self, register): # Check data type. if not register.data_type == "bool": GlobalErrorHandler.log_bad_register_value(self.__logger, register) return self.__set_door_window_blind(register.value)
def __door_window_blind_output_cb(self, register): # Check data type. if not register.data_type == "str": GlobalErrorHandler.log_bad_register_value(self.__logger, register) return self.__door_window_blind_output = register.value
def __lock_mechanism_output_cb(self, register): # Check data type. if not register.data_type == "str": GlobalErrorHandler.log_bad_register_value(self.__logger, register) return self.__lock_mechanism_output = register.value
def __exit_btn_input_cb(self, register): # Check data type. if not register.data_type == "str": GlobalErrorHandler.log_bad_register_value(self.__logger, register) return self.__exit_btn_input = register.value
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 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 __error_gain_cb(self, register): # Check data type. if not (register.data_type == "float" or register.data_type == "int"): GlobalErrorHandler.log_bad_register_value(self.__logger, register) return if self.__error_gain != register.value: self.__error_gain = register.value
def __is_empty_timeout_cb(self, register): # Check data type. if not register.data_type == "int": GlobalErrorHandler.log_bad_register_data_type( self.__logger, register) return self.__presence_timer.expiration_time = register.value
def __target_illum_cb(self, register): # Check data type. if not (register.data_type == "float" or register.data_type == "int"): GlobalErrorHandler.log_bad_register_value(self.__logger, register) return if self.__target_illumination != register.value: self.__target_illumination = register.value
def __thermal_mode_cb(self, register): # Check data type. if not register.data_type == "int": GlobalErrorHandler.log_bad_register_data_type(self.__logger, register) return mode = ThermalMode(register.value) self.__thermal_mode.set_state(mode)
def __envm_energy_cb(self, register): # Check data type. if not ((register.data_type == "int") or (register.data_type == "float")): GlobalErrorHandler.log_bad_register_data_type(self.__logger, register) return # TODO: Get energy mode for the building. pass
def __lower_fan_power_gpio_cb(self, register: Register): # Check data type. if not (register.data_type == "str"): GlobalErrorHandler.log_bad_register_data_type( self.__logger, register) return self.__lower_fan_power_gpio = register.value
def __position_cb(self, register): # Check data type. if not ((register.data_type == "float") or (register.data_type == "int")): GlobalErrorHandler.log_bad_register_value(self.__logger, register) return if self.__blind_mechanism is not None: self.__blind_mechanism.set_position(register.value)
def __sunspot_limit_cb(self, register): # Check data type. if not ((register.data_type == "float") or (register.data_type == "int")): GlobalErrorHandler.log_bad_register_value(self.__logger, register) return if self.__sun_spot_limit != register.value: self.__sun_spot_limit = register.value
def __object_height_cb(self, register): # Check data type. if not ((register.data_type == "float") or (register.data_type == "int")): GlobalErrorHandler.log_bad_register_value(self.__logger, register) return if self.__object_height != register.value: self.__object_height = register.value
def __underfloor_east_bypass_calib_cb(self, register: Register): # Check data type. if not register.data_type == "bool": GlobalErrorHandler.log_bad_register_data_type( self.__logger, register) return if register.value: if self.__v_underfloor_east_bypass is not None: self.__v_underfloor_east_bypass.calibrate()