feat(v2.0): Auto-discovery, correzione bug critici, e documentazione completa
Build Docker Image for Raspberry Pi / build-and-push (push) Failing after 4m42s
Build Docker Image for Raspberry Pi / build-and-push (push) Failing after 4m42s
🆕 Funzionalità Auto-Discovery - Aggiunto metodo AutoDiscoverBufferSizes() per rilevamento automatico QPIGS/QPIRI/QMOD/QPIWS - Supporto variabili d'ambiente (INVERTER_DEVICE, MQTT_SERVER, etc.) - Caching persistente buffer sizes in /cache/inverter.conf.cache - Flag -a/--auto-discover per modalità auto-detection 🐛 Bug Fixes Critici - **Parsing interi**: Aggiunta attemptAddSettingInt() con stoi() invece di stof() - Fix: stof('98') = 98.0f → 97 (int), ora stoi('98') = 98 direttamente - Applicato a: qpiri, qpiws, qmod, qpigs - **Thread sync**: Aggiunto ups_qpiws_changed a main loop e condizione exit poll() - Fix: loop principale controllava solo 3 flag su 4, causava hang - Fix: thread poll() non usciva in runOnce perché mancava controllo QPIWS - **Config accuracy**: Corretti buffer sizes (qpiri: 98→103, qpiws: 36→40) - Rimosso sources/inverter-cli/inverter.conf che sovrascriveva config globale - Validato con test: inverter_poller -1 completa in 6s con JSON completo 📚 Documentazione Completa - Creato documentation/CODE_ARCHITECTURE.md (38KB) - Mappa logica variabili globali - Flusso esecuzione main() con diagrammi ASCII - Sequence diagram classe cInverter (poll, query, auto-discovery) - Thread synchronization diagrams - MQTT integration bash scripts flow - Mappa concettuale 5-layer system architecture - Error handling e performance optimizations - Organizzati file .md in documentation/ (AUTO_DISCOVERY, IMPLEMENTATION, QUICKSTART, DEBUG) - Aggiornato README.md con sezione v2.0 e indice documentazione - Aggiornato .github/copilot-instructions.md con novità v2.0 🔧 Miglioramenti Build & CI/CD - Gitea Actions per build multi-arch (arm/v6, arm/v7, arm64, amd64, 386) - Configurazione VS Code completa (tasks, launch, debug GDB) - Script test-autodiscovery.sh e test-device.sh ✅ Testing Validato - inverter_poller -1 completa in 6 secondi - Output JSON completo con tutte le metriche - Exit pulito senza timeout (exit code 0) - Tutte le 4 query QMOD/QPIGS/QPIRI/QPIWS funzionanti
This commit is contained in:
Executable
+133
@@ -0,0 +1,133 @@
|
||||
#!/bin/bash
|
||||
# Script per testare comunicazione diretta con inverter
|
||||
# Usa questo per verificare se il device risponde correttamente
|
||||
|
||||
DEVICE="${1:-/dev/ttyUSB0}"
|
||||
|
||||
echo "=== Test Comunicazione Inverter su $DEVICE ==="
|
||||
echo ""
|
||||
|
||||
# Verifica device esiste
|
||||
if [ ! -e "$DEVICE" ]; then
|
||||
echo "ERROR: Device $DEVICE non trovato!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verifica permessi
|
||||
if [ ! -r "$DEVICE" ] || [ ! -w "$DEVICE" ]; then
|
||||
echo "ERROR: Permessi insufficienti su $DEVICE"
|
||||
echo "Esegui: sudo chmod 666 $DEVICE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "1. Configurazione device seriale..."
|
||||
stty -F $DEVICE 2400 cs8 -cstopb -parenb -echo raw
|
||||
|
||||
echo "2. Test con cat (premi Ctrl+C dopo 5 secondi)..."
|
||||
echo " Questo mostrerà eventuali dati inviati dall'inverter..."
|
||||
timeout 5 cat $DEVICE | od -A x -t x1z -v | head -20
|
||||
|
||||
echo ""
|
||||
echo "3. Invio comando raw QMOD all'inverter..."
|
||||
|
||||
# Crea script Python per inviare comando con CRC corretto
|
||||
python3 << 'PYTHON_EOF'
|
||||
import sys
|
||||
import serial
|
||||
import time
|
||||
|
||||
def calc_crc(data):
|
||||
"""Calcola CRC secondo protocollo Voltronic"""
|
||||
crc_ta = [
|
||||
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
|
||||
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef
|
||||
]
|
||||
|
||||
crc = 0
|
||||
for byte in data:
|
||||
da = ((crc >> 8) >> 4)
|
||||
crc = (crc << 4) & 0xFFFF
|
||||
crc ^= crc_ta[da ^ (byte >> 4)]
|
||||
da = ((crc >> 8) >> 4)
|
||||
crc = (crc << 4) & 0xFFFF
|
||||
crc ^= crc_ta[da ^ (byte & 0x0f)]
|
||||
|
||||
crc_high = (crc >> 8) & 0xFF
|
||||
crc_low = crc & 0xFF
|
||||
|
||||
# Adjust for special bytes
|
||||
if crc_low in [0x28, 0x0d, 0x0a]:
|
||||
crc_low += 1
|
||||
if crc_high in [0x28, 0x0d, 0x0a]:
|
||||
crc_high += 1
|
||||
|
||||
return bytes([crc_high, crc_low])
|
||||
|
||||
try:
|
||||
ser = serial.Serial(
|
||||
port=sys.argv[1] if len(sys.argv) > 1 else '/dev/ttyUSB0',
|
||||
baudrate=2400,
|
||||
bytesize=serial.EIGHTBITS,
|
||||
parity=serial.PARITY_NONE,
|
||||
stopbits=serial.STOPBITS_ONE,
|
||||
timeout=3
|
||||
)
|
||||
|
||||
# Flush buffers
|
||||
ser.reset_input_buffer()
|
||||
ser.reset_output_buffer()
|
||||
time.sleep(0.2)
|
||||
|
||||
# Test comandi
|
||||
commands = ['QMOD', 'QPIGS', 'QPIRI', 'QPIWS']
|
||||
|
||||
for cmd in commands:
|
||||
print(f"\n--- Testing {cmd} ---")
|
||||
|
||||
# Prepare command
|
||||
cmd_bytes = cmd.encode('ascii')
|
||||
crc = calc_crc(cmd_bytes)
|
||||
full_cmd = cmd_bytes + crc + b'\r'
|
||||
|
||||
print(f"Sending: {full_cmd.hex()}")
|
||||
|
||||
# Send
|
||||
ser.write(full_cmd)
|
||||
ser.flush()
|
||||
time.sleep(0.3)
|
||||
|
||||
# Read response
|
||||
response = ser.read(200)
|
||||
|
||||
if len(response) > 0:
|
||||
print(f"Received {len(response)} bytes")
|
||||
print(f"Hex: {response.hex()}")
|
||||
try:
|
||||
print(f"ASCII: {response.decode('ascii', errors='replace')}")
|
||||
except:
|
||||
print(f"ASCII: {response}")
|
||||
|
||||
if response[0:1] == b'(':
|
||||
print(f"[OK] Valid start byte")
|
||||
if response[-1:] == b'\r':
|
||||
print(f"[OK] Valid end byte")
|
||||
print(f">>> Buffer size for {cmd}: {len(response)}")
|
||||
else:
|
||||
print(f"[ERROR] Invalid end byte: {response[-1]:02x}")
|
||||
else:
|
||||
print(f"[ERROR] Invalid start byte: {response[0]:02x}")
|
||||
else:
|
||||
print("✗ No response received")
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
ser.close()
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
PYTHON_EOF
|
||||
|
||||
echo ""
|
||||
echo "=== Test completato ===="
|
||||
Reference in New Issue
Block a user