From 94ac952644ccaf23e5d871afc40021f7687f9dcf Mon Sep 17 00:00:00 2001 From: Pi Developer Date: Sun, 22 Feb 2026 15:22:14 +0100 Subject: [PATCH] fix: PV_in_current/watts tramite bilancio energetico DC bus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Il protocollo QPGS non espone la corrente reale lato pannelli. DATA[25] = corrente SCC→batteria SOLTANTO (0 quando batteria carica). Formula corretta via conservazione energetica del DC bus: P_pv = V_batt×DATA[25] + max(0, Load_W − V_batt×DATA[26]) Dove: V_batt×DATA[25] = potenza SCC inviata alla batteria Load_W = potenza consumata dal carico dal bus DC V_batt×DATA[26] = potenza fornita dalla batteria in scarica Casi coperti: 1. Bat. in carica (DATA[25]>0, DATA[26]=0): P = V_b×I_scc + Load 2. Bat. piena (DATA[25]=0, DATA[26]=0): P = Load 3. Bat. in scar. (DATA[25]=0, DATA[26]>0): P = max(0, Load−Pdisch) Guard: calcolo solo quando SCC_charging (STATUS b5=1), altrimenti 0. Aggiunto SCC_current (=DATA[25]) come campo separato per monitorare la corrente SCC→batteria indipendentemente dalla produzione PV. Aggiunto SCC_current al topic di discovery HA in mqtt-init-parallel.sh --- sources/inverter-mqtt/mqtt-init-parallel.sh | 1 + sources/inverter-mqtt/mqtt-push-parallel.sh | 55 ++++++++++----------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/sources/inverter-mqtt/mqtt-init-parallel.sh b/sources/inverter-mqtt/mqtt-init-parallel.sh index a7643a3..cd8b8a7 100755 --- a/sources/inverter-mqtt/mqtt-init-parallel.sh +++ b/sources/inverter-mqtt/mqtt-init-parallel.sh @@ -93,6 +93,7 @@ for inv_id in $(seq 1 $INVERTER_COUNT); do registerTopic $inv_id "Battery_capacity" "%" "battery-outline" registerTopic $inv_id "Battery_voltage" "V" "battery-outline" registerTopic $inv_id "Battery_charge_current" "A" "current-dc" + registerTopic $inv_id "SCC_current" "A" "current-dc" registerTopic $inv_id "Battery_discharge_current" "A" "current-dc" registerTopic $inv_id "Load_status_on" "" "power" registerTopic $inv_id "SCC_charge_on" "" "power" diff --git a/sources/inverter-mqtt/mqtt-push-parallel.sh b/sources/inverter-mqtt/mqtt-push-parallel.sh index c93b696..448bbdb 100755 --- a/sources/inverter-mqtt/mqtt-push-parallel.sh +++ b/sources/inverter-mqtt/mqtt-push-parallel.sh @@ -103,53 +103,50 @@ processInverter () { [ "${DATA[12]}" ] && pushMQTTData "$inv_id" "Battery_charge_current" "${DATA[12]}" [ "${DATA[13]}" ] && pushMQTTData "$inv_id" "Battery_capacity" "${DATA[13]}" [ "${DATA[14]}" ] && pushMQTTData "$inv_id" "PV_in_voltage" "${DATA[14]}" + [ "${DATA[25]}" ] && pushMQTTData "$inv_id" "SCC_current" "${DATA[25]}" [ "${DATA[26]}" ] && pushMQTTData "$inv_id" "Battery_discharge_current" "${DATA[26]}" - # ─── PV panel-side power calculation ───────────────────────────────────── - # DATA[25] is labeled "PV input current" by the inverter but is actually - # the SCC *output* current flowing to the battery at battery voltage. - # The inverter protocol does NOT expose the real panel-side current directly. + # ─── Real PV panel power calculation via DC-bus energy balance ──────────── + # The QPGS protocol does NOT expose the true PV panel input current directly. + # DATA[25] = "PV input current for battery" = SCC output current to battery ONLY. + # This is 0 when battery is full even though panels are producing. + # DATA[26] = battery discharge current (at battery voltage). + # DATA[9] = AC output load watt (power drawn from DC bus by the inverter). # - # The SCC is a DC-DC converter: power_in ≈ power_out (ignoring ~5% losses). - # P_pv = V_batt × I_scc (SCC output power = panel power) - # I_pv = P_pv / V_pv (real panel current at panel voltage) + # The DC bus balance equation gives us the real SCC output power: + # SCC_out = Load_watt + Bat_charge − Bat_discharge + # = Load + (V_batt × DATA[25]) − (V_batt × DATA[26]) + # When SCC is the sole DC source: + # P_pv ≈ SCC_out = V_batt×DATA[25] + max(0, Load − V_batt×DATA[26]) # - # Edge case - battery fully charged (DATA[25] = 0): - # If SCC_OK (b7=1) and line_loss (b2=1, no AC grid) → solar feeds load directly. - # Best proxy: Load_watt (solar production = what the load is consuming). - # If AC grid is present → solar floats battery, nothing meaningful to report. + # Guard: only calculate when SCC_charging bit (STATUS b5, index 2) = 1. + # When SCC is off, PV production = 0 regardless of field values. local BATT_V="${DATA[11]:-0}" local SCC_A="${DATA[25]:-0}" + local DISCH_A="${DATA[26]:-0}" local PV_V="${DATA[14]:-0}" local LOAD_W="${DATA[9]:-0}" local STATUS="${DATA[19]:-00000000}" - # STATUS string b7b6b5b4b3b2b1b0 - each char is one bit: - # index 0=b7=SCC_OK, index 1=b6=AC_charge, index 2=b5=SCC_charge, - # index 5=b2=line_loss (1=no AC grid), index 6=b1=load_on - local SCC_OK="${STATUS:0:1}" - local LINE_LOSS="${STATUS:5:1}" + # STATUS bit layout (b7b6b5b4b3b2b1b0 as string, index 0=b7): + # index 2 = b5 = SCC_charging (1 = SCC actively converting solar) + local SCC_CHARGING="${STATUS:2:1}" local PV_WATTS PV_CURRENT - if awk -v v="$SCC_A" 'BEGIN{exit !(v+0 > 0)}' 2>/dev/null; then - # SCC delivering current to battery: compute panel-side values - # P_pv = V_batt × I_scc - PV_WATTS=$(echo "$BATT_V $SCC_A" | awk '{printf "%.1f", $1 * $2}') - # I_pv = P_pv / V_pv (real current from panels at panel voltage) - if awk -v v="$PV_V" 'BEGIN{exit !(v+0 > 0)}' 2>/dev/null; then - PV_CURRENT=$(echo "$PV_WATTS $PV_V" | awk '{printf "%.2f", $1 / $2}') - else - PV_CURRENT="0.00" - fi - elif [ "$SCC_OK" = "1" ] && [ "$LINE_LOSS" = "1" ]; then - # SCC OK, battery full, no AC grid → solar feeds load directly - PV_WATTS="$LOAD_W" + if [ "$SCC_CHARGING" = "1" ]; then + # SCC is active: estimate total PV power via DC bus balance + # P_pv = V_batt × I_scc_to_battery + max(0, Load − V_batt × I_bat_discharge) + local BATT_CHARGE_W=$(echo "$BATT_V $SCC_A" | awk '{printf "%.1f", $1 * $2}') + local BATT_DISCH_W=$(echo "$BATT_V $DISCH_A" | awk '{printf "%.1f", $1 * $2}') + local LOAD_FROM_SCC=$(echo "$LOAD_W $BATT_DISCH_W" | awk '{v=$1-$2; printf "%.1f", (v>0)?v:0}') + PV_WATTS=$(echo "$BATT_CHARGE_W $LOAD_FROM_SCC" | awk '{printf "%.1f", $1 + $2}') if awk -v v="$PV_V" 'BEGIN{exit !(v+0 > 0)}' 2>/dev/null; then PV_CURRENT=$(echo "$PV_WATTS $PV_V" | awk '{printf "%.2f", $1 / $2}') else PV_CURRENT="0.00" fi else + # SCC off: no solar conversion PV_WATTS="0.0" PV_CURRENT="0.00" fi