fix: PV_in_watts tramite QPIGS DATA[19] per inv1 (MPPT diretto) + correzione efficienza η per inv2
Build Docker Image for Raspberry Pi / build-and-push (push) Successful in 13m15s
Docker Image Cleanup / cleanup-old-images (push) Waiting to run

- Aggiunto Step 1.5: query QPIGS prima del loop QPGS
- inv1 (master RS232): usa QPIGS DATA[19] = potenza PV misurata direttamente
  dal controller MPPT (campo aggiunto nel firmware 'after_current_upgrade')
- inv2 (slave): formula DC-bus balance divisa per η_total (SCC+inverter losses)
- η calcolato dinamicamente da QPIGS quando batteria ferma (<2A carica/scarica)
  altrimenti usa default 0.93 (~93.7% da misura reale su questo impianto)
- Corregge sottostima sistematica ~7% dovuta alle perdite DC→AC ignorate
This commit is contained in:
Pi Developer
2026-02-22 15:50:26 +01:00
parent 94ac952644
commit 874ece5529
+64 -6
View File
@@ -134,12 +134,20 @@ processInverter () {
local PV_WATTS PV_CURRENT local PV_WATTS PV_CURRENT
if [ "$SCC_CHARGING" = "1" ]; then if [ "$SCC_CHARGING" = "1" ]; then
# SCC is active: estimate total PV power via DC bus balance if [ "$inv_id" = "1" ] && awk -v v="$INV1_PV_DIRECT" 'BEGIN{exit !(v+0 > 0)}' 2>/dev/null; then
# P_pv = V_batt × I_scc_to_battery + max(0, Load V_batt × I_bat_discharge) # inv1 (RS232 master): use QPIGS DATA[19] = direct PV watts from MPPT controller.
local BATT_CHARGE_W=$(echo "$BATT_V $SCC_A" | awk '{printf "%.1f", $1 * $2}') # This is the most accurate reading, bypassing DC-bus estimation entirely.
local BATT_DISCH_W=$(echo "$BATT_V $DISCH_A" | awk '{printf "%.1f", $1 * $2}') PV_WATTS=$(printf "%.1f" "$INV1_PV_DIRECT")
local LOAD_FROM_SCC=$(echo "$LOAD_W $BATT_DISCH_W" | awk '{v=$1-$2; printf "%.1f", (v>0)?v:0}') else
PV_WATTS=$(echo "$BATT_CHARGE_W $LOAD_FROM_SCC" | awk '{printf "%.1f", $1 + $2}') # inv2+ (slaves, no QPIGS): DC bus balance corrected for SCC+inverter losses.
# Without efficiency correction Load_W (AC) < P_PV (DC) by factor η_total ≈ 0.93.
# P_PV = (V_batt×SCC_A + max(0, Load_W V_batt×DISCH_A)) / η_total
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}')
local PV_DC_EST=$(echo "$BATT_CHARGE_W $LOAD_FROM_SCC" | awk '{printf "%.1f", $1 + $2}')
PV_WATTS=$(echo "$PV_DC_EST $ETA_EFF" | awk '{printf "%.1f", $1 / $2}')
fi
if awk -v v="$PV_V" 'BEGIN{exit !(v+0 > 0)}' 2>/dev/null; then 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}') PV_CURRENT=$(echo "$PV_WATTS $PV_V" | awk '{printf "%.2f", $1 / $2}')
else else
@@ -210,6 +218,56 @@ else
echo "⚠ QPIRI failed - config parameters unavailable" echo "⚠ QPIRI failed - config parameters unavailable"
fi fi
# ── Step 1.5: QPIGS (direct PV measurement from master/inv1) ─────────────────
# QPIGS DATA[19] = PV panel watts measured directly by the MPPT controller.
# This field was added in the firmware upgrade (present in HS_MS_MSX_RS232_Protocol_..._after_current_upgrade).
# QPIGS only returns data for the RS232 master (inv1); inv2 must use the formula.
# QPIGS status byte layout (differs from QPGS!): b7=SBU,b6=cfg,b5=SCC_fw,b4=load_on,b3=batt_steady,b2=charging,b1=SCC_on,b0=AC_on
INV1_PV_DIRECT=0
ETA_EFF="0.93" # combined SCC+inverter efficiency (default, overridden dynamically from QPIGS)
QPIGS_RAW=""
for attempt in 1 2 3; do
QPIGS_RAW=`$SUDO_CMD "$INVERTER_BIN" -r "QPIGS" 2>&1 | grep "Reply:" | cut -d: -f2- | xargs`
[ ! -z "$QPIGS_RAW" ] && [ "$QPIGS_RAW" != "NAK" ] && break
sleep 0.5
done
if [ ! -z "$QPIGS_RAW" ] && [ "$QPIGS_RAW" != "NAK" ]; then
echo "✓ QPIGS retrieved"
IFS=' ' read -ra QPIGS_F <<< "$QPIGS_RAW"
# QPIGS fields ("after_current_upgrade" firmware):
# [0]=GridV [1]=GridF [2]=OutV [3]=OutF [4]=OutVA [5]=OutW [6]=LoadPct
# [7]=BusV [8]=BattV [9]=BattChgA [10]=BattCap [11]=Temp
# [12]=PV_I_for_Batt [13]=PV_V1 [14]=BattV_SCC [15]=BattDischA [16]=Status
# [17-18]=reserved [19]=PV_input_watts (direct MPPT reading) [20]=unknown
QPIGS_STATUS="${QPIGS_F[16]:-00000000}"
QPIGS_SCC_ON="${QPIGS_STATUS:6:1}" # b1 = index 6 (b7=index 0) SCC on/off
QPIGS_PV_W="${QPIGS_F[19]:-0}"
QPIGS_LOAD="${QPIGS_F[5]:-0}"
QPIGS_BATT_CHG_I=$(echo "${QPIGS_F[9]:-0}" | awk '{printf "%d", $1+0}')
QPIGS_BATT_DCH_I=$(echo "${QPIGS_F[15]:-0}" | awk '{printf "%d", $1+0}')
# Direct PV reading for inv1
if [ "$QPIGS_SCC_ON" = "1" ] && awk -v v="$QPIGS_PV_W" 'BEGIN{exit !(v+0 > 0)}' 2>/dev/null; then
INV1_PV_DIRECT="$QPIGS_PV_W"
echo " QPIGS inv1: PV_direct=${QPIGS_PV_W}W Load=${QPIGS_LOAD}W SCC=ON"
fi
# Derive η when battery effects are negligible (batt charge <2A AND discharge <2A)
# η_total = Load_AC / PV_direct ≈ η_scc × η_inv
if [ "$QPIGS_BATT_CHG_I" -lt 2 ] && [ "$QPIGS_BATT_DCH_I" -lt 2 ] \
&& awk -v v="$QPIGS_PV_W" 'BEGIN{exit !(v+0 > 0)}' 2>/dev/null \
&& awk -v v="$QPIGS_LOAD" 'BEGIN{exit !(v+0 > 0)}' 2>/dev/null; then
ETA_EFF=$(echo "$QPIGS_LOAD $QPIGS_PV_W" | awk '{e=$1/$2; if(e<0.75)e=0.75; if(e>0.98)e=0.98; printf "%.4f",e}')
echo " η computed from QPIGS: $ETA_EFF (${QPIGS_LOAD}W AC / ${QPIGS_PV_W}W PV)"
else
echo " η default: $ETA_EFF (battery active or QPIGS PV=0)"
fi
else
echo "⚠ QPIGS failed - using default efficiency η=0.93"
fi
# ── Step 2: QPGS per each inverter ─────────────────────────────────────────── # ── Step 2: QPGS per each inverter ───────────────────────────────────────────
SUCCESS_IDS=() SUCCESS_IDS=()