Test reception of ASTM-1394 messages from serial port

This flow receive messages at the serial port, that use the standard ASTM-1394. It is just a testing tool to validate communication or capture the frames to a file in order to process them later.

It is a proof of concept to demonstrate use of Node-RED in the healthcare industry.

[{"id":"bb14d97d.325b68","type":"tab","label":"Serial ASTM","disabled":false,"info":""},{"id":"36ab0272.30094e","type":"serial in","z":"bb14d97d.325b68","name":"","serial":"8269401d.f3814","x":130,"y":160,"wires":[["c19bf630.72c698"]]},{"id":"80e8be74.e5135","type":"serial out","z":"bb14d97d.325b68","name":"","serial":"8269401d.f3814","x":610,"y":60,"wires":[]},{"id":"596915de.fc7c9c","type":"debug","z":"bb14d97d.325b68","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":400,"wires":[]},{"id":"c19bf630.72c698","type":"function","z":"bb14d97d.325b68","name":"Analize char in","func":"// msg1 is the answer sent to serial port\n// msg2 interprets the received character for the log file\n// msg3 when ready is the complete frame to be analized.\n\nvar frame=global.get('frame')  // Buffer for the current frame\nvar chksum=global.get('chksum');  // Check sum of frame\nvar calchksum=global.get('calchksum'); // Calculate checksum\nvar framechksum = global.get('framechksum'); // We store here the frame chcksum\nvar numchars = context.get('numchars');\nvar cks = context.get('cks');\nvar tracechars = global.get('tracechars');\n\nvar msg1 = {payload: [0]};\nvar msg2 = {payload:\"\"};\nvar msg3 = {payload:\"\"};\n\n\nif (calchksum !== false) {\n    global.set('chksum', chksum + msg.payload[0]);\n    tracechars.push(msg.payload[0]);\n    global.set('tracechars',tracechars);\n    if (global.get('chksum') > 255) {\n        global.set('chksum', global.get('chksum') - 256);\n    }\n} else {\n    if (context.get('finished') === true) {\n        if (numchars <= 2) {\n            framechksum = framechksum + String.fromCharCode(msg.payload[0]);\n            global.set('framechksum',framechksum);\n            numchars++;\n            context.set('numchars',numchars)\n            if (numchars >= 2) {\n                context.set('finished',false);\n            }\n        }\n    }\n    \n}\n\nswitch(msg.payload[0]) {\n    case 2:\n        global.set('chksum',false);         // Check sum of frame\n        global.set('calchksum',1);          // Flag to Calculate checksum\n        global.set('frame', \"\");            // Buffer for the current frame\n        global.set('framechksum',\"\");       // We store here the frame chcksum\n        context.set('numchars',0);          // Number of characters of received frame checksum\n        context.set('finished',false);      // Has finished summing chksum\n        context.set('cks',\"\");              // String version of calculated checksum\n        msg1 = null;\n        msg2.payload = \"<STX>\";\n        msg3 = null;\n        break;\n    case 3:\n        global.set('calchksum',false);\n        context.set('finished',true);\n        msg1 = null;\n        msg2.payload = \"<ETX>\";\n        frame = frame + msg.payload.toString();\n        global.set('frame', frame);\n\n        msg3 = null;\n        break;\n    case 4:\n        msg1.payload = new Buffer([0x04]);\n        msg2.payload = \"<EOT>\";\n        msg3 = null;\n        break;\n    case 5:\n        global.set(\"frame\",\"\");\n        msg1.payload = new Buffer([0x06]);\n        msg2.payload = \"<ENQ>\";\n        msg3 = null;\n        break;\n    case 6:\n        msg1 = null;\n        msg2.payload = \"<ACK>\";\n        msg3 = null;\n        break;\n    case 10:\n        cks = chksum.toString(16).padStart(2, '0').toUpperCase();\n        context.set('cks',cks);\n        if (cks == framechksum) {\n            msg1.payload = new Buffer([0x06]);  // Checksum OK = ACK\n            msg3.payload = frame + \"\\n\";\n        } else {\n            msg1.payload = new Buffer([0x15]);  // Checksum not OK = NAK\n            msg3.payload = null;\n    }\n        msg2.payload = \"<LF>\";\n        break;\n    case 13:\n        msg1 = null;\n        msg2.payload = \"<CR>\";\n        frame = frame + msg.payload.toString();\n        global.set('frame', frame);\n        msg3 = null;\n        break;\n    case 21:\n        msg1 = null;\n        msg2.payload = \"<NAK>\";\n        msg3 = null;\n        break;\n    case 23:\n        msg1 = null;\n        global.set('calchksum',false);\n        context.set('finished',true);\n        msg2.payload = \"<ETB>\";\n        frame = frame + msg.payload.toString();\n        global.set('frame', frame);\n        msg3 = null;\n        break;\n    default:\n        msg1 = null;\n        msg2.payload = msg.payload.toString();\n        frame = frame + msg.payload.toString();\n        global.set('frame', frame);\n        msg3 = null;\n}\nmsg2.topic = \"Rx: \";\nreturn [msg1,msg2,msg3];","outputs":3,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\n\nglobal.set('frame', \"\");            // Buffer for the current frame\nglobal.set('chksum',false);         // Check sum of frame\nglobal.set('calchksum',0);          // Flag to Calculate checksum\nglobal.set('framechksum',\"\");       // We store here the frame chcksum\ncontext.set('numchars',0);          // Number of characters of received frame checksum\ncontext.set('finished',false);      // Has finished summing chksum\ncontext.set('cks',\"\");              // String version of calculated checksum\n// debug arrays\nglobal.set('tracechars',[]);\n","finalize":"","x":360,"y":160,"wires":[["668f6f5d.2b7ce","80e8be74.e5135"],["aa909449.3b1258","69746b1f.3e14e4"],["596915de.fc7c9c"]]},{"id":"95dfb24.554b05","type":"debug","z":"bb14d97d.325b68","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1236,"y":160,"wires":[]},{"id":"668f6f5d.2b7ce","type":"function","z":"bb14d97d.325b68","name":"Analize char out","func":"// msg1 es la respuesta del puerto serial\n// msg1 es la interpretación del character recibido para el log\nvar msg1 = {payload:[0]};\nswitch(msg.payload[0]) {\n    case 0:\n        msg1.payload = \"<NUL>\";\n        break;\n    case 1:\n        msg1.payload = \"<SOH>\";\n        break;\n    case 2:\n        msg1.payload = \"<STX>\";\n        break;\n    case 3:\n        msg1.payload = \"<ETX>\";\n        break;\n    case 4:\n        msg1.payload = \"<EOT>\";\n        break;\n    case 5:\n        msg1.payload = \"<ENQ>\";\n        break;\n    case 6:\n        msg1.payload = \"<ACK>\";\n        break;\n    case 7:\n        msg1.payload = \"<BEL>\";\n        break;\n    case 8:\n        msg1.payload = \"<BS>\";\n        break;\n    case 9:\n        msg1.payload = \"<TAB>\";\n        break;\n    case 10:\n        msg1.payload = \"<LF>\";\n        break;\n    case 13:\n        msg1.payload = \"<CR>\";\n        break;\n    case 21:\n        msg1.payload = \"<NAK>\";\n        break;\n    case 23:\n        msg1.payload = \"<ETB>\";\n        break;\n    default:\n        msg1.payload = msg.payload.toString();\n}\nmsg1.topic = 'Tx: ';\nreturn msg1;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":620,"y":120,"wires":[["aa909449.3b1258","69746b1f.3e14e4"]]},{"id":"ef197f01.a89f9","type":"flogger","z":"bb14d97d.325b68","name":"serialtst.log","logfile":"serialtst.log","inputchoice":"fullmsg","inputobject":"payload","inputobjectType":"msg","inputmoustache":"Recieved payload {{payload}} and topic {{topic}}","loglevel":"INFO","logconfig":"8c711f6a.8cc4","sendpane":false,"x":1056,"y":160,"wires":[["95dfb24.554b05"]]},{"id":"c2554a97.c3e728","type":"file","z":"bb14d97d.325b68","name":"","filename":"/tmp/tramas.txt","appendNewline":false,"createDir":false,"overwriteFile":"false","encoding":"none","x":1260,"y":220,"wires":[[]]},{"id":"4cb748c4.aa2038","type":"inject","z":"bb14d97d.325b68","name":"Capture frames to a file","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"control","payload":"toggle","payloadType":"str","x":640,"y":240,"wires":[["aa909449.3b1258"]]},{"id":"aa909449.3b1258","type":"gate","z":"bb14d97d.325b68","name":"","controlTopic":"control","defaultState":"closed","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":850,"y":220,"wires":[["e05a99c.b468968"]]},{"id":"69746b1f.3e14e4","type":"function","z":"bb14d97d.325b68","name":"","func":"var trama=context.get('trama') || \"\";\nvar tmp=\"\";\ntmp = trama.concat(msg.payload);\ncontext.set('trama',tmp);  \nif (msg.payload.includes(\"<LF>\") || msg.payload.includes(\"<ACK>\") || msg.payload.includes(\"<NAK>\") || msg.payload.includes(\"<ENQ>\") || msg.payload.includes(\"<EOT>\") ) {\n    msg.payload = msg.topic.concat(tmp);\n    context.set(\"trama\",\"\");  \n    return msg;    \n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":880,"y":160,"wires":[["ef197f01.a89f9"]]},{"id":"e05a99c.b468968","type":"function","z":"bb14d97d.325b68","name":"","func":"if (msg.payload.includes(\"<LF>\") || msg.payload.includes(\"<ACK>\") || msg.payload.includes(\"<NAK>\") || msg.payload.includes(\"<ENQ>\") || msg.payload.includes(\"<EOT>\") ) {\n    msg.payload = msg.payload.concat(\"\\n\");\n}\nreturn msg; ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1060,"y":220,"wires":[["c2554a97.c3e728"]]},{"id":"8269401d.f3814","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","waitfor":"","newline":"1","bin":"bin","out":"count","addchar":"","responsetimeout":"10000"},{"id":"8c711f6a.8cc4","type":"config-log","z":"","logname":"logserial","logdir":"/var/log","stamp":"local","logstyle":"plain","logrotate":false,"logcompress":false,"logrotatecount":"5","logsize":"1000","logtopic":false,"logsource":true}]

Flow Info

Created 5 years, 3 months ago
Rating:

Owner

Actions

Rate:

Node Types

Core
  • debug (x2)
  • file (x1)
  • function (x4)
  • inject (x1)
Other
  • config-log (x1)
  • flogger (x1)
  • gate (x1)
  • serial in (x1)
  • serial out (x1)
  • serial-port (x1)
  • tab (x1)

Tags

  • ASTM
  • 1394
  • 1381
  • Clinical
  • laboratory
  • equipment
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option