Skip to content

Commit

Permalink
improve handling of a com.victronenergy.inverter (#167)
Browse files Browse the repository at this point in the history
Added some more values bases on experiments and https://github.com/victronenergy/venus/wiki/dbus#inverter

In the "Advanced" Section of the VRM portal, the inverter seems to show up correctly now (power, voltage, current and even state changes correctly).
  • Loading branch information
dsteinkopf authored May 10, 2024
1 parent 75166da commit dfcc91d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
3 changes: 2 additions & 1 deletion dbus-opendtu.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def _v(_p, value: float) -> str:
"/Ac/L3/Energy/Forward": {"initial": None, "textformat": _kwh},
"/Ac/Out/L1/I": {"initial": None, "textformat": _a},
"/Ac/Out/L1/V": {"initial": None, "textformat": _v},
"/Ac/Out/L1/P": {"initial": None, "textformat": _w},
"/Dc/0/Voltage": {"initial": None, "textformat": _v},
}

Expand All @@ -113,7 +114,7 @@ def _v(_p, value: float) -> str:
actual_inverter=0,
)

if number_of_inverters == 0:
if number_of_inverters == 0:
number_of_inverters = service.get_number_of_inverters()

if number_of_inverters > 1:
Expand Down
30 changes: 23 additions & 7 deletions dbus_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ def __init__(
onchangecallback=self._handlechangedvalue,
)

# add _sign_of_life 'timer' to get feedback in log every 5minutes
gobject.timeout_add(self._get_sign_of_life_interval() * 60 * 1000, self._sign_of_life)
gobject.timeout_add(self._get_polling_interval(), self._update)

@staticmethod
def get_ac_inverter_state(current):
Expand Down Expand Up @@ -287,8 +287,6 @@ def _get_serial(self, pvinverternumber):
elif self.dtuvariant == constants.DTUVARIANT_TEMPLATE:
serial = self.serial

gobject.timeout_add(self._get_polling_interval(), self._update)

return serial

def _get_name(self):
Expand Down Expand Up @@ -534,6 +532,7 @@ def _sign_of_life(self):
return True

def _update(self):
logging.debug("_update")
successful = False
try:
# update data from DTU once per _update call:
Expand Down Expand Up @@ -603,13 +602,13 @@ def get_values_for_inverter(self):
# OpenDTU v24.2.12 breaking API changes 2024-02-19
if "AC" in meter_data["inverters"][self.pvinverternumber]:
root_meter_data = meter_data["inverters"][self.pvinverternumber]
firmware_v24_2_12_or_newer=True
firmware_v24_2_12_or_newer = True
else:
inverter_serial = meter_data["inverters"][self.pvinverternumber]["serial"]
logging.info(f"Inverter #{self.pvinverternumber} Serial: {inverter_serial}")
root_meter_data = self.fetch_opendtu_inverter_data(inverter_serial)["inverters"][0]
logging.debug(f"{root_meter_data}")
firmware_v24_2_12_or_newer=False
firmware_v24_2_12_or_newer = False

producing = is_true(root_meter_data["producing"])
power = (root_meter_data["AC"]["0"]["Power"]["v"]
Expand Down Expand Up @@ -639,23 +638,40 @@ def get_values_for_inverter(self):
def set_dbus_values(self):
'''read data and set dbus values'''
(power, pvyield, current, voltage, dc_voltage) = self.get_values_for_inverter()
state = self.get_ac_inverter_state(current)

# This will be refactored later in classes
if self._servicename == "com.victronenergy.inverter":
# see https://github.com/victronenergy/venus/wiki/dbus#inverter
self._dbusservice["/Ac/Out/L1/V"] = voltage
self._dbusservice["/Ac/Out/L1/I"] = current
self._dbusservice["/Ac/Out/L1/P"] = power
self._dbusservice["/Dc/0/Voltage"] = dc_voltage
self._dbusservice["/State"] = self.get_ac_inverter_state(current)
self._dbusservice["/Ac/Power"] = power

self._dbusservice["/Ac/Energy/Forward"] = pvyield
self._dbusservice["/State"] = state
self._dbusservice["/Mode"] = 2 # Switch position: 2=Inverter on; 4=Off; 5=Low Power/ECO

self._dbusservice["/Ac/L1/Current"] = current
self._dbusservice["/Ac/L1/Energy/Forward"] = pvyield
self._dbusservice["/Ac/L1/Power"] = power
self._dbusservice["/Ac/L1/Voltage"] = voltage

logging.debug(f"Inverter #{self.pvinverternumber} Voltage (/Ac/Out/L1/V): {voltage}")
logging.debug(f"Inverter #{self.pvinverternumber} Current (/Ac/Out/L1/I): {current}")

logging.debug(f"Inverter #{self.pvinverternumber} Current (/Dc/0/Voltage): {dc_voltage}")
logging.debug(f"Inverter #{self.pvinverternumber} Voltage (/Ac/Power): {power}")
logging.debug(f"Inverter #{self.pvinverternumber} Current (/Ac/Energy/Forward): {pvyield}")
logging.debug(f"Inverter #{self.pvinverternumber} Current (/State): {state}")
logging.debug("---")
else:
# three-phase inverter: split total power equally over all three phases
if ("3P" == self.pvinverterphase):
powerthird = power/3

#Single Phase Voltage = (3-Phase Voltage) / (sqrt(3))
# Single Phase Voltage = (3-Phase Voltage) / (sqrt(3))
# This formula assumes that the three-phase voltage is balanced and that
# the phase angles are 120 degrees apart
# sqrt(3) = 1.73205080757 <-- So we do not need to include Math Library
Expand Down

0 comments on commit dfcc91d

Please sign in to comment.