0143e8eb36
Build Docker Image for Raspberry Pi / build-and-push (push) Successful in 7m6s
- Rimosso timeout e detection automatica - Sempre modalità parallela forzata - Default 2 inverter se parallel discovery fallisce - Registra discovery per voltronic_inv1 e voltronic_inv2 NOTA: Se gli inverter non rispondono a QPGS, NON sono in modalità parallela. Per gestire 2 inverter fisici separati, serve INVERTER_DEVICES=/dev/ttyUSB0:/dev/ttyUSB1
135 lines
5.3 KiB
Bash
Executable File
135 lines
5.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# MQTT Push for Parallel Inverters
|
|
# Discovers parallel inverters and publishes data for each one separately
|
|
|
|
# Detect environment (container vs development)
|
|
if [ -f "/etc/inverter/mqtt.json" ] && [ -x "/opt/inverter-cli/bin/inverter_poller" ]; then
|
|
# Container mode
|
|
MQTT_CONFIG="/etc/inverter/mqtt.json"
|
|
INVERTER_BIN="/opt/inverter-cli/bin/inverter_poller"
|
|
MQTT_FALLBACK="/opt/inverter-mqtt/mqtt-push.sh"
|
|
CONTAINER_MODE=true
|
|
else
|
|
# Development mode
|
|
MQTT_CONFIG="/home/pi/Progetti/config/mqtt.json"
|
|
INVERTER_BIN="/home/pi/Progetti/sources/inverter-cli/bin/inverter_poller"
|
|
MQTT_FALLBACK="/home/pi/Progetti/sources/inverter-mqtt/mqtt-push.sh"
|
|
CONTAINER_MODE=false
|
|
fi
|
|
|
|
echo "Mode: $([ "$CONTAINER_MODE" = true ] && echo "Container" || echo "Development")"
|
|
echo "Using binary: $INVERTER_BIN"
|
|
|
|
# Check if jq is installed
|
|
if ! command -v jq &> /dev/null; then
|
|
echo "ERROR: jq is not installed. Install it with: sudo apt-get install jq"
|
|
exit 1
|
|
fi
|
|
|
|
MQTT_SERVER=`cat $MQTT_CONFIG | jq '.server' -r`
|
|
MQTT_PORT=`cat $MQTT_CONFIG | jq '.port' -r`
|
|
MQTT_TOPIC=`cat $MQTT_CONFIG | jq '.topic' -r`
|
|
MQTT_DEVICENAME=`cat $MQTT_CONFIG | jq '.devicename' -r`
|
|
MQTT_USERNAME=`cat $MQTT_CONFIG | jq '.username' -r`
|
|
MQTT_PASSWORD=`cat $MQTT_CONFIG | jq '.password' -r`
|
|
MQTT_CLIENTID=`cat $MQTT_CONFIG | jq '.clientid' -r`
|
|
INFLUX_ENABLED=`cat $MQTT_CONFIG | jq '.influx.enabled' -r`
|
|
|
|
pushMQTTData () {
|
|
# $1 = inverter_id, $2 = metric, $3 = value
|
|
local inverter_id=$1
|
|
local metric=$2
|
|
local value=$3
|
|
|
|
mosquitto_pub \
|
|
-h $MQTT_SERVER \
|
|
-p $MQTT_PORT \
|
|
-u "$MQTT_USERNAME" \
|
|
-P "$MQTT_PASSWORD" \
|
|
-i $MQTT_CLIENTID \
|
|
-r \
|
|
-t "$MQTT_TOPIC/sensor/${MQTT_DEVICENAME}_inv${inverter_id}_${metric}" \
|
|
-m "$value"
|
|
|
|
if [[ $INFLUX_ENABLED == "true" ]] ; then
|
|
pushInfluxData $inverter_id $metric $value
|
|
fi
|
|
}
|
|
|
|
pushInfluxData () {
|
|
INFLUX_HOST=`cat $MQTT_CONFIG | jq '.influx.host' -r`
|
|
INFLUX_USERNAME=`cat $MQTT_CONFIG | jq '.influx.username' -r`
|
|
INFLUX_PASSWORD=`cat $MQTT_CONFIG | jq '.influx.password' -r`
|
|
INFLUX_DEVICE=`cat $MQTT_CONFIG | jq '.influx.device' -r`
|
|
INFLUX_PREFIX=`cat $MQTT_CONFIG | jq '.influx.prefix' -r`
|
|
INFLUX_DATABASE=`cat $MQTT_CONFIG | jq '.influx.database' -r`
|
|
INFLUX_MEASUREMENT_NAME=`cat $MQTT_CONFIG | jq '.influx.namingMap.'$2'' -r`
|
|
|
|
curl -i -XPOST "$INFLUX_HOST/write?db=$INFLUX_DATABASE&precision=s" -u "$INFLUX_USERNAME:$INFLUX_PASSWORD" --data-binary "$INFLUX_PREFIX,device=${INFLUX_DEVICE}_inv${1} $INFLUX_MEASUREMENT_NAME=$3" > /dev/null 2>&1
|
|
}
|
|
|
|
# Discover parallel inverters
|
|
SUDO_CMD=""
|
|
if [ "$EUID" -ne 0 ] && [ -c "/dev/ttyUSB0" ]; then
|
|
SUDO_CMD="sudo"
|
|
fi
|
|
|
|
PARALLEL_DISCOVERY=`$SUDO_CMD "$INVERTER_BIN" -p 2>&1`
|
|
PARALLEL_COUNT=`echo "$PARALLEL_DISCOVERY" | grep "PARALLEL_COUNT=" | cut -d= -f2`
|
|
|
|
echo "Parallel discovery: count=$PARALLEL_COUNT"
|
|
|
|
# If no parallel count detected, assume 2 inverters
|
|
if [ -z "$PARALLEL_COUNT" ] || [ "$PARALLEL_COUNT" -eq 0 ]; then
|
|
echo "⚠ No parallel count detected, assuming 2 inverters"
|
|
PARALLEL_COUNT=2
|
|
fi
|
|
|
|
echo "Processing $PARALLEL_COUNT parallel inverters"
|
|
|
|
# Publish discovery info
|
|
pushMQTTData "system" "parallel_count" "$PARALLEL_COUNT"
|
|
|
|
# Extract inverter serials and QPGS indices
|
|
for i in $(seq 1 $PARALLEL_COUNT); do
|
|
SERIAL=`echo "$PARALLEL_DISCOVERY" | grep "INVERTER_${i}_SERIAL=" | cut -d= -f2`
|
|
QPGS_IDX=`echo "$PARALLEL_DISCOVERY" | grep "INVERTER_${i}_QPGS=" | cut -d= -f2`
|
|
|
|
echo "Processing Inverter #$i (Serial: $SERIAL, QPGS$QPGS_IDX)"
|
|
|
|
# Get QPGS data for this inverter
|
|
QPGS_DATA=`$SUDO_CMD "$INVERTER_BIN" -r "QPGS$QPGS_IDX" 2>&1 | grep "Reply:" | cut -d: -f2- | xargs`
|
|
|
|
if [ ! -z "$QPGS_DATA" ] && [ "$QPGS_DATA" != "NAK" ]; then
|
|
# Parse QPGS response format:
|
|
# 1 SERIAL MODE STATUS GRID_V GRID_F OUT_V OUT_F VA W PCT BATT_V CHRG CAP PV_V CHRG_A ...
|
|
|
|
# Publish serial number
|
|
pushMQTTData "$i" "serial" "$SERIAL"
|
|
|
|
# Parse and publish data (QPGS format parsing)
|
|
IFS=' ' read -ra DATA <<< "$QPGS_DATA"
|
|
|
|
[ "${DATA[2]}" ] && pushMQTTData "$i" "mode" "${DATA[2]}"
|
|
[ "${DATA[4]}" ] && pushMQTTData "$i" "AC_grid_voltage" "${DATA[4]}"
|
|
[ "${DATA[5]}" ] && pushMQTTData "$i" "AC_grid_frequency" "${DATA[5]}"
|
|
[ "${DATA[6]}" ] && pushMQTTData "$i" "AC_out_voltage" "${DATA[6]}"
|
|
[ "${DATA[7]}" ] && pushMQTTData "$i" "AC_out_frequency" "${DATA[7]}"
|
|
[ "${DATA[8]}" ] && pushMQTTData "$i" "Load_va" "${DATA[8]}"
|
|
[ "${DATA[9]}" ] && pushMQTTData "$i" "Load_watt" "${DATA[9]}"
|
|
[ "${DATA[10]}" ] && pushMQTTData "$i" "Load_pct" "${DATA[10]}"
|
|
[ "${DATA[11]}" ] && pushMQTTData "$i" "Battery_voltage" "${DATA[11]}"
|
|
[ "${DATA[12]}" ] && pushMQTTData "$i" "Battery_charge_current" "${DATA[12]}"
|
|
[ "${DATA[13]}" ] && pushMQTTData "$i" "Battery_capacity" "${DATA[13]}"
|
|
[ "${DATA[14]}" ] && pushMQTTData "$i" "PV_in_voltage" "${DATA[14]}"
|
|
[ "${DATA[15]}" ] && pushMQTTData "$i" "PV_in_current" "${DATA[15]}"
|
|
|
|
echo " ✓ Published data for inverter #$i"
|
|
echo " Topics: ${MQTT_TOPIC}/sensor/${MQTT_DEVICENAME}_inv${i}_{serial,mode,Battery_voltage,Load_watt,...}"
|
|
else
|
|
echo " ✗ No valid data for inverter #$i"
|
|
fi
|
|
done
|
|
|
|
echo "Parallel MQTT push completed"
|