diff options
Diffstat (limited to 'collectors/node.d.plugin/sma_webbox')
-rw-r--r-- | collectors/node.d.plugin/sma_webbox/Makefile.inc | 13 | ||||
-rw-r--r-- | collectors/node.d.plugin/sma_webbox/README.md | 29 | ||||
-rw-r--r-- | collectors/node.d.plugin/sma_webbox/sma_webbox.node.js | 239 |
3 files changed, 281 insertions, 0 deletions
diff --git a/collectors/node.d.plugin/sma_webbox/Makefile.inc b/collectors/node.d.plugin/sma_webbox/Makefile.inc new file mode 100644 index 0000000..38f2fe9 --- /dev/null +++ b/collectors/node.d.plugin/sma_webbox/Makefile.inc @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +# THIS IS NOT A COMPLETE Makefile +# IT IS INCLUDED BY ITS PARENT'S Makefile.am +# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT + +# install these files +dist_node_DATA += sma_webbox/sma_webbox.node.js +# dist_nodeconfig_DATA += sma_webbox/sma_webbox.conf + +# do not install these files, but include them in the distribution +dist_noinst_DATA += sma_webbox/README.md sma_webbox/Makefile.inc + diff --git a/collectors/node.d.plugin/sma_webbox/README.md b/collectors/node.d.plugin/sma_webbox/README.md new file mode 100644 index 0000000..cff7645 --- /dev/null +++ b/collectors/node.d.plugin/sma_webbox/README.md @@ -0,0 +1,29 @@ +
+# SMA Sunny Webbox
+
+[SMA Sunny Webbox](http://files.sma.de/dl/4253/WEBBOX-DUS131916W.pdf)
+
+Example netdata configuration for node.d/sma_webbox.conf
+
+The module supports any number of name servers, like this:
+
+```json
+{
+ "enable_autodetect": false,
+ "update_every": 5,
+ "servers": [
+ {
+ "name": "plant1",
+ "hostname": "10.0.1.1",
+ "update_every": 10
+ },
+ {
+ "name": "plant2",
+ "hostname": "10.0.2.1",
+ "update_every": 15
+ }
+ ]
+}
+```
+
+[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnode.d.plugin%2Fsma_webbox%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
diff --git a/collectors/node.d.plugin/sma_webbox/sma_webbox.node.js b/collectors/node.d.plugin/sma_webbox/sma_webbox.node.js new file mode 100644 index 0000000..aa60ae8 --- /dev/null +++ b/collectors/node.d.plugin/sma_webbox/sma_webbox.node.js @@ -0,0 +1,239 @@ +'use strict'; +// SPDX-License-Identifier: GPL-3.0-or-later + +// This program will connect to one or more SMA Sunny Webboxes +// to get the Solar Power Generated (current, today, total). + +// example configuration in /etc/netdata/node.d/sma_webbox.conf +/* +{ + "enable_autodetect": false, + "update_every": 5, + "servers": [ + { + "name": "plant1", + "hostname": "10.0.1.1", + "update_every": 10 + }, + { + "name": "plant2", + "hostname": "10.0.2.1", + "update_every": 15 + } + ] +} +*/ + +require('url'); +require('http'); +var netdata = require('netdata'); + +if(netdata.options.DEBUG === true) netdata.debug('loaded ' + __filename + ' plugin'); + +var webbox = { + name: __filename, + enable_autodetect: true, + update_every: 1, + base_priority: 60000, + charts: {}, + + processResponse: function(service, data) { + if(data !== null) { + var r = JSON.parse(data); + + var d = { + 'GriPwr': { + unit: null, + value: null + }, + 'GriEgyTdy': { + unit: null, + value: null + }, + 'GriEgyTot': { + unit: null, + value: null + } + }; + + // parse the webbox response + // and put it in our d object + var found = 0; + var len = r.result.overview.length; + while(len--) { + var e = r.result.overview[len]; + if(typeof(d[e.meta]) !== 'undefined') { + found++; + d[e.meta].value = e.value; + d[e.meta].unit = e.unit; + } + } + + // add the service + if(found > 0 && service.added !== true) + service.commit(); + + + // Grid Current Power Chart + if(d['GriPwr'].value !== null) { + const id = 'smawebbox_' + service.name + '.current'; + let chart = webbox.charts[id]; + + if(typeof chart === 'undefined') { + chart = { + id: id, // the unique id of the chart + name: '', // the unique name of the chart + title: service.name + ' Current Grid Power', // the title of the chart + units: d['GriPwr'].unit, // the units of the chart dimensions + family: 'now', // the family of the chart + context: 'smawebbox.grid_power', // the context of the chart + type: netdata.chartTypes.area, // the type of the chart + priority: webbox.base_priority + 1, // the priority relative to others in the same family + update_every: service.update_every, // the expected update frequency of the chart + dimensions: { + 'GriPwr': { + id: 'GriPwr', // the unique id of the dimension + name: 'power', // the name of the dimension + algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm + multiplier: 1, // the multiplier + divisor: 1, // the divisor + hidden: false // is hidden (boolean) + } + } + }; + + chart = service.chart(id, chart); + webbox.charts[id] = chart; + } + + service.begin(chart); + service.set('GriPwr', Math.round(d['GriPwr'].value)); + service.end(); + } + + if(d['GriEgyTdy'].value !== null) { + const id = 'smawebbox_' + service.name + '.today'; + let chart = webbox.charts[id]; + + if(typeof chart === 'undefined') { + chart = { + id: id, // the unique id of the chart + name: '', // the unique name of the chart + title: service.name + ' Today Grid Power', // the title of the chart + units: d['GriEgyTdy'].unit, // the units of the chart dimensions + family: 'today', // the family of the chart + context: 'smawebbox.grid_power_today', // the context of the chart + type: netdata.chartTypes.area, // the type of the chart + priority: webbox.base_priority + 2, // the priority relative to others in the same family + update_every: service.update_every, // the expected update frequency of the chart + dimensions: { + 'GriEgyTdy': { + id: 'GriEgyTdy', // the unique id of the dimension + name: 'power', // the name of the dimension + algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm + multiplier: 1, // the multiplier + divisor: 1000, // the divisor + hidden: false // is hidden (boolean) + } + } + }; + + chart = service.chart(id, chart); + webbox.charts[id] = chart; + } + + service.begin(chart); + service.set('GriEgyTdy', Math.round(d['GriEgyTdy'].value * 1000)); + service.end(); + } + + if(d['GriEgyTot'].value !== null) { + const id = 'smawebbox_' + service.name + '.total'; + let chart = webbox.charts[id]; + + if(typeof chart === 'undefined') { + chart = { + id: id, // the unique id of the chart + name: '', // the unique name of the chart + title: service.name + ' Total Grid Power', // the title of the chart + units: d['GriEgyTot'].unit, // the units of the chart dimensions + family: 'total', // the family of the chart + context: 'smawebbox.grid_power_total', // the context of the chart + type: netdata.chartTypes.area, // the type of the chart + priority: webbox.base_priority + 3, // the priority relative to others in the same family + update_every: service.update_every, // the expected update frequency of the chart + dimensions: { + 'GriEgyTot': { + id: 'GriEgyTot', // the unique id of the dimension + name: 'power', // the name of the dimension + algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm + multiplier: 1, // the multiplier + divisor: 1000, // the divisor + hidden: false // is hidden (boolean) + } + } + }; + + chart = service.chart(id, chart); + webbox.charts[id] = chart; + } + + service.begin(chart); + service.set('GriEgyTot', Math.round(d['GriEgyTot'].value * 1000)); + service.end(); + } + } + }, + + // module.serviceExecute() + // this function is called only from this module + // its purpose is to prepare the request and call + // netdata.serviceExecute() + serviceExecute: function(name, hostname, update_every) { + if(netdata.options.DEBUG === true) netdata.debug(this.name + ': ' + name + ': hostname: ' + hostname + ', update_every: ' + update_every); + + var service = netdata.service({ + name: name, + request: netdata.requestFromURL('http://' + hostname + '/rpc'), + update_every: update_every, + module: this + }); + service.postData = 'RPC={"proc":"GetPlantOverview","format":"JSON","version":"1.0","id":"1"}'; + service.request.method = 'POST'; + service.request.headers['Content-Length'] = service.postData.length; + + service.execute(this.processResponse); + }, + + configure: function(config) { + var added = 0; + + if(typeof(config.servers) !== 'undefined') { + var len = config.servers.length; + while(len--) { + if(typeof config.servers[len].update_every === 'undefined') + config.servers[len].update_every = this.update_every; + + if(config.servers[len].update_every < 5) + config.servers[len].update_every = 5; + + this.serviceExecute(config.servers[len].name, config.servers[len].hostname, config.servers[len].update_every); + added++; + } + } + + return added; + }, + + // module.update() + // this is called repeatidly to collect data, by calling + // netdata.serviceExecute() + update: function(service, callback) { + service.execute(function(serv, data) { + service.module.processResponse(serv, data); + callback(); + }); + }, +}; + +module.exports = webbox; |