Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
 def clear_level_1_error_flag(self):
     """
         Method clears the level_1_error_flag
     """
     try:
         self.pack_variables['is_not_safe_level_1'] = False
         return True
     except Exception as err:
         log_battery.exception(
             'Unable to clear error fral level 1 in batt on port %s. Reason is %s',
             self.com_port, err)
         return False
Exemplo n.º 6
0
    def __init__(self, com_port):
        self.status_message = b''

        self.pack_variables = {
            'serial_number': 0,
            'cv_1': 0,
            'cv_2': 0,
            'cv_3': 0,
            'cv_4': 0,
            'cv_5': 0,
            'cv_6': 0,
            'cv_7': 0,
            'cv_8': 0,
            'cv_9': 0,
            'cv_max': 0,
            'cv_min': 0,
            'mosfet_temp': 0,
            'pack_temp': 0,
            'dc_current': 0,
            'is_cell_overvoltage_level_1': False,
            'is_cell_overvoltage_level_2': False,
            'is_cell_undervoltage_level_1': False,
            'is_cell_undervoltage_level_2': False,
            'is_not_safe_level_1': False,
            'is_not_safe_level_2': False,
            'is_pack_overcurrent': False,
            'is_overtemperature_mosfets': False,
            'is_overtemperature_cells': False,
            'is_on': False,
            'last_status_update': time.time()
        }

        self.start_timestamp = time.time()

        self.com_port = com_port

        try:
            self.serial_handle = serial.Serial()
            self.serial_handle.port = self.com_port
            self.serial_handle.baudrate = 19200
            self.serial_handle.timeout = 0.1
            self.serial_handle.parity = 'N'
            self.serial_handle.setDTR(False)
            self.serial_handle.bytesize = serial.EIGHTBITS
            self.serial_handle.stopbits = serial.STOPBITS_TWO
            self.serial_handle.open()
        except Exception as err:
            log_battery.exception(
                'Cannot open comms to battery on port %s because of the following error: %s',
                self.com_port, err)
Exemplo n.º 7
0
 def get_pack_current(self):
     """
         Extract the pack current out of the battery message reply (get_Status command). Updates self.dc_current
         input: none
         output: True if successful. False otherwise
     """
     try:
         temp_variable = struct.unpack('<f', self.status_message[50:54])
         self.pack_variables['dc_current'] = "{0:.3f}".format(
             temp_variable[0])
         return True
     except Exception as err:
         log_battery.exception(
             'Cannot refresh pack current value for batt on port %s. Reason is: %s.',
             self.com_port, err)
         return False
Exemplo n.º 8
0
    def get_temperatures(self):
        """
            method extracts the temperature readouts from self.status and populates mosfet and pack temperature readings
        """
        try:
            mosfet_temp = struct.unpack('<f', self.status_message[6:10])
            pack_temp = struct.unpack('<f', self.status_message[10:14])

            self.pack_variables['mosfet_temp'] = "{0:.3f}".format(
                mosfet_temp[0])
            self.pack_variables['pack_temp'] = "{0:.3f}".format(pack_temp[0])
            return True
        except Exception as err:
            log_battery.exception(
                'Could not refresh temperature values for pack on port %s. Exception is: %s.',
                self.com_port, err)
            return False
Exemplo n.º 9
0
 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
Exemplo n.º 10
0
    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
Exemplo n.º 11
0
 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
Exemplo n.º 12
0
    def get_cell_voltages(self):
        """
            Function gets cell voltages out of self.status and populates cv1 -> cv9 as well as cv_max and cv_min
        """
        try:
            data = self.status_message
            C1 = (struct.unpack(
                '>f',
                struct.pack("B", data[17]) + struct.pack("B", data[16]) +
                struct.pack("B", data[15]) + struct.pack("B", data[14])))
            C2 = (struct.unpack(
                '>f',
                struct.pack("B", data[21]) + struct.pack("B", data[20]) +
                struct.pack("B", data[19]) + struct.pack("B", data[18])))
            C3 = (struct.unpack(
                '>f',
                struct.pack("B", data[25]) + struct.pack("B", data[24]) +
                struct.pack("B", data[23]) + struct.pack("B", data[22])))
            C4 = (struct.unpack(
                '>f',
                struct.pack("B", data[29]) + struct.pack("B", data[28]) +
                struct.pack("B", data[27]) + struct.pack("B", data[26])))
            C5 = (struct.unpack(
                '>f',
                struct.pack("B", data[33]) + struct.pack("B", data[32]) +
                struct.pack("B", data[31]) + struct.pack("B", data[30])))
            C6 = (struct.unpack(
                '>f',
                struct.pack("B", data[37]) + struct.pack("B", data[36]) +
                struct.pack("B", data[35]) + struct.pack("B", data[34])))
            C7 = (struct.unpack(
                '>f',
                struct.pack("B", data[41]) + struct.pack("B", data[40]) +
                struct.pack("B", data[39]) + struct.pack("B", data[38])))
            C8 = (struct.unpack(
                '>f',
                struct.pack("B", data[45]) + struct.pack("B", data[44]) +
                struct.pack("B", data[43]) + struct.pack("B", data[42])))
            C9 = (struct.unpack(
                '>f',
                struct.pack("B", data[49]) + struct.pack("B", data[48]) +
                struct.pack("B", data[47]) + struct.pack("B", data[46])))

            self.pack_variables['cv_1'] = "{0:.3f}".format(C1[0])
            self.pack_variables['cv_2'] = "{0:.3f}".format(C2[0])
            self.pack_variables['cv_3'] = "{0:.3f}".format(C3[0])
            self.pack_variables['cv_4'] = "{0:.3f}".format(C4[0])
            self.pack_variables['cv_5'] = "{0:.3f}".format(C5[0])
            self.pack_variables['cv_6'] = "{0:.3f}".format(C6[0])
            self.pack_variables['cv_7'] = "{0:.3f}".format(C7[0])
            self.pack_variables['cv_8'] = "{0:.3f}".format(C8[0])
            self.pack_variables['cv_9'] = "{0:.3f}".format(C9[0])

            self.pack_variables['cv_min'] = min([
                self.pack_variables['cv_1'], self.pack_variables['cv_2'],
                self.pack_variables['cv_3'], self.pack_variables['cv_4'],
                self.pack_variables['cv_5'], self.pack_variables['cv_6'],
                self.pack_variables['cv_7'], self.pack_variables['cv_8'],
                self.pack_variables['cv_9']
            ])

            self.pack_variables['cv_max'] = max([
                self.pack_variables['cv_1'], self.pack_variables['cv_2'],
                self.pack_variables['cv_3'], self.pack_variables['cv_4'],
                self.pack_variables['cv_5'], self.pack_variables['cv_6'],
                self.pack_variables['cv_7'], self.pack_variables['cv_8'],
                self.pack_variables['cv_9']
            ])
            return True
        except Exception as err:
            log_battery.exception(
                'Could not refresh cell voltages on port %s. Reason: %s.',
                self.com_port, err)
            return False