#!/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 /opt/inverter-cli/bin/inverter_poller -a" fi fi echo "" echo "=== Starting MQTT Bridge Services ===" echo "Using parallel inverter mode (2 inverters)" 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" # Init the mqtt server for the first time, then 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)..." watch -n 300 "$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