summaryrefslogtreecommitdiffstats
path: root/node.d
diff options
context:
space:
mode:
authorBrainDoctor <github.account@chrigel.net>2017-07-05 19:16:17 +0200
committerBrainDoctor <github.account@chrigel.net>2017-07-05 19:16:17 +0200
commit74456806d18d22b57911be316a5573f89a32f7c8 (patch)
tree59934620d38fe9999131c65c616334aa07a3751a /node.d
parent9c9da64f30eec4bb7a804369ec781b33487bf67f (diff)
First implementation
Diffstat (limited to 'node.d')
-rw-r--r--node.d/stiebeleltron.node.js290
1 files changed, 82 insertions, 208 deletions
diff --git a/node.d/stiebeleltron.node.js b/node.d/stiebeleltron.node.js
index 0c862c9fd1..14973ee609 100644
--- a/node.d/stiebeleltron.node.js
+++ b/node.d/stiebeleltron.node.js
@@ -1,31 +1,25 @@
'use strict';
-// This program will connect to one or more Fronius Symo Inverters.
-// to get the Solar Power Generated (current, today).
+// This program will connect to one Stiebel Eltron ISG for heatpump heating.
+// to get the heat pump metrics.
-// example configuration in netdata/conf.d/node.d/fronius.conf.md
+// example configuration in netdata/conf.d/node.d/stiebeleltron.conf.md
-var url = require('url');
-var http = require('http');
-var netdata = require('netdata');
+var url = require("url");
+var http = require("http");
+var netdata = require("netdata");
-netdata.debug('loaded ' + __filename + ' plugin');
+netdata.debug("loaded " + __filename + " plugin");
-const power_grid_id = 'p_grid';
-const power_pv_id = 'p_pv';
-const power_accu_id = 'p_akku'; // not my typo! Using the ID from the API
-const consumption_load_id = 'p_load';
-const autonomy_id = 'rel_autonomy';
-const consumption_self_id = 'rel_selfconsumption';
-
-var fronius = {
- name: "Fronius",
+var stiebeleltron = {
+ name: "Stiebel Eltron",
enable_autodetect: false,
- update_every: 5,
+ update_every: 10,
base_priority: 60000,
charts: {},
+ pages: {},
- createBasicDimension: function (id, name) {
+ createBasicDimension(id, name) {
return {
id: id, // the unique id of the dimension
name: name, // the name of the dimension
@@ -33,136 +27,60 @@ var fronius = {
multiplier: 1, // the multiplier
divisor: 1, // the divisor
hidden: false // is hidden (boolean)
- }
- },
-
- // Gets the site power chart. Will be created if not existing.
- getSitePowerChart: function (service, id) {
-
- var chart = fronius.charts[id];
- if (fronius.isDefined(chart)) return chart;
-
- var dim = {};
- dim[power_grid_id] = this.createBasicDimension(power_grid_id, "Grid");
- dim[power_pv_id] = this.createBasicDimension(power_pv_id, "Photovoltaics");
- dim[power_accu_id] = this.createBasicDimension(power_accu_id, "Accumulator");
-
- chart = {
- id: id, // the unique id of the chart
- name: '', // the unique name of the chart
- title: service.name + ' Current Site Power', // the title of the chart
- units: 'W', // the units of the chart dimensions
- family: 'Power', // the family of the chart
- context: 'fronius.power', // the context of the chart
- type: netdata.chartTypes.area, // the type of the chart
- priority: fronius.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: dim
};
- chart = service.chart(id, chart);
- fronius.charts[id] = chart;
-
- return chart;
},
- // Gets the site consumption chart. Will be created if not existing.
- getSiteConsumptionChart: function (service, id) {
+ processResponse(service, html) {
+ if (html === null) return;
- var chart = fronius.charts[id];
- if (fronius.isDefined(chart)) return chart;
- var dim = {};
- dim[consumption_load_id] = this.createBasicDimension(consumption_load_id, "Load");
-
- chart = {
- id: id, // the unique id of the chart
- name: '', // the unique name of the chart
- title: service.name + ' Current Load', // the title of the chart
- units: 'W', // the units of the chart dimensions
- family: 'Consumption', // the family of the chart
- context: 'fronius.consumption', // the context of the chart
- type: netdata.chartTypes.area, // the type of the chart
- priority: fronius.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: dim
- };
- chart = service.chart(id, chart);
- fronius.charts[id] = chart;
+ // add the service
+ service.commit();
+
+ var page = stiebeleltron.pages[service.name];
+ var categories = page.categories;
+ var categoriesCount = categories.length;
+ while (categoriesCount--) {
+ var category = categories[categoriesCount];
+ var context = {
+ html: html,
+ service: service,
+ category: category,
+ page: page
+ };
+ stiebeleltron.processCategory(context);
- return chart;
+ }
},
-
- // Gets the site consumption chart. Will be created if not existing.
- getSiteAutonomyChart: function (service, id) {
- var chart = fronius.charts[id];
- if (fronius.isDefined(chart)) return chart;
- var dim = {};
- dim[autonomy_id] = this.createBasicDimension(autonomy_id, "Autonomy");
- dim[consumption_self_id] = this.createBasicDimension(consumption_self_id, "Self Consumption");
-
- chart = {
- id: id, // the unique id of the chart
- name: '', // the unique name of the chart
- title: service.name + ' Current Autonomy', // the title of the chart
- units: '%', // the units of the chart dimensions
- family: 'Autonomy', // the family of the chart
- context: 'fronius.autonomy', // the context of the chart
- type: netdata.chartTypes.area, // the type of the chart
- priority: fronius.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: dim
- };
- chart = service.chart(id, chart);
- fronius.charts[id] = chart;
-
- return chart;
+ processCategory(context) {
+ var charts = context.category.charts;
+ var chartCount = charts.length;
+ while (chartCount--) {
+ var chart = charts[chartCount];
+ context.chartDefinition = chart;
+ stiebeleltron.processChart(context);
+ }
},
- // Gets the inverter power chart. Will be created if not existing.
- // Needs the array of inverters in order to create a chart with all inverters as dimensions
- getInverterPowerChart: function (service, chartId, inverters) {
- var chart = fronius.charts[chartId];
- if (fronius.isDefined(chart)) return chart;
-
- var dim = {};
+ processChart(context) {
+ var dimensions = context.chartDefinition.dimensions;
+ var dimensionCount = dimensions.length;
+ context.service.begin(stiebeleltron.getChartUsing(context));
- var inverter_count = Object.keys(inverters).length;
- var inverter = inverters[inverter_count.toString()];
- var i = 1;
- for (i; i <= inverter_count; i++) {
- if (fronius.isUndefined(inverter)) {
- netdata.error("Expected an Inverter with a numerical name! " +
- "Have a look at your JSON output to verify.");
- continue;
- }
- dim[i.toString()] = this.createBasicDimension("inverter_" + i, "Inverter " + i);
+ while(dimensionCount--) {
+ var dimension = dimensions[dimensionCount];
+ stiebeleltron.processDimension(dimension, context);
}
-
- chart = {
- id: chartId, // the unique id of the chart
- name: '', // the unique name of the chart
- title: service.name + ' Current Inverter Output', // the title of the chart
- units: 'W', // the units of the chart dimensions
- family: 'Inverters', // the family of the chart
- context: 'fronius.inverter', // the context of the chart
- type: netdata.chartTypes.stacked, // the type of the chart
- priority: fronius.base_priority + 4, // the priority relative to others in the same family
- update_every: service.update_every, // the expected update frequency of the chart
- dimensions: dim
- };
- chart = service.chart(chartId, chart);
- fronius.charts[chartId] = chart;
-
- return chart;
+ context.service.end();
},
- // Gets the inverter energy production chart for today. Will be created if not existing.
- // Needs the array of inverters in order to create a chart with all inverters as dimensions
- getInverterEnergyTodayChart: function (service, chartId, inverters) {
-
- var chart = fronius.charts[chartId];
- if (fronius.isDefined(chart)) return chart;
+ getChartUsing(context) {
+ var chartId = "stiebeleltron_" + context.page.id +
+ "." + context.category.id +
+ "." + context.chartDefinition.id;
+ var chart = stiebeleltron.charts[chartId];
+ if (stiebeleltron.isDefined(chart)) return chart;
var dim = {};
@@ -170,7 +88,7 @@ var fronius = {
var inverter = inverters[inverter_count.toString()];
var i = 1;
for (i; i <= inverter_count; i++) {
- if (fronius.isUndefined(inverter)) {
+ if (stiebeleltron.isUndefined(inverter)) {
netdata.error("Expected an Inverter with a numerical name! " +
"Have a look at your JSON output to verify.");
continue;
@@ -188,81 +106,35 @@ var fronius = {
chart = {
id: chartId, // the unique id of the chart
name: '', // the unique name of the chart
- title: service.name + ' Inverter Energy production for today', // the title of the chart
- units: 'kWh', // the units of the chart dimensions
+ title: service.name + " " + chartDefinition.title, // the title of the chart
+ units: chartDefinition.unit, // the units of the chart dimensions
family: 'Inverters', // the family of the chart
- context: 'fronius.inverter', // the context of the chart
+ context: 'stiebeleltron.inverter', // the context of the chart
type: netdata.chartTypes.stacked, // the type of the chart
- priority: fronius.base_priority + 5, // the priority relative to others in the same family
+ priority: stiebeleltron.base_priority + 5, // the priority relative to others in the same family
update_every: service.update_every, // the expected update frequency of the chart
dimensions: dim
};
chart = service.chart(chartId, chart);
- fronius.charts[chartId] = chart;
+ stiebeleltron.charts[chartId] = chart;
return chart;
},
+ processDimension(dimension, context) {
+ var value = stiebeleltron.parseRegex(dimension.regex, context.html);
+ context.service.set(dimension.name, Math.round(value));
+ },
- processResponse: function (service, content) {
- if (content === null) return;
- var json = JSON.parse(content);
- // validating response
- if (fronius.isUndefined(json.Body)) return;
- if (fronius.isUndefined(json.Body.Data)) return;
- if (fronius.isUndefined(json.Body.Data.Site)) return;
- if (fronius.isUndefined(json.Body.Data.Inverters)) return;
-
- // add the service
- if (service.added !== true) service.commit();
-
- var site = json.Body.Data.Site;
-
- // Site Current Power Chart
- service.begin(fronius.getSitePowerChart(service, 'fronius_' + service.name + '.power'));
- service.set(power_grid_id, Math.round(site.P_Grid));
- service.set(power_pv_id, Math.round(site.P_PV));
- service.set(power_accu_id, Math.round(site.P_Akku));
- service.end();
-
- // Site Consumption Chart
- var consumption = site.P_Load;
- if (consumption === null) consumption = 0;
- consumption *= -1;
-
- service.begin(fronius.getSiteConsumptionChart(service, 'fronius_' + service.name + '.consumption'));
- service.set(consumption_load_id, Math.round(consumption));
- service.end();
-
- // Site Autonomy Chart
- service.begin(fronius.getSiteAutonomyChart(service, 'fronius_' + service.name + '.autonomy'));
- service.set(autonomy_id, Math.round(site.rel_Autonomy));
- service.set(consumption_self_id, Math.round(site.rel_SelfConsumption));
- service.end();
+ parseRegex(regex, html) {
- // Inverters
- var inverters = json.Body.Data.Inverters;
- var inverter_count = Object.keys(inverters).length;
- if (inverter_count <= 0) return;
- var i = 1;
- for (i; i <= inverter_count; i++) {
- var inverter = inverters[i];
- if (fronius.isUndefined(inverter)) continue;
- netdata.debug("Setting values");
- service.begin(fronius.getInverterPowerChart(service, 'fronius_' + service.name + '.inverters.output', inverters));
- service.set(i.toString(), Math.round(inverter.P));
- service.end();
- service.begin(fronius.getInverterEnergyTodayChart(service, 'fronius_' + service.name + '.inverters.today', inverters));
- service.set(i.toString(), Math.round(inverter.E_Day));
- 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, uri, update_every) {
+ serviceExecute(name, uri, update_every) {
netdata.debug(this.name + ': ' + name + ': url: ' + uri + ', update_every: ' + update_every);
var service = netdata.service({
@@ -276,16 +148,20 @@ var fronius = {
},
- configure: function (config) {
- if (fronius.isUndefined(config.servers)) return 0;
+ configure(config) {
+ if (stiebeleltron.isUndefined(config.pages)) return 0;
var added = 0;
- var len = config.servers.length;
- while (len--) {
- var server = config.servers[len];
- if (fronius.isUndefined(server.update_every)) server.update_every = this.update_every;
-
- var url = server.hostname + server.api_path;
- this.serviceExecute(server.name, url, server.update_every);
+ var pageCount = config.pages.length;
+ while (pageCount--) {
+ var page = config.pages[pageCount];
+ // some validation
+ if (stiebeleltron.isUndefined(page.categories) || page.categories.length < 1) {
+ netdata.error("Your Stiebel Eltron config is invalid. Disabling plugin.");
+ return 0;
+ }
+ if (stiebeleltron.isUndefined(page.update_every)) page.update_every = this.update_every;
+ this.pages[page.id] = page;
+ this.serviceExecute(page.name, page.url, page.update_every);
added++;
}
return added;
@@ -294,22 +170,20 @@ var fronius = {
// module.update()
// this is called repeatedly to collect data, by calling
// netdata.serviceExecute()
- update: function (service, callback) {
+ update(service, callback) {
service.execute(function (serv, data) {
service.module.processResponse(serv, data);
callback();
});
},
- isUndefined: function (value) {
+ isUndefined(value) {
return typeof value === 'undefined';
},
- isDefined: function (value) {
+ isDefined(value) {
return typeof value !== 'undefined';
- }
-
-
+ },
};
-module.exports = fronius;
+module.exports = stiebeleltron;