Okay, here’s the basic recipe to get the Eagle to send to openHAB via nodejs. First, this is the uploader manual from Rainforest.
These are the settings I used in the Rainforest uploader page after logging in (the custom uploader). You will need to match the IP address to wherever you run the nodejs server and match the port in the nodejs code (set to 8079 in my code below).
Here is my nodejs code. I do not have much experience with this coding and I’m sure it can be improved, but it works for me. You can see that it collects the current power and energy reading from the meter and sends it to the openHAB Items InstantaneousDemand and CurrentSummationDelivered (this is the terminology Rainforest uses, but you can certainly change to Power and Energy or anything else you like). The Eagle can send other information but none of it was useful for me. In some areas you can get price information which might be interesting to track if it changes. I can help with that.
I went to this site to get nodejs: https://nodejs.org/en/ I found this for Synology https://www.synology.com/en-us/dsm/packages/Node_js I’ve never used Synology so I can’t say much about it.
const express = require('express')
const http = require('http')
const app = express()
const bodyParser = require('body-parser')
// Eagle sends out data quite often. This limits the rate of packets going to openHAB. Note
// that it could be more sophisticated and do averaging or other processing, but this is just
// dropping packets.
//
// 5 min * 60 seconds * 1000ms = 300000
const InstaneousDemandTimeLimit = 300000;
// 15 min * 60 seconds * 1000ms = 1800000
const SummationTimeLimit = 1800000;
//
var LastInstantaneousDemandTimestamp = 0;
var LastSummationTimestamp = 0;
// Tell express to use the body-parser middleware and to not parse extended bodies
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json()); // for parsing application/json
// the content-length header and the path header (to define the openHAB Item) are generated
// on the fly in the post request handling
var options = {
// set the openHAB IP/hostname and port here
host: '192.168.1.216',
port: 8080,
method: 'PUT',
headers: {
'Content-Type': 'text/plain',
'Accept': 'application/json'
}
};
// this one handles the Eagle 200 packets
app.post('/eagle200', (req, res) => {
if (req.body.body[0].dataType == 'InstantaneousDemand') {
if (parseInt(req.body.body[0].timestamp) > (LastInstantaneousDemandTimestamp + InstaneousDemandTimeLimit)) {
LastInstantaneousDemandTimestamp = parseInt(req.body.body[0].timestamp);
console.log('PUT Instantaneous Demand: ' + req.body.body[0].data.demand);
// console.log('Instantaneous TS: ' + req.body.body[0].timestamp);
options.path = '/rest/items/InstantaneousDemand/state';
options.headers['Content-Length'] = req.body.body[0].data.demand.toString().length;
putReq = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
// if you are getting something here, it is probably an error from the server
console.log('post2put error from openHAB server: ' + chunk);
});
});
putReq.on('error', (error) => {
console.error(error) });
putReq.write(req.body.body[0].data.demand.toString());
putReq.end();
}
}
if (req.body.body[0].dataType == 'CurrentSummation') {
if (parseInt(req.body.body[0].timestamp) > (LastSummationTimestamp + SummationTimeLimit)) {
LastSummationTimestamp = parseInt(req.body.body[0].timestamp);
console.log('Current Summation: ' + req.body.body[0].data.summationDelivered);
// console.log(req.body.body[0].data);
options.path = '/rest/items/CurrentSummationDelivered/state';
options.headers['Content-Length'] = req.body.body[0].data.summationDelivered.toString().length;
putReq = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
// if you are getting something here, it is probably an error from the server
console.log('post2put error from openHAB server: ' + chunk);
});
});
putReq.on('error', (error) => {
console.error(error) });
putReq.write(req.body.body[0].data.summationDelivered.toString());
putReq.end();
}
}
res.set('Content-Type', 'text/plain')
res.send('Okay')
})
// choose an unused port for this use:
app.listen(8079)
Save this code in a file. I called it “post2put.js”.
You can see that I am rate limiting the Eagle in this code. I do plan to take a look at the uploader manual and use it to lower the rate instead of doing it here.
To test this out on my Ubuntu based system I ran this command:
nodejs post2put.js
Once you are happy with it, set it up as a service.