Tidy up and commenting code
This commit is contained in:
parent
fbb528d937
commit
2b72ffa036
|
@ -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')
|
||||
|
||||
|
|
Loading…
Reference in New Issue