En este hilo vamos a diseñar una conexión TCPIP con un hibrido Voltronic con protocolo P30 como puede ser un MAX, King, PIP5048, etc.
El flujo NODERED resultante nos dara un JSON con toda la parametrizacion standard del hibrido (solo lectura).
Para ello vamos a usar un conversor USRIOT externo con caja de este tipo:
Archivo adjunto 23960
Este modelo concretamente lleva conversion tambien para RS485 (modbus). Ahora creo que hay otro modelo mas actualizado con otro tipo de carcasa pero basicamente son iguales en hardware.
He elegido este modelo porque su alimentacion es entre 5 y 36V por lo que lleva un regulador interno y podremos usar la alimentacion del propio hibrido para ello sin necesitar de un alimentador externo.
Hay otro modelo de USR que es exclusivo para rs232 pero su alimentacion es a 5V y aquí tendremos que usar un alimentador externo o hacer las modificaciones oportunas incorporando algun tipo de 7805 dentro para usar la alimentacion del hibrido si no queremos usar un alimentador externo. Me refiero a este:
Archivo adjunto 23961
La mayoria de Voltronics sacan +12V por su puerto RJ45 aunque los cables que llevan no lo usen excepto algunos modelos. Estos +12V son para alimentar los displays remotos o para otras cosas, en este caso por el consumo que tiene el conversor nos va a venir muy bien para no usar un alimentador externo. Eso si, hay que tomar precauciones y no hacer cortos con estos +12V.
Si lo veis mucho riesgo usad el alimentador externo del conversor.
Lo siguiente que voy a comentar es como he modificado el conversor para recibir los +12V del hibrido. Asi que si no vais a hacer esto podeis saltar directamente este parrafo.
*****************************
Los cables que proporciona Voltronic son:
Archivo adjunto 23962Archivo adjunto 23963
Es decir vamos a tener +12V en la pata 6 del DB9, asi que en el conversor TCP232-410 haremos un puente asi:
Archivo adjunto 23964
De esta forma tendremos alimentado el conversor con el hibrido. Obviamente no deberemos enchufar ningun alimentador externo mientras usemos la alimentacion del hibrido para no romper nada. La pata 6 del DB9 esta libre en el conversor por eso es seguro hacer ese puente.
Y queda asi de bonito:
Archivo adjunto 23967
******************************
Bien, vamos a configurar el conversor USR para que nuestro hibrido tenga un ip local asociada a un puerto serie de comunicaciones.
Nos conectaremos con un navegador a la ip fija que viene por defecto en el conversor entrando con el user y passwd que vendra todo en la pegatina del conversor.
Los parametros que necesariamente tendremos que configurar en el conversor seran la ip local fija asignada, el puerto local de esa ip fija asignada y el modo de trabajo del conversor rs232 que sera en TCP server. El resto de parametros por defecto no son criticos.
Es conveniente que la ip fija asignada localmente este dentro de nuestra subred de trabajo. Yo lo he configurado asi:
Archivo adjunto 23965Archivo adjunto 23966
Con esto tenemos asociada a la ip 192,168,1,4:26 un puerto serie RS232 a 2400,8N1 listo para usarse en nuestro Voltronic.
Para usar este tipo de conexión en nuestro NODERED tendremos que encapsular el flujo TCPIP en una comunicación serie. Para ello usaremos el comando SOCAT que si no lo tenemos en nuestro sistema lo instalaremos con sudo apt-get install socat
Una vez instalado lo invocamos desde consola para que nos cree un encapsulamiento asociado a nuestro conversor de la siguiente forma:
sudo socat PTY,link=/dev/Voltronic,mode=777,echo=0,ignoreeof,b115200,raw TCP:192.168.1.4:26
Asi nos creara un device virtual llamado Voltronic que es el que pondremos en nuestro nodo serial request del flujo.
Esto lo podemos poner como servicio mediante systemctl para que al arrancar nuestra Rpi ya lo tengamos activo. Para ello tendremos que crear el servicio en:
sudo nano /lib/systemd/system/socatVoltronic.service
con el siguiente contenido:
Despues ya lo invocamos con los comandos tipicos del systemctl:Código:[Unit]
Description=Socat Voltronic
[Service]
ExecStart=/usr/bin/socat PTY,link=/dev/Voltronic,mode=777,echo=0,ignoreeof,b115200,raw TCP:192.168.1.4:26
Restart=always
RestartSec=15
[Install]
WantedBy=multi-user.target
sudo systemctl start socatVoltronic
sudo systemctl stop socatVoltronic
Para el arranque automatico sudo systemctl enable socatVoltronic
O para quitarlo del arranque sudo systemctl disable socatVoltronic
Despues ya en nuestro flujo de nodered lo podemos sacar asi:
https://tejota.net/media/k2/images/S...osportcpip.gif
El flujo usado es este:
Código HTML:[ { "id": "b7272dd8.a8c48", "type": "tab", "label": "Voltronic MKS RS232-TCPIP", "disabled": false, "info": "" }, { "id": "7017e122.28a9a", "type": "inject", "z": "b7272dd8.a8c48", "name": "QPIRI Configuracion", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "Configuracion", "payload": "QPIRI", "payloadType": "str", "x": 160, "y": 700, "wires": [ [ "935a89a9.60ff98" ] ] }, { "id": "555726e6.22b9a8", "type": "inject", "z": "b7272dd8.a8c48", "name": "QFLAG Miscelanea", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "Miscelanea", "payload": "QFLAG", "payloadType": "str", "x": 160, "y": 660, "wires": [ [ "935a89a9.60ff98" ] ] }, { "id": "9e49c576.73d638", "type": "inject", "z": "b7272dd8.a8c48", "name": "QBEQI Ecualizacion Bateria", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "Ecualizacion Bateria", "payload": "QBEQI", "payloadType": "str", "x": 190, "y": 740, "wires": [ [ "935a89a9.60ff98" ] ] }, { "id": "c305e810.73d668", "type": "inject", "z": "b7272dd8.a8c48", "name": "QPIWS Informacion Warnings", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "Informacion Warnings", "payload": "QPIWS", "payloadType": "str", "x": 190, "y": 780, "wires": [ [ "935a89a9.60ff98" ] ] }, { "id": "2e92bce8.8eeb64", "type": "inject", "z": "b7272dd8.a8c48", "name": "QPIGS Estado General", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "Estado General", "payload": "QPIGS", "payloadType": "str", "x": 170, "y": 540, "wires": [ [ "935a89a9.60ff98" ] ] }, { "id": "519b6978.c6fb28", "type": "inject", "z": "b7272dd8.a8c48", "name": "QID Numero de Serie", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "Numero de Serie", "payload": "QID", "payloadType": "str", "x": 160, "y": 500, "wires": [ [ "935a89a9.60ff98" ] ] }, { "id": "25aa30b6.220b4", "type": "function", "z": "b7272dd8.a8c48", "name": "CRCTJ", "func": " // Algoritmo para lanzar los comandos hacia Voltronics por puerto serie con CRC propietario\n // Algoritmo realizado por Tejota [email protected]\n var topic = (msg.payload) + (\" \") + (msg.topic); // Topic con el comando string y posible descripcion\n var comandobuffer = Buffer.from(msg.payload); // pasando a buffer el string del comando \n var crc = 0x0000; // inicio del crc\n for (tj = 0; tj < comandobuffer.length; tj++) // scaneo del buffer\n {\n const byte = comandobuffer[tj]; // analizando el byte para aplicarle el crc16xmodem\n tejota = (crc >>> 8) & 0xff;\n tejota ^= byte & 0xff;\n tejota ^= tejota >>> 4;\n crc = (crc << 8) & 0xffff; // Algoritmo\n crc ^= tejota; // crc16 xmodem \n tejota = (tejota << 5) & 0xffff; // sin tabla estatica\n crc ^= tejota;\n tejota = (tejota << 7) & 0xffff;\n crc ^= tejota;\n } // resultante crc numerico \n var crchexastring = crc.toString(16).padStart(4,'0'); // crc numerico a string hexa añadiendo ceros a izquierda si es preciso\n var crchexabuffer = Buffer.from(crchexastring, \"hex\"); // buffer del crchexa\n for (mdk=0; mdk < crchexabuffer.length; mdk++) // scaneo del buffer\n {\n if (crchexabuffer[mdk]==10 || crchexabuffer[mdk]==13 || crchexabuffer[mdk]==40) // Exceptuando estos bytes mdk \n {\n crchexabuffer[mdk]++; // se pone el byte siguiente si es alguno de las excepciones mdk\n }\n } \n const retornodecarro = Buffer.from(\"\\r\");\n var crctotalbuffer = [comandobuffer, crchexabuffer, retornodecarro]; // construyendo el buffer final hacia el hibrido\n msg.payload = Buffer.concat(crctotalbuffer);\n msg.topic = topic;\n return msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 300, "y": 160, "wires": [ [ "b068fb31.21c118" ] ] }, { "id": "fb44831e.f07d", "type": "debug", "z": "b7272dd8.a8c48", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1170, "y": 580, "wires": [] }, { "id": "e0624e7d.38c2e", "type": "inject", "z": "b7272dd8.a8c48", "name": "QVFW Firmware CPU1", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "Version CPU1", "payload": "QVFW", "payloadType": "str", "x": 170, "y": 580, "wires": [ [ "935a89a9.60ff98" ] ] }, { "id": "a742c979.20d098", "type": "inject", "z": "b7272dd8.a8c48", "name": "QVFW2 Firmware CPU2", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "Firmware CPU2", "payload": "QVFW2", "payloadType": "str", "x": 170, "y": 620, "wires": [ [ "935a89a9.60ff98" ] ] }, { "id": "935a89a9.60ff98", "type": "link out", "z": "b7272dd8.a8c48", "name": "ParaCRCTJ", "links": [ "c7ab3199.432e8" ], "x": 430, "y": 660, "wires": [], "l": true }, { "id": "9874d159.40a27", "type": "comment", "z": "b7272dd8.a8c48", "name": "Comandos de monitorizacion", "info": "Comandos de Monitorizacion", "x": 160, "y": 460, "wires": [] }, { "id": "c7ab3199.432e8", "type": "link in", "z": "b7272dd8.a8c48", "name": "ParaCRCTJ", "links": [ "935a89a9.60ff98" ], "x": 130, "y": 160, "wires": [ [ "25aa30b6.220b4" ] ], "l": true }, { "id": "8e74c9a3.c798a8", "type": "link out", "z": "b7272dd8.a8c48", "name": "ParaExtractores", "links": [ "35dd29ca.9c5866" ], "x": 680, "y": 160, "wires": [], "l": true }, { "id": "5f40922d.df5d1c", "type": "switch", "z": "b7272dd8.a8c48", "name": "Repartidor Datos Lecturas", "property": "topic", "propertyType": "msg", "rules": [ { "t": "cont", "v": "QID", "vt": "str" }, { "t": "cont", "v": "QPIGS", "vt": "str" }, { "t": "cont", "v": "CPU1", "vt": "str" }, { "t": "cont", "v": "QVFW2", "vt": "str" }, { "t": "cont", "v": "QFLAG", "vt": "str" }, { "t": "cont", "v": "QPIRI", "vt": "str" }, { "t": "cont", "v": "QBEQI", "vt": "str" }, { "t": "cont", "v": "QPIWS", "vt": "str" }, { "t": "cont", "v": "QMOD", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 9, "x": 390, "y": 360, "wires": [ [ "79430109.77fdc" ], [ "457440bc.4ce9a" ], [ "6ba497b0.ef49b8" ], [ "f2beb2df.dc655" ], [ "5e34b45b.62b02c" ], [ "f6fdf9db.830318" ], [ "f856d2e.2e8473" ], [ "be5098a0.4b0628" ], [ "d3deff20.5ad7b" ] ] }, { "id": "35dd29ca.9c5866", "type": "link in", "z": "b7272dd8.a8c48", "name": "ParaExtractores", "links": [ "8e74c9a3.c798a8" ], "x": 140, "y": 360, "wires": [ [ "5f40922d.df5d1c" ] ], "l": true }, { "id": "4689d658.e22818", "type": "comment", "z": "b7272dd8.a8c48", "name": "Repartiendo por topic", "info": "", "x": 380, "y": 260, "wires": [] }, { "id": "5e34b45b.62b02c", "type": "function", "z": "b7272dd8.a8c48", "name": "QFLAGExtraccion", "func": "var output = msg.payload.substr(1, 11);\nvar E = output.indexOf(\"E\")+1;\nvar D = output.indexOf(\"D\");\nvar enables = output.substr(E, (D-E));\nvar disables = output.substr(D+1);\nswitch (enables.includes(\"a\")){\n case true:\n buzzer = 1;\n break;\n case false: \n buzzer = 0;\n} \nswitch (enables.includes(\"b\")){\n case true:\n bypassoverload = 1;\n break;\n case false:\n bypassoverload = 0;\n break;\n} \nswitch (enables.includes(\"k\")){\n case true:\n guardapantallalcd = 1;\n break;\n case false: \n guardapantallalcd = 0;\n} \nswitch (enables.includes(\"j\")){\n case true:\n powersaving = 1;\n break;\n case false:\n powersaving = 0;\n break;\n} \nswitch (enables.includes(\"u\")){\n case true:\n overloadrestart = 1;\n break;\n case false: \n overloadrestart = 0;\n} \nswitch (enables.includes(\"v\")){\n case true:\n overtemperaturerestart = 1;\n break;\n case false:\n overtemperaturerestart = 0;\n break;\n}\nswitch (enables.includes(\"x\")){\n case true:\n luzlcd = 1;\n break;\n case false:\n luzlcd = 0;\n break;\n} \nswitch (enables.includes(\"y\")){\n case true:\n pitidosifuenteprimariafalla = 1;\n break;\n case false:\n pitidosifuenteprimariafalla = 0;\n break;\n} \nswitch (enables.includes(\"z\")){\n case true:\n grabarerrores = 1;\n break;\n case false:\n grabarerrores = 0;\n break;\n} \nreturn [\n {\n payload: {\n buzzer: buzzer,\n bypassoverload: bypassoverload,\n guardapantallalcd: guardapantallalcd,\n powersaving: powersaving,\n overloadrestart: overloadrestart,\n overtemperaturerestart: overtemperaturerestart,\n luzlcd: luzlcd,\n pitidosifuenteprimariafalla: pitidosifuenteprimariafalla,\n grabarerrores: grabarerrores,\n }\n }\n]\n", "outputs": 1, "noerr": 0, "x": 650, "y": 420, "wires": [ [ "5016d8f3.520b58" ] ] }, { "id": "457440bc.4ce9a", "type": "function", "z": "b7272dd8.a8c48", "name": "QPIGSExtraccion", "func": "var output = msg.payload.split(\" \");\nlet voltajered = parseFloat(output[0].slice(1, 5));\nlet frecuenciared = parseFloat(output[1]);\nlet voltajesalida = parseFloat(output[2]);\nlet frecuenciasalida = parseFloat(output[3]);\nlet potenciaparentesalida = parseInt(output[4]);\nlet potenciaactivasalida = parseInt(output[5]);\nlet porcentajecargasalida = parseInt(output[6]);\nlet voltajebusalta = parseInt(output[7]);\nlet voltajebateria = parseFloat(output[8]);\nlet amperioscargabat = parseInt(output[9]);\nlet capacidadbateria = parseInt(output[10])\nlet temperaturainversor = parseInt(output[11]);\nlet amperiosenplaca = parseInt(output[12]);\nlet voltajeenplaca = parseInt(output[13]);\nlet voltajescc = parseFloat(output[14]);\nlet amperiosdescargabat = parseInt(output[15]);\nlet prioridadSBU = parseInt(output[16].slice(0,1));\nlet estadoconf = parseInt(output[16].slice(1,2));\nlet estadoscc = parseInt(output[16].slice(2,3));\nlet cargasconectadas = parseInt(output[16].slice(3,4));\nlet voltajeconstantemientrascarga = parseInt(output[16].slice(4,5));\nlet estadodecargageneral = parseInt(output[16].slice(5,6));\nlet estadodecargasolar = parseInt(output[16].slice(6,7));\nlet estadodecargared = parseInt(output[16].slice(7,9));\nlet potenciaenplaca = parseInt(output[19]);\nlet estadodelmppt = parseInt(output[20].slice(0,1));\nlet estadodelswitch = parseInt(output[20].slice(1,2));\n/*var numerodeserie = flow.get(numerodeserie);*/\nreturn [\n {\n payload: {\n voltajered: voltajered,\n frecuenciared: frecuenciared,\n voltajesalida: voltajesalida,\n frecuenciasalida: frecuenciasalida,\n potenciaparentesalida: potenciaparentesalida,\n potenciaactivasalida: potenciaactivasalida,\n porcentajecargasalida: porcentajecargasalida,\n voltajebateria: voltajebateria,\n amperiosdescargabat: amperiosdescargabat,\n amperioscargabat: amperioscargabat,\n temperaturainversor: temperaturainversor,\n potenciaenplaca: potenciaenplaca,\n voltajeenplaca: voltajeenplaca,\n estadodelmppt: estadodelmppt,\n cargasconectadas: cargasconectadas,\n voltajebusalta: voltajebusalta,\n capacidadbateria: capacidadbateria,\n amperiosenplaca: amperiosenplaca, \n voltajescc: voltajescc,\n prioridadSBU: prioridadSBU,\n estadoconf: estadoconf,\n estadoscc: estadoscc,\n voltajeconstantemientrascarga: voltajeconstantemientrascarga,\n estadodecargageneral: estadodecargageneral,\n estadodecargasolar: estadodecargasolar,\n estadodecargared: estadodecargared,\n estadodelswitch: estadodelswitch\n } ,\n/* topic: {numerodeserie: numerodeserie}*/\n }\n];", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 650, "y": 300, "wires": [ [ "5016d8f3.520b58" ] ] }, { "id": "f6fdf9db.830318", "type": "function", "z": "b7272dd8.a8c48", "name": "QPIRIExtraccion", "func": "var output = msg.payload.split(\" \");\nlet voltajeredconf = parseFloat((output[0].slice(1, 5)));\nlet amperiosredmaxconf = parseFloat(output[1]);\nlet voltajesalidaconf = parseFloat(output[2]);\nlet frecuenciasalidaconf = parseFloat(output[3]);\nlet amperiossalidaconf = parseFloat(output[4]);\nlet potenciaaparentesalidaconf = parseFloat(output[5]);\nlet potenciaactivasalidaconf = parseFloat(output[6]);\nlet voltajebateriaconf = parseInt(output[7]);\nlet voltajelimitedescargabatconf = parseFloat(output[8]);\nlet voltajelimiterecargabatconf = parseFloat(output[22]);\nlet voltajeminimoparacorteconf = parseFloat(output[9]);\nlet voltajeabsorcionconf = parseFloat(output[10]);\nlet voltajeflotacionconf = parseFloat(output[11]);\nlet tipodebateriaconf = parseInt(output[12]);\nlet amperiosmaxcargadorbatconf = parseInt(output[13]);\nlet amperiosmaxtotalesabatconf = parseInt(output[14]);\nlet rangovoltajedentradaconf = parseInt(output[15]);\nlet prioridadfuentesalidaconf = parseInt(output[16]);\nlet prioridadcargadorbatconf = parseInt(output[17]);\nlet maximonumeroparalelosconf = parseInt(output[18]);\nlet tipodemaquina = parseInt(output[19]);\nlet tipodehibridoconf = parseInt(output[20]);\nlet tipodesalidaparaleloconf = parseInt(output[21]);\nlet potenciasolarparaleloconf = parseInt(output[23]);\nlet potenciasolarbalanceconf = parseInt(output[24]);\nreturn [\n {\n payload: {\n voltajeredconf: voltajeredconf,\n amperiosredmaxconf: amperiosredmaxconf,\n voltajesalidaconf: voltajesalidaconf,\n frecuenciasalidaconf: frecuenciasalidaconf,\n amperiossalidaconf: amperiossalidaconf,\n potenciaaparentesalidaconf: potenciaaparentesalidaconf,\n potenciaactivasalidaconf: potenciaactivasalidaconf,\n voltajebateriaconf: voltajebateriaconf,\n voltajelimiterecargabatconf: voltajelimiterecargabatconf,\n voltajelimitedescargabatconf: voltajelimitedescargabatconf,\n voltajeminimoparacorteconf: voltajeminimoparacorteconf,\n voltajeabsorcionconf: voltajeabsorcionconf,\n voltajeflotacionconf: voltajeflotacionconf,\n tipodebateriaconf: tipodebateriaconf,\n amperiosmaxcargadorbatconf: amperiosmaxcargadorbatconf,\n amperiosmaxtotalesabatconf: amperiosmaxtotalesabatconf,\n rangovoltajedentradaconf: rangovoltajedentradaconf,\n prioridadfuentesalidaconf: prioridadfuentesalidaconf,\n prioridadcargadorbatconf: prioridadcargadorbatconf,\n maximonumeroparalelosconf: maximonumeroparalelosconf,\n tipodemaquina: tipodemaquina,\n tipodehibridoconf: tipodehibridoconf,\n tipodesalidaparaleloconf: tipodesalidaparaleloconf,\n potenciasolarparaleloconf: potenciasolarparaleloconf,\n potenciasolarbalanceconf: potenciasolarbalanceconf\n }\n }\n]", "outputs": 1, "noerr": 0, "x": 640, "y": 460, "wires": [ [ "5016d8f3.520b58" ] ] }, { "id": "6ba497b0.ef49b8", "type": "function", "z": "b7272dd8.a8c48", "name": "QVFW Extraccion U1", "func": "var output = msg.payload;\nlet Firmware = (output.slice(10, 15));\nreturn [\n {\n payload: {\n Firmware: Firmware\n }\n }\n]", "outputs": 1, "noerr": 0, "x": 660, "y": 340, "wires": [ [ "5016d8f3.520b58" ] ] }, { "id": "f2beb2df.dc655", "type": "function", "z": "b7272dd8.a8c48", "name": "QVFW2 Firmware U2", "func": "var output = msg.payload;\nlet Firmware2 = (output.slice(11, 16));\nreturn [\n {\n payload: {\n Firmware2: Firmware2\n }\n }\n]", "outputs": 1, "noerr": 0, "x": 660, "y": 380, "wires": [ [ "5016d8f3.520b58" ] ] }, { "id": "f856d2e.2e8473", "type": "function", "z": "b7272dd8.a8c48", "name": "QBEQI Ecu Extrac", "func": "var output = msg.payload.split(\" \");\nlet activacionecualizacion = parseInt(output[0].slice(1, 2));\nlet tiempoecualizacion = parseInt(output[1]);\nlet diasentreecualizaciones = parseInt(output[2]);\nlet maxamperiosparaecualizar = parseInt(output[3]);\nlet diasquefaltanparaecualizar = parseInt(output[4]);\nlet voltajedeecualizacion = parseFloat(output[5]);\nlet tiempodeabsorcion = parseInt(output[6]);\nlet timeoutecualizacion = parseInt(output[7]);\nreturn [\n {\n payload: {\n activacionecualizacion: activacionecualizacion,\n tiempoecualizacion: tiempoecualizacion,\n diasentreecualizaciones: diasentreecualizaciones,\n maxamperiosparaecualizar: maxamperiosparaecualizar,\n diasquefaltanparaecualizar: diasquefaltanparaecualizar,\n voltajedeecualizacion: voltajedeecualizacion,\n tiempodeabsorcion: tiempodeabsorcion,\n timeoutecualizacion: timeoutecualizacion\n }\n }\n]", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 650, "y": 500, "wires": [ [ "5016d8f3.520b58" ] ] }, { "id": "79430109.77fdc", "type": "function", "z": "b7272dd8.a8c48", "name": "QID Nº Serie Extrac", "func": "var numerodeserie = msg.payload.slice(1, 15);\nflow.set('numerodeserie', numerodeserie);\nreturn [\n {\n payload: {\n numerodeserie: numerodeserie\n }\n }\n];\n// Numero de Serie va a flow o incluso podria ir a global para identificar en paralelos ", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 660, "y": 260, "wires": [ [ "5016d8f3.520b58" ] ] }, { "id": "971745c4.0b0de8", "type": "comment", "z": "b7272dd8.a8c48", "name": "Extractores", "info": "", "x": 670, "y": 220, "wires": [] }, { "id": "be5098a0.4b0628", "type": "function", "z": "b7272dd8.a8c48", "name": "QPIWS Warnings Extrac", "func": "var output = msg.payload;\nlet reservado = parseInt(output.slice(1, 2));\nlet falloinversor = parseInt(output.slice(2, 3));\nlet fallo08voltajebusalto = parseInt(output.slice(3, 4));\nlet fallo52voltajebusbajo = parseInt(output.slice(4, 5));\nlet fallo09softwarebus = parseInt(output.slice(5, 6));\nlet peligronoacinput = parseFloat(output.slice(6, 7));\nlet peligrocortopv = parseInt(output.slice(7, 8));\nlet fallo58voltajeinversorbajo = parseInt(output.slice(8, 9));\nlet fallo06voltajeinversoralto = parseInt(output.slice(9, 10));\nlet peligro02sobretemperatura = parseInt(output.slice(10, 11));\nlet peligro01ventilador = parseInt(output.slice(11, 12));\nlet peligro03altovoltajebateria = parseInt(output.slice(12, 13));\nlet peligro04bajovoltajebateria = parseInt(output.slice(13, 14));\nlet peligro07sobrecargar = parseInt(output.slice(14, 15));\nlet peligrobateriashutdown = parseInt(output.slice(15, 16));\nlet peligro10bateriaderating = parseInt(output.slice(16, 17));\nlet peligroeeprom = parseInt(output.slice(17, 18));\nlet fallo51sobrecorriente = parseInt(output.slice(18, 19));\nlet fallosoftwareinversor = parseInt(output.slice(19, 20));\nlet falloautotest = parseInt(output.slice(20, 21));\nlet fallo55continuaenac = parseInt(output.slice(21, 22));\nlet fallo56bateriaabierta = parseInt(output.slice(22, 23));\nlet fallo57sensorcorriente = parseInt(output.slice(23, 24));\nlet fallocortobateria = parseInt(output.slice(24, 25));\nlet peligrolimitepotencia = parseInt(output.slice(25, 26));\nlet peligro13altovoltajeplaca = parseInt(output.slice(26, 27));\nlet fallompptsobrecarga = parseInt(output.slice(27, 28));\nlet peligro14mpptsobrecarga = parseInt(output.slice(28, 29));\nlet peligro12bateriabajaparamppt = parseInt(output.slice(29, 30));\nreturn [\n {\n payload: {\n falloinversor: falloinversor,\n fallo08voltajebusalto: fallo08voltajebusalto,\n fallo52voltajebusbajo: fallo52voltajebusbajo,\n fallo09softwarebus: fallo09softwarebus,\n peligronoacinput: peligronoacinput,\n peligrocortopv: peligrocortopv,\n fallo06voltajeinversoralto: fallo06voltajeinversoralto,\n peligro02sobretemperatura: peligro02sobretemperatura,\n peligro01ventilador: peligro01ventilador,\n peligro03altovoltajebateria: peligro03altovoltajebateria,\n peligro04bajovoltajebateria: peligro04bajovoltajebateria,\n peligro07sobrecargar: peligro07sobrecargar,\n peligrobateriashutdown: peligrobateriashutdown,\n peligro10bateriaderating: peligro10bateriaderating,\n peligroeeprom: peligroeeprom,\n fallo51sobrecorriente: fallo51sobrecorriente,\n fallosoftwareinversor: fallosoftwareinversor,\n falloautotest: falloautotest,\n fallo55continuaenac: fallo55continuaenac,\n fallo56bateriaabierta: fallo56bateriaabierta,\n fallo57sensorcorriente: fallo57sensorcorriente,\n fallocortobateria: fallocortobateria,\n peligro13altovoltajeplaca: peligro13altovoltajeplaca,\n fallompptsobrecarga: fallompptsobrecarga,\n peligro14mpptsobrecarga: peligro14mpptsobrecarga,\n peligro12bateriabajaparamppt: peligro12bateriabajaparamppt\n }\n }\n]", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 670, "y": 540, "wires": [ [ "5016d8f3.520b58" ] ] }, { "id": "5016d8f3.520b58", "type": "join", "z": "b7272dd8.a8c48", "name": "Juntando Todo 4 s", "mode": "custom", "build": "merged", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": false, "timeout": "4", "count": "", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "", "reduceFixup": "", "x": 910, "y": 380, "wires": [ [ "6d3bf727.d4d4e8" ] ] }, { "id": "59e74f6f.e908c", "type": "link out", "z": "b7272dd8.a8c48", "name": "TodasLecturasHibrido", "links": [ "610e750b.29bacc" ], "x": 1060, "y": 460, "wires": [], "l": true }, { "id": "a77dcf5d.713a8", "type": "comment", "z": "b7272dd8.a8c48", "name": "Creando Objeto con todas las lecturas del Hibrido", "info": "", "x": 1040, "y": 320, "wires": [] }, { "id": "6d3bf727.d4d4e8", "type": "function", "z": "b7272dd8.a8c48", "name": "Id en topic num serie", "func": "var topic = flow.get('numerodeserie');\nmsg.topic = topic;\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 1120, "y": 380, "wires": [ [ "59e74f6f.e908c", "fb44831e.f07d" ] ] }, { "id": "7189e778.2dea78", "type": "inject", "z": "b7272dd8.a8c48", "name": "QMOD Modo de Trabajo", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "Modo de Trabajo", "payload": "QMOD", "payloadType": "str", "x": 170, "y": 820, "wires": [ [ "935a89a9.60ff98" ] ] }, { "id": "1a34c73e.2bbb09", "type": "comment", "z": "b7272dd8.a8c48", "name": "RS232-ETHERNET Conversor (Ver comentario dentro)", "info": "Si no teneis el comando socat instalado. Lo instalais con sudo apt-get install socat .\nPara iniciar un socat de ese puerto automaticamente hay que crear un archivo service en /lib/systemd/system/socatVoltronic.service\ncon el siguiente contenido:\n****************************\n\n[Unit]\nDescription=Socat Voltronic\n\n[Service]\nExecStart=/usr/bin/socat PTY,link=/dev/Voltronic,mode=777,echo=0,ignoreeof,b115200,raw TCP:192.168.1.4:26\nRestart=always\nRestartSec=15\n\n[Install]\nWantedBy=multi-user.target\n\n*******************************\nLa ip y el puerto TCP server sera la del conversor rs232-ethernet. En la linea de ejemplo es ip: 192.168.1.4 y puerto 26. El nombre del dispositivo lo he llamado Voltronic, lo podeis llamar como querais en el parametro link=/dev/loquequerais\n\nDespues en consola sudo systemctl enable socatVoltronic\n\nReiniciar la Raspberry y nos aparecera en los /dev un pts llamado Voltronic. Ese sera el puerto serie asociado al server conversor que configuraremos en nuestro nodo serial request", "x": 380, "y": 80, "wires": [] }, { "id": "d3deff20.5ad7b", "type": "function", "z": "b7272dd8.a8c48", "name": "QMOD Extractor", "func": "var output = msg.payload;\nlet mdts = output.slice(1, 2);\nlet mododetrabajo;\nif (mdts === \"P\") {\n mododetrabajo = 0;\n} else if (mdts === \"S\") {\n mododetrabajo = 1;\n} else if (mdts === \"L\") {\n mododetrabajo = 2;\n} else if (mdts === \"B\") {\n mododetrabajo = 3;\n} else if (mdts === \"F\") {\n mododetrabajo = 4;\n} else if (mdts === \"H\") {\n mododetrabajo = 5;\n} \nreturn [{\n payload: {\n mododetrabajo: mododetrabajo\n }\n }\n ];", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 660, "y": 580, "wires": [ [ "5016d8f3.520b58" ] ] }, { "id": "b068fb31.21c118", "type": "serial request", "z": "b7272dd8.a8c48", "name": "", "serial": "afed2560.a91e08", "x": 480, "y": 160, "wires": [ [ "8e74c9a3.c798a8" ] ] }, { "id": "afed2560.a91e08", "type": "serial-port", "z": "", "serialport": "/dev/Voltronic", "serialbaud": "115200", "databits": "8", "parity": "none", "stopbits": "1", "waitfor": "", "dtr": "none", "rts": "none", "cts": "none", "dsr": "none", "newline": "\\r", "bin": "false", "out": "char", "addchar": "", "responsetimeout": "10000" }]