def __update_warning(self, sid: int, data: str) -> None: """Update the warning message :param sid: Source id :type sid: int :param data: Data str :type data: str :return: None """ module_uuid = unpack_data(data, (6, 1))[0] warning_type = unpack_data(data, (6, 1))[1] # If warning shows current module works fine, return immediately if not warning_type: return module_id = sid module_type = self.__get_module_type_from_uuid(module_uuid) # No need to update network module's STM firmware if module_type == 'network': return if warning_type == 1: self.check_to_update_firmware(module_id) elif warning_type == 2: # Note that more than one warning type 2 message can be received if self.update_in_progress: self.add_to_waitlist(module_id, module_type) else: self.update_module(module_id, module_type)
def __update_modules(self, message: Dict[str, Union[str, int]]) -> None: """ Update module information :param message: Dictionary format module info :type message: Dictionary :return: None """ module_id = message['s'] module_uuid, module_version_info = \ unpack_data(message['b'], (6, 2)) # Handle new modules if module_id not in (module.id for module in self._modules): module_type = get_module_type_from_uuid(module_uuid) self.request_topology(module_id) new_module = self.__add_new_module(module_type, module_id, module_uuid, module_version_info) new_module.module_type = module_type if module_type != 'Network' and not new_module.is_up_to_date: print(f"{str(new_module)} is not up to date. " f"Please update the module by calling " f"modi.update_module_firmware") elif not self.__get_module_by_id(module_id).is_connected: # Handle Reconnected modules self.__get_module_by_id(module_id).is_connected = True
def __update_health(self, message: Dict[str, Union[int, str]]) -> None: """ Update information by health message :param message: Dictionary format message of the module :type message: Dictionary :return: None """ # Record battery information and user code state module_id = message["s"] _, _, _, battery_state, user_code_state \ = unpack_data(message['b'], (1, 1, 1, 1, 1)) curr_time = time.time() # Checking starts only when module is registered if module_id in (module.id for module in self._modules): module = self.__get_module_by_id(module_id) module.last_updated = curr_time module.is_connected = True # Update user code status if module.user_code_status < 0: module.user_code_status = user_code_state % 2 # Turn off pnp if pnp flag is on if module.module_type != 'Network' and user_code_state < 2: self.__set_module_state(module_id, Module.RUN, Module.PNP_OFF) # Disconnect module with no health message for more than 2 second for module in self._modules: if curr_time - module.last_updated > 2: module.is_connected = False module._last_set_message = None
def __update_firmware_state(self, sid: int, data: str): message_decoded = unpack_data(data, (4, 1)) stream_state = message_decoded[1] if stream_state == self.CRC_ERROR: self.update_response(response=True, is_error_response=True) elif stream_state == self.CRC_COMPLETE: self.update_response(response=True) elif stream_state == self.ERASE_ERROR: self.update_response(response=True, is_error_response=True) elif stream_state == self.ERASE_COMPLETE: self.update_response(response=True)
def __update_property(self, message: Dict[str, str]) -> None: """ Update module property :param message: Dictionary format message :type message: Dictionary :return: None """ # Do not update reserved property property_number = message["d"] if property_number == 0 or property_number == 1: return module = self.__get_module_by_id(message['s']) if not module: return data = message['b'] if module.module_type == 'Network': module.update_property(property_number, unpack_data(data)[0]) else: module.update_property(property_number, decode_data(data))
def __update_topology(self, message: Dict[str, Union[int, str]]) -> None: """Update the topology of the connected modules :param message: Dictionary format message of the module :return: None """ # Setup prerequisites src_id = message["s"] byte_data = message["b"] topology_by_id = {} topology_ids = unpack_data(byte_data, (2, 2, 2, 2)) module = self.__get_module_by_id(src_id) if module: topology_by_id['type'] = get_module_type_from_uuid(module.uuid) else: topology_by_id['type'] = None for idx, direction in enumerate(('r', 't', 'l', 'b')): topology_by_id[direction] = topology_ids[idx] \ if topology_ids[idx] != 0xFFFF else None # Handle battery module if topology_ids[idx] == 0: if 0 not in self._topology_data: self._modules.append(Battery(0, -1, None)) battery_topology = { 'type': 'Battery', 'r': None, 't': None, 'l': None, 'b': src_id } self._topology_data[0] = battery_topology elif src_id not in self._topology_data[0].values(): self._topology_data[0]['l'] = src_id # Update topology data for the module self._topology_data[src_id] = topology_by_id