python-rctclient icon indicating copy to clipboard operation
python-rctclient copied to clipboard

Add support to request the current cell voltage, please!

Open niklas85 opened this issue 4 months ago • 2 comments

To monitor the health of the battery modules, I'd like to monitor the current cell voltages and compare to each other, so I can be notified and see if anything gets worse.

In the RCT-App the info can be found under:

Device->Measurements->Battery-> scroll to the buttom -> click on the last item

-> now you received an overview of all modules

Image

-> click on one of the modules overview items

-> now you have a detailed information on cell base. -> I would like this information!

Image

At the moment there is only the possibility to get the max or min voltage from the past, thats not the needed information.

Would you be so kind and add this feature to the tool?!

Thanks in advance.

niklas85 avatar Sep 05 '25 06:09 niklas85

It's quite difficult, because this information can not be requested by simple commands, but but by a single command and you'd need to pare the (undocumented) format to get to the values.

sfudeus avatar Sep 05 '25 14:09 sfudeus

All the current cell values can be obtained through decoding the OIDs named battery.cells[n] (with n = 0...6). Reading such a OID returns 96 bytes, or rather 24 * 4 bytes, with 4 bytes per cell (0..23). One would have to add some own code for that, e.g. a decoding fct as shown below. The actual voltage is encoded as integer in there and needs an extra division by 1000 to get a float value like 3,245 V. See the comment section in the suggested function code for the encoding. For those familiar with rctclient software and python, this deconding fct could be added to utils.py, along with a new datatype in types.py (e.g. BAT_CELL_DATA = 22), and giving the relevant OIDs named battery.cells[n] that new datatype in registry.py. Extracting the MIN / MAX values then is the smallest problem.

def _decode_bat_celldata(data: bytes) -> List[Tuple[int, float, int]]:
    '''
    Helper function to decode the battery call data type.

    Decodes OIDs named battery.cells[n] with n in range 0..6
    Returns an 24-element list of tuples, with each tuple having 
    temperatur (int, Celsius), voltage (float) and the remainder (int)
    of the cell.

    data octet structure (4 bytes per cell):
    +---------+---------+---------+
    | TEMP    | VOLTAGE | SPARE   |
    +---------+---------+---------+
    | 1 octet | 2 octet | 1 octet |
    | UINT8   | UINT16  | ?       |
    +---------+---------+---------+
    voltage: fixed point number by obtained by division by 1000. E.g. 3245 --> 3.245 V
    spare: unknown meaning, retured as integer for time being

    '''
    # check data length
    if len(data) != 24*4:
        raise ValueError(f'Incorrect length of battery.cells[] data: {len(data)} bytes')

    fmt = '<' + 'BHB'*24                  # format string, repeat 24x
    unpacked = struct.unpack(fmt, data)   # tuple w/ all cell data elements

    # Extract temperature and voltage for each cell
    celldata = [(unpacked[i*3],
                 unpacked[i*3 + 1]/1000.0,
                 unpacked[i*3 + 2]) for i in range(24)]
    return celldata

SaxonWood avatar Sep 26 '25 10:09 SaxonWood