refactor: Rimuove discovery, usa QPGS diretto in cascade mode
Build Docker Image for Raspberry Pi / build-and-push (push) Has been cancelled

- mqtt-push-parallel.sh: riscritto da 659 a 230 righe
  * Rimosse tutte le meccaniche di serial discovery (VALID_SERIALS,
    VALID_QPGS, PARALLEL_DISCOVERY, DIRECT_SERIALS, ecc.)
  * Ora query direte QPGS0→inv1, QPGS1→inv2 senza discovery preliminare
  * Numero inverter configurabile via CASCADE_COUNT env var (default 2)
  * Fix PV_in_watts: quando DATA[25]=0 (batteria carica) e SCC_OK e
    no AC grid (line_loss=1), usa Load_watt come proxy di produzione PV
  * Aggiunto publish di PV_in_watthour e Load_watthour
  * Aggiunto parsing corretto dei status flags dal byte di stato QPGS

- entrypoint.sh: riscritto da 240 a 131 righe
  * Rimossa intera logica di auto-discovery buffer sizes
  * Rimossi FORCE_DISCOVERY, SKIP_DISCOVERY, DISCOVERY_FLAG
  * Rimossi run_discovery() e update_config_with_discovery()
  * Startup immediato senza attese/tentativi di discovery
  * CASCADE_COUNT env var propagata agli script

- healthcheck: corretto per processi effettivi del container
  * Prima: cercava mqtt-subscriber + mosquitto_sub + watch (3 proc)
  * watch non viene mai avviato → sempre unhealthy
  * Ora: controlla mosquitto_sub (subscriber) + sleep (push loop cicla)
This commit is contained in:
Pi Developer
2026-02-22 15:02:22 +01:00
parent 4d5ed5d845
commit 078544381e
3 changed files with 195 additions and 783 deletions
+49 -213
View File
@@ -2,20 +2,27 @@
export TERM=xterm
echo "=== Voltronic MQTT Bridge Starting ==="
echo "Version: 2.0 with Auto-Discovery"
echo "Version: 2.0 - Cascade Mode"
echo ""
# Configuration paths
CONF_FILE="/etc/inverter/inverter.conf"
MQTT_CONF="/etc/inverter/mqtt.json"
DISCOVERY_FLAG="/etc/inverter/.discovery_done"
TEMP_CONF="/tmp/inverter_discovered.conf"
# Ensure config files exist (copy defaults if missing due to empty volume mount)
# Environment variables with defaults
INVERTER_DEVICE="${INVERTER_DEVICE:-/dev/ttyUSB0}"
MQTT_SERVER="${MQTT_SERVER:-192.168.1.37}"
MQTT_PORT="${MQTT_PORT:-1883}"
MQTT_TOPIC="${MQTT_TOPIC:-homeassistant}"
MQTT_DEVICENAME="${MQTT_DEVICENAME:-voltronic}"
MQTT_USERNAME="${MQTT_USERNAME:-}"
MQTT_PASSWORD="${MQTT_PASSWORD:-}"
CASCADE_COUNT="${CASCADE_COUNT:-2}"
# ── Ensure config files exist ─────────────────────────────────────────────────
if [ ! -f "$CONF_FILE" ]; then
echo "⚠ inverter.conf not found, creating default..."
cat > "$CONF_FILE" << 'EOF'
# Basic configuration options for the actual inverter polling process...
device=/dev/ttyUSB0
run_interval=120
amperage_factor=1.0
@@ -45,42 +52,21 @@ if [ ! -f "$MQTT_CONF" ]; then
EOF
fi
# Environment variables with defaults
INVERTER_DEVICE="${INVERTER_DEVICE:-/dev/ttyUSB0}"
FORCE_DISCOVERY="${FORCE_DISCOVERY:-false}"
SKIP_DISCOVERY="${SKIP_DISCOVERY:-false}"
MQTT_SERVER="${MQTT_SERVER:-192.168.1.37}"
MQTT_PORT="${MQTT_PORT:-1883}"
MQTT_TOPIC="${MQTT_TOPIC:-homeassistant}"
MQTT_DEVICENAME="${MQTT_DEVICENAME:-voltronic}"
MQTT_USERNAME="${MQTT_USERNAME:-}"
MQTT_PASSWORD="${MQTT_PASSWORD:-}"
# ── Apply device path to config ───────────────────────────────────────────────
sed -i "s|^device=.*|device=$INVERTER_DEVICE|g" "$CONF_FILE"
echo "Configuration:"
echo " Device: $INVERTER_DEVICE"
echo " Force Discovery: $FORCE_DISCOVERY"
echo " Skip Discovery: $SKIP_DISCOVERY"
echo " MQTT Server: $MQTT_SERVER:$MQTT_PORT"
echo " MQTT Topic: $MQTT_TOPIC"
echo " MQTT Device: $MQTT_DEVICENAME"
echo " Device: $INVERTER_DEVICE"
echo " Cascade count: $CASCADE_COUNT inverters"
echo " MQTT Server: $MQTT_SERVER:$MQTT_PORT"
echo " MQTT Topic: $MQTT_TOPIC"
echo " MQTT Device: $MQTT_DEVICENAME"
echo ""
# Function to update MQTT configuration
update_mqtt_config() {
local mqtt_conf="/etc/inverter/mqtt.json"
# Solo aggiorna se le ENV variables sono impostate
if [ -z "$MQTT_USERNAME" ] && [ -z "$MQTT_PASSWORD" ]; then
echo " MQTT credentials not provided via ENV, using values from mqtt.json"
return 0
fi
# ── Update MQTT config from ENV (only when credentials are provided) ──────────
if [ ! -z "$MQTT_USERNAME" ] || [ ! -z "$MQTT_PASSWORD" ]; then
echo "Updating MQTT configuration from environment variables..."
# Backup original
cp $mqtt_conf ${mqtt_conf}.backup 2>/dev/null || true
# Update MQTT settings using jq
cp $MQTT_CONF ${MQTT_CONF}.backup 2>/dev/null || true
jq --arg server "$MQTT_SERVER" \
--arg port "$MQTT_PORT" \
--arg topic "$MQTT_TOPIC" \
@@ -88,208 +74,58 @@ update_mqtt_config() {
--arg username "$MQTT_USERNAME" \
--arg password "$MQTT_PASSWORD" \
'.server = $server | .port = $port | .topic = $topic | .devicename = $devicename | .username = $username | .password = $password' \
$mqtt_conf > ${mqtt_conf}.tmp && mv ${mqtt_conf}.tmp $mqtt_conf
$MQTT_CONF > ${MQTT_CONF}.tmp && mv ${MQTT_CONF}.tmp $MQTT_CONF
echo "✓ MQTT configuration updated"
echo " Server: $MQTT_SERVER:$MQTT_PORT"
echo " Topic: $MQTT_TOPIC/sensor/$MQTT_DEVICENAME"
[ ! -z "$MQTT_USERNAME" ] && echo " Auth: Enabled (username: $MQTT_USERNAME)"
# Verifica che le credenziali siano state scritte
local check_user=$(jq -r '.username' $mqtt_conf)
local check_pass=$(jq -r '.password' $mqtt_conf)
if [ -z "$check_user" ] || [ -z "$check_pass" ]; then
echo "⚠ WARNING: MQTT credentials were not properly written to config file!"
fi
echo ""
}
# Update MQTT config from ENV on startup
update_mqtt_config
# Function to update config file with discovered values
update_config_with_discovery() {
local qmod=$1
local qpigs=$2
local qpiri=$3
local qpiws=$4
echo "Updating configuration with discovered values..."
# Backup original config
cp $CONF_FILE ${CONF_FILE}.backup
# Update device
sed -i "s|^device=.*|device=$INVERTER_DEVICE|g" $CONF_FILE
# Update buffer sizes
sed -i "s/^qmod=.*/qmod=$qmod/g" $CONF_FILE
sed -i "s/^qpigs=.*/qpigs=$qpigs/g" $CONF_FILE
sed -i "s/^qpiri=.*/qpiri=$qpiri/g" $CONF_FILE
sed -i "s/^qpiws=.*/qpiws=$qpiws/g" $CONF_FILE
echo "✓ Configuration updated successfully"
echo ""
grep -E "^(device|qmod|qpigs|qpiri|qpiws)=" $CONF_FILE
}
# Function to run auto-discovery
run_discovery() {
echo "=== Running Auto-Discovery ==="
echo "This will take about 10-15 seconds..."
echo ""
# Temporarily set device in config for discovery
cp $CONF_FILE $TEMP_CONF
sed -i "s|^device=.*|device=$INVERTER_DEVICE|g" $TEMP_CONF
cp $TEMP_CONF $CONF_FILE
# Run discovery and capture output
DISCOVERY_OUTPUT=$(/opt/inverter-cli/bin/inverter_poller -d -a 2>&1)
echo "$DISCOVERY_OUTPUT"
echo ""
# Parse discovery output
QMOD=$(echo "$DISCOVERY_OUTPUT" | grep "DISCOVERY_QMOD=" | cut -d= -f2)
QPIGS=$(echo "$DISCOVERY_OUTPUT" | grep "DISCOVERY_QPIGS=" | cut -d= -f2)
QPIRI=$(echo "$DISCOVERY_OUTPUT" | grep "DISCOVERY_QPIRI=" | cut -d= -f2)
QPIWS=$(echo "$DISCOVERY_OUTPUT" | grep "DISCOVERY_QPIWS=" | cut -d= -f2)
SUCCESS=$(echo "$DISCOVERY_OUTPUT" | grep "DISCOVERY_SUCCESS=" | cut -d= -f2)
if [ "$SUCCESS" = "true" ]; then
echo "✓ Auto-discovery completed successfully!"
update_config_with_discovery $QMOD $QPIGS $QPIRI $QPIWS
# Mark discovery as done
echo "device=$INVERTER_DEVICE" > $DISCOVERY_FLAG
echo "qmod=$QMOD" >> $DISCOVERY_FLAG
echo "qpigs=$QPIGS" >> $DISCOVERY_FLAG
echo "qpiri=$QPIRI" >> $DISCOVERY_FLAG
echo "qpiws=$QPIWS" >> $DISCOVERY_FLAG
echo "timestamp=$(date -Iseconds)" >> $DISCOVERY_FLAG
echo "✓ Discovery results saved to $DISCOVERY_FLAG"
return 0
else
echo "✗ Auto-discovery failed!"
echo "Please check:"
echo " 1. Inverter is powered on"
echo " 2. Cable is properly connected"
echo " 3. Device path is correct: $INVERTER_DEVICE"
echo ""
echo "Falling back to default configuration..."
# Update device but keep default buffer sizes
sed -i "s|^device=.*|device=$INVERTER_DEVICE|g" $CONF_FILE
return 1
fi
}
# Check if we need to run discovery
NEED_DISCOVERY=false
if [ "$FORCE_DISCOVERY" = "true" ]; then
echo "⚠ Force discovery requested via environment variable"
rm -f $DISCOVERY_FLAG
NEED_DISCOVERY=true
elif [ "$SKIP_DISCOVERY" = "true" ]; then
echo "⚠ Discovery skipped via environment variable"
# Just update device in config
sed -i "s|^device=.*|device=$INVERTER_DEVICE|g" $CONF_FILE
NEED_DISCOVERY=false
elif [ ! -f "$DISCOVERY_FLAG" ]; then
echo " No previous discovery found, will run auto-discovery"
NEED_DISCOVERY=true
else
# Check if device changed
SAVED_DEVICE=$(grep "^device=" $DISCOVERY_FLAG 2>/dev/null | cut -d= -f2)
if [ "$SAVED_DEVICE" != "$INVERTER_DEVICE" ]; then
echo "⚠ Device changed from $SAVED_DEVICE to $INVERTER_DEVICE"
echo " Running new discovery..."
rm -f $DISCOVERY_FLAG
NEED_DISCOVERY=true
else
echo "✓ Using previous discovery results from $DISCOVERY_FLAG"
# Restore saved config
while IFS= read -r line; do
if [[ $line =~ ^(device|qmod|qpigs|qpiri|qpiws)= ]]; then
key=$(echo "$line" | cut -d= -f1)
value=$(echo "$line" | cut -d= -f2)
sed -i "s|^$key=.*|$key=$value|g" $CONF_FILE
fi
done < "$DISCOVERY_FLAG"
echo "Current configuration:"
grep -E "^(device|qmod|qpigs|qpiri|qpiws)=" $CONF_FILE
fi
fi
# Run discovery if needed
if [ "$NEED_DISCOVERY" = "true" ]; then
if ! run_discovery; then
echo "⚠ Continuing with default configuration..."
echo " You can manually run discovery later with:"
echo " docker exec -it <container> /opt/inverter-cli/bin/inverter_poller -a"
fi
fi
# ── Wait for serial device ────────────────────────────────────────────────────
echo "Waiting for device $INVERTER_DEVICE to be ready..."
sleep 3
# ── Clean up legacy single-inverter MQTT topics ───────────────────────────────
_MQTT_SERVER=$(jq -r '.server' $MQTT_CONF)
_MQTT_PORT=$(jq -r '.port' $MQTT_CONF)
_MQTT_USER=$(jq -r '.username' $MQTT_CONF)
_MQTT_PASS=$(jq -r '.password' $MQTT_CONF)
_MQTT_DEVICENAME=$(jq -r '.devicename' $MQTT_CONF)
_MQTT_TOPIC=$(jq -r '.topic' $MQTT_CONF)
mosquitto_pub -h $_MQTT_SERVER -p $_MQTT_PORT -u "$_MQTT_USER" -P "$_MQTT_PASS" \
-t "$_MQTT_TOPIC/sensor/$_MQTT_DEVICENAME/config" -n -r > /dev/null 2>&1 || true
echo ""
echo "=== Starting MQTT Bridge Services ==="
if [ -n "$INVERTER_DEVICES" ]; then
echo "Using multi-device mode (INVERTER_DEVICES=${INVERTER_DEVICES})"
else
echo "Using parallel inverter mode (2 inverters)"
fi
echo "Cascade mode: $CASCADE_COUNT inverters on $INVERTER_DEVICE"
echo ""
# Wait a bit for the device to be ready
sleep 2
# Always use parallel scripts
MQTT_PUSH_SCRIPT="/opt/inverter-mqtt/mqtt-push-parallel.sh"
MQTT_INIT_SCRIPT="/opt/inverter-mqtt/mqtt-init-parallel.sh"
# Remove old single-inverter discovery topics (legacy cleanup)
echo "Cleaning up legacy MQTT topics..."
MQTT_SERVER=$(jq -r '.server' /etc/inverter/mqtt.json)
MQTT_PORT=$(jq -r '.port' /etc/inverter/mqtt.json)
MQTT_USERNAME=$(jq -r '.username' /etc/inverter/mqtt.json)
MQTT_PASSWORD=$(jq -r '.password' /etc/inverter/mqtt.json)
MQTT_DEVICENAME=$(jq -r '.devicename' /etc/inverter/mqtt.json)
mosquitto_pub -h $MQTT_SERVER -p $MQTT_PORT -u "$MQTT_USERNAME" -P "$MQTT_PASSWORD" \
-t "$MQTT_TOPIC/sensor/$MQTT_DEVICENAME/config" -n -r > /dev/null 2>&1
echo "✓ Legacy topics cleaned"
# Run MQTT initialization immediately on startup
echo "Initializing MQTT discovery topics for both inverters..."
"$MQTT_INIT_SCRIPT"
# ── Initialize MQTT discovery topics ─────────────────────────────────────────
echo "Initializing MQTT discovery topics..."
CASCADE_COUNT="$CASCADE_COUNT" "$MQTT_INIT_SCRIPT"
echo "✓ MQTT discovery topics initialized"
# Init the mqtt server every 5 minutes (300 seconds)
# This will re-create the auto-created topics in the MQTT server if HA is restarted...
echo "Starting MQTT initialization service (every 5 minutes)..."
# ── Periodic MQTT init (re-register topics every 5 min for HA restarts) ──────
(
while true; do
"$MQTT_INIT_SCRIPT" > /dev/null 2>&1
sleep 300
CASCADE_COUNT="$CASCADE_COUNT" "$MQTT_INIT_SCRIPT" > /dev/null 2>&1
done
) &
# Run the MQTT Subscriber process in the background (so that way we can change the configuration on the inverter from home assistant)
echo "Starting MQTT subscriber for commands..."
# ── MQTT subscriber (listen for commands from Home Assistant) ─────────────────
echo "Starting MQTT command subscriber..."
/opt/inverter-mqtt/mqtt-subscriber.sh > /dev/null 2>&1 &
# execute exactly every 30 seconds...
echo "Starting MQTT data push service (every 30 seconds)..."
# ── Main data push loop (every 30 seconds) ────────────────────────────────────
echo "Starting data push loop (every 30s)..."
echo ""
echo "✓ All services started successfully!"
echo " Logs will appear below..."
echo "✓ All services started. Logs appear below..."
echo ""
while true; do
"$MQTT_PUSH_SCRIPT" > /dev/null 2>&1
CASCADE_COUNT="$CASCADE_COUNT" "$MQTT_PUSH_SCRIPT" > /dev/null 2>&1
sleep 30
done