Files
docker-voltronic-homeassistant/sources/inverter-mqtt/entrypoint.sh
T
Pi Developer c73ebc825c
Build Docker Image for Raspberry Pi / build-and-push (push) Successful in 7m13s
feat: Auto-discovery parallelo con timeout e stile originale
- Aggiunto timeout 15s al parallel discovery per evitare blocchi
- mqtt-init-parallel.sh in stile originale semplice
- Per ogni inverter scoperto: registra topic discovery (voltronic_inv1_*, inv2_*, ...)
- Discovery topics ogni 10 minuti invece di 5
- Fallback automatico a single-mode se timeout o count=0
- Mantiene la semplicità dello script originale

Il parallel discovery testa QPGS0-9 per trovare inverter configurati in parallelo.
Se timeout o nessun inverter trovato, usa modalità standard.
2026-02-02 23:32:56 +01:00

296 lines
9.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
export TERM=xterm
echo "=== Voltronic MQTT Bridge Starting ==="
echo "Version: 2.0 with Auto-Discovery"
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)
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
watt_factor=1.01
qpiri=103
qpiws=40
qmod=5
qpigs=110
EOF
fi
if [ ! -f "$MQTT_CONF" ]; then
echo "⚠ mqtt.json not found, creating default..."
cat > "$MQTT_CONF" << 'EOF'
{
"server": "192.168.1.37",
"port": "1883",
"topic": "homeassistant",
"devicename": "voltronic",
"username": "",
"password": "",
"clientid": "voltronic_default",
"influx": {
"enabled": "false"
}
}
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:-}"
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 ""
# 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
echo "Updating MQTT configuration from environment variables..."
# Backup original
cp $mqtt_conf ${mqtt_conf}.backup 2>/dev/null || true
# Update MQTT settings using jq
jq --arg server "$MQTT_SERVER" \
--arg port "$MQTT_PORT" \
--arg topic "$MQTT_TOPIC" \
--arg devicename "$MQTT_DEVICENAME" \
--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
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
echo ""
echo "=== Detecting Inverter Configuration ==="
echo ""
# Wait a bit for the device to be ready
sleep 2
# Check for parallel inverters (with timeout to avoid hanging)
echo "Checking for parallel inverters..."
PARALLEL_CHECK=$(timeout 15 /opt/inverter-cli/bin/inverter_poller -p 2>&1)
PARALLEL_EXIT=$?
if [ $PARALLEL_EXIT -eq 124 ]; then
echo "⚠ Parallel discovery timed out (15s), using single inverter mode"
USE_PARALLEL=false
else
PARALLEL_COUNT=$(echo "$PARALLEL_CHECK" | grep "PARALLEL_COUNT=" | cut -d= -f2)
if [ ! -z "$PARALLEL_COUNT" ] && [ "$PARALLEL_COUNT" -gt 0 ]; then
echo "✓ Detected $PARALLEL_COUNT parallel inverter(s)"
echo " Using parallel mode scripts..."
USE_PARALLEL=true
else
echo " Single inverter mode (count=$PARALLEL_COUNT)"
echo " Using standard scripts..."
USE_PARALLEL=false
fi
fi
# Set script paths based on mode
if [ "$USE_PARALLEL" = true ]; then
MQTT_PUSH_SCRIPT="/opt/inverter-mqtt/mqtt-push-parallel.sh"
MQTT_INIT_SCRIPT="/opt/inverter-mqtt/mqtt-init-parallel.sh"
else
MQTT_PUSH_SCRIPT="/opt/inverter-mqtt/mqtt-push.sh"
MQTT_INIT_SCRIPT="/opt/inverter-mqtt/mqtt-init.sh"
fi
echo ""
echo "=== Starting MQTT Bridge Services ==="
echo ""
# Init the mqtt server for the first time, then every 10 minutes (600 seconds)
# This will re-create the auto-created topics in the MQTT server if HA is restarted...
echo "Starting MQTT initialization service (every 10 minutes)..."
watch -n 600 "$MQTT_INIT_SCRIPT" > /dev/null 2>&1 &
# 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..."
/opt/inverter-mqtt/mqtt-subscriber.sh &
# execute exactly every 30 seconds...
echo "Starting MQTT data push service (every 30 seconds)..."
echo ""
echo "✓ All services started successfully!"
echo " Logs will appear below..."
echo ""
watch -n 30 "$MQTT_PUSH_SCRIPT" > /dev/null 2>&1