def check_safety_level_1(self): """ Method returns True if everything OK. False if the level 1 limits have been exceeded. """ try: c_ovp = self.pack_variables[ 'cv_max'] > settings.BATTERY_CELL_OVP_LEVEL_1 c_uvp = self.pack_variables[ 'cv_min'] < settings.BATTERY_CELL_UVP_LEVEL_1 if c_uvp: log_battery.info('Cell undervoltage, level 1 on port: %s', self.com_port) self.pack_variables['is_cell_undervoltage_level_1'] = True self.pack_variables['is_not_safe_level_1'] = True return False elif c_ovp: log_battery.info('Cell overvoltage, level 1 on port: %s', self.com_port) self.pack_variables['is_cell_overvoltage_level_1'] = True self.pack_variables['is_not_safe_level_1'] = True return False else: return True except Exception as err: log_battery.exception( 'Exception in checking cell safety level 1 on port %s. Exception is: %s', self.com_port, err) return False
def get_pack_status(self): """ Method gets the status message from the battery pack. It populates self.status with the reply """ try: message = b'\x57\x01\x34\x40\x01\x00\x00\x41\x03' self.serial_handle.write(message) time.sleep(0.1) reply = self.serial_handle.read(10) message = b'\x54\x41\x3E' #this matches the length of the message read self.serial_handle.reset_input_buffer() self.serial_handle.write(message) time.sleep(0.1) self.status_message = self.serial_handle.read(100) crc = 0 # what is the hell? is that a dict or a list? crc_received = int.from_bytes( {self.status_message[-2], self.status_message[-1]}, byteorder='little') for i in range(60): crc = crc + self.status_message[i] if crc == crc_received: return True else: log_battery.info( 'Status message CRC failed for battery on port %s.', self.com_port) return False except Exception as err: log_battery.exception( 'Could not refresh pack values on port %s. Reason: %s.', self.com_port, err) return False
def check_safety_level_2(self): """ Method return True if everything OK. False if a test stop trigger should be issued. """ if time.time() - self.start_timestamp >= 20: return False return True try: c_ovp = self.pack_variables[ 'cv_max'] > settings.BATTERY_CELL_OVP_LEVEL_2 c_uvp = self.pack_variables[ 'cv_min'] < settings.BATTERY_CELL_UVP_LEVEL_2 ocp = self.pack_variables['dc_current'] > settings.BATTERY_OCP ovt_mosfet = self.pack_variables[ 'mosfet_temp'] > settings.MOSFETS_OVERTEMPERATURE ovt_cells = self.pack_variables[ 'pack_temp'] > settings.CELLS_OVERTEMPERATURE if c_ovp: log_battery.info('Cell over-voltage, level 2. Port: %s', self.com_port) self.pack_variables['is_cell_overvoltage_level_2'] = True self.pack_variables['is_not_safe_level_2'] = True return False elif c_uvp: log_battery.info('Cell under-voltage, level 2. Port: %s', self.com_port) self.pack_variables['is_cell_undervoltage_level_2'] = True self.pack_variables['is_not_safe_level_2'] = True return False elif ocp: log_battery.info('Battery over-current. Port: %s', self.com_port) self.pack_variables['is_pack_overcurrent'] = True self.pack_variables['is_not_safe_level_2'] = True return False elif ovt_mosfet: log_battery.info('Over-temperature (mosfets) on port: %s', self.com_port) self.pack_variables['is_overtemperature_mosfets'] = True self.pack_variables['is_not_safe_level_2'] = True return False elif ovt_cells: log_battery.info('Over-temperature (mosfets) on port: %s', self.com_port) self.pack_variables['is_overtemperature_cells'] = True self.pack_variables['is_not_safe_level_2'] = True return False else: return True except Exception as err: log_battery.exception( 'Error in checking safety level 2 on port %s. Exception is: %s', self.com_port, err) return False
def close_coms(self): """ Closes resources for battery serial """ try: self.serial_handle.close() log_battery.info('Closed battery port %s.', self.com_port) return True except Exception as err: log_battery.exception('Could not close battery port %s because %s', self.com_port, err)
def turn_pack_on(self, com_port_handle): """ This method turns the pack on. Note: function needs to be send every 10 sec minimum to maintain pack on. input: com_port handler output: True if successful. False otherwise """ try: test = b'\x57\x01\x35\x40\x04\x01\x03\x00\x48\x03' self.serial_handle.write(test) time.sleep(0.01) test = b'\x57\x01\x30\x41\x20\x03' self.serial_handle.write(test) time.sleep(0.01) log_battery.info('Pack on port %s has been turned on.', self.com_port) return True except Exception as err: log_battery.exception( 'Error when turning pack on port: %s. Pack serial number: %s', self.com_port, self.serial_number) return False
def configure_USB_ISS(self): """ This function will take care of configuring the USB-> I2C bridge. """ try: message = b'\x5A\x01' self.serial_handle.write(message) time.sleep(0.5) self.serial_handle.read(10) # Setting the mode I2C_mode_message = b'\x5A\x02\x60\x04' self.serial_handle.write(I2C_mode_message) time.sleep(0.5) self.serial_handle.read(10) log_battery.info('Configure the ISS adapter for com: %s', self.com_port) return True except Exception as err: log_battery.exception( 'Error when configuring the USB ISS bridge on com %s. Error is: %s', self.com_port, err) return False
def update_values(self): """ Call this function to update all the model attributes that are read from the battery. """ try: if not self.get_pack_status(): log_battery.info( 'Asked for new status but failed. Either CRC or exception. Port: %s', self.com_port) return False self.get_serial_number() self.get_pack_current() self.get_cell_voltages() self.get_temperatures() log_battery.info('Pack values updated. Pack serial number:') # log_battery.info('Pack cell voltages: %s, %s, %s, %s, %s, %s, %s, %s, %s', self.cv_1, # self.cv_2, self.cv_3, self.cv_4, self.cv_5, self.cv_6, self.cv_7, self.cv_8, self.cv_9) self.pack_variables['last_status_update'] = time.time() return True except Exception as err: log_battery.exception( 'Error encountered while updating pack values. Exception is: %s', err) return False