huidige versie

This commit is contained in:
bart
2026-11-11 18:52:40 +01:00
parent f206365b9d
commit 0b17034b68
11 changed files with 28937 additions and 0 deletions
Executable
+71
View File
@@ -0,0 +1,71 @@
#!/bin/bash -e
# Quick start-stop-daemon example, derived from Debian /etc/init.d/ssh
NAME=chargeman
DIR=/data
PIDFILE=/run/$NAME.pid
DAEMON=/data/chargeman/chargeman.py
DAEMON_ARGS=""
STOP_SIGNAL=INT
USER=root
LOG=/var/log/$NAME.log
export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
common_opts="--quiet --chuid $USER --pidfile $PIDFILE"
do_start(){
start-stop-daemon --start $common_opts --chdir $DIR --make-pidfile --background --startas /bin/bash -- -c "exec /usr/bin/python $DAEMON $DAEMON_ARGS > $LOG 2>&1"
}
do_stop(){
opt=${@:-}
start-stop-daemon --stop $common_opts --signal $STOP_SIGNAL --oknodo $opt --remove-pidfile
}
do_status(){
start-stop-daemon --status $common_opts && exit_status=$? || exit_status=$?
echo asdf $exit_status
case "$exit_status" in
0)
echo "Program '$NAME' is running."
;;
1)
echo "Program '$NAME' is not running and the pid file exists."
;;
3)
echo "Program '$NAME' is not running."
;;
4)
echo "Unable to determine program '$NAME' status."
;;
esac
}
case "$1" in
status)
do_status
;;
start)
echo -n "Starting daemon: "$NAME
do_start
echo "."
;;
stop)
echo -n "Stopping daemon: "$NAME
do_stop
echo "."
;;
restart)
echo -n "Restarting daemon: "$NAME
do_stop --retry 30
do_start
echo "."
;;
*)
echo "Usage: "$1" {status|start|stop|restart}"
exit 1
esac
exit 0
Executable
+135
View File
@@ -0,0 +1,135 @@
from queue import SimpleQueue
import time
import threading
import configparser
import atexit
import logging
import logging.handlers
import tibberclient
import victronclient
import controller
import mqtthandler
queue = SimpleQueue()
queue_handler = logging.handlers.QueueHandler(queue)
listener = logging.handlers.QueueListener(
queue,
logging.StreamHandler(),
)
logger = logging.getLogger('main')
logger.addHandler(queue_handler)
formatter = logging.Formatter('[%(asctime)s] %(message)s')
queue_handler.setFormatter(formatter)
logging.basicConfig(level=logging.INFO)
logger.info("Chargeman v0.2 starting")
config = configparser.ConfigParser()
config.read('config.ini')
if not 'tibber' in config:
raise Exception("Missing section tibber in config")
if not 'key' in config['tibber']:
raise Exception("Missing tibber key in config")
victronconn = victronclient.client()
tibber = tibberclient.client(config['tibber']['key'])
cm = controller.chargeman_controller(victronconn,tibber)
mqtt = mqtthandler.handler(cm)
if 'battery_total' in config:
try:
cm.set_battery_total_net_delivery(float(config['battery_total']['net_delivery']))
except:
logger.error("Unable to load net_delivery {}".format(config['battery_total']['net_delivery']))
exit()
try:
cm.set_battery_total_net_usage(float(config['battery_total']['net_usage']))
except:
logger.error("Unable to load net_usage {}".format(config['battery_total']['net_usage']))
exit()
if 'status' in config:
logger.info("Chargemode loaded: {}".format(int(config['status']['chargemode'])))
cm.set_chargemode(controller.Chargemode(int(config['status']['chargemode'])))
if 'chargevalue' in config['status']:
logger.info("Chargevalue loaded: {}".format(int(config['status']['chargevalue'])))
cm.set_chargevalue(int(config['status']['chargevalue']))
if 'valuekwh' in config['status']:
logger.info("valuekwh loaded: {}".format(float(config['status']['valuekwh'])))
cm.set_chargevaluekwh(float(config['status']['valuekwh']))
lasthour = -1
lock = threading.Lock()
def update():
logger.debug("Run update")
victronconn.update()
cm.update()
config['battery_total'] = {}
config['battery_total']['net_usage'] = str(cm.get_battery_total_net_usage())
config['battery_total']['net_delivery'] = str(cm.get_battery_total_net_delivery())
config['status'] = {}
config['status']['chargemode'] = str(cm.get_chargemode_int())
config['status']['chargevalue'] = str(cm.get_chargevalue())
config['status']['valuekwh'] = str(cm.get_chargevaluekwh())
with open('config.ini', 'w') as configfile:
config.write(configfile)
pass
def main():
while True:
update()
time.sleep(10)
#pub=threading.Thread(target=publishing)
sub=threading.Thread(target=mqtt.subscribing)
main=threading.Thread(target=main)
listener.start()
sub.start()
tibber.start()
main.start()
atexit.register(listener.stop)
Executable
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
cd /data
/usr/bin/python dbustest.py > /var/log/chargeman.log
+12
View File
@@ -0,0 +1,12 @@
[battery_total]
net_usage = 229505.52499994054
net_delivery = 135455.02500000477
[tibber]
key = nXJ69u_76l2cPpS3xn6F1HV-PKOmrT8-akCZE4Uru0c
[status]
chargemode = 8
chargevalue = 0
valuekwh = 0.0
+223
View File
@@ -0,0 +1,223 @@
import logging
import victronclient
import mqttpublisher
import tibberclient
from enum import IntEnum
logger = logging.getLogger('main')
charge_max_price_level = 0.024
MAX_POWER=4000
MAX_CHARGE_POWER=4000
class Chargemode(IntEnum):
FLOATING=0
CHARGING_MANUAL=1
CHARGING_MAX=2
DISCHARGING_MANUAL=3
DISCHARGING_MAX=4
CHARGING_CHEAP=5
BALANCE_DYN=6
CHARGE_DYN=7
DISCHARGE_DYN=8
class chargeman_controller:
def __init__(self, victronconn: victronclient.client, tibber: tibberclient.client) -> None:
self.chargemode=Chargemode.FLOATING
self.chargevalue=0
self.consump_updated=False
self.return_updated=False
self.consumption=0
self.return_delivery=0
self.netp1usage =0
self.valuekwh = 0.0
self.battery_total_net_usage = 0.0
self.battery_total_net_delivery = 0.0
self.setpoint = 0
self.netp1usageupdated = False
self.victronconn = victronconn
self.tibber = tibber
self.mqtt = mqttpublisher.publisher()
def set_battery_total_net_delivery(self, value):
self.battery_total_net_delivery = value
def get_battery_total_net_delivery(self):
return self.battery_total_net_delivery
def set_battery_total_net_usage(self, value):
self.battery_total_net_usage = value
def get_battery_total_net_usage(self):
return self.battery_total_net_usage
def set_net_consumption(self, value):
self.consumption = value
self.consump_updated = True
self.check_net_usage()
def set_net_delivery(self, value):
self.return_delivery = value
self.return_updated = True
self.check_net_usage()
def check_net_usage(self):
if self.return_updated and self.consump_updated:
self.consump_updated=False
self.return_updated=False
if self.netp1usageupdated: # skip till next p1 cycle
self.netp1usageupdated=False
return
self.netp1usage = self.consumption - self.return_delivery
self.netp1usageupdated = True
#logger.info("Update P1 usage: {}".format(netp1usage))
if self.chargemode in [Chargemode.BALANCE_DYN,Chargemode.CHARGE_DYN,Chargemode.DISCHARGE_DYN]:
setpoint = -1 * self.victronconn.get_power_usage()
setpoint = self.netp1usage+setpoint
if self.chargemode==Chargemode.CHARGE_DYN and setpoint > 0:
setpoint =0
elif self.chargemode==Chargemode.DISCHARGE_DYN and setpoint < 0:
setpoint =0
self.setpoint = -1 * setpoint
if self.setpoint > MAX_CHARGE_POWER:
self.setpoint = MAX_CHARGE_POWER
elif self.setpoint < -MAX_POWER:
self.setpoint = MAX_POWER
#logger.info ("Dynamic setpoint: {}".format(setpoint))
self.apply_charge_mode()
def set_chargemode(self, mode: Chargemode):
self.chargemode = mode
self.apply_charge_mode()
def set_chargemode_int(self, mode: int):
self.chargemode = Chargemode(mode)
self.apply_charge_mode()
def set_chargevalue(self,value):
self.chargevalue = value
def get_chargevalue(self):
return self.chargevalue
def get_chargemode(self) -> Chargemode:
return self.chargemode
def get_chargemode_int(self) -> int:
return int(self.chargemode)
def get_chargevaluekwh(self) -> float:
return self.valuekwh
def set_chargevaluekwh(self,value: float):
self.valuekwh = value
def update(self):
logger.debug("Run controller update")
self.mqtt.loop()
logger.debug("Controller update mqtt loop done")
if self.victronconn.get_power_usage() > 0:
self.battery_total_net_usage += self.victronconn.get_power_usage() /60/60*10
elif self.victronconn.get_power_usage() < 0:
self.battery_total_net_delivery += (self.victronconn.get_power_usage() * -1 ) /60/60*10
self.apply_charge_mode()
logger.debug("Controller update mqtt update batteries")
for battery in self.victronconn.batteries:
self.mqtt.publish_battery(battery)
logger.debug("Controller update mqtt update done")
logger.info('Mode={} CV={}W L1: SP={}W Net usage={}W Power={}W Battery: SoC={}% Current={:.2f}A TUsage={:.1f}KwH TDelivery{:.1f}KwH Tibber=€{}'.format(
str(self.chargemode),
int(self.chargevalue),
self.victronconn.get_setpoint(),
self.netp1usage,
self.victronconn.get_power_usage(),
self.victronconn.get_soc() ,
float(self.victronconn.get_battery_current() ),
self.battery_total_net_usage,
self.battery_total_net_delivery,
self.tibber.getPrice() ))
def apply_charge_mode(self):
if self.chargemode in [Chargemode.CHARGING_MANUAL, Chargemode.DISCHARGING_MANUAL]:
self.setpoint = self.chargevalue
elif self.chargemode in [Chargemode.CHARGING_MAX]:
self.setpoint = MAX_CHARGE_POWER
elif self.chargemode in [Chargemode.DISCHARGING_MAX]:
self.setpoint = -MAX_POWER
elif self.chargemode == Chargemode.CHARGING_CHEAP:
if self.tibber.getPrice() == None:
logger.info("Tibber price unknown, doing nothing")
self.setpoint = 0
elif round(self.tibber.getPrice(),2) > charge_max_price_level:
logger.info("Energy prive {} too expensive, no charging".format(round(self.tibber.getPrice(),2)))
self.setpoint = 0
else:
logger.info("Energy prive {} ok, charging".format(round(self.tibber.getPrice(),2)))
self.setpoint = MAX_CHARGE_POWER
elif self.chargemode == Chargemode.FLOATING:
self.setpoint = 0
if self.setpoint > 0:
self.victronconn.set_charging()
elif self.setpoint == 0:
self.victronconn.set_idle()
else:
if self.setpoint < -MAX_POWER:
self.setpoint = -MAX_POWER
self.victronconn.set_discharging()
self.victronconn.set_setpoint(self.setpoint)
self.mqtt.publish_controller(self)
+27969
View File
File diff suppressed because it is too large Load Diff
+82
View File
@@ -0,0 +1,82 @@
import paho.mqtt.client as mqtt
import logging
import time
import controller
from mqtttopic import *
logger = logging.getLogger('main')
class handler:
def __init__(self, controller: controller.chargeman_controller):
self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
self.publisher = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
self.client.on_connect = self.on_connect
self.client.on_message = self.on_message
self.controller = controller
self.variables = {}
while True:
try:
self.client.connect(broker,port, 60)
self.client.loop_start()
break
except:
logger.info("Unable to connect to mqtt")
time.sleep(5)
def subscribing(self):
pass
#while True:
# rc = self.client.loop(timeout=0.1)
# if rc != 0:
# if not self.client.is_connected:
# logger.warning("MQTT subscriber connection disconnected. Reconnecting...")
# self.client.reconnect()
# The callback for when the client receives a CONNACK response from the server.
def on_connect(self,client, userdata, flags, rc):
logger.info("Connected mqtt handler to mqtt with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe(topic_chargemode)
client.subscribe(topic_p1_consumption)
client.subscribe(topic_p1_return)
# The callback for when a PUBLISH message is received from the server.
def on_message(self,client, userdata, msg):
logger.debug(msg.topic+" "+str(msg.payload))
if msg.topic == topic_chargemode:
self.controller.set_chargemode_int(int(msg.payload))
elif msg.topic == topic_p1_consumption:
self.controller.set_net_consumption( int(msg.payload))
elif msg.topic == topic_p1_return:
self.controller.set_net_delivery( int(msg.payload))
+120
View File
@@ -0,0 +1,120 @@
import paho.mqtt.client as mqtt
import logging
import time
from mqtttopic import *
import victronclient
import dbus
logger = logging.getLogger('main')
class publisher:
def __init__(self):
self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
self.sensors = {}
self.mqtt_discovery_next_time = 0
self.client.on_connect = self.on_connect
while True:
try:
self.client.connect(broker,port, 60)
self.client.loop_start()
break
except:
logger.info("Unable to connect to mqtt")
time.sleep(5)
def dbus_to_python(self,data):
'''
convert dbus data types to python native data types
'''
if isinstance(data, dbus.String):
data = str(data)
elif isinstance(data, dbus.Boolean):
data = bool(data)
elif isinstance(data, dbus.Int64):
data = int(data)
elif isinstance(data, dbus.Int32):
data = int(data)
elif isinstance(data, dbus.Double):
data = float(data)
elif isinstance(data, dbus.Array):
data = [self.dbus_to_python(value) for value in data]
elif isinstance(data, dbus.Dictionary):
new_data = dict()
for key in data.keys():
new_data[self.dbus_to_python(key)] = self.dbus_to_python(data[key])
data = new_data
return data
def check_update_value(self, name, value):
value = self.dbus_to_python(value)
if not name in self.sensors:
self.sensors[name] = {'value': None, 'writable' : False}
if not (type(value) is int or type(value) is str or type(value) is float or value is None):
print ("Value {} for {} is not accepted (type {})".format(value, name,type(value)))
return
if not name in self.sensors or self.sensors[name]['value'] != value:
self.client.publish(topic_base + name + topic_state_postfix, value,retain=True)
self.sensors[name]['value'] = value
def publish_controller(self, controller):
self.check_update_value('chargemode', controller.get_chargemode_int())
self.check_update_value('chargevalue', controller.get_chargevalue())
self.check_update_value('actual_returndelivery', round(controller.get_battery_total_net_delivery()/ 1000,2))
self.check_update_value('actual_consumption', round(controller.get_battery_total_net_usage()/ 1000,2))
self.check_update_value('gridpower', controller.victronconn.get_power_usage())
self.check_update_value('soc', controller.victronconn.get_soc())
self.check_update_value('setpoint', controller.victronconn.get_setpoint())
self.check_update_value('battery_current', controller.victronconn.get_battery_current())
self.check_update_value('battery_power', controller.victronconn.get_battery_power())
self.check_update_value('battery_max_chargecurrent', controller.victronconn.get_battery_max_chargecurrent())
def publish_battery(self, battery: victronclient.battery):
self.check_update_value(battery.name + '_soc', battery.get_soc())
self.check_update_value(battery.name + '_power', battery.get_power())
self.check_update_value(battery.name + '_current', battery.get_current())
self.check_update_value(battery.name + '_temperature', battery.get_temperature())
self.check_update_value(battery.name + '_sum', battery.get_voltage_sum())
self.check_update_value(battery.name + '_low', battery.get_voltage_lowest())
self.check_update_value(battery.name + '_high', battery.get_voltage_highest())
self.check_update_value(battery.name + '_diff', battery.get_voltage_diff())
def loop(self):
pass
#rc = self.client.loop(timeout=0.1)
#if rc != 0:
# if not self.client.is_connected:
# logger.warning("MQTT publisher connection disconnected. Reconnecting...")
# self.client.reconnect()
#if self.mqtt_discovery_next_time < time.time():
# self.mqtt_discovery_next_time = time.time() + 60
# self.announce()
# The callback for when the client receives a CONNACK response from the server.
def on_connect(self,client, userdata, flags, rc):
logger.info("Connected publisher to mqtt with result code "+str(rc))
+24
View File
@@ -0,0 +1,24 @@
#mqtt topics
topic_discovery_base = "homeassistant/"
topic_discovery = "/config"
topic_discovery_battery_component = "sensor"
topic_base = "avr95/battery/"
topic_command_postfix = "/set"
topic_state_postfix = "/state"
topic_p1_consumption = 'sensors/power/p1meter/actual_consumption'
topic_p1_return = 'sensors/power/p1meter/actual_returndelivery'
topic_chargemode = topic_base + "chargemode" + topic_command_postfix
topic_power = topic_base + "chargevalue" + topic_command_postfix
topic_bat_consumption = topic_base + 'actual_consumption'
#battery packs
topic_batpack_soc = topic_base + '{}_soc' + topic_state_postfix
broker="10.2.0.15"
port=1883
+65
View File
@@ -0,0 +1,65 @@
import tibber.const
import tibber
import asyncio
import time
import logging
import datetime
import threading
logger = logging.getLogger('main')
TAXFEE=0.1088
TAX_RATE=1.21
SURCHARGE_PER_KWH=0.017520661
class client:
def __init__(self, key):
self.key = key
self.lasthour =-1
self.current_price = None
self.tibberupdate = threading.Thread(target=self.__updateTibber)
def start(self):
self.tibberupdate.start()
async def __getTibberData(self):
try:
tibber_connection = tibber.Tibber(self.key)
await tibber_connection.update_info()
logger.debug(tibber_connection.name)
home = tibber_connection.get_homes()[0]
await home.fetch_consumption_data()
await home.update_info()
logger.debug(home.address1)
await home.update_price_info()
logger.debug(home.current_price_info)
newrate=(home.current_price_info['energy'] + SURCHARGE_PER_KWH) * TAX_RATE
logger.info("Tibber price updated to {}".format(newrate))
await tibber_connection.close_connection()
return newrate
except Exception as e:
logger.error("Unable to refresh Tibber data: %s", repr(e))
def getPrice(self):
return self.current_price
def __updateTibber(self):
while True:
now = datetime.datetime.now()
if now.hour != self.lasthour:
logger.info("Tibber price needs updating")
self.current_price = asyncio.run(self.__getTibberData())
self.lasthour= now.hour
time.sleep(1)
+232
View File
@@ -0,0 +1,232 @@
import dbus
import time
import logging
import xml.etree.ElementTree as ET
logger = logging.getLogger('main')
#dbus paths
path_setpoint= '/Hub4/L1/AcPowerSetpoint'
path_power= '/Ac/ActiveIn/L1/P'
path_bat_max_chargecurrent= '/BatteryOperationalLimits/MaxChargeCurrent'
path_bat_current= '/Dc/0/Current'
path_bat_power= '/Dc/0/Power'
path_disable_feedin ='/Hub4/DisableFeedIn'
path_disable_charge ='/Hub4/DisableCharge'
path_socvalue = '/Soc'
path_batt_socvalue = '/Soc'
path_batt_current = '/Dc/0/Current'
path_batt_power = '/Dc/0/Power'
path_batt_temperature = '/Dc/0/Temperature'
path_batt_voltage_sum = '/Dc/0/Voltage'
path_batt_voltage_lowest = '/System/MinCellVoltage'
path_batt_voltage_highest = '/System/MaxCellVoltage'
path_batt_voltage_diff = '/Voltages/Diff'
class client:
def __init__(self) -> None:
self.setpoint = 0
self.soc = None
self.power_usage = None
self.session_bus = dbus.SystemBus()
self.battery_power = None
self.battery_current = None
self.battery_max_chargecurrent = None
self.batteries = []
self.locate_device()
def __getPaths(self, object, current_path):
objectManager = self.session_bus.get_object(object, '/' if current_path == '' else current_path)
introspection_interface = dbus.Interface(
objectManager,
dbus.INTROSPECTABLE_IFACE,
)
tree = ET.ElementTree(ET.fromstring(introspection_interface.Introspect()))
retval = []
root = tree.getroot()
for node in root:
if node.tag =='node':
print (current_path + '/' + node.attrib['name'])
for path in self.__getPaths(object,current_path + '/' + node.attrib['name'] ):
retval.append(current_path + node.attrib['name'] + '/' +path )
return retval
def listPaths(self, object):
print(self.__getPaths(object,''))
#return self.__getPaths(object,'/')
def locate_device(self):
logger.info("Locating victron devices")
for name in self.session_bus.list_names():
if name[0:17] == "com.victronenergy":
parts = name.split(".")
if parts[2]=='vebus':
print("Detected vbus {}".format(name))
self.device = name
if parts[2]=='battery':
batteryname = self.session_bus.call_blocking(name, "/Serial",None,"GetValue","",[])
print("Detected battery {} ({})".format(name,batteryname))
self.batteries.append(battery(self,name,batteryname))
def set_charging(self):
self.session_bus.call_blocking(self.device, path_disable_feedin ,None,'SetValue', 'v', [1])
self.session_bus.call_blocking(self.device, path_disable_charge ,None,'SetValue', 'v', [0])
def set_idle(self):
self.session_bus.call_blocking(self.device, path_disable_feedin ,None,'SetValue', 'v', [1])
self.session_bus.call_blocking(self.device, path_disable_charge ,None,'SetValue', 'v', [1])
def set_discharging(self):
self.session_bus.call_blocking(self.device, path_disable_feedin ,None,'SetValue', 'v', [0])
self.session_bus.call_blocking(self.device, path_disable_charge ,None,'SetValue', 'v', [0])
def connect(self):
while True:
try:
logger.info("Connecting to dbus...")
logger.info("Return from setpoint: {}".format(self.session_bus.call_blocking(self.device, path_setpoint ,None,'SetValue', 'v', [self.setpoint])))
break
except:
logger.info("Unable to connect to dbus {}".format(path_setpoint))
time.sleep(5)
def get_power_usage(self):
return self.power_usage
def get_soc(self):
return self.soc
def get_setpoint(self):
return self.setpoint
def set_setpoint(self, setpoint):
try:
self.session_bus.call_blocking(self.device, path_setpoint ,None,'SetValue', 'v', [setpoint])
self.setpoint = setpoint
except:
logger.info("Unable to connect to dbus {}".format(path_setpoint))
self.setpoint = None
def get_battery_current(self):
return self.battery_current
def get_battery_power(self):
return self.battery_power
def get_battery_max_chargecurrent(self):
return self.battery_max_chargecurrent
def update(self):
logger.debug("Run victron update")
self.power_usage = self.session_bus.call_blocking(self.device, path_power ,None,'GetValue', '', [])
if not isinstance(self.power_usage, int):
logger.info('Power usage is not an int value')
self.power_usage = None
return
self.soc = self.session_bus.call_blocking(self.device, path_socvalue ,None,'GetValue', '', [])
if not isinstance(self.soc, float):
logger.info('SoC is not a float value')
self.soc = None
return
self.setpoint = self.session_bus.call_blocking(self.device, path_setpoint ,None,'GetValue', '', [])
self.battery_power = self.session_bus.call_blocking(self.device, path_bat_power ,None,'GetValue', '', [])
self.battery_current = self.session_bus.call_blocking(self.device, path_bat_current ,None,'GetValue', '', [])
self.battery_max_chargecurrent = self.session_bus.call_blocking(self.device, path_bat_max_chargecurrent ,None,'GetValue', '', [])
for battery in self.batteries:
battery.update()
class battery:
def __init__(self, victron: client, device: str, name: str) -> None:
self.soc = None
self.current = None
self.power = None
self.temperature = None
self.voltage_sum = None
self.voltage_lowest = None
self.voltage_highest = None
self.voltage_diff = None
self.name = name
self.device = device
self.victron = victron
#self.paths = victron.listPaths(device)
def get_name(self):
return self.snameoc
def get_soc(self):
return self.soc
def get_current(self):
return self.current
def get_power(self):
return self.power
def get_temperature(self):
return self.temperature
def get_voltage_sum(self):
return self.voltage_sum
def get_voltage_lowest(self):
return self.voltage_lowest
def get_voltage_highest(self):
return self.voltage_highest
def get_voltage_diff(self):
return self.voltage_diff
def update(self):
self.soc = self.victron.session_bus.call_blocking(self.device,path_batt_socvalue,None,'GetValue', '', [])
self.current = self.victron.session_bus.call_blocking(self.device,path_batt_current,None,'GetValue', '', [])
self.power = self.victron.session_bus.call_blocking(self.device,path_batt_power,None,'GetValue', '', [])
self.temperature = self.victron.session_bus.call_blocking(self.device,path_batt_temperature,None,'GetValue', '', [])
self.voltage_sum = self.victron.session_bus.call_blocking(self.device,path_batt_voltage_sum,None,'GetValue', '', [])
self.voltage_lowest = self.victron.session_bus.call_blocking(self.device,path_batt_voltage_lowest,None,'GetValue', '', [])
self.voltage_highest = self.victron.session_bus.call_blocking(self.device,path_batt_voltage_highest,None,'GetValue', '', [])
self.voltage_diff = self.victron.session_bus.call_blocking(self.device,path_batt_voltage_diff,None,'GetValue', '', [])