CM160 OWL energy monitor - direct from 'serial' USB port

This flow queries the OWL energy monitor (mine is on COM8 on windows using the OWL USB drivers), and generates both a real-time gauge and a graph of data since the flow started.

It uses dashboard for display.

Credit to cm160server.py and other sources for data interpretation.

This is a work in progress, but hopefully will be of use to someone.

At first start, or start after a timeout, the OWL device will send a LOT of stored data. This will take a minute or two, and shows int he counts stats in the GUI. Only when this is over will the gauge fire up.

Usage (windows): Install the standard OWL software, but make sure the software is not running; we only need the usb drivers. Make sure you have node-red-dashboard (not the older contrib-ui). Import the blow into your flow. Set the comport number in the flow correctly for your OWL device; make sure it takes the 250000 baud rate. See the ui at /ui

I assume this would work in linux; although there seem to be questions about selecting a baud rate of 250000 in std linux usb serial drivers. Reading tells me there may be modified drivers for the USB.

[{"id":"efa334e1.867128","type":"ui_gauge","z":"82482361.bfd2","name":"","group":"afbdecec.9f6f7","order":2,"width":0,"height":0,"gtype":"gage","title":"KW","label":"KW","format":"{{value | number:3}}kw","min":0,"max":10,"colors":["#00b500","#e6e600","#ca3838"],"x":490,"y":40,"wires":[]},{"id":"19c1f50c.3f12db","type":"change","z":"82482361.bfd2","name":"kw->payload","rules":[{"t":"set","p":"payload","pt":"msg","to":"kw","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":80,"wires":[["efa334e1.867128","7bee852b.2c000c","86a016c2.83eca8"]]},{"id":"86a016c2.83eca8","type":"ui_chart","z":"82482361.bfd2","name":"","group":"afbdecec.9f6f7","order":3,"width":0,"height":0,"label":"kw past","chartType":"line","legend":"false","xformat":"%H:%M:%S","interpolate":"linear","nodata":"","ymin":"0","ymax":"10","removeOlder":"24","removeOlderUnit":"3600","x":490,"y":100,"wires":[[],[]]},{"id":"7bee852b.2c000c","type":"ui_text","z":"82482361.bfd2","group":"afbdecec.9f6f7","order":1,"width":0,"height":0,"name":"","label":"Last Time","format":"{{msg.orgtimestamp}}","layout":"row-spread","x":500,"y":160,"wires":[]},{"id":"ef4f277c.040e78","type":"switch","z":"82482361.bfd2","name":"sort realtime","property":"realtime","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","outputs":2,"x":430,"y":280,"wires":[["e23ce094.1525f","19c1f50c.3f12db","6d44d745.76b1b8"],["509cc014.b260b","e1ebdf42.3a0d7"]]},{"id":"863c91a0.9df97","type":"function","z":"82482361.bfd2","name":"breakout msg","func":"msg.year    = 2000 + msg.payload[1];\nmsg.month   = msg.payload[2] & 0xf;\nmsg.day     = msg.payload[3];\nmsg.hour    = msg.payload[4];\nmsg.minute  = msg.payload[5];\nmsg.cost    = msg.payload[6] + (msg.payload[7] << 8);\nmsg.cost    = msg.cost/100;\nmsg.amps    = (msg.payload[8] + (msg.payload[9] << 8))  *0.07;\nmsg.kw      = (msg.amps * 230 ) / 1000;\n\nmsg.orgtimestamp = new Date(msg.year, msg.month, msg.day, msg.hour, msg.minute, 0, 0);\n\nif (msg.type == 'stored'){\n    var lastrealtime = flow.get('lastrealtime');\n    if (lastrealtime){\n        if (lastrealtime.orgtimestamp <= msg.orgtimestamp){\n            msg.realtime = true;\n            var counts = flow.get('count') || {};\n            counts.converted = (counts.converted | 0) + 1;\n            flow.set('count', counts);\n            console.log('Converted (last reatime:' + lastrealtime.orgtimestamp + \" this \" + msg.orgtimestamp + \")\");\n        } else {\n            var counts = flow.get('count') || {};\n            counts.converted = (counts.converted | 0) + 0;\n            flow.set('count', counts);\n            console.log('Not Converted (last reatime:' + lastrealtime.orgtimestamp + \" this \" + msg.orgtimestamp + \")\");\n        }\n    }\n} else {\n    flow.set('lastrealtime', msg);\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":410,"y":380,"wires":[["ef4f277c.040e78"]]},{"id":"e23ce094.1525f","type":"debug","z":"82482361.bfd2","name":"realtime","active":false,"console":"false","complete":"true","x":730,"y":260,"wires":[]},{"id":"509cc014.b260b","type":"debug","z":"82482361.bfd2","name":"stored","active":false,"console":"false","complete":"true","x":720,"y":320,"wires":[]},{"id":"ab591890.268968","type":"function","z":"82482361.bfd2","name":"split on msg type","func":"a = new Uint8Array(msg.payload);\nif (a[0] == 0x51){\n    msg.realtime = true;\n    msg.type = 'change';\n    return[msg, null, null, null];\n}\nif (a[0] == 0x59){\n    msg.realtime = false;\n    msg.type = 'stored';\n    return[null, msg, null, null];\n}\nif (a[0] == 0xA9)\n    return[null, null, msg, null];\n\nmsg.here = true;\nreturn[null, null, null, msg];","outputs":"4","noerr":0,"x":160,"y":420,"wires":[["863c91a0.9df97"],["863c91a0.9df97"],["2369d4bd.ffaa1c"],["3b5e24ed.73e25c"]]},{"id":"6cf75224.8afa2c","type":"serial in","z":"82482361.bfd2","name":"","serial":"c6f4a4ce.53e7b8","x":80,"y":280,"wires":[["ab591890.268968"]]},{"id":"2369d4bd.ffaa1c","type":"function","z":"82482361.bfd2","name":"split type A9","func":"a = new Uint8Array(msg.payload);\nif (a[4] == 0x57){\n    msg.type = 'W';\n    return[msg, null, null];\n}\nif (a[4] == 0x43){\n    \n    msg.type = 'C';\n\n    return[null, msg, null];\n}\n\nmsg.type = a[4];\nreturn[null, null, msg];\n","outputs":"3","noerr":0,"x":400,"y":440,"wires":[["bbafcabc.6fe268","b4f7837f.e579d"],["fc9838ed.fe2c88","fed2d84d.316e18"],["c30848e.74faab8"]]},{"id":"3b5e24ed.73e25c","type":"debug","z":"82482361.bfd2","name":"","active":false,"console":"false","complete":"false","x":250,"y":600,"wires":[]},{"id":"bbafcabc.6fe268","type":"function","z":"82482361.bfd2","name":"Send A5","func":"msg.payload = Buffer([0xa5]);\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":400,"wires":[["1ba04015.e4c91"]]},{"id":"fc9838ed.fe2c88","type":"function","z":"82482361.bfd2","name":"Send 5A","func":"msg.payload = Buffer([0x5a]);\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":480,"wires":[["1ba04015.e4c91"]]},{"id":"c30848e.74faab8","type":"debug","z":"82482361.bfd2","name":"","active":false,"console":"false","complete":"false","x":520,"y":600,"wires":[]},{"id":"1ba04015.e4c91","type":"change","z":"82482361.bfd2","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":420,"wires":[["e3124e24.19b09","ecb6783e.7b9868"]]},{"id":"e3124e24.19b09","type":"serial out","z":"82482361.bfd2","name":"","serial":"c6f4a4ce.53e7b8","x":880,"y":540,"wires":[]},{"id":"ecb6783e.7b9868","type":"debug","z":"82482361.bfd2","name":"Output messages","active":false,"console":"false","complete":"true","x":840,"y":600,"wires":[]},{"id":"6d44d745.76b1b8","type":"function","z":"82482361.bfd2","name":"count realtime","func":"count = flow.get('count') || {};\ncount.realtime = (count.realtime || 0) + 1;\nflow.set('count', count);\nmsg.payload = count;\nreturn msg;","outputs":1,"noerr":0,"x":720,"y":60,"wires":[["f7b6d4c7.e0b158"]]},{"id":"e1ebdf42.3a0d7","type":"function","z":"82482361.bfd2","name":"count stored","func":"count = flow.get('count') || {};\ncount.stored = (count.stored || 0) + 1;\nflow.set('count', count);\nmsg.payload = count;\nreturn msg;","outputs":1,"noerr":0,"x":710,"y":100,"wires":[["f7b6d4c7.e0b158"]]},{"id":"b4f7837f.e579d","type":"function","z":"82482361.bfd2","name":"count IDENT","func":"count = flow.get('count') || {};\ncount.ident = (count.ident || 0) + 1;\nflow.set('count', count);\nmsg.payload = count;\nreturn msg;","outputs":1,"noerr":0,"x":710,"y":140,"wires":[["381848d3.aa8548","f7b6d4c7.e0b158"]]},{"id":"fed2d84d.316e18","type":"function","z":"82482361.bfd2","name":"count WAIT","func":"count = flow.get('count') || {};\ncount.wait = (count.wait || 0) + 1;\nflow.set('count', count);\nmsg.payload = count;\nreturn msg;","outputs":1,"noerr":0,"x":710,"y":180,"wires":[["f7b6d4c7.e0b158"]]},{"id":"f7b6d4c7.e0b158","type":"ui_template","z":"82482361.bfd2","group":"41f1c9f5.cc8fb8","name":"Counts","order":2,"width":0,"height":0,"format":"<div>\n    <p>Ident: {{msg.payload.ident || 'unknown'}}</p>\n    <p>Wait: {{msg.payload.wait || ''}}</p>\n    <p>Realtime: {{msg.payload.realtime || ''}}</p>\n    <p>Stored: {{msg.payload.stored || ''}}</p>\n    <p>Converted: {{msg.payload.converted || ''}}</p>\n</div>","storeOutMessages":true,"fwdInMessages":true,"x":1000,"y":100,"wires":[["381848d3.aa8548"]]},{"id":"381848d3.aa8548","type":"debug","z":"82482361.bfd2","name":"","active":false,"console":"false","complete":"payload","x":1050,"y":240,"wires":[]},{"id":"27008198.26d69e","type":"ui_button","z":"82482361.bfd2","name":"","group":"41f1c9f5.cc8fb8","order":1,"width":0,"height":0,"label":"Reset","color":"","icon":"","payload":"","payloadType":"str","topic":"Reset","x":100,"y":140,"wires":[["c9d1f0a0.4068d"]]},{"id":"c9d1f0a0.4068d","type":"function","z":"82482361.bfd2","name":"Reset","func":"var count = {};\nflow.set('count', count);\nmsg.payload = count;\nreturn msg;","outputs":1,"noerr":0,"x":120,"y":200,"wires":[["f7b6d4c7.e0b158"]]},{"id":"afbdecec.9f6f7","type":"ui_group","z":"","name":"kw","tab":"59ab55d3.a9255c","disp":true,"width":"6"},{"id":"c6f4a4ce.53e7b8","type":"serial-port","z":"","serialport":"com8","serialbaud":"250000","databits":"8","parity":"none","stopbits":"1","newline":"11","bin":"bin","out":"count","addchar":false},{"id":"41f1c9f5.cc8fb8","type":"ui_group","z":"","name":"graph","tab":"59ab55d3.a9255c","disp":true,"width":"8"},{"id":"59ab55d3.a9255c","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}]
btsimonh

Flow Info

created 9 months ago

Node Types

Core
  • change (x2)
  • debug (x6)
  • function (x10)
  • serial in (x1)
  • serial out (x1)
  • serial-port (x1)
  • switch (x1)
Other
  • ui_button (x1)
  • ui_chart (x1)
  • ui_gauge (x1)
  • ui_group (x2)
  • ui_tab (x1)
  • ui_template (x1)
  • ui_text (x1)

Tags

  • owl
  • cm160
  • energy
  • serial
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option