From 874ece552909840b71c2bb1180a5d307cc69c4bb Mon Sep 17 00:00:00 2001 From: Pi Developer Date: Sun, 22 Feb 2026 15:50:26 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20PV=5Fin=5Fwatts=20tramite=20QPIGS=20DATA?= =?UTF-8?q?[19]=20per=20inv1=20(MPPT=20diretto)=20+=20correzione=20efficie?= =?UTF-8?q?nza=20=CE=B7=20per=20inv2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- sources/inverter-mqtt/mqtt-push-parallel.sh | 70 +++++++++++++++++++-- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/sources/inverter-mqtt/mqtt-push-parallel.sh b/sources/inverter-mqtt/mqtt-push-parallel.sh index 448bbdb..75b362c 100755 --- a/sources/inverter-mqtt/mqtt-push-parallel.sh +++ b/sources/inverter-mqtt/mqtt-push-parallel.sh @@ -134,12 +134,20 @@ processInverter () { local PV_WATTS PV_CURRENT 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 [ "$inv_id" = "1" ] && awk -v v="$INV1_PV_DIRECT" 'BEGIN{exit !(v+0 > 0)}' 2>/dev/null; then + # inv1 (RS232 master): use QPIGS DATA[19] = direct PV watts from MPPT controller. + # This is the most accurate reading, bypassing DC-bus estimation entirely. + PV_WATTS=$(printf "%.1f" "$INV1_PV_DIRECT") + else + # 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 PV_CURRENT=$(echo "$PV_WATTS $PV_V" | awk '{printf "%.2f", $1 / $2}') else @@ -210,6 +218,56 @@ else echo "⚠ QPIRI failed - config parameters unavailable" 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 ─────────────────────────────────────────── SUCCESS_IDS=()