Tidy up and commenting code

This commit is contained in:
Carsten Schmiemann 2023-06-12 21:44:19 +02:00
parent fbb528d937
commit 2b72ffa036
1 changed files with 46 additions and 34 deletions

View File

@ -23,7 +23,7 @@ from argparse import ArgumentParser
from batrium import *
# our own packages
# Victron energy libraries
sys.path.insert(1, os.path.join(os.path.dirname(__file__), '/opt/victronenergy/dbus-systemcalc-py/ext/velib_python'))
from vedbus import VeDbusService
from ve_utils import exit_on_error
@ -53,7 +53,7 @@ class DbusBatteryService:
except:
exit
# Create the management objects, as specified in the ccgx dbus-api document
# Create the management objects, as specified in the Venus OS dbus-api document https://github.com/victronenergy/venus/wiki/dbus-api
self._dbusservice.add_path('/Mgmt/ProcessName', __file__)
self._dbusservice.add_path('/Mgmt/ProcessVersion', VERSION + ' running on Python ' + platform.python_version())
self._dbusservice.add_path('/Mgmt/Connection', connection)
@ -66,7 +66,7 @@ class DbusBatteryService:
self._dbusservice.add_path('/HardwareVersion', 'unknown')
self._dbusservice.add_path('/Connected', 0)
# Create battery specific objects
self._dbusservice.add_path('/Status', None, writeable=True)
self._dbusservice.add_path('/Status', 0, writeable=False)
self._dbusservice.add_path('/Dc/0/Temperature', None, writeable=True)
self._dbusservice.add_path('/Info/BatteryLowVoltage', None, writeable=True)
self._dbusservice.add_path('/Alarms/CellImbalance', None, writeable=True)
@ -104,7 +104,6 @@ class DbusBatteryService:
},
eventCallback=handle_changed_setting)
self._summeditems = {
'/System/MaxCellVoltage': {'gettext': '%.3F V'},
'/System/MinCellVoltage': {'gettext': '%.3F V'},
@ -131,24 +130,27 @@ class DbusBatteryService:
for path in self._summeditems.keys():
self._dbusservice.add_path(path, value=None, gettextcallback=self._gettext)
## Load settings from Venus OS config xml ##
self._dbusservice['/History/AverageDischarge'] = self._settings['AvgDischarge']
self._dbusservice['/History/TotalAhDrawn'] = self._settings['TotalAhDrawn']
self._dbusservice.add_path('/History/TimeSinceLastFullCharge', 0)
self._dbusservice.add_path('/History/MinCellVoltage', self._settings['MinCellVoltage'])
self._dbusservice.add_path('/History/MaxCellVoltage', self._settings['MaxCellVoltage'])
## Set variables I will use later to standard values ##
self._dbusservice['/Soh'] = 100
self._dbusservice['/Status'] = 0
self._dbusservice['/ConsumedAmphours'] = 0
## Set CCL to 1 amp temporarily, it will overwritte immediately after first message, suppresing BMS missing after script crash ##
self._dbusservice['/Info/MaxChargeCurrent'] = 1
logging.info("History cell voltage min: %.3f, max: %.3f, totalAhDrawn: %d", self._settings['MinCellVoltage'], self._settings['MaxCellVoltage'], self._settings['TotalAhDrawn'])
## Set SOC according to Batrium as init values, if Cerbo or script is restarted at 100% SOC
if self._bat.soc <= 99:
self._dbusservice['/Soc'] = self._bat.soc
else:
self._dbusservice['/Soc'] = 100
## Log values written to history/XML ##
logging.info("History cell voltage min: %.3f, max: %.3f, totalAhDrawn: %d", self._settings['MinCellVoltage'], self._settings['MaxCellVoltage'], self._settings['TotalAhDrawn'])
GLib.timeout_add( self._settings['interval'], exit_on_error, self._update)
def _gettext(self, path, value):
@ -159,7 +161,7 @@ class DbusBatteryService:
def __del__(self):
self._safe_history()
logging.info('Stopping dbus_Batrium')
logging.info('Stopping dbus-batrium-native integration')
def _safe_history(self):
logging.debug('Saving history to localsettings')
@ -170,6 +172,7 @@ class DbusBatteryService:
self._settings['TargetChargeVoltage'] = self._dbusservice['/Info/MaxChargeVoltage']
def _daily_stats(self):
## Update daily statistics and reset energy counters
if (self._dbusservice['/History/DischargedEnergy'] == 0): return
logging.info("Updating stats, SOC: %d, Discharged: %.2f, Charged: %.2f ",self._bat.soc, self._dbusservice['/History/DischargedEnergy'], self._dbusservice['/History/ChargedEnergy'])
self._dbusservice['/History/AverageDischarge'] = (6*self._dbusservice['/History/AverageDischarge'] + self._dbusservice['/History/DischargedEnergy'])/7 #rolling week
@ -180,10 +183,20 @@ class DbusBatteryService:
self.dailyResetDone = datetime.now().day
def _update(self):
#logging.debug("Update CAN %d, Time Now: %d", self._bat.updated, self.lastUpdated)
time = datetime.now()
self.lastUpdated = time.timestamp()
## Monitor communication ##
if (self._bat.updated != -1 and self.lastUpdated == 0) or ((self.lastUpdated - self._bat.updated) < 10):
self._dbusservice['/Connected'] = 1
else:
self._dbusservice['/Connected'] = 0
## Call daily statistics and reset energy counters function
if datetime.now().hour == 6 and datetime.now().minute == 0 and datetime.now().day != self.dailyResetDone :
self._daily_stats()
## Alarms ##
if self._bat.alarm_high_temperature:
self._dbusservice['/Alarms/HighTemperature'] = 2
else:
@ -208,69 +221,64 @@ class DbusBatteryService:
self._dbusservice['/Alarms/HighDischargeCurrent'] = 2
else:
self._dbusservice['/Alarms/HighDischargeCurrent'] = 0
if (self._bat.updated != -1 and self.lastUpdated == 0) or ((self.lastUpdated - self._bat.updated) < 10):
self._dbusservice['/Connected'] = 1
else:
self._dbusservice['/Connected'] = 0
## State of Charge, Batrium couting SoC above 100, stay at 99 till all cells are balanced, then set timestamp and SoC to 100 ##
if self._bat.soc <= 99:
self._dbusservice['/Soc'] = self._bat.soc
# calculate time since last full charge
dt = datetime.now() - datetime.fromtimestamp( float(self._settings['TimeLastFull']) )
self._dbusservice['/History/TimeSinceLastFullCharge'] = (dt.seconds + dt.days * 24 * 3600)
elif (self._bat.soc > 99) and (self.cell_balanced):
self._dbusservice['/Soc'] = 100
self._dbusservice['/ConsumedAmphours'] = 0
#if datetime.fromtimestamp(time()).day != datetime.fromtimestamp(float(self._settings['TimeLastFull'])).day:
self._settings['TimeLastFull'] = time()
## Cells are balancing or not ##
if self._bat.NumberInBypass != 0:
self._dbusservice['/Balancing'] = 1
else:
self._dbusservice['/Balancing'] = 0
self._dbusservice['/InstalledCapacity'] = self._bat.capacity
self._dbusservice['/Capacity'] = self._bat.capacity
## Write Batrium values direct to Venus OS registers ##
self._dbusservice['/Dc/0/Current'] = self._bat.current
self._dbusservice['/Dc/0/Voltage'] = self._bat.voltage
power = self._bat.voltage * self._bat.current
self._dbusservice['/Dc/0/Power'] = power
self._dbusservice['/Dc/0/Temperature'] = self._bat.maxCellTemperature
self._dbusservice['/Info/MaxChargeCurrent'] = self._bat.maxChargeCurrent
self._dbusservice['/Info/MaxDischargeCurrent'] = self._bat.maxDischargeCurrent
self._dbusservice['/System/NrOfModulesOnline'] = self._bat.numberOfModules
self._dbusservice['/System/NrOfBatteriesBalancing'] = self._bat.NumberInBypass
self._dbusservice['/System/BatteriesSeries'] = self._bat.numberOfModules
self._dbusservice['/InstalledCapacity'] = self._bat.capacity
self._dbusservice['/Capacity'] = self._bat.capacity
## Set Charge Voltage Limit according to Batrium, if charging is disabled, Batrium sent 0.0V. Stay at last CVL and save it to Venus OS config xml, to workaround if restarted with charge off ##
if self._bat.maxChargeVoltage != 0:
self._dbusservice['/Info/MaxChargeVoltage'] = self._bat.maxChargeVoltage
self.maxChargeVoltage = self._bat.maxChargeVoltage
# Workaround lower charge voltage a bit, because Batrium sends TCL 0V if charge is disabled
# If all cells are balanced, lower CVL 0.1V to spare cells mons
elif self.maxChargeVoltage != 0:
self._dbusservice['/Info/MaxChargeVoltage'] = self.maxChargeVoltage - 0.1
elif self.maxChargeVoltage == 0 and self._bat.maxChargeVoltage == 0:
self._dbusservice['/Info/MaxChargeVoltage'] = self._settings['TargetChargeVoltage']
self._dbusservice['/System/NrOfModulesOnline'] = self._bat.numberOfModules
self._dbusservice['/System/NrOfBatteriesBalancing'] = self._bat.NumberInBypass
self._dbusservice['/System/BatteriesSeries'] = self._bat.numberOfModules
#update energy statistics daily at 6:00,
if datetime.now().hour == 6 and datetime.now().minute == 0 and datetime.now().day != self.dailyResetDone :
self._daily_stats()
## Calculation every minute ##
now = datetime.now().time()
if now.minute != self.minUpdateDone:
self.minUpdateDone = now.minute
## Display min and max cell temperatures every minute, because of better readability
self._dbusservice['/System/MinCellTemperature'] = self._bat.minCellTemperature
self._dbusservice['/System/MaxCellTemperature'] = self._bat.maxCellTemperature
self._dbusservice['/System/MinTemperatureCellId'] = self._bat.minCellTemperatureId
self._dbusservice['/System/MaxTemperatureCellId'] = self._bat.maxCellTemperatureId
## Same for cell voltages and saving to history
self._dbusservice['/System/MaxCellVoltage'] = self._bat.maxCellVoltage
if (self._bat.maxCellVoltage > self._dbusservice['/History/MaxCellVoltage'] ):
self._dbusservice['/History/MaxCellVoltage'] = self._bat.maxCellVoltage
logging.info("New maximum cell voltage: %f", self._bat.maxCellVoltage)
self._dbusservice['/System/MinCellVoltage'] = self._bat.minCellVoltage
if (0 < self._bat.minCellVoltage < self._dbusservice['/History/MinCellVoltage'] ):
self._dbusservice['/History/MinCellVoltage'] = self._bat.minCellVoltage
@ -278,7 +286,8 @@ class DbusBatteryService:
self._dbusservice['/System/MaxVoltageCellId'] = self._bat.maxCellVoltageId
self._dbusservice['/System/MinVoltageCellId'] = self._bat.minCellVoltageId
# Time remaining to full and to empty, show None if under 1 amp and under 5 days left for nicer looking readings
if self._bat.current > 1:
#charging
if self._bat.TimeToFull < 432000:
@ -296,16 +305,19 @@ class DbusBatteryService:
else :
self._dbusservice['/TimeToGo'] = None
## Check if all cells are balancing
if self._bat.NumberInBypass == self._bat.numberOfModules:
self.cell_balanced = True
elif self._bat.NumberInBypass == 0:
self.cell_balanced = False
## Call history save function to write history items to Venus OS config xml
self._safe_history()
## Calculation every second ##
if now.second != self.secUpdateDone:
self.secUpdateDone = now.second
#Workaround because of missing messages of Batrium BMS
# Calculated charged and discharged energy and save it to history, because Batrium not sending
if power > 0:
self.ChargedEnergy += (power / 3600.0) / 1000
if power < 0:
@ -316,9 +328,9 @@ class DbusBatteryService:
return True
def main():
## Cli parser to set interface and for debbuging purposes
parser = ArgumentParser(description='dbus_batrium', add_help=True)
parser.add_argument('-d', '--debug', help='enable debug logging',
action='store_true')
parser.add_argument('-d', '--debug', help='enable debug logging', action='store_true')
parser.add_argument('-i', '--interface', help='CAN interface')
parser.add_argument('-p', '--print', help='print only')