Conexión del inversor fotovoltaico HUAWEI sun2000 a broker MQTT (Node Red), integración de FreeDS y vinculación con domoticz

JJ del grupo de telegram «OpenEVSE» nos cuenta cómo establecer una conexión entre inversor fotovoltaico Huawei sun2000 a broker MQTT​ (node red).

El objetivo es conectar el único cliente MODBUS-TCP que permite este inversor a una raspberry para, mediante un script python, publicar las lecturas obtenidas en el broker MQTT instalado en la misma máquina.

Una vez publicado, cualquier aplicación que soporte MQTT se puede suscribir al topic deseado (como domoticz). Por ejemplo, OpenEVSE, puede suscribirse directamente al topic del meter, que indica la cantidad de energía que estamos importando o exportando.

Otras aplicaciones, por ejemplo, FreeDS, están diseñadas para leer los datos desde un topic concreto que no podemos modificar. En estos casos, debemos echar mano de Node-red, que se encargará de “cambiar” los topic que publica nuestro script por los que “entiende” FreeDS, que se corresponden con los que usa ICCSolar.

Dividimos esta guía en varios apartados

Requisitos inciales

Para poder seguir este tutorial es necesario tener instalado Node Red en nuestra Raspberry, además de Domoticz (si queremos implementar su uso), MQTT y demás.

También es fundamental, lógicamente, disponer de un inversor Huawei en nuestro poder.

Os dejamos el listado de tutoriales para poder instalar lo que necesitéis antes de empezar esta guía:

  1. Material necesario para poner en marcha domoticz
  2. Instalación de domoticz desde cero
  3. Instalación de Mosquitto MQTT Broker en Raspberry Pi 
  4. Configurar MQTT con usuario y contraseña (opcional)
  5. Cargamos MQTT en nuestro domoticz
  6. Instalar Watchdog en domoticz
  7. Crear usuario y contraseña para domoticz (opcional)
  8. Cómo instalar node red en nuestra raspberry pi

Descarga del software necesario

Damos por hecho que ya tenemos el software necesario a consecuencia del seguimiento de los tutoriales anteriores para instalar Node red.

OJO a los que tenéis USER y PASS en MQTT de la raspberry y en MQTT de domoticz. Debéis tenerlo en cuenta a la hora de seguir el tutorial.

Configuración en pUTTY

Abrimos putty y lanzamos la siguiente línea para instalar pymodbus:

sudo pip install  -U pymodbus

Instalamos paho-mqtt con esta linea:

sudo pip install paho-mqtt

Ir a la carpeta donde queramos copiar el script. En mi caso es la siguiente:

cd home/pi/data

Crear el fichero:

sudo nano Modbus-TCP_Huawei_to_MQTT.py

Editar el siguiente script con nuestros datos y guardarlo. Explicamos en el siguiente apartado cómo editar dichos datos:

(nota: esta basado en el script de Pedestre que compartió en solarweb.net. Se puede encontrar en la siguiente dirección: https://www.dropbox.com/s/9zaa1zexnr6cv60/detalles_modbus-tcp.py?dl=0 )

#!/usr/bin/python
#Script para conectar como cliente MODBUS-TCP a inversor Huawei y publicar los valores en MQTT
#By JJOsuna. marzo 2020. Basado en script de Pedestre.
#String 2. enero 2021

from pymodbus.client.sync import ModbusTcpClient as ModbusClient
import subprocess
import json
import time
import pdb
import os
import paho.mqtt.client as mqtt

def leerDetalles(ip_inverter):

#intervalo de actualizacion en segundos
intervalo=10
lecturasMinuto=(60/intervalo)+1

client = ModbusClient(ip_inverter, port=502, unit_id=0)
client.connect()
if client.connect():
time.sleep(1)
cont=1
while cont<lecturasMinuto:
potenciaPico=-1
while potenciaPico<0:
try:
energiaExportada,activePowerInv,energiaDiaria,potenciaPico,String_1_Voltaje,String_1_Corriente,String_2_Voltaje,String_2_Corriente,activePowerPaneles,TempInversor,VoltajeINV=leerDelInversor(client)
except:
client = ModbusClient(ip_inverter, port=502, unit_id=0)
client.connect()
time.sleep(1)
energiaExportada,activePowerInv,energiaDiaria,potenciaPico,String_1_Voltaje,String_1_Corriente,String_2_Voltaje,String_2_Corriente,activePowerPaneles,TempInversor,VoltajeINV=leerDelInversor(client)

try:

clientMQTT.publish(topic="emon/NodeHuawei/Meter", payload= str(energiaExportada), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/EnergiaDia", payload=str(energiaDiaria/100.0), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/Power_inversor", payload=str(activePowerInv), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/Power_pico", payload=str(potenciaPico), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/String_1_Voltaje", payload=str(String_1_Voltaje/10.0), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/String_1_Corriente", payload=str(String_1_Corriente/100.0), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/String_2_Voltaje", payload=str(String_2_Voltaje/10.0), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/String_2_Corriente", payload=str(String_2_Corriente/100.0), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/Power_paneles", payload=str(activePowerPaneles), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/Temp_Inversor", payload=str(TempInversor/10.0), qos=1, retain=False)
clientMQTT.publish(topic="emon/NodeHuawei/VoltajeINV", payload=str(VoltajeINV/10.0), qos=1, retain=False)

except (IOError, OSError):
pass

time.sleep(intervalo)
cont += 1
if cont==lecturasMinuto:
cont=1

def leerDelInversor(client):
try:
#Leer la potencia solar actual
rr = client.read_holding_registers(0x7D50, 0x02) #32080 POTENCIA FV
activePowerInv=rr.registers[1]

#Leer la lectura del meter (exported2 - exported1) positivo exportando, negativo consumiendo
rr1 = client.read_holding_registers(0x90f9, 0x02) #37113 CONSUMO TOTAL
#rr1 = client.read_holding_registers(0x9cb8, 0x01) #40120
exported1=rr1.registers[0]
exported2=rr1.registers[1]
#pdb.set_trace()
energiaExportada=exported2-exported1

#Leer la produccion del dia
rr = client.read_holding_registers(0x7d72, 0x02) #32114
energiaDiaria=rr.registers[1]

#Leer Pico de produccion del dia
rr = client.read_holding_registers(0x7d4e, 0x02) #32078
potenciaPico=rr.registers[1]

#Leer Voltaje String 1
rr = client.read_holding_registers(0x7D10, 0x01) #32016
String_1_Voltaje=rr.registers[0]
#Leer Corriente String 1
rr = client.read_holding_registers(0x7D11, 0x01) #32017
String_1_Corriente=rr.registers[0]

#Leer Voltaje String 2
rr = client.read_holding_registers(0x7D12, 0x01) #32018
String_2_Voltaje=rr.registers[0]
#Leer Corriente String 2
rr = client.read_holding_registers(0x7D13, 0x01) #32019
String_2_Corriente=rr.registers[0]

#Leer la potencia paneles solares que entra en inversor
rr = client.read_holding_registers(0x7D40, 0x02) #32064
activePowerPaneles=rr.registers[1]

#Leer temperatura interna inversor
rr = client.read_holding_registers(0x7D57, 0x01) #32087
TempInversor=rr.registers[0]

#Leer Voltaje de salida del inversor
rr = client.read_holding_registers(0x7D42, 0x01) #32066
VoltajeINV=rr.registers[0]


return energiaExportada,activePowerInv,energiaDiaria,potenciaPico,String_1_Voltaje,String_1_Corriente,String_2_Voltaje,String_2_Corriente,activePowerPaneles,TempInversor,VoltajeINV
except:
return 0,0,0,-1,0,0,0,0,0,0,0

def on_connect(client, userdata, flags, rc):
if rc==0:
client.connected_flag=True #set flag
print("conectado OK")
else:
print("No conectado, codigo retornado=",rc)

mqtt.Client.connected_flag=False#create flag in class
broker_url = "192.168.1.66"
broker_port = 1883

clientMQTT = mqtt.Client()
clientMQTT.on_connect=on_connect #bind call back function
clientMQTT.loop_start()
#Some Executable Code Here
print("Connecting to broker ",broker_url)
clientMQTT.username_pw_set(username="",password="")
clientMQTT.connect(broker_url, broker_port) #connect to broker
while not clientMQTT.connected_flag: #wait in loop
print("In wait loop")
time.sleep(1)
print("in Main Loop")

leerDetalles("192.168.1.105")

clientMQTT.loop_stop()

Modificaciones importantes:

El script está comentado y creo que es fácil de entender y hacer cambios.

Poner la Ip del broker MQTT (de vuestra Rpi) en la línea:

broker_url = "192.168.1.20"

Poner el user y password del broker MQTT, en la línea:

clientMQTT.username_pw_set(username="XXXXX",password="XXXXXX")

Si se quiere cambiar los topic, hay que hacerlo a partir de la siguiente línea:

clientMQTT.publish(topic="emon/NodeHuawei/Meter", payload= str(energiaExportada), qos=1, retain=False)

Cambiar por vuestro topic aquí:

 emon/NodeHuawei/

Poner la IP de vuestro inversor (debéis configurarla fija en el router), en la línea:

leerDetalles("192.168.1.58")

Últimos pasos

Ahora hay que hacerlo ejecutable al inicio creando un servicio con systemd:

Abrimos el editor y creamos el archivo:

sudo nano /lib/systemd/system/Modbus_Huawei_MQTT.service

Y pegamos y guardamos el siguiente código (atención a la ruta del ExecStart):

[Unit]
Description=Mi Servicio para lanzar mi script Modbus_Huawei_MQTT
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python /home/pi/data/Modbus-TCP_Huawei_to_MQTT.py

[Install]
WantedBy=multi-user.target


Nuestro archivo debe tener el permiso como 644 para poder ejecutarse:

sudo chmod 644 /lib/systemd/system/Modbus_Huawei_MQTT.service

Para que el script corra al inicio, escribir en la consola los siguientes comandos:

sudo systemctl daemon-reload
sudo systemctl enable Modbus_Huawei_MQTT.service

Comprobamos su funcionamiento

Puedes revisar si tu script funciona con la siguiente línea:

sudo systemctl status Modbus_Huawei_MQTT.service

Configuramos Node Red

Abrimos node red (Recuerda que accedemos a ella introduciendo la IP de nuestra raspberry seguido de :1880) y cargamos el flow:

Introducimos en el recuadro siguiente texto (lo copiamos con control +c) y lo pegamos en el recuadro (con control + v):

[{"id":"2c11129a.b1b0be","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"3e709931.b785de","type":"mqtt in","z":"2c11129a.b1b0be","name":"","topic":"emon/NodeHuawei/#","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":240,"y":200,"wires":[["e0eecaba.032e58"]]},{"id":"e0eecaba.032e58","type":"debug","z":"2c11129a.b1b0be","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":490,"y":200,"wires":[]},{"id":"8d9bb244.7ccb2","type":"mqtt-broker","z":"","broker":"192.168.1.20","port":"1883","clientid":"","usetls":false,"verifyservercert":true,"compatmode":true,"keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":null,"birthPayload":"","willTopic":"","willQos":"0","willRetain":null,"willPayload":""}]

Y tras pegar el texto clicamos sobre IMPORT:

Y veremos que se nos carga el flow completo. 

Vamos a comprobar fácilmente si hemos introducido bien los datos. Para ello, clicamos sobre DEPLOY a la derecha.

En la ventana de debug de node red se veran todos los valores publicados:

Reinicio del script

Si por algún motivo se detiene el script, hay que lanzarlo de nuevo escribiendo en la consola (putty) el siguiente comando:

sudo systemctl restart  Modbus_Huawei_MQTT.service

Tengo pendiente crear un script watchdog que vigile si esta funcionando y lo reinicie si esta detenido.

Integración de FreeDS en el sistema:

He considerado más robusto y estable tener como cliente Modbus-TCP a la raspberry y no el ESP32 de FreeDS, ya que la rpi siempre esta conectada como “servidor domótico” y el ESP32 no siempre lo tendré conectado. De este modo está todo más centralizado para publicar los valores del inversor en el broker MQTT y tenerlos disponibles para la domótica.

Se podría usar FreeDS igualmente, ya que una vez configurado como cliente Modbus-TCP del inversor (seleccionando “Huawei Modbus TCP”), también publica los valores en el broker MQTT, con el topic definido en la configuración, que por defecto es freeds_xxxx/, siendo xxxx los dos ultimos bytes de la MAC de vuestro ESP32.

Si queremos usar FreeDS con nuestro script, debemos seleccionar como fuente de datos “ICC Solar (Mqtt)” y echar mano de node-red. Lo único que tenemos que hacer es suscribirnos a los topic que publica el script python con los valores obtenidos del inversor y publicarlos como los topic de ICCSolar, que estan soportados por FreeDS.

El flow a importar en node-red es el siguiente:

[{"id":"6b0de1c1.e3901","type":"tab","label":"FreeDS","disabled":false,"info":""},{"id":"4170b486.8af64c","type":"mqtt in","z":"6b0de1c1.e3901","name":"","topic":"emon/NodeHuawei/Power_inversor","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":220,"y":160,"wires":[["e706f60e.ed4598","487e99ba.c0d5e8"]]},{"id":"110d3dac.e9670a","type":"mqtt in","z":"6b0de1c1.e3901","name":"","topic":"emon/NodeHuawei/Meter","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":190,"y":260,"wires":[["d86adf7f.2f7e08"]]},{"id":"e706f60e.ed4598","type":"mqtt out","z":"6b0de1c1.e3901","name":"","topic":"Inverter/PvWattsTotal","qos":"2","retain":"","broker":"8d9bb244.7ccb2","x":600,"y":160,"wires":[]},{"id":"ddcf5d6f.7deb8","type":"mqtt in","z":"6b0de1c1.e3901","name":"","topic":"Inverter/#","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":660,"y":60,"wires":[["d33760f1.118e88"]]},{"id":"d33760f1.118e88","type":"debug","z":"6b0de1c1.e3901","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":850,"y":60,"wires":[]},{"id":"11bcff15.faedb1","type":"mqtt out","z":"6b0de1c1.e3901","name":"","topic":"Inverter/GridWatts","qos":"2","retain":"","broker":"8d9bb244.7ccb2","x":770,"y":260,"wires":[]},{"id":"ee26402c.c807d8","type":"mqtt in","z":"6b0de1c1.e3901","name":"","topic":"emon/NodeHuawei/EnergiaDia","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":210,"y":320,"wires":[["bcdc4724.7db838"]]},{"id":"bcdc4724.7db838","type":"mqtt out","z":"6b0de1c1.e3901","name":"","topic":"Inverter/SolarKwUse","qos":"2","retain":"","broker":"8d9bb244.7ccb2","x":540,"y":320,"wires":[]},{"id":"a653c8c2.09d778","type":"mqtt in","z":"6b0de1c1.e3901","name":"","topic":"emon/NodeHuawei/String_1_Voltaje","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":220,"y":380,"wires":[["b7f34d17.573e78"]]},{"id":"b4a42715.ea0b9","type":"mqtt in","z":"6b0de1c1.e3901","name":"","topic":"emon/NodeHuawei/String_1_Corriente","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":230,"y":440,"wires":[["4b4bf8a6.c9cee8"]]},{"id":"ac1eb267.8edc28","type":"mqtt in","z":"6b0de1c1.e3901","name":"","topic":"emon/NodeHuawei/Power_paneles","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":220,"y":500,"wires":[["e5d94cf.f37dfb"]]},{"id":"b7f34d17.573e78","type":"mqtt out","z":"6b0de1c1.e3901","name":"","topic":"Inverter/MPPT1_Volts","qos":"2","retain":"","broker":"8d9bb244.7ccb2","x":540,"y":380,"wires":[]},{"id":"4b4bf8a6.c9cee8","type":"mqtt out","z":"6b0de1c1.e3901","name":"","topic":"Inverter/MPPT1_Amps","qos":"2","retain":"","broker":"8d9bb244.7ccb2","x":550,"y":440,"wires":[]},{"id":"e5d94cf.f37dfb","type":"mqtt out","z":"6b0de1c1.e3901","name":"","topic":"Inverter/MPPT1_Watts","qos":"2","retain":"","broker":"8d9bb244.7ccb2","x":550,"y":500,"wires":[]},{"id":"aad8f98b.da4ab8","type":"mqtt in","z":"6b0de1c1.e3901","name":"","topic":"emon/NodeHuawei/Temp_Inversor","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":220,"y":560,"wires":[["1603b1cd.0f1c16"]]},{"id":"1603b1cd.0f1c16","type":"mqtt out","z":"6b0de1c1.e3901","name":"","topic":"Inverter/Temperature","qos":"2","retain":"","broker":"8d9bb244.7ccb2","x":520,"y":560,"wires":[]},{"id":"95c12365.5f2158","type":"inject","z":"6b0de1c1.e3901","name":"DEBUG: Simular produccion solar de1000W","topic":"solar","payload":"1000","payloadType":"num","repeat":"10","crontab":"","once":false,"onceDelay":"","x":220,"y":120,"wires":[[]]},{"id":"3d709165.e6140e","type":"inject","z":"6b0de1c1.e3901","name":"DEBUG: Simular exceso 300W","topic":"solar","payload":"300","payloadType":"num","repeat":"10","crontab":"","once":false,"onceDelay":"","x":180,"y":220,"wires":[[]]},{"id":"487e99ba.c0d5e8","type":"debug","z":"6b0de1c1.e3901","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":570,"y":120,"wires":[]},{"id":"c1d88e.3b83477","type":"comment","z":"6b0de1c1.e3901","name":"Inversor Huawei SUN2000 en FreeDS con MQTT","info":"Nos suscribimos a los topic que publica, en el broker mqtt, el script python con los valores obtenidos del inversor y se publican como los topic de ICCSolar, que estan soportados por FreeDS.","x":210,"y":40,"wires":[]},{"id":"fc264e86.63a7a8","type":"debug","z":"6b0de1c1.e3901","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":750,"y":220,"wires":[]},{"id":"d86adf7f.2f7e08","type":"change","z":"6b0de1c1.e3901","name":"convertir a numero y cambio signo","rules":[{"t":"set","p":"payload","pt":"msg","to":"($number(payload))*-1","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":260,"wires":[["fc264e86.63a7a8","11bcff15.faedb1"]]},{"id":"8d9bb244.7ccb2","type":"mqtt-broker","z":"","broker":"192.168.1.20","port":"1883","clientid":"","usetls":false,"verifyservercert":true,"compatmode":true,"keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":null,"birthPayload":"","willTopic":"","willQos":"0","willRetain":null,"willPayload":""}]

El aspecto que tiene es el siguiente:

Cómo localizar errores en node red

Os damos un truquito para vuestra información. Tenemos un node en el listado de la izquierda que se llama DEBUG. Cuando lo llevamos a la pantalla principal, lo conectamos a un node y lo activamos, nos dá mucha información (como un LOG) en la columna de la derecha del todo. Os explicamos con unas cuantas imágenes cómo conseguirlo:

Mantén el cursor pulsando la bola del final del recuadro del mqtt/in y arrástrala hasta la bola del inicio del recuadro del debug:

Clicamos sobre deploy:

Activamos la cucaracha y a la derecha nos aparecerá el debug con info de errores /( y así podremos analizar qué estamos haciendo mal) o info correcta:

Vinculación de los datos con domoticz

Para que los datos del inversor nos aparezcan en domoticz, vamos a vincular la información entre Node Red y domoticz.

Para ello abrimos de nuevo Node Red (si es que no lo teníamos abierto).

Estos son los flows que utilizo para crear unas variables globales que se pueden emplear para programaciones en node-red y también los envío a domoticz.

Variables globales de Produccion solar, consumo de la casa y exceso de FV.

Importamos los flows exactamente igual que en el caso anterior, vamos a:

Node Red > Import > Clipboard

Copiamos y pegamos el siguiente texto:

[{"id":"b6c4d89e.3fb528","type":"tab","label":"ValoresFV","disabled":false,"info":""},{"id":"36144a7d.c21556","type":"mqtt in","z":"b6c4d89e.3fb528","name":"","topic":"emon/NodeHuawei/Power_inversor","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":140,"y":160,"wires":[["d9558c01.e3772"]]},{"id":"ceeed17a.f780b8","type":"mqtt in","z":"b6c4d89e.3fb528","name":"","topic":"emon/NodeHuawei/Meter","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":130,"y":236,"wires":[["c67f8a69.55291"]]},{"id":"d9558c01.e3772","type":"change","z":"b6c4d89e.3fb528","name":"Esolar Input","rules":[{"t":"set","p":"topic","pt":"msg","to":"Esolar","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":371.25,"y":101.25,"wires":[["edf211f9.9dc648"]]},{"id":"c67f8a69.55291","type":"change","z":"b6c4d89e.3fb528","name":"Meter Input","rules":[{"t":"set","p":"topic","pt":"msg","to":"meter","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":371.25,"y":241.25,"wires":[["df83c173.876de","db1d84f7.4d032"]]},{"id":"edf211f9.9dc648","type":"delay","z":"b6c4d89e.3fb528","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":571.25,"y":101.25,"wires":[["df83c173.876de"]]},{"id":"db1d84f7.4d032","type":"debug","z":"b6c4d89e.3fb528","name":"debug","active":false,"tosidebar":true,"console":false,"complete":"payload","x":463,"y":295,"wires":[]},{"id":"df83c173.876de","type":"function","z":"b6c4d89e.3fb528","name":"Almacenar consumo casa","func":"// Load defaults\nvar Esolar = global.get(\"Esolar\");\nvar uso = global.get(\"uso\");\nvar exceso = global.get(\"exceso\");\n\n// Almacenar Solar PV en variable \nif (msg.topic === \"Esolar\") {\n    Esolar = msg.payload ;\n    global.set(\"Esolar\",Esolar)\n}\n\n// Almacenar consumo casa en variable\nif (msg.topic === \"meter\") {\n    uso = (msg.payload*-1)+(1*Esolar) ;\n    global.set(\"uso\",uso)\n}\n\n exceso = Esolar - uso;\n\n global.set(\"exceso\",exceso)\n\n \n\nreturn [{payload: global.get('Esolar')}, {payload: global.get('uso')},{payload: global.get('exceso')}];\n","outputs":"3","noerr":0,"x":571.25,"y":181.25,"wires":[["88b196cd.6bb05","f45b8da1.628a4"],["d34415ce.3a5","abd7d624.3da3d"],["bdd9d389.b4435","22603d.45ef77c4"]]},{"id":"88b196cd.6bb05","type":"debug","z":"b6c4d89e.3fb528","name":"produccion solar","active":false,"tosidebar":true,"console":false,"complete":"payload","x":911.25,"y":41.25,"wires":[]},{"id":"f45b8da1.628a4","type":"mqtt out","z":"b6c4d89e.3fb528","name":"","topic":"emon/NodeHuawei/PowerSOLAR","qos":"1","retain":"","broker":"8d9bb244.7ccb2","x":981.25,"y":81.25,"wires":[]},{"id":"d34415ce.3a5","type":"debug","z":"b6c4d89e.3fb528","name":"Consumo Casa","active":false,"tosidebar":true,"console":false,"complete":"payload","x":941.25,"y":121.25,"wires":[]},{"id":"abd7d624.3da3d","type":"mqtt out","z":"b6c4d89e.3fb528","name":"","topic":"emon/NodeHuawei/ConsumoCASA","qos":"","retain":"","broker":"8d9bb244.7ccb2","x":1001.25,"y":161.25,"wires":[]},{"id":"bdd9d389.b4435","type":"debug","z":"b6c4d89e.3fb528","name":"exceso","active":false,"console":"false","complete":"payload","x":901.25,"y":201.25,"wires":[]},{"id":"22603d.45ef77c4","type":"mqtt out","z":"b6c4d89e.3fb528","name":"emon/NodeHuawei/ExcesoFV","topic":"emon/NodeHuawei/ExcesoFV","qos":"","retain":"","broker":"8d9bb244.7ccb2","x":961.25,"y":241.25,"wires":[]},{"id":"8d9bb244.7ccb2","type":"mqtt-broker","z":"","broker":"192.168.1.20","port":"1883","clientid":"","usetls":false,"verifyservercert":true,"compatmode":true,"keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":null,"birthPayload":"","willTopic":"","willQos":"0","willRetain":null,"willPayload":""}]

Creamos los Dummys (sensores) en domoticz

Iniciamos domoticz, y vamos a:

Domoticz > Setup > Hardware

Creamos uno por uno varios sensores, en total 3, clicando sobre Create Virtual Sensors:

Necesitremos crear 3 dummys tipo Usage (electric) (aunque el inversor permite vincular más información).

Los tres dummys que crearemos tipo Usage (Electric) los llamaremos:

  • Produccion solar
  • Exceso FV
  • Consumo Casa

Nos vamos a:

Domoticz > Setup > Devices

Nos aparecen los dummys que acabamos de crear y anotamos los IDX y los nombres. Nos harán falta posteriormente.

Configuramos Node Red

Flow para exportar esos valores a Domoticz en mis dummys IDX 615, 616 y 617, que acabamos de crear. Tendrás que modificar estos números de IDX en tu node red tras importar el flow, además de los datos de tu domoticz.

Se incluye un cambio de signo en el exceso de FV para OpenEVSE, que entiende el signo negativo como exportado, al contrario que FreeDS).

[{"id":"94f4c4a7.04874","type":"tab","label":"DomoticZ","disabled":false,"info":""},{"id":"73dc5ba2.2e578c","type":"mqtt out","z":"94f4c4a7.04874","name":"Publicar en DomoticZ","topic":"domoticz/in","qos":"","retain":"","broker":"8d9bb244.7ccb2","x":960,"y":160,"wires":[]},{"id":"8e9a471f.c25dd","type":"function","z":"94f4c4a7.04874","name":"DomoticZ_IDX 615_Esolar","func":"\nvar smes = msg.payload;\nmsg.payload = {};\nmsg.payload.idx = 615\nmsg.payload.svalue = smes//smes;\nreturn msg;","outputs":1,"noerr":0,"x":680,"y":120,"wires":[["73dc5ba2.2e578c"]]},{"id":"6b9acaef.41eb84","type":"function","z":"94f4c4a7.04874","name":"DomoticZ_IDX 616_uso","func":"\nvar smes = msg.payload;\nmsg.payload = {};\nmsg.payload.idx = 616\nmsg.payload.svalue = smes//smes;\nreturn msg;","outputs":1,"noerr":0,"x":670,"y":180,"wires":[["73dc5ba2.2e578c"]]},{"id":"4a45be1c.7c6228","type":"function","z":"94f4c4a7.04874","name":"DomoticZ_IDX 617_exceso","func":"\nvar smes = msg.payload;\nmsg.payload = {};\nmsg.payload.idx = 617\nmsg.payload.svalue = smes//smes;\nreturn msg;","outputs":1,"noerr":0,"x":740,"y":240,"wires":[["73dc5ba2.2e578c"]]},{"id":"adbb235f.b86f3","type":"mqtt in","z":"94f4c4a7.04874","name":"","topic":"emon/NodeHuawei/Power_inversor","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":220,"y":60,"wires":[["945869a1.e7ab4","cb477005.44ba98"]]},{"id":"135afbda.7e475c","type":"function","z":"94f4c4a7.04874","name":"Valores FV para Domoticz","func":"var solar = global.get(\"Esolar\");\nvar use = global.get(\"uso\");\nvar excess = global.get(\"exceso\");\n\n\nreturn [{payload: solar}, {payload: use}, {payload:excess}];","outputs":3,"noerr":0,"x":260,"y":200,"wires":[["8e9a471f.c25dd"],["ca7dab87.25def8"],["d1c78ff6.d53fd8","6f9aec20.743ef4"]]},{"id":"945869a1.e7ab4","type":"delay","z":"94f4c4a7.04874","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":240,"y":120,"wires":[["135afbda.7e475c"]]},{"id":"ca7dab87.25def8","type":"change","z":"94f4c4a7.04874","name":"num to str","rules":[{"t":"set","p":"payload","pt":"msg","to":"$string(payload)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":200,"wires":[["6b9acaef.41eb84"]]},{"id":"d1c78ff6.d53fd8","type":"change","z":"94f4c4a7.04874","name":"num to str","rules":[{"t":"set","p":"payload","pt":"msg","to":"$string(payload)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":240,"wires":[["4a45be1c.7c6228"]]},{"id":"89c0d59b.d0c868","type":"debug","z":"94f4c4a7.04874","name":"output","active":false,"console":"false","complete":"payload","x":610,"y":460,"wires":[]},{"id":"dfa5d23f.1a03c8","type":"mqtt in","z":"94f4c4a7.04874","name":"domoticz/in/#","topic":"domoticz/in/#","qos":"2","datatype":"auto","broker":"8d9bb244.7ccb2","x":110,"y":380,"wires":[["7aa9abd5.fc38c4"]]},{"id":"7aa9abd5.fc38c4","type":"debug","z":"94f4c4a7.04874","name":"output","active":false,"tosidebar":true,"console":false,"complete":"payload","x":330,"y":380,"wires":[]},{"id":"cb477005.44ba98","type":"debug","z":"94f4c4a7.04874","name":"output","active":false,"tosidebar":true,"console":false,"complete":"payload","x":470,"y":40,"wires":[]},{"id":"14a6b3b2.1b77ec","type":"mqtt out","z":"94f4c4a7.04874","name":"emon/NodeHuawei/ExcesoFV_OpenEvse","topic":"emon/NodeHuawei/ExcesoFV_OpenEvse","qos":"","retain":"","broker":"8d9bb244.7ccb2","x":790,"y":340,"wires":[]},{"id":"6f9aec20.743ef4","type":"change","z":"94f4c4a7.04874","name":"Cambio de signo (OpenEvse)","rules":[{"t":"set","p":"payload","pt":"msg","to":"($number(payload))*-1","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":530,"y":300,"wires":[["14a6b3b2.1b77ec","89c0d59b.d0c868"]]},{"id":"8d9bb244.7ccb2","type":"mqtt-broker","z":"","broker":"192.168.1.20","port":"1883","clientid":"","usetls":false,"verifyservercert":true,"compatmode":true,"keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":null,"birthPayload":"","willTopic":"","willQos":"0","willRetain":null,"willPayload":""}]

Comprobamos el funcionamiento en domoticz

Una vez hemos clicado en DEPLOY y nos aparece domoticz/in como connected, nos vamos a domoticz y comprobamos que está funcionando correctamente:

Cómo localizar errores en node red

Os damos un truquito para vuestra información. Tenemos un node en el listado de la izquierda que se llama DEBUG. Cuando lo llevamos a la pantalla principal, lo conectamos a un node y lo activamos, nos dá mucha información (como un LOG) en la columna de la derecha del todo. Os explicamos con unas cuantas imágenes cómo conseguirlo:

Mantén el cursor pulsando la bola del final del recuadro del mqtt/in y arrástrala hasta la bola del inicio del recuadro del debug:

Clicamos sobre deploy:

Activamos la cucaracha y a la derecha nos aparecerá el debug con info de errores /( y así podremos analizar qué estamos haciendo mal) o info correcta:

Inicio automático de Node RED con Raspberry Pi

Recordar que por defecto Node RED está apagado. Podemos iniciarlo de dos formas diferentes: manual o automático.

Para inicio manual introducimos en puTTY:

node-red-start

Para que Node Red inicie de forma automática (tras caídas de red, o tras apagar y encender la raspberry) lanzamos el siguiente comando en puTTY:

sudo systemctl enable nodered.service

Sacar el máximo partido al inversor

Tienes a tu disposición dos tutoriales para incluir también en domoticz dos derivadores de excedentes solares para sacar el máximo partido a la producción solar aunque tengas activado el veritido o inyección cero. Te los dejamos a continuación para que les eches un vistazo:

Para cualquier duda o consulta tienes disponible el grupo de telegram «Domoticz a lo Spain» para entrar, ponerte cómodo y participar cuanto quieras.

Clica aquí para entrar en él

Cualquier duda, sugerencia o comentario será bien recibida en la web!