Fix registers, add debugging, first dbus try
This commit is contained in:
parent
fc01f2a569
commit
9ade6ed80a
|
@ -14,33 +14,36 @@ from argparse import ArgumentParser
|
|||
VERSION = '1.0'
|
||||
|
||||
class BatriumBattery(can.Listener):
|
||||
def __init__(self, capacity, connection):
|
||||
self.capacity = capacity
|
||||
def __init__(self, connection):
|
||||
self.capacity = 2.2
|
||||
self.maxChargeVoltage = 0
|
||||
self.numberOfModules = 3
|
||||
self.numberOfModules = 0
|
||||
self.chargeComplete = 0
|
||||
self.soc = 0
|
||||
self.voltage = 0
|
||||
self.current = 0
|
||||
self.temperature = 0
|
||||
self.maxCellTemperature = 0
|
||||
self.maxCellTemperatureId = 0
|
||||
self.minCellTemperature = 0
|
||||
self.cellVoltages_min =[(0,0,0,0) for i in range(self.numberOfModules)]
|
||||
self.cellVoltages_max =[(0,0,0,0) for i in range(self.numberOfModules)]
|
||||
self.cellTemperatures =[(0,0,0,0) for i in range(self.numberOfModules)]
|
||||
self.cellBypassTemperatures =[(0,0,0,0) for i in range(self.numberOfModules)]
|
||||
self.cellBypassPWM =[(0,0,0,0) for i in range(self.numberOfModules)]
|
||||
self.minCellTemperatureId = 0
|
||||
self.cellVoltages_min = dict()
|
||||
self.cellVoltages_max = dict()
|
||||
self.cellTemperatures = dict()
|
||||
self.cellBypassTemperatures = dict()
|
||||
self.cellBypassPWM = dict()
|
||||
self.maxCellVoltage = 0
|
||||
self.maxCellVoltageId = 0
|
||||
self.minCellVoltage = 0
|
||||
self.minCellVoltageId = 0
|
||||
self.maxChargeCurrent = 0
|
||||
self.maxDischargeCurrent = 0
|
||||
self.firmwareVersion = '2.17.39'
|
||||
self.updated = -1
|
||||
self.cyclicModeTask = None
|
||||
self.TimeToEmpty = 0
|
||||
self.TimeToFull = 0
|
||||
self.AhToEmpty = 0
|
||||
self.AhToFull = 0
|
||||
|
||||
self._ci = can.interface.Bus(channel=connection, bustype='socketcan')
|
||||
|
||||
|
@ -79,48 +82,63 @@ class BatriumBattery(can.Listener):
|
|||
self.current = round((struct.unpack('>f', bytearray([msg.data[7], msg.data[6], msg.data[5], msg.data[4]])))[0] * 0.001, 2)
|
||||
self.temperature = msg.data[1] - 40
|
||||
|
||||
elif msg.arbitration_id == 0x00111900:
|
||||
logging.debug("Ah 0x00111900 received")
|
||||
self.AhToFull = round((struct.unpack('>f', bytearray([msg.data[3], msg.data[2], msg.data[1], msg.data[0]])))[0] * 0.001, 2)
|
||||
self.AhToEmpty = round((struct.unpack('>f', bytearray([msg.data[7], msg.data[6], msg.data[5], msg.data[4]])))[0] * 0.001, 2)
|
||||
self.capacity = self.AhToEmpty + self.AhToFull
|
||||
logging.debug("Ah to Full: %2.2f", self.AhToFull)
|
||||
logging.debug("Ah to Empty: %2.2f", self.AhToEmpty)
|
||||
logging.debug("Capacity: %2.2f", self.capacity)
|
||||
|
||||
elif msg.arbitration_id == 0x00111800:
|
||||
self.TimeToEmpty = ((msg.data[2] * 256) + msg.data[1])
|
||||
self.TimeToEmpty = ((msg.data[5] * 256) + msg.data[4])
|
||||
logging.debug("Time to empty: %dmin", self.TimeToEmpty)
|
||||
|
||||
elif msg.arbitration_id == 0x00111700:
|
||||
self.TimeToFull = ((msg.data[2] * 256) + msg.data[1])
|
||||
self.TimeToFull = ((msg.data[5] * 256) + msg.data[4])
|
||||
logging.debug("Time to full: %dmin", self.TimeToFull)
|
||||
|
||||
elif msg.arbitration_id == 0x00140400:
|
||||
self.maxDischargeCurrent = ((msg.data[3] * 256) + msg.data[2]) * 0.1
|
||||
logging.debug("Idmax %dA", self.maxDischargeCurrent)
|
||||
logging.debug("I: %dA U: %dV",self.current, self.voltage)
|
||||
self.maxDischargeCurrent = ((msg.data[3] * 256) + msg.data[2]) * 0.01
|
||||
logging.debug("MaxDischargeCurrent (DCL) %2.2fA", self.maxDischargeCurrent)
|
||||
logging.debug("I: %2.2fA U: %2.2fV",self.current, self.voltage)
|
||||
|
||||
elif msg.arbitration_id == 0x00140300:
|
||||
self.maxChargeVoltage = ((msg.data[7] * 256) + msg.data[6]) * 0.01
|
||||
self.maxChargeCurrent = ((msg.data[3] * 256) + msg.data[2]) * 0.01
|
||||
logging.debug("Icmax %dA, Ivmax %dA", self.maxChargeCurrent, self.maxChargeVoltage)
|
||||
logging.debug("I: %dA U: %dV",self.current, self.voltage)
|
||||
logging.debug("MaxChargeCurrent (CCL) %2.2fA, MaxChargeVoltage (CVL) %2.2fV", self.maxChargeCurrent, self.maxChargeVoltage)
|
||||
logging.debug("I: %2.2fA U: %2.2fV",self.current, self.voltage)
|
||||
|
||||
elif msg.arbitration_id == 0x00161700:
|
||||
elif msg.arbitration_id == 0x00111200:
|
||||
self.minCellTemperature = msg.data[0] - 40
|
||||
self.maxCellTemperature = msg.data[1] - 40
|
||||
logging.debug("Min Cell Temp: %d, Max Cell Temp: %d", self.minCellTemperature, self.maxCellTemperature)
|
||||
self.minCellTemperatureId = msg.data[4]
|
||||
self.maxCellTemperatureId = msg.data[5]
|
||||
logging.debug("MinCellTemp: %d (ID: %d), MaxCellTemp: %d (ID: %d)", self.minCellTemperature, self.minCellTemperatureId, self.maxCellTemperature, self.maxCellTemperatureId)
|
||||
|
||||
elif msg.arbitration_id == 0x00161100:
|
||||
elif msg.arbitration_id == 0x00111100:
|
||||
self.minCellVoltage = ((msg.data[1] * 256) + msg.data[0]) * 0.001
|
||||
self.maxCellVoltage = ((msg.data[3] * 256) + msg.data[2]) * 0.001
|
||||
self.minCellVoltageId = msg.data[4]
|
||||
self.maxCellVoltageId = msg.data[5]
|
||||
logging.debug("Umin %1.3fV Umax %1.3fV", self.minCellVoltage, self.maxCellVoltage)
|
||||
logging.debug("MinCellVolt %1.3fV (ID: %d), MaxCellVolt %1.3fV (ID: %d)", self.minCellVoltage, self.minCellVoltageId, self.maxCellVoltage, self.maxCellVoltageId)
|
||||
|
||||
elif ((msg.arbitration_id >= 0x001D1101) and (msg.arbitration_id <= 0x001D11F9)):
|
||||
cell_id = msg.arbitration_id & 0xff
|
||||
logging.debug("Cell ID: %d, Voltage_min: %2.2f, Voltage_max: %2.2f, Temperature: %d, Bypass_Temperature: %d, BypassPWM: %d", cell_id, ((msg.data[1] * 256) + msg.data[0]) * 0.001, ((msg.data[3] * 256) + msg.data[2]) * 0.001, msg.data[4] - 40, msg.data[5] - 40, msg.data[6])
|
||||
#self.cellVoltages_min[cell_id] = ((msg.data[1] * 256) + msg.data[0]) * 0.001
|
||||
#self.cellVoltages_max[cell_id] = ((msg.data[3] * 256) + msg.data[2]) * 0.001
|
||||
#self.cellTemperatures[cell_id] = msg.data[4] - 40
|
||||
#self.cellBypassTemperatures[cell_id] = msg.data[5] - 40
|
||||
#self.cellBypassPWM[cell_id] = msg.data[6]
|
||||
#logging.debug("Cell ID: %d, Voltage_min: %2.2f, Voltage_max: %2.2f, Temperature: %d, Bypass_Temperature: %d, BypassPWM: %d", cell_id, ((msg.data[1] * 256) + msg.data[0]) * 0.001, ((msg.data[3] * 256) + msg.data[2]) * 0.001, msg.data[4] - 40, msg.data[5] - 40, msg.data[6])
|
||||
self.cellVoltages_min[cell_id] = ((msg.data[1] * 256) + msg.data[0]) * 0.001
|
||||
self.cellVoltages_max[cell_id] = ((msg.data[3] * 256) + msg.data[2]) * 0.001
|
||||
self.cellTemperatures[cell_id] = msg.data[4] - 40
|
||||
self.cellBypassTemperatures[cell_id] = msg.data[5] - 40
|
||||
self.cellBypassPWM[cell_id] = msg.data[6]
|
||||
|
||||
def prnt(self):
|
||||
print("SOC: %2d, I: %2.2fA, U: %2.2fV, T:%2.1fC" % (self.soc, self.current, self.voltage, self.maxCellTemperature))
|
||||
print("Umin: %1.2f, Umax: %1.2f Udelta: %1.2f" % (self.minCellVoltage, self.maxCellVoltage, self.maxCellVoltage-self.minCellVoltage))
|
||||
print("CCL: %4.1f A CVL: %2.2f V" % (self.maxChargeCurrent, self.maxChargeVoltage))
|
||||
print("MinCellVolt: %1.2f, MaxCellVolt: %1.2f CellVoltDelta: %1.2f" % (self.minCellVoltage, self.maxCellVoltage, self.maxCellVoltage-self.minCellVoltage))
|
||||
print("MaxChargeCurrent (CCL): %4.1f A MaxChargeVoltage (CVL): %2.2f V" % (self.maxChargeCurrent, self.maxChargeVoltage))
|
||||
self.numberOfModules = len(self.cellVoltages_min.keys())
|
||||
print("Number of modules found: %1.0f" % (self.numberOfModules))
|
||||
|
||||
# === All code below is to simply run it from the commandline for debugging purposes ===
|
||||
def main():
|
||||
|
@ -134,7 +152,7 @@ def main():
|
|||
|
||||
#logger = can.Logger('logfile.asc')
|
||||
|
||||
bat = BatriumBattery(capacity=300, connection='can0')
|
||||
bat = BatriumBattery(connection='can0')
|
||||
|
||||
listeners = [
|
||||
#logger, # Regular Listener object
|
||||
|
|
|
@ -36,11 +36,11 @@ def handle_changed_setting(setting, oldvalue, newvalue):
|
|||
|
||||
|
||||
class DbusBatteryService:
|
||||
def __init__(self, servicename, deviceinstance, capacity, productname='Batrium BMS', connection='can0'):
|
||||
def __init__(self, servicename, deviceinstance, productname='Batrium BMS', connection='can0'):
|
||||
self.minUpdateDone = 0
|
||||
self.dailyResetDone = 0
|
||||
self.lastUpdated = 0
|
||||
self._bat = BatriumBattery(capacity=capacity, connection=connection)
|
||||
self._bat = BatriumBattery(connection=connection)
|
||||
|
||||
try:
|
||||
self._dbusservice = VeDbusService(servicename+'.socketcan_'+connection+'_di'+str(deviceinstance))
|
||||
|
@ -62,8 +62,8 @@ class DbusBatteryService:
|
|||
# Create battery specific objects
|
||||
self._dbusservice.add_path('/Status', 0)
|
||||
self._dbusservice.add_path('/Soh', 100)
|
||||
self._dbusservice.add_path('/Capacity', int(capacity))
|
||||
self._dbusservice.add_path('/InstalledCapacity', int(capacity))
|
||||
self._dbusservice.add_path('/Capacity', 0)
|
||||
self._dbusservice.add_path('/InstalledCapacity', 0)
|
||||
self._dbusservice.add_path('/Dc/0/Temperature', 20)
|
||||
self._dbusservice.add_path('/Info/MaxChargeCurrent', 5)
|
||||
self._dbusservice.add_path('/Info/MaxDischargeCurrent', 5)
|
||||
|
@ -166,21 +166,18 @@ class DbusBatteryService:
|
|||
self._dbusservice['/History/DischargedEnergy'] = 0
|
||||
dt = datetime.now() - datetime.fromtimestamp( float(self._settings['TimeLastFull']) )
|
||||
|
||||
#if full within the last 24h and more than *0% consumed, estimate actual capacity and SOH based on consumed amphours from full and SOC reported
|
||||
if dt.total_seconds() < 24*3600 and self._bat.soc < 70:
|
||||
self._dbusservice['/Capacity'] = int(-self._dbusservice['/ConsumedAmphours'] * 100 / (100-self._bat.soc))
|
||||
self._dbusservice['/Soh'] = int(self._dbusservice['/Capacity']*100 / self._dbusservice['/InstalledCapacity'])
|
||||
logging.info("SOH: %d, Capacity: %d ", self._dbusservice['/Soh'], self._dbusservice['/Capacity'])
|
||||
self.dailyResetDone = datetime.now().day
|
||||
|
||||
|
||||
def _update(self):
|
||||
logging.debug("Update")
|
||||
if (self._bat.updated != -1 and self.lastUpdated == 0) or ((self._bat.updated - self.lastUpdated) < 1000):
|
||||
self.lastUpdated = self._bat.updated
|
||||
self._dbusservice['/Connected'] = 1
|
||||
else:
|
||||
self._dbusservice['/Connected'] = 0
|
||||
|
||||
self._dbusservice['/InstalledCapacity'] = self._bat.capacity
|
||||
self._dbusservice['/Dc/0/Current'] = self._bat.current
|
||||
self._dbusservice['/Dc/0/Voltage'] = self._bat.voltage
|
||||
power = self._bat.voltage * self._bat.current
|
||||
|
@ -227,7 +224,6 @@ def main():
|
|||
parser.add_argument('-d', '--debug', help='enable debug logging',
|
||||
action='store_true')
|
||||
parser.add_argument('-i', '--interface', help='CAN interface')
|
||||
parser.add_argument('-c', '--capacity', help='capacity in Ah')
|
||||
parser.add_argument('-p', '--print', help='print only')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
@ -244,10 +240,6 @@ def main():
|
|||
logging.info('No CAN interface specified, using default can0')
|
||||
args.interface = 'can0'
|
||||
|
||||
if not args.capacity:
|
||||
logging.warning('Battery capacity not specified, using default (100Ah)')
|
||||
args.capacity = 100
|
||||
|
||||
logging.info('Starting dbus_batrium %s on %s ' %
|
||||
(VERSION, args.interface))
|
||||
|
||||
|
@ -263,7 +255,6 @@ def main():
|
|||
servicename='com.victronenergy.battery',
|
||||
connection = args.interface,
|
||||
deviceinstance = 0,
|
||||
capacity = int(args.capacity),
|
||||
)
|
||||
|
||||
logging.debug('Connected to dbus, and switching over to GLib.MainLoop() (= event based)')
|
||||
|
|
Loading…
Reference in New Issue