diff options
author | BrainDoctor <github.account@chrigel.net> | 2017-07-05 19:16:17 +0200 |
---|---|---|
committer | BrainDoctor <github.account@chrigel.net> | 2017-07-05 19:16:17 +0200 |
commit | 74456806d18d22b57911be316a5573f89a32f7c8 (patch) | |
tree | 59934620d38fe9999131c65c616334aa07a3751a /node.d | |
parent | 9c9da64f30eec4bb7a804369ec781b33487bf67f (diff) |
First implementation
Diffstat (limited to 'node.d')
-rw-r--r-- | node.d/stiebeleltron.node.js | 290 |
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; |