forked from tomcosk/BMSBatteryMonitor
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbms.py
More file actions
90 lines (77 loc) · 3.48 KB
/
bms.py
File metadata and controls
90 lines (77 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import bmscore
import binascii
import time
class Bms():
def __init__(self, serial, config):
self.serial = serial
self.protocol_config = config
self.num_cells = None
self.set_num_cells()
self.vendor = None
while self.vendor is None:
self.vendor = self.get_vendor()
time.sleep(1)
def set_num_cells(self):
self.num_cells = self.get_basic_info()["battery_serial_number"]
def get_vendor(self):
data = bmscore.getbmsdat(self.serial, bytes.fromhex(
self.protocol_config['vendor']['command']))
if data is not None:
text = str(binascii.unhexlify(binascii.hexlify(data)))
else:
text = 'Unknown'
return text
def get_basic_info(self):
data = bmscore.getbmsdat(self.serial, bytes.fromhex(
self.protocol_config['basicInfo']['command']))
reply = {}
if data is not None:
for key in self.protocol_config['basicInfo']['replyDataStringBytes']:
byte_from = self.protocol_config['basicInfo']['replyDataStringBytes'][key]['from']
byte_to = self.protocol_config['basicInfo']['replyDataStringBytes'][key]['to']
reply[key] = int(binascii.hexlify(data[byte_from:byte_to]), 16)
# reply['overall_current'] = int(binascii.hexlify(data[2:4]), 16)
# reply['residual_capacity'] = int(binascii.hexlify(data[4:6]), 16)
# reply['nominal_capacity'] = int(binascii.hexlify(data[6:8]), 16)
# reply['cycle_times'] = int(binascii.hexlify(data[8:10]), 16)
# reply['rsoc'] = int(binascii.hexlify(data[19:20]), 16)
# reply['battery_serial_number'] = int(binascii.hexlify(data[21:22]), 16)
# reply['ntc_quantity'] = int(binascii.hexlify(data[22:23]), 16)
start_byte = 23
for i in range(0, reply['ntc_quantity']):
reply['ntc_'+str(i)+'_kelvin'] = int(
binascii.hexlify(data[start_byte:start_byte+2]), 16)
reply['ntc_'+str(i)+'_celsius'] = round(self.kelvin2celsius(
int(binascii.hexlify(data[start_byte:start_byte+2]), 16)/10)*100)/100
start_byte = start_byte + 2
else:
return None
return reply
def get_cells_info(self):
while self.num_cells is None:
self.set_num_cells
time.sleep(1)
data = bmscore.getbmsdat(self.serial, bytes.fromhex(
self.protocol_config['cellsInfo']['command']))
reply = {}
if data is not None:
start_byte = 0
for i in range(0, self.num_cells):
# print("reading cell: "+str(start_byte)+":"+str(start_byte+2))
reply['cell_' +
str(i)] = int(binascii.hexlify(data[start_byte:start_byte+2]), 16)
start_byte = start_byte + 2
else:
return None
return reply
def read_settings(self):
for command in self.protocol_config['settings']['commandSequence']:
data = bmscore.getbmsdat(self.serial, bytes.fromhex(command))
reply = {}
for key in self.protocol_config['settings']['registers']:
data = bmscore.getbmsdat(self.serial, bytes.fromhex(
self.protocol_config['settings']['registers'][key]['command']))
reply[key] = int(binascii.hexlify(data), 16)
return reply
def kelvin2celsius(self, temp):
return temp-273.15