Comunicación con la z21 a través de Node-RED

Bien es sabido por muchos de vosotros mi gran “adicción” a Node-RED desde hace ya bastante tiempo… Y mi gran afán por intentar usarlo para todo… o al menos casi todo, jejejeje.

Por lo que no me he podido resistir a… intentar comunicarme con la maravillosa z21 mediante esta gran herramienta!

En este pequeño artículo vamos a describir lo que será, espero, tan sólo la primera entrega de un pequeño documento en el que iré trabajando. Espero poder ofreceros mis avances con la programación y acceso a la z21 desde aplicaciones externas, hechas por mi, desde 0.

En este caso, la mejor forma de llegar a la z21 es mediante un entorno de prototipado, ágil y sencillo, como es Node-RED. Crearemos una serie de nodos para poder empezar a desgranar las posibilidades que esta pequeña fiera nos ofrece. Espero, con todo, quizá poder jugar algún día con ella, jajajaja.

Nota importante: para poder alcanzar a entender todo lo que aquí se describe es imprescindible haber echado un ojo (sino haber leído detenidamente) la documentación oficial de Roco acerca de cómo se accede y se explota la api de comunicación de la central z21 (podéis verlo aquí)

Vamos a ello…

 

Previos

Para poder realizar este sencillo tutorial, necesitaréis:

  • Una instancia de Node-RED en marcha en nuestro entorno local (no sirve distribuida!)
  • Tener la central z21 encendida
  • Tener el router encendido y conectado a la z21
  • Estar conectados a la red wifi del router o bien conectarnos por ethernet al router
  • Conocer nuestra ip dentro de la red de la z21 (normalmente será 192.168.0.100 que es la primera ip asignada por DHCP)
  • Ciertos conocimientos en redes, especialmente con el protocolo UDP

 

Conectando por primera vez con la central: haciendo “ping”

Lo primero que tenemos que hacer es ver si tenemos conectividad con la central z21. Para ello, simplemente le haremos “ping”, para ver si está conectada y llegamos desde nuestra red.

Yo tengo esta IP dentro del rango de la red de la z21: 192.168.0.100 (si no conocéis vuestra ip, deberéis investigar sobre cómo conseguirla, normalmente desde propiedades del adaptador de red, o bien desde la línea de comandos con ipconfig en Windows, o ifconfig en Linux).

Ahora que ya sabemos nuestra ip local, vamos a conectarnos a Node-RED.

Necesitaremos instalar un nuevo nodo para hacer peticiones ping de forma sencilla: node-red-node-ping

 

Ahora ya podemos hacer ping a la central, para ver si está viva:

Con esta configuración de nodos:

Guardamos, desplegamos y arrancamos el flow…

Con el anterior esquema, obtendremos un “ping” a la central cada 30 segundos, tal y como muestra el log de debug.

Como veis, el nodo de function sólo añade un poco de traza. Lo importante está en el nodo de ping, en el que hemos configurado el tiempo que queremos que pase entre petición y petición (30s) y la ip a la que atacamos (192.168.0.111, nuestra central z21).

Bien, ya tenemos nuestra central conectada a la red, y esperando conexiones entrantes…

 

Conexión básica: obtener el número de serie

Ahora que ya sabemos que podemos acceder a nuestra central, lo que vamos a hacer es realizar una primera conexión, muy sencilla. Le solicitaremos el número de serie…

Si observamos el documento de especificación del protocolo LAN de la z21, vemos que el primer comando que se nos explica, y el mas sencillo, es cómo obtener el número de serie de nuestra central:

El datagrama UDP de conexión con la z21 es de, como máximo, 4 + 4 + 32 bytes, divididos en 3 campos, con representación LittleEndian:

  • DataLen: indica el tamaño completo del datagrama, incluyéndose a si mismo (4 bytes)
  • Header: normalmente indicará el tipo de petición (4 bytes)
  • Data: el dato que enviamos (hasta 32 bytes)

Sin entrar mucho en detalle (a partir de aquí entra muy en juego vuestros conocimientos en redes!), vemos que:

Sentencia de petición: 

  • DataLen: 0x04, 0x00
  • Header: 0x10, 0x00 (identifica la sentencia de request de LAN_GET_SERIAL_NUMBER)
  • Data: –

Sentencia de respuesta:

  • DataLen: 0x08, 0x00
  • Header: 0x10, 0x00 (indica la sentencia de respuesta de LAN_GET_SERIAL_NUMBER)
  • Data: … (dato de la respuesta, en sistema hexadecimal)

Veamos cómo lo conseguimos con Node-RED…

En la primera línea tenemos la petición de ping, que ya conocemos del punto anterior…

En la parte inferior aparecen los nodos de petición UDP y recepción UDP.

¿Qué estamos haciendo aquí? Sencillo: enviamos la petición UDP de LAN_GET_SERIAL_NUMBER, y esperamos a que la z21 nos responda… Ojo, y muy importante!!! La respuesta de la z21 es por multicast y se realiza de forma asíncrona! Esto es muy importante, dado que no responderá a nuestra request de forma directa, sino que puede responder posteriormente, dependiendo de la carga que lleve…

Si desplegamos el flow (lo tenéis mas abajo), veremos que el nodo de ping irá haciendo peticiones cada 30s de forma automática, que podréis comprobar en la ventana de debug. 

Luego, para hacer la petición UDP que hemos preparado, tendremos que pulsar sobre el nodo de acción “timestamp”, que desencadenará la creación del mensaje del datagrama de la petición, en el nodo de función LAN_GET_SERIAL_NUMBER:

Como veis, hemos insertado en el msg.payload el mensaje que debe contener el datagrama UDP de la petición. Éste es: DataLen | Header | Data, siendo Data vacío, según lo que ya hemos visto anteriormente…

Este es el nodo de request UDP que hemos preparado:

en el que hemos configurado la IP de la central (192.168.0.111) y el puerto al que vamos a atacar (por defecto, el 21105, pero también aceptaría el 21106).

Una vez realizada la petición, esperamos la respuesta en los nodos de escucha UDP inferiores (uno para cada puerto):

en el que hemos configurado el listener para mensajes UDP en el puerto 21105 (la respuesta la hemos configurado como un Buffer de entrada, lo que nos ayudará a poder desgranarlo mas tarde).

Y finalmente, el nodo de funcionalidad que realiza el tratamiento del dato una vez nos llama la z21 con su respuesta:

en el que obtenemos el dato (datagrama completo en hex, ojo!) desde msg.payload, y que ya podremos sacar por la consola de debug…

El buffer de 8 bytes es el datagrama de respuesta al completo…

El dato sería de la posición 4 a la 7. Si lo pasamos a numérico, sería nuestro número de serie…

Con esto tenemos listo nuestro primer ejemplo de comunicación entre PC y la z21, con una simple llamada UDP.

A continuación os dejo el código fuente del flow:

[{"id":"7998ab03070b9208","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"8aa9ea3a41b3ebee","type":"ping","z":"7998ab03070b9208","protocol":"IPv4","mode":"timed","name":"z21 ping (30s)","host":"192.168.0.111","timer":"30","inputs":0,"x":130,"y":60,"wires":[["8e2677c47600f2ab"]]},{"id":"218a364c10dc2bd8","type":"debug","z":"7998ab03070b9208","name":"z21 ping result","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":720,"y":60,"wires":[]},{"id":"8e2677c47600f2ab","type":"function","z":"7998ab03070b9208","name":"ping message","func":"msg.payload = 'z21 ping? ' + msg.payload;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":60,"wires":[["218a364c10dc2bd8"]]},{"id":"5f90fe4a8045fa54","type":"inject","z":"7998ab03070b9208","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":120,"wires":[["b4666071cd5b71d5"]]},{"id":"ca03501d5d43a3b7","type":"debug","z":"7998ab03070b9208","name":"UDP incomming messages","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":760,"y":240,"wires":[]},{"id":"595bb2d86b37bfcf","type":"debug","z":"7998ab03070b9208","name":"UDP outgoing message","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":750,"y":180,"wires":[]},{"id":"175f9b18db2d61da","type":"udp in","z":"7998ab03070b9208","name":"","iface":"192.168.0.100:21105","port":"21105","ipv":"udp4","multicast":"false","group":"192.168.0.255:21105","datatype":"buffer","x":120,"y":240,"wires":[["72c41f1e1c094be0"]]},{"id":"c4f987f3cbc8f544","type":"udp out","z":"7998ab03070b9208","name":"LAN_GET_SERIAL_NUMBER req.","addr":"192.168.0.111","iface":"","port":"21105","ipv":"udp4","outport":"21105","base64":true,"multicast":"false","x":780,"y":120,"wires":[]},{"id":"b4666071cd5b71d5","type":"function","z":"7998ab03070b9208","name":"LAN_GET_SERIAL_NUMBER","func":"// LAN_GET_SERIAL_NUMBER\nmsg.payload = [0x04, 0x00, 0x10, 0x00, 0x00];\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":120,"wires":[["c4f987f3cbc8f544","595bb2d86b37bfcf"]]},{"id":"79cfd92b4d39e437","type":"udp in","z":"7998ab03070b9208","name":"","iface":"","port":"21106","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":120,"y":280,"wires":[["c1cb166ac01609d2"]]},{"id":"72c41f1e1c094be0","type":"function","z":"7998ab03070b9208","name":"Read incomming UDP@21105 message","func":"var data = msg.payload;\n\nmsg.payload = {\n    port: 21105,\n    data: msg.payload\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":240,"wires":[["ca03501d5d43a3b7"]]},{"id":"c1cb166ac01609d2","type":"function","z":"7998ab03070b9208","name":"Read incomming UDP@21106 message","func":"msg.payload = {\n    port: 21106,\n    data: msg.payload\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":280,"wires":[["ca03501d5d43a3b7"]]}]

 

Con esto finalizo esta primera toma de contacto con la programación y comunicación con la z21. En esta ocasión he querido presentar algo “rápido” y sencillo, si se conoce Node-RED, claro. En futuras entregas veremos cómo atacar ya directamente la central, interpretar los resultados y mejorar un poco el proceso de intercambio de información.

Espero que haya sido de vuestro agrado y de interés. 

No dudéis en dejar vuestros comentarios para ver qué os ha parecido.

🙂


Volver a Central digital z21 de Roco / Fleischmann

 

 

Share Button

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.