Skip to content

Instantly share code, notes, and snippets.

@RaidAndFade
Created December 6, 2023 16:15
Show Gist options
  • Select an option

  • Save RaidAndFade/9f5339d36ba559f18755e2ffcf5800ed to your computer and use it in GitHub Desktop.

Select an option

Save RaidAndFade/9f5339d36ba559f18755e2ffcf5800ed to your computer and use it in GitHub Desktop.
import obd
import re
def raw_to_data_array(inp):
lines = inp.split("\n")
dat = {}
for l in lines:
ldat = re.findall('..',l[3:])
dat[ldat[0]] = [int(x,16) for x in ldat[1:]]
return dat
def hex_signed_int(dat_arr,decimalplace=0):
int = 0
bytes = 0
for x in dat_arr:
bytes+=1
int = int * 256
int += x
negborder = 2**(8*bytes-1)
bitlength = 2**(8*bytes)
return (((int+negborder)%bitlength)-negborder)*(10**decimalplace)
def get_obd_data():
connection = obd.OBD("/dev/rfcomm0")
bms_res=connection.query(obd.OBDCommand('BMSDATA', 'BMSDATA', b'220101', 0, obd.decoders.noop, obd.ECU.ALL, fast=False),force=True)
bms_data = raw_to_data_array(bms_res.messages[0].raw())
odo_res=connection.query(obd.OBDCommand('DASHDATA', 'DASHDATA', b'22b002', 0, obd.decoders.noop, obd.ECU.ALL, header=b'7c6', fast=False),force=True)
odo_data = raw_to_data_array(odo_res.messages[0].raw())
data_points = {}
#'10': [62, 98, 1, 1, 239, 251, 231] -- ID values
#'21': [239, 124, 0, 0, 0, 0, 0] -- 239, SOC[1], AVAIL_CHARGE[2,3], AVAIL_DISCHARGE[4,5], BITFIELDS[6]
#'22': [0, 19, 28, 247, 8, 6, 5] -- BATT_CURRENT[0:1], BATT_VOLTAGE[2:3], BATT_MAX_TEMP[4], BATT_MIN_TEMP[5], MOD1TEMP[6]
#'23': [7, 6, 8, 6, 0, 41, 193] -- MOD2TEMP[0], MOD3TEMP[1], MOD4TEMP[2], 0,0,41, MAX_CELLVOLT[6]
#'24': [2, 193, 13, 0, 0, 143, 0] -- MAX_CELLVOLT_ID[0], MIN_CELLVOLT[1], MIN_CELLVOLT_ID[2], 0, 0, AUX_BAT_VOLT[5], CHARGE_CURRENT[6]
#'25': [0, 38, 12, 0, 0, 36, 31] -- CHARGE_CURRENT[0,1,2], DISCHARGE_CURRENT[3,4,5,6]
#'26': [0, 0, 28, 122, 0, 0, 26] -- CHARGE_ENERGY[0,1,2,3], DISCHARGE_ENERGY[4,5,6]
#'27': [6, 0, 30, 214, 20, 0, 2] -- DISCHARGE_ENERGY[0], OPERATING_TIME[1,2,3,4], 0d, INVERTER_CAP_VOLTAGE[6]
#'28': [229, 0, 0, 0, 0, 6, 129] -- INVERTER_CAP_VOLTAGE[0], 0, 0, 0, 0, ISOLATION_RESISTENCE[5,6]
data_points['battery_level'] = bms_data["21"][1]/2
data_points['battery_current'] = hex_signed_int(bms_data['22'][0:1+1]) #*256+bms_data['22'][1]
data_points['battery_voltage'] = hex_signed_int(bms_data['22'][2:3+1],-1) #*256+bms_data['22'][3]
data_points['battery_max_temp'] = hex_signed_int(bms_data['22'][4:4+1])
data_points['battery_min_temp'] = hex_signed_int(bms_data['22'][5:5+1])
data_points['avail_charge'] = hex_signed_int(bms_data['21'][2:3+1],-2)
data_points['avail_discharge'] = hex_signed_int(bms_data['21'][4:5+1],-2)
data_points['cum_charge_energy'] = hex_signed_int(bms_data['26'][0:3+1],-1) #*(2**24)+bms_data['26'][1]*(2**16)+bms_data['26'][2]*(2**8)+bms_data['26'][3]
data_points['cum_discharge_energy'] = hex_signed_int(list(bms_data['26'][4:6+1])+list(bms_data['27'][0:0+1]),-1) #*(2**24)+bms_data['26'][5]*(2**16)+bms_data['26'][6]*(2**8)+bms_data['27'][0]
data_points['batt_op_time'] = hex_signed_int(bms_data['27'][1:4+1]) #*(2**24)+bms_data['27'][2]*(2**16)+bms_data['27'][3]*(2**8)+bms_data['27'][4]
#21 - [0, 255, 182, 0, 8, 143, 0] -- UNK[1,2,3], ODO_KM[3,4,5], ODO_MI[6]
#'22': [5, 81, 170, 170, 170, 170, 170] - ODO_MI[0,1]
odo_kms = hex_signed_int(odo_data['21'][3:5+1])
odo_mi = hex_signed_int(odo_data['21'][6:6+1] + odo_data['22'][0:1+1])
if odo_mi == 0:
odo_mi = int(odo_kms * 0.62137)
data_points['odometer'] = odo_mi
return data_points
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment