gmanic / daly_bms_bt

BT data retrieval utility for Daly Smart BMS
MIT License
6 stars 2 forks source link

cell_voltages #1

Open andihobby opened 1 year ago

andihobby commented 1 year ago

Hi, I have found solution to get the cell_voltages. This ist my first time on Github for writing an issue. Down you will find changed code, thats working for me. In Python I'm a dirty progger. Regards Andy

DALY 8S 300A "SoftwareVersion", "20210729-1002A" "HardwareVersion", "BMS-ST030-309E"

def _calc_num_responses(self, status_field, num_per_frame):
    if not self.status:
        self.logger.error("get_status has to be called at least once before calling get_cell_voltages")
        return False
      # now on my BT BMS it also replies only required frames, hence this is not necessary
      #        # each response message includes 3 cell voltages
    if self.address == 8:
       #           # via Bluetooth the BMS returns all frames, even when they don't have data
        #self.logger.error("status_field %s" % status_field)
        if status_field == 'cell_voltages':
            #compare to cells
            max_responses = 8
        elif status_field == 'cells':
            #compare to cells
            max_responses = 8
        elif status_field == 'temperature_sensors':
            max_responses = 1
        elif status_field == 'temperatures':
            max_responses = 3
        else:
            self.logger.error("unkonwn status_field %s" % status_field)
            return False
    else:
        # via UART/USB the BMS returns only frames that have data
        return math.ceil(self.status[status_field] / num_per_frame)

    return max_responses

===============================

def get_cell_voltages(self, response_data=None):
    if not response_data:
        max_responses = self._calc_num_responses(status_field="cells", num_per_frame=3)
        if not max_responses:
            return
        response_data = self._read_request("95", max_responses=max_responses, return_list=True)
    if not response_data:
        return False

    #cell_voltages = self._split_frames(response_data=response_data, status_field="cells", structure=">b 3h x")
    #only 7 Byte return
    cell_voltages = self._split_frames(response_data=response_data, status_field="cells", structure=">b 3h")

    for id in cell_voltages:
        cell_voltages[id] = cell_voltages[id] / 1000

    return cell_voltages

===============================

def _notification_callback(self, handle, data):
    self.logger.debug("handle %s, data %s, len %s" % (handle, repr(data), len(data)))
    responses = []
    if len(data) == 13:
        if int.from_bytes(self._calc_crc(data[:12]), 'little') != data[12]:
            self.logger.info("Return from BMS: CRC wrong")
            return
        responses.append(data)
    elif len(data) == 26:
        if (int.from_bytes(self._calc_crc(data[:12]), 'little') != data[12]) or (int.from_bytes(self._calc_crc(data[13:25]), 'little') != data[25]):
            self.logger.info("Return from BMS: CRC wrong")
            return
        responses.append(data[:13])
        responses.append(data[13:])

    #compare to cells
    elif len(data) == 143:
        if (int.from_bytes(self._calc_crc(data[:12]), 'little') != data[12]) or (int.from_bytes(self._calc_crc(data[13:25]), 'little') != data[25]) or (int.from_bytes(self._calc_crc(data[26:38]), 'little') != data[38]) or (int.from_bytes(self._calc_crc(data[39:51]), 'little') != data[51]) or (int.from_bytes(self._calc_crc(data[52:64]), 'little') != data[64]) or (int.from_bytes(self._calc_crc(data[65:77]), 'little') != data[77]) or (int.from_bytes(self._calc_crc(data[78:90]), 'little') != data[90]) or (int.from_bytes(self._calc_crc(data[91:103]), 'little') != data[103]):
            self.logger.info("Return from BMS: CRC wrong")
            return
        responses.append(data[0:12])
        responses.append(data[13:25])
        responses.append(data[26:38])
        responses.append(data[39:51])
        responses.append(data[52:64])
        responses.append(data[65:77])
        responses.append(data[78:90])
        responses.append(data[91:103])            
    else:
        self.logger.info("did not receive 13 or 26 or 143 bytes, not implemented bytes: %i" % len(data))
gmanic commented 1 year ago

Could you please create a pull request?

Thx.