Add support to request the current cell voltage, please!
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
-> click on one of the modules overview items
-> now you have a detailed information on cell base. -> I would like this information!
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.
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.
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