I want to modify Victron’s DVCC feature’s code to make it use (take) and account “DC system’s consuming current” calculated by difference if there is no “DC meter”, for the DVCC’s feature “Limit Charing Current”.
I realize that most possibly this modification would not be welcomed at all by Victron’s developers, but at least I really want to understand the REASON why they didn’t make it this way or why it is just NOT possible maybe?
From the documentation: https://www.victronenergy.com/media/pg/CCGX/en/dvcc—distributed-voltage-and-current-control.html
11.4. DVCC features for all systems
11.4.1. Limit charge current: in short: “Limit charge current is a user-configurable maximum charge current setting”. Supposed to be the settable “maximum current” which can go into battery.
But, DC Loads may not be accounted for, unless a SmartShunt or BMV-712 is installed and correctly configured as a DC meter. For example, without the DC load monitor a configured maximum charge current of 50A and DC Loads drawing 20A, the battery will be charged with 30A, not with the full allowed 50A. With the SmartShunt configured as a DC meter, maximum charge current configured at 50A and DC system shunt reports a draw of 25A, then the chargers are set to charge with 50 + 25 = 75A.
Although, in the settings in GX device / Venus OS, If we set “has DC system” even if we don’t have DC meter then it anyway shows “DC power” calculating as remaining current after deducting from current of “PV power” the current consumed by battery (measured by shunt) and measured power of inverter (if any). So, the “DC loads current” still IS KNOWN. But, by some reason, the implementation of the DVCC’s feature “Limit charge current” they made it that way so that despite the current consumed by “DC system” is known, but it may not be accounted for, unless it is directly measured by a SmartShunt or BMV-712 configured as a “DC Meter”.
I found the following code (with comments) in the file: /opt/victronenergy/dbus-systemcalc-py/delegates/DVCC.py
delegates/DVCC.py
def dcsyscurrent(self):
""" Return non-zero DC system current, if it is based on
a real measurement. If an estimate/calculation, we cannot use it.
"""
if self._dbusservice['/Dc/System/MeasurementType'] == 1:
try:
v = self._dbusservice['/Dc/Battery/Voltage']
return self._dcsyscurrent.update(
float(self._dbusservice['/Dc/System/Power'])/v)
except (TypeError, ZeroDivisionError):
pass
return 0.0
Is there some particular reason WHY it is impossible to use DC system current if it is “estimated/calculated” for the purpose to “compensate for DC loads” in DVCC’s “limit charge current” feature ?
What if I change the code in a following way, will it work ?
Details and modified code below:
So, I want to modify the behavior of the dcsyscurrent property in the Dvcc class so that It use a calculated DC current value (if no direct measurement is available).
The current calculation will be: [ “pv_current” = “/Dc/Pv/Power” divided by “/Dc/Battery/Voltage” ; If “battery_current” (measured by shunt as battery meter) is positive, then use dcsyscurrent = (pv_current - battery_current), if negative, then dcsyscurrent = (pv_current + abs(battery_current) ) ]
Currently, “dcsyscurrent” returns a value only if MeasurementType == 1. I want it to fall back to the calculated current if it’s not directly measured, and use it to account for (compensate for) in the DVCC’s “limit charge current” feature the same way as it originally uses directly measured DC loads.
modified part of "delegates/DVCC.py"
def dcsyscurrent(self):
"""
Return DC system current in Amps.
Prefer real measurement if available.
If not, calculate it as:
(PV power / Battery voltage) +/- battery current
depending on whether battery current is charging or discharging.
"""
try:
# Use directly measured value if available
if self._dbusservice['/Dc/System/MeasurementType'] == 1:
v = self._dbusservice['/Dc/Battery/Voltage']
return self._dcsyscurrent.update(
float(self._dbusservice['/Dc/System/Power']) / v)
except (TypeError, ZeroDivisionError, KeyError):
pass
# Fallback: Calculate PV current and compute dcsyscurrent
try:
voltage = self._dbusservice['/Dc/Battery/Voltage']
pv_power = self._dbusservice['/Dc/Pv/Power']
battery_current = self._dbusservice['/Dc/Battery/Current']
if None in (voltage, pv_power, battery_current):
return 0.0
# Calculate PV current
pv_current = float(pv_power) / float(voltage)
# Adjust based on battery current sign
battery_current = float(battery_current)
if battery_current < 0:
dcsys = pv_current + abs(battery_current)
else:
dcsys = pv_current - battery_current
return self._dcsyscurrent.update(dcsys)
except (TypeError, ZeroDivisionError, KeyError, ValueError):
return 0.0
(Actually , instead of calculating that pv_current via “/Dc/Pv/Power” / “/Dc/Battery/Voltage” I could simply take it from “Dc/Pv/Current”, but anyway)
Or, WHY it will NOT work?