Benvenuti su Paesi al Tramonto, il mio mondo visto dall’alto! Qui troverete spettacolari riprese aeree in alta definizione, catturate con il mio drone al tramonto o in condizioni di luce uniche. Esploriamo insieme i paesi italiani, castelli, ville, luoghi speciali e paesaggi mozzafiato..
La mia flotta è costituita da due droni un piccolo DJI Mini 2SE e un DJI Air 2S.
Ho conseguito le licenza di volo ENAV A1, A2 e A3 e a breve otterrò la STS01 e 02.
L’attività principale svolta è il girare mini documentati aerei per il mio canale YouTube “Paesi al Tramonto”, di seguito gli articoli su gli ultimi video pubblicati.
Se avete la fortuna di poter collegare il dongle RS485 che legge i dati del vostro inverter direttamente a raspderry che ospita il vostro HA, la parte iniziale di questa guida non vi serve e potete andare direttamente al capito dedicato.
Se invece avete un raspberry con il dongle RS485 collegato all’inverter, e un altro raspberry con HA ecco come è possible metterli in comunicazione vi MQTT.
Sul raspberry con il dongle RS485 installare Pyton:
Prima di procedere è necessario conoscere l’IP del raspberry che ospita HA, nel mio caso 192.168.0.7 comando:
ping -c 4 192.168.0.7 verificare che risponda.
Prima di procedere è necessario installare nel raspberry che ospita HA l’applicazione Mosquitto Broker. Andare poi nelle integrazioni e verificare che MQTT si sia aggiunta e non ci siano errori. Creare l’utente mqtt_powerx e scegliere una password (attenzione deve essere un’utente e non una persona)
Installata l’App Mosquitto torniamo sul raspberry collegato all0inverte e verifichiamo che MQTT risponda sulla porta 1883 con il comando:
nc -vz 192.168.0.7 1883
la risposta dovrebbe essere: Connection to 192.168.0.7 1883 port [tcp/*] succeeded!
Al posto di PASSWORD metti quella da te scelta. Se funziona non dovrebbe dare errori. Eseguiamo un test di comunicazione, sempre sul raspberry inverter digitare il comando:
se ha funzionato il primo terminale dovrebbe sbloccarsi e scrivere “ciao” poi rimanere nuovamente in attesa. Fermare tutto con CTRL + C .
Sempre sul raspberry inverter creare il file “powerx_soc.py “dentro una cartella dove si hanno diritti di lettura e scrittura, che contiene il seguente codice. Modificare il file con il giusto nome utente e password.
import time
import struct
import paho.mqtt.publish as publish
from pymodbus.client import ModbusSerialClient
MQTT_BROKER = "192.168.0.7"
MQTT_USER = "mqtt_powerx"
MQTT_PASSWORD = "LA_TUA_PASSWORD"
client = ModbusSerialClient(
port="/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0",
baudrate=115200,
parity="N",
stopbits=1,
bytesize=8,
timeout=2
)
discovery_sent = False
while True:
try:
if client.connect():
result = client.read_input_registers(
address=4626,
count=2,
slave=1
)
if not result.isError():
raw = struct.pack(
'>HH',
result.registers[0],
result.registers[1]
)
soc = struct.unpack('>f', raw)[0]
if not discovery_sent:
publish.single(
"homeassistant/sensor/powerx_soc/config",
payload='{"name":"PowerX SOC","state_topic":"powerx/soc","unit_of_measurement":"%","unique_id":"powerx_soc","state_class":"measurement","device":{"name":"FEB PowerX","manufacturer":"FEB","model":"PowerX"}}',
hostname=MQTT_BROKER,
auth={
"username": MQTT_USER,
"password": MQTT_PASSWORD
}
)
discovery_sent = True
publish.single(
"powerx/soc",
round(soc, 1),
hostname=MQTT_BROKER,
auth={
"username": MQTT_USER,
"password": MQTT_PASSWORD
}
)
print(f"SOC: {soc:.1f}%")
client.close()
except Exception as e:
print(e)
time.sleep(10)
Posizionarsi sulla cartella, verificare che il file sia presente, digitare il comando:
python3 powerx_soc.py
Dovrebbe iniziare a generare su ogni riga il valore di carica della batteria. Aprire un nuovo terminale e digitare il comando:
se c’è comunicazione dovrebbe comparire lo stesso valore della finestra 1.
Creiamo l’entità che riceve il dato sul raspberry HA digitando dal terminale del raspberry inverter il seguente comando (inserendo la password corretta):
Sul raspberry HA nell’Integrazione MQTT dovrebbe comparire la nuova identità e se lo script Python è in esecuzione il suo valore dovrebbe essere uguale alla carica delle batterie del nostro impianto.
Se tutto funziona si può creare uno script più completo che legga anche gli altri valori come il PC, BAT, LOAD e GRID:
import time
import struct
import paho.mqtt.publish as publish
from pymodbus.client import ModbusSerialClient
MQTT_BROKER = "192.168.0.7"
MQTT_USER = "mqtt_powerx"
MQTT_PASSWORD = "TUA_PASSWORD"
MODBUS_PORT = "/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0"
client = ModbusSerialClient(
port=MODBUS_PORT,
baudrate=115200,
parity="N",
stopbits=1,
bytesize=8,
timeout=2
)
discovery_done = False
def read_float(address):
result = client.read_input_registers(
address=address,
count=2,
slave=1
)
if result.isError():
return None
raw = struct.pack(">HH",
result.registers[0],
result.registers[1])
return round(struct.unpack(">f", raw)[0], 2)
def mqtt_send(topic, value):
publish.single(
topic,
str(value),
hostname=MQTT_BROKER,
auth={
"username": MQTT_USER,
"password": MQTT_PASSWORD
}
)
while True:
try:
if client.connect():
if not discovery_done:
entities = {
"soc": "%",
"pv_power": "kW",
"battery_power": "kW",
"load_power": "kW",
"grid_power": "kW",
}
for sensor, unit in entities.items():
payload = (
f'{{'
f'"name":"PowerX {sensor}",'
f'"state_topic":"powerx/{sensor}",'
f'"unique_id":"powerx_{sensor}",'
f'"unit_of_measurement":"{unit}"'
f'}}'
)
publish.single(
f"homeassistant/sensor/powerx_{sensor}/config",
payload=payload,
hostname=MQTT_BROKER,
retain=True,
auth={
"username": MQTT_USER,
"password": MQTT_PASSWORD
}
)
discovery_done = True
soc = read_float(4626)
pv = read_float(4720)
battery = read_float(4722)
load = read_float(4724)
grid = read_float(4726)
if soc is not None:
mqtt_send("powerx/soc", soc)
if pv is not None:
mqtt_send("powerx/pv_power", pv)
if battery is not None:
mqtt_send("powerx/battery_power", battery)
if load is not None:
mqtt_send("powerx/load_power", load)
if grid is not None:
mqtt_send("powerx/grid_power", grid)
print(
f"SOC={soc}% "
f"PV={pv}kW "
f"BAT={battery}kW "
f"LOAD={load}kW "
f"GRID={grid}kW"
)
client.close()
except Exception as e:
print(e)
time.sleep(10)
Se avete usato lo stesso script powerx_soc in HA compariranno le nuove entità e finalmente il vostro HA ha tutti i valori necessari a monitorare il vostro impianto fotovoltaico.
Come accade spesso questi inverter pubblicano i dati di produzione solo via App proprietaria, questo non permette di usare i dati di produzione del proprio impianto fotovoltaico sulla propria domotica. Il mio obbiettivo era quello di poter visualizzare sulla mia domotica basata su Home Assistant dei dati di produzione del mio impianto fotovoltaico.
Dopo alcune prove sono riuscito a collegare il mio inverter FEB PowerX a un Raspberry Pi 4 e a leggere correttamente i registri Modbus RTU tramite RS485.
Hardware utilizzato
Raspberry Pi 3, 4 o 5 con Raspberry Pi OS
Dongle USB RS485 CH340
Inverter FEB PowerX
Cavo RJ45 modificato
Questo è il dongle che ho acquistato:
Questo è il cavo che ho realizzato:
Il mio inverter ha una porta RS485, questa è impegnata dal cavo di rete che mette in comunicazione le batterie con l’inverter, le batterie però usano il canale BMS e non il canale EMS come si vede dalla figura sotto:
al posto di cercare un deviatore come quello di figura sopra, di difficile reperibilità, ho creato con due connettore di rete RJ45, uno maschio e uno femmina, un cavo che estrae i soli PIN 7 e 8.
Con questo cavo i PIN dal 1 al 6 continuano ad andare dall’inverter alla batteria, questo è fondamentale per il funzionamento corretto dell’inverter e dell’App. I soli PIN 7 e 8 adesso non vanno più alla batteria ma con i cavetti rosso e bianco sono pronti per essere collegato al dongle RS485 per la comunicazione RS485.
Ultimo passaggio è quello di impostare nell’App il canale slave:
Adesso è tutto pronto per testare la comunicazione RS485.
Collegamento RS485
Collegare il cavo del PIN 7 alla porta A del dongle e il PIN 8 alla porta B il GND non è necessario per cavi corti.
Verifica del dongle USB
Inserire il dongle in una porta USB del raspberry e verificare che venga riconosciuto con il comando:
ls /dev/ttyUSB*
nel mio caso il risultato è: /dev/ttyUSB0
Per identificare il dispositivo: dmesg | grep ttyUSB
Utilizzare il nome persistente del dispositivo
Se si dovesse riavviare il Raspberry la porta potrebbe cambiare, per evitare questo problema dare il comando: -l /dev/serial/by-id/
Nel mio caso la risposta è stata:
/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0
lo useremo da ora in poi per identificare il dongle.
Installazione di mbpoll
sudo apt update
sudo apt install mbpoll
Verifica:
which mbpoll
Parametri Modbus corretti
Dopo vari tentativi i parametri funzionanti sono risultati: