Rainforest Eagle Power Monitor, upgraded
This is an update to Mike Thompson, (GitHub: mike-linus) Flow for the Eagle Rainforest power monitor.
Updated by Tom Lafleur 14-OCT-2019:
The units go off-line, sometimes they recover on their own, other times one must reboot the device. It appears that the devices may have a memory leak in there code that causes this problem.
Rainforest support is very much lacking as can be seen by the large number of comments on-line and on the Amazon website for the device. Email's to them concerning this issue, go back a number of years.
This modified flow attempts to fix this by rebooting the device at a periodic rate to clear any internal issues with the device...
Data is formatted for MQTT output, but one can send the data to any function for processing or output.
As set, this flow make an XML request for data to the device every minute, and a cloud request every 10 minutes as backup. It sends an XML reboot command to the device every hour.
Author: Mike Thompson, GitHub: mike-linus Date: 24/2/2016
These examples show how to extract data and control the Rainforest Eagle using the recommended HTTP Rest API both locally and via the Internet Gateway.
For those of you trying to get the most out of the Rainforest Eagle, these example Node-Red flows should get you going. Having the flows in Node-Red opens up a huge range of automation possibilities. Enjoy :)
To use the flows:
- Modify the 'Format Request' function nodes to your specific credentials. For local requests, you need to add your own MAC address. For the Relay Gateway, the message headers need to be altered to your Gateway account.
- For all flows except the Gateway flow, modify the 'http request' nodes, tick 'use basic authentication?', add your 'Cloud ID' as the username, your 'Installation Code' as the password and your Eagle's IP address.
- For the Gateway flow, basic authentication is not used as the credentials are passed in the message header.
- To automate the flows, simply modify the 'inject node' to repeat at the required interval.
- To publish the data on a MQTT topic, just replace the debug node with an MQTT node.
Creating your own commands simply requires creating the appropriate command string in the 'Format request' node. Refer to the Eagle Rest API documentation for more information.
[{"id":"c0b1638f.685588","type":"tab","label":"Rainforest-Export","disabled":true,"info":""},{"id":"dbe297df.5c6ef","type":"http request","z":"c0b1638f.685588","name":"","method":"POST","ret":"txt","url":"https://rainforestcloud.com:9445/cgi-bin/post_manager","x":690,"y":340,"wires":[["c48c45be.86c748"]]},{"id":"4f419936.7fd14","type":"function","z":"c0b1638f.685588","name":"Format request","func":"//Create Eagle command XML fragment\nvar command = \"<Command>\\n\";\ncommand += \" <Name>get_instantaneous_demand</Name>\\n\";\ncommand += \"</Command>\\n\";\n\n//Modify header to include Gateway authentication\nmsg.headers = {\n \"Cloud-ID\" : \"000123\",\n \"User\" : \"MyEmail\",\n \"Password\" : \"MyPass\"\n };\n \nmsg.payload = command;\n\nreturn msg;","outputs":1,"noerr":0,"x":520,"y":340,"wires":[["dbe297df.5c6ef"]]},{"id":"6501fbbe.3208a4","type":"xml","z":"c0b1638f.685588","name":"","attr":"","chr":"","x":510,"y":440,"wires":[["25685d5e.f8ac22"]]},{"id":"30da6719.5897d8","type":"inject","z":"c0b1638f.685588","name":"Rainforest Relay Gateway request","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":220,"y":340,"wires":[["4f419936.7fd14"]]},{"id":"ae419847.e81d08","type":"inject","z":"c0b1638f.685588","name":"Get Schedule","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":150,"y":560,"wires":[["ea14d921.711838"]]},{"id":"ea14d921.711838","type":"function","z":"c0b1638f.685588","name":"Format request","func":"//Create Eagle command XML fragment\nvar command = \"<Command>\\n\";\ncommand += \" <Name>get_schedule</Name>\\n\";\ncommand += \" <MacId>0xd8d5b90000001234</MacId>\\n\";\ncommand += \" <Event>demand</Event>\\n\";\ncommand += \"</Command>\\n\";\n\nmsg.payload = command;\n\nreturn msg;","outputs":1,"noerr":0,"x":320,"y":560,"wires":[["dcc05917.78bfd8"]]},{"id":"dcc05917.78bfd8","type":"http request","z":"c0b1638f.685588","name":"","method":"POST","ret":"txt","url":"http://192.94.167.185/cgi-bin/post_manager","tls":"","x":510,"y":560,"wires":[["b926b03d.14de8"]]},{"id":"84c863d2.080b6","type":"debug","z":"c0b1638f.685588","name":"","active":false,"console":"false","complete":"false","x":1050,"y":560,"wires":[]},{"id":"25685d5e.f8ac22","type":"function","z":"c0b1638f.685588","name":"Calculate Demand Value","func":"\n// Ignore bad data...\nif (!msg.payload.InstantaneousDemand) \n {return;}\n\n// Parse response from Rainforest device.\nstrDemand=msg.payload.InstantaneousDemand.Demand[0];\n\n// This trick, using Bitwise-NOT (~), forces Int to 32 bit,\n// 2nd one re-instate the correct value. This allow us to \n// correctly parse 2's complement numbers. System's with\n// Solar will return a negative demand.\nintDemand = ~~parseInt(strDemand);\n\nstrMultiplier=msg.payload.InstantaneousDemand.Multiplier[0];\nintMultiplier=parseInt(strMultiplier);\n\nstrDivisor=msg.payload.InstantaneousDemand.Divisor[0];\nintDivisor=parseInt(strDivisor);\n\nif (intDemand>2147483647) {\n intDemand = 0;\n}\n\nif (intMultiplier===0) {\n intMultiplier = 1;\n} \n\nif (intDivisor===0) {\n intDivisor = 1;\n}\n\nmsg.payload = (intDemand * intMultiplier) / intDivisor;\n\nreturn [msg];\n","outputs":1,"noerr":0,"x":710,"y":440,"wires":[["79b0cc53.065124","23438150.4dce8e"]]},{"id":"79b0cc53.065124","type":"debug","z":"c0b1638f.685588","name":"","active":false,"tosidebar":true,"console":false,"complete":"false","x":1050,"y":440,"wires":[]},{"id":"c48c45be.86c748","type":"function","z":"c0b1638f.685588","name":"Ignore bad data","func":"//ignore bad data\nif (!msg.payload || msg.payload === null || msg.payload === '') \n{\n return;\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":900,"y":340,"wires":[["6501fbbe.3208a4"]]},{"id":"b926b03d.14de8","type":"xml","z":"c0b1638f.685588","name":"","attr":"","chr":"","x":650,"y":560,"wires":[["d517d071.0b1ba8"]]},{"id":"d517d071.0b1ba8","type":"function","z":"c0b1638f.685588","name":"Extract Value","func":"msg.payload = \"Demand Polling set for: \" + msg.payload.ScheduleList.ScheduleInfo[0].Frequency[0] + \" secs\"\nreturn msg;","outputs":1,"noerr":0,"x":810,"y":560,"wires":[["84c863d2.080b6"]]},{"id":"779b5359.ea3b74","type":"comment","z":"c0b1638f.685588","name":"Read Me: Notes (please retain these notes if distributing the flows)","info":"Updated by Tom Lafleur 14-OCT-2019:\n\nRainforest support is very much lacking as can be seen by \nthe large number of comments on-line and on the Amazon website. \nEmail's to them concerning this issue, go back a number of years. \nThe units go off-line, sometimes they recover on their own, other times \none must reboot the device. It appears that the devices may have\na memory leak in there code that causes this problem. This modified flow\nattempts to fix this by rebooting the device at a periodic rate to clear\nany internal issues with the device.. \n\nAuthor: Mike Thompson, GitHub: mike-linus\nDate: 24/2/2016\n\nThese examples show how to extract data and control the Rainforest Eagle using the recommended HTTP Rest API both locally and via the Internet Gateway.\n\nFor those of you trying to get the most out of the Rainforest Eagle, these example Node-Red flows should get you going. Having the flows in Node-Red opens up a huge range of automation possibilities. Enjoy :)\n\nTo use the flows:\n1. Modify the 'Format Request' function nodes to your specific credentials. For local requests, you need to add your own MAC address. For the Relay Gateway, the message headers need to be altered to your Gateway account.\n2. For all flows except the Gateway flow, modify the 'http request' nodes, tick 'use basic authentication?', add your 'Cloud ID' as the username, your 'Installation Code' as the password and your Eagle's IP address.\n3. For the Gateway flow, basic authentication is not used as the credentials are passed in the message header.\n4. To automate the flows, simply modify the 'inject node' to repeat at the required interval.\n5. To publish the data on a MQTT topic, just replace the debug node with an MQTT node.\n\nCreating your own commands simply requires creating the appropriate command string in the 'Format request' node. Refer to the Eagle Rest API documentation for more information.","x":300,"y":100,"wires":[]},{"id":"16fc7837.84b438","type":"comment","z":"c0b1638f.685588","name":"Main House","info":"","x":130,"y":180,"wires":[]},{"id":"23438150.4dce8e","type":"function","z":"c0b1638f.685588","name":"Rainforest Formating to MQTT","func":"// This will decode and build a MQTT message\n// with Rainforest data\n\n \nvar tmp_msg = {payload: msg.payload, topic: (\"RSF/Power/Main/\")};\nnode.send(tmp_msg);\n","outputs":1,"noerr":0,"x":730,"y":500,"wires":[["2a033641.d0cdea","265110f0.3ca23"]],"outputLabels":["Master Bedroom"]},{"id":"f4614ab1.da07f8","type":"debug","z":"c0b1638f.685588","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":890,"y":220,"wires":[]},{"id":"2a033641.d0cdea","type":"debug","z":"c0b1638f.685588","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1050,"y":500,"wires":[]},{"id":"265110f0.3ca23","type":"mqtt out","z":"c0b1638f.685588","name":"To iot.winlink.org","topic":"","qos":"","retain":"","broker":"210c6fac.d2d328","x":1350,"y":380,"wires":[]},{"id":"276fe591.589ef2","type":"inject","z":"c0b1638f.685588","name":"Rainforest request 30-Sec","topic":"","payload":"","payloadType":"str","repeat":"30","crontab":"","once":true,"onceDelay":"","x":200,"y":280,"wires":[["cd0a6a19.430f28"]]},{"id":"bd4eb15f.bcd528","type":"inject","z":"c0b1638f.685588","name":"Local Eagle request","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":170,"y":220,"wires":[["cd0a6a19.430f28"]]},{"id":"183ab91a.8aab87","type":"http request","z":"c0b1638f.685588","name":"","method":"POST","ret":"txt","url":"http://192.94.167.185/cgi-bin/post_manager","tls":"","x":690,"y":220,"wires":[["c48c45be.86c748","f4614ab1.da07f8"]]},{"id":"cd0a6a19.430f28","type":"function","z":"c0b1638f.685588","name":"Format request","func":"//Create Eagle command XML fragment\nvar command = \"<Command>\\n\";\n command += \" <Name>get_instantaneous_demand</Name>\\n\";\n command += \" <MacId>0xd8d5b90000001234</MacId>\\n\";\n command += \"</Command>\\n\";\n\nmsg.payload = command;\n\nreturn msg;","outputs":1,"noerr":0,"x":520,"y":220,"wires":[["183ab91a.8aab87"]]},{"id":"fed9f233.508a28","type":"inject","z":"c0b1638f.685588","name":"Rainforest request via Gateway 10-Min","topic":"","payload":"","payloadType":"str","repeat":"600","crontab":"","once":true,"onceDelay":".25","x":240,"y":400,"wires":[["4f419936.7fd14"]]},{"id":"b94b1403.436038","type":"inject","z":"c0b1638f.685588","name":"Reboot Eagle","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":150,"y":620,"wires":[["4f15a074.c8b54"]]},{"id":"4f15a074.c8b54","type":"function","z":"c0b1638f.685588","name":"Format request","func":"//Create Eagle command XML fragment\nvar command = \"<Command>\\n\";\ncommand += \" <Name>reboot</Name>\\n\";\ncommand += \" <MacId>0xd8d5b90000001234</MacId>\\n\";\ncommand += \" <Target>Eagle</Target>\\n\";\ncommand += \"</Command>\\n\";\n\nmsg.payload = command;\n\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":620,"wires":[["956d9a29.21607"]]},{"id":"956d9a29.21607","type":"http request","z":"c0b1638f.685588","name":"","method":"POST","ret":"txt","url":"http://192.94.167.185/cgi-bin/post_manager","tls":"","x":530,"y":620,"wires":[["5f250b1b.b8cad4"]]},{"id":"5f250b1b.b8cad4","type":"debug","z":"c0b1638f.685588","name":"","active":false,"console":"false","complete":"false","x":730,"y":620,"wires":[]},{"id":"b3117645.d04988","type":"function","z":"c0b1638f.685588","name":"Format request","func":"//Create Eagle command XML fragment\nvar command = \"<Command>\\n\";\ncommand += \" <Name>set_schedule</Name>\\n\";\ncommand += \" <MacId>0xd8d5b90000001234</MacId>\\n\";\ncommand += \" <Event>demand</Event>\\n\";\ncommand += \" <Frequency>5</Frequency>\\n\";\ncommand += \" <Enabled>Y</Enabled>\\n\";\ncommand += \"</Command>\\n\";\n\nmsg.payload = command;\n\nreturn msg;","outputs":1,"noerr":0,"x":520,"y":740,"wires":[["4cf0dfbf.22b8f"]]},{"id":"df17a44b.3fa0e8","type":"inject","z":"c0b1638f.685588","name":"Set Demand Poll Schedule to 5 seconds","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":240,"y":740,"wires":[["b3117645.d04988"]]},{"id":"4cf0dfbf.22b8f","type":"http request","z":"c0b1638f.685588","name":"","method":"POST","ret":"txt","url":"http://192.94.167.185/cgi-bin/post_manager","tls":"","x":710,"y":740,"wires":[["d234b42b.b73bb8"]]},{"id":"d234b42b.b73bb8","type":"debug","z":"c0b1638f.685588","name":"","active":true,"console":"false","complete":"false","x":890,"y":740,"wires":[]},{"id":"7aa3f222.a470dc","type":"inject","z":"c0b1638f.685588","name":"Force Reset","topic":"","payload":"","payloadType":"str","repeat":"3600","crontab":"","once":true,"onceDelay":".25","x":150,"y":680,"wires":[["4f15a074.c8b54"]]},{"id":"af7f79c8.5b4f78","type":"comment","z":"c0b1638f.685588","name":"Pleasde read notes below...","info":"","x":180,"y":60,"wires":[]},{"id":"210c6fac.d2d328","type":"mqtt-broker","z":"","name":"IOT","broker":"iot.my.org","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]