summaryrefslogtreecommitdiffstats
path: root/node.d
diff options
context:
space:
mode:
authorLennart Weller <lhw@ring0.de>2017-07-27 09:55:47 +0000
committerLennart Weller <lhw@ring0.de>2017-07-27 09:55:47 +0000
commita133c9c3b637b1dbe7b5b053f7e2572c1950cead (patch)
tree2207939a88e96bca329457f40a9d9d18ab659dc1 /node.d
parentNew upstream version 1.6.0+dfsg (diff)
downloadnetdata-upstream/1.7.0+dfsg.tar.xz
netdata-upstream/1.7.0+dfsg.zip
New upstream version 1.7.0+dfsgupstream/1.7.0+dfsg
Diffstat (limited to 'node.d')
-rw-r--r--node.d/Makefile.am1
-rw-r--r--node.d/Makefile.in124
-rw-r--r--node.d/README.md63
-rw-r--r--node.d/fronius.node.js317
-rw-r--r--node.d/node_modules/net-snmp.js63
5 files changed, 507 insertions, 61 deletions
diff --git a/node.d/Makefile.am b/node.d/Makefile.am
index c1caa4f0e..28008aeb7 100644
--- a/node.d/Makefile.am
+++ b/node.d/Makefile.am
@@ -3,6 +3,7 @@ MAINTAINERCLEANFILES= $(srcdir)/Makefile.in
dist_node_DATA = \
README.md \
named.node.js \
+ fronius.node.js \
sma_webbox.node.js \
snmp.node.js \
$(NULL)
diff --git a/node.d/Makefile.in b/node.d/Makefile.in
index 2af9a4a65..35024cb12 100644
--- a/node.d/Makefile.in
+++ b/node.d/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -16,6 +15,51 @@
@SET_MAKE@
VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -35,9 +79,9 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = node.d
-DIST_COMMON = $(dist_node_DATA) $(dist_nodemodules_DATA) \
- $(dist_nodemodulesber_DATA) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(dist_node_DATA) $(dist_nodemodules_DATA) \
+ $(dist_nodemodulesber_DATA)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___atomic.m4 \
$(top_srcdir)/m4/ax_c__generic.m4 $(top_srcdir)/m4/ax_c_lto.m4 \
@@ -53,8 +97,25 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
SOURCES =
DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -86,9 +147,11 @@ am__installdirs = "$(DESTDIR)$(nodedir)" "$(DESTDIR)$(nodemodulesdir)" \
"$(DESTDIR)$(nodemodulesberdir)"
DATA = $(dist_node_DATA) $(dist_nodemodules_DATA) \
$(dist_nodemodulesber_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
@@ -234,6 +297,7 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
dist_node_DATA = \
README.md \
named.node.js \
+ fronius.node.js \
sma_webbox.node.js \
snmp.node.js \
$(NULL)
@@ -291,8 +355,11 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
install-dist_nodeDATA: $(dist_node_DATA)
@$(NORMAL_INSTALL)
- test -z "$(nodedir)" || $(MKDIR_P) "$(DESTDIR)$(nodedir)"
@list='$(dist_node_DATA)'; test -n "$(nodedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(nodedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(nodedir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -309,8 +376,11 @@ uninstall-dist_nodeDATA:
dir='$(DESTDIR)$(nodedir)'; $(am__uninstall_files_from_dir)
install-dist_nodemodulesDATA: $(dist_nodemodules_DATA)
@$(NORMAL_INSTALL)
- test -z "$(nodemodulesdir)" || $(MKDIR_P) "$(DESTDIR)$(nodemodulesdir)"
@list='$(dist_nodemodules_DATA)'; test -n "$(nodemodulesdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(nodemodulesdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(nodemodulesdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -327,8 +397,11 @@ uninstall-dist_nodemodulesDATA:
dir='$(DESTDIR)$(nodemodulesdir)'; $(am__uninstall_files_from_dir)
install-dist_nodemodulesberDATA: $(dist_nodemodulesber_DATA)
@$(NORMAL_INSTALL)
- test -z "$(nodemodulesberdir)" || $(MKDIR_P) "$(DESTDIR)$(nodemodulesberdir)"
@list='$(dist_nodemodulesber_DATA)'; test -n "$(nodemodulesberdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(nodemodulesberdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(nodemodulesberdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -343,11 +416,11 @@ uninstall-dist_nodemodulesberDATA:
@list='$(dist_nodemodulesber_DATA)'; test -n "$(nodemodulesberdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(nodemodulesberdir)'; $(am__uninstall_files_from_dir)
-tags: TAGS
-TAGS:
+tags TAGS:
+
+ctags CTAGS:
-ctags: CTAGS
-CTAGS:
+cscope cscopelist:
distdir: $(DISTFILES)
@@ -488,17 +561,18 @@ uninstall-am: uninstall-dist_nodeDATA uninstall-dist_nodemodulesDATA \
.MAKE: install-am install-strip
-.PHONY: all all-am check check-am clean clean-generic distclean \
- distclean-generic distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am \
- install-dist_nodeDATA install-dist_nodemodulesDATA \
- install-dist_nodemodulesberDATA install-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-info install-info-am install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
- pdf-am ps ps-am uninstall uninstall-am uninstall-dist_nodeDATA \
+.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
+ ctags-am distclean distclean-generic distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dist_nodeDATA \
+ install-dist_nodemodulesDATA install-dist_nodemodulesberDATA \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \
+ uninstall uninstall-am uninstall-dist_nodeDATA \
uninstall-dist_nodemodulesDATA \
uninstall-dist_nodemodulesberDATA
diff --git a/node.d/README.md b/node.d/README.md
index e69de29bb..3c2977905 100644
--- a/node.d/README.md
+++ b/node.d/README.md
@@ -0,0 +1,63 @@
+# Disclaimer
+
+Module configurations are written in JSON and **node.js is required**.
+
+to be edited.
+
+---
+
+The following node.d modules are supported:
+
+# fronius
+
+This module collects metrics from the configured solar power installation from Fronius Symo.
+See `netdata/conf.d/node.d/fronius.conf.md` for more details.
+
+**Requirements**
+ * Configuration file `fronius.conf` in the node.d netdata config dir (default: `/etc/netdata/node.d/fronius.conf`)
+ * Fronius Symo with network access (http)
+
+It produces per server:
+
+1. **Power**
+ * Current power input from the grid (positive values), output to the grid (negative values), in W
+ * Current power input from the solar panels, in W
+ * Current power stored in the accumulator (if present), in W (in theory, untested)
+
+2. **Consumption**
+ * Local consumption in W
+
+3. **Autonomy**
+ * Relative autonomy in %. 100 % autonomy means that the solar panels are delivering more power than it is needed by local consumption.
+ * Relative self consumption in %. The lower the better
+
+4. **Energy**
+ * The energy produced during the current day, in kWh
+ * The energy produced during the current year, in kWh
+
+5. **Inverter**
+ * The current power output from the connected inverters, in W, one dimension per inverter. At least one is always present.
+
+
+### configuration
+
+Sample:
+
+```json
+{
+ "enable_autodetect": false,
+ "update_every": 5,
+ "servers": [
+ {
+ "name": "Symo",
+ "hostname": "symo.ip.or.dns",
+ "update_every": 5,
+ "api_path": "/solar_api/v1/GetPowerFlowRealtimeData.fcgi"
+ }
+ ]
+}
+```
+
+If no configuration is given, the module will be disabled. Each `update_every` is optional, the default is `5`.
+
+---
diff --git a/node.d/fronius.node.js b/node.d/fronius.node.js
new file mode 100644
index 000000000..f771f6c3d
--- /dev/null
+++ b/node.d/fronius.node.js
@@ -0,0 +1,317 @@
+'use strict';
+
+// This program will connect to one or more Fronius Symo Inverters.
+// to get the Solar Power Generated (current, today).
+
+// example configuration in netdata/conf.d/node.d/fronius.conf.md
+
+var url = require('url');
+var http = require('http');
+var netdata = require('netdata');
+
+netdata.debug('loaded ' + __filename + ' plugin');
+
+var fronius = {
+ name: "Fronius",
+ enable_autodetect: false,
+ update_every: 5,
+ base_priority: 60000,
+ charts: {},
+
+ powerGridId: "p_grid",
+ powerPvId: "p_pv",
+ powerAccuId: "p_akku", // not my typo! Using the ID from the AP
+ consumptionLoadId: "p_load",
+ autonomyId: "rel_autonomy",
+ consumptionSelfId: "rel_selfconsumption",
+ energyTodayId: "e_day",
+ energyYearId: "e_year",
+
+ createBasicDimension: function (id, name, divisor) {
+ return {
+ id: id, // the unique id of the dimension
+ name: name, // the name of the dimension
+ algorithm: netdata.chartAlgorithms.absolute,// the id of the netdata algorithm
+ multiplier: 1, // the multiplier
+ divisor: divisor, // 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[fronius.powerGridId] = this.createBasicDimension(fronius.powerGridId, "Grid", 1);
+ dim[fronius.powerPvId] = this.createBasicDimension(fronius.powerPvId, "Photovoltaics", 1);
+ dim[fronius.powerAccuId] = this.createBasicDimension(fronius.powerAccuId, "Accumulator", 1);
+
+ 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) {
+ var chart = fronius.charts[id];
+ if (fronius.isDefined(chart)) return chart;
+ var dim = {};
+ dim[fronius.consumptionLoadId] = this.createBasicDimension(fronius.consumptionLoadId, "Load", 1);
+
+ 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;
+
+ 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[fronius.autonomyId] = this.createBasicDimension(fronius.autonomyId, "Autonomy", 1);
+ dim[fronius.consumptionSelfId] = this.createBasicDimension(fronius.consumptionSelfId, "Self Consumption", 1);
+
+ 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;
+ },
+
+ // Gets the site energy chart for today. Will be created if not existing.
+ getSiteEnergyTodayChart: function (service, chartId) {
+ var chart = fronius.charts[chartId];
+ if (fronius.isDefined(chart)) return chart;
+ var dim = {};
+ dim[fronius.energyTodayId] = this.createBasicDimension(fronius.energyTodayId, "Today", 1000);
+ chart = {
+ id: chartId, // the unique id of the chart
+ name: '', // the unique name of the chart
+ title: service.name + ' Energy production for today', // the title of the chart
+ units: 'kWh', // the units of the chart dimensions
+ family: 'energy', // the family of the chart
+ context: 'fronius.energy.today', // the context of the chart
+ type: netdata.chartTypes.area, // 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;
+ },
+
+ // Gets the site energy chart for today. Will be created if not existing.
+ getSiteEnergyYearChart: function (service, chartId) {
+ var chart = fronius.charts[chartId];
+ if (fronius.isDefined(chart)) return chart;
+ var dim = {};
+ dim[fronius.energyYearId] = this.createBasicDimension(fronius.energyYearId, "Year", 1000);
+ chart = {
+ id: chartId, // the unique id of the chart
+ name: '', // the unique name of the chart
+ title: service.name + ' Energy production for this year', // the title of the chart
+ units: 'kWh', // the units of the chart dimensions
+ family: 'energy', // the family of the chart
+ context: 'fronius.energy.year', // the context of the chart
+ type: netdata.chartTypes.area, // the type of the chart
+ priority: fronius.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;
+
+ return chart;
+ },
+
+ // 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 = {};
+
+ var inverterCount = Object.keys(inverters).length;
+ var inverter = inverters[inverterCount.toString()];
+ var i = 1;
+ for (i; i <= inverterCount; 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, 1);
+ }
+
+ 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.output', // the context of the chart
+ type: netdata.chartTypes.stacked, // the type of the chart
+ priority: fronius.base_priority + 6, // 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;
+ },
+
+ processResponse: function (service, content) {
+ if (content === null) return;
+ var json = JSON.parse(content);
+ if (!fronius.isResponseValid(json)) return;
+
+ // add the service
+ service.commit();
+
+ var site = json.Body.Data.Site;
+
+ // Site Current Power Chart
+ service.begin(fronius.getSitePowerChart(service, 'fronius_' + service.name + '.power'));
+ service.set(fronius.powerGridId, Math.round(site.P_Grid));
+ service.set(fronius.powerPvId, Math.round(site.P_PV));
+ service.set(fronius.powerAccuId, Math.round(site.P_Akku));
+ service.end();
+
+ // Site Consumption Chart
+ service.begin(fronius.getSiteConsumptionChart(service, 'fronius_' + service.name + '.consumption'));
+ service.set(fronius.consumptionLoadId, Math.round(Math.abs(site.P_Load)));
+ service.end();
+
+ // Site Autonomy Chart
+ service.begin(fronius.getSiteAutonomyChart(service, 'fronius_' + service.name + '.autonomy'));
+ service.set(fronius.autonomyId, Math.round(site.rel_Autonomy));
+ var selfConsumption = site.rel_SelfConsumption;
+ service.set(fronius.consumptionSelfId, Math.round(selfConsumption === null ? 100 : selfConsumption));
+ service.end();
+
+ // Site Energy Today Chart
+ service.begin(fronius.getSiteEnergyTodayChart(service, 'fronius_' + service.name + '.energy.today'));
+ service.set(fronius.energyTodayId, Math.round(site.E_Day));
+ service.end();
+
+ // Site Energy Year Chart
+ service.begin(fronius.getSiteEnergyYearChart(service, 'fronius_' + service.name + '.energy.year'));
+ service.set(fronius.energyYearId, Math.round(site.E_Year));
+ service.end();
+
+ // Inverters
+ var inverters = json.Body.Data.Inverters;
+ var inverterCount = Object.keys(inverters).length + 1;
+ while (inverterCount--) {
+ var inverter = inverters[inverterCount];
+ if (fronius.isUndefined(inverter)) continue;
+ service.begin(fronius.getInverterPowerChart(service, 'fronius_' + service.name + '.inverters.output', inverters));
+ service.set(inverterCount.toString(), Math.round(inverter.P));
+ service.end();
+ }
+ },
+
+ // some basic validation
+ isResponseValid: function (json) {
+ if (fronius.isUndefined(json.Body)) return false;
+ if (fronius.isUndefined(json.Body.Data)) return false;
+ if (fronius.isUndefined(json.Body.Data.Site)) return false;
+ return fronius.isDefined(json.Body.Data.Inverters);
+ },
+
+ // 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) {
+ netdata.debug(this.name + ': ' + name + ': url: ' + uri + ', update_every: ' + update_every);
+
+ var service = netdata.service({
+ name: name,
+ request: netdata.requestFromURL('http://' + uri),
+ update_every: update_every,
+ module: this
+ });
+ service.execute(this.processResponse);
+ },
+
+
+ configure: function (config) {
+ if (fronius.isUndefined(config.servers)) 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);
+ added++;
+ }
+ return added;
+ },
+
+ // module.update()
+ // this is called repeatedly to collect data, by calling
+ // netdata.serviceExecute()
+ update: function (service, callback) {
+ service.execute(function (serv, data) {
+ service.module.processResponse(serv, data);
+ callback();
+ });
+ },
+
+ isUndefined: function (value) {
+ return typeof value === 'undefined';
+ },
+
+ isDefined: function (value) {
+ return typeof value !== 'undefined';
+ }
+};
+
+module.exports = fronius;
diff --git a/node.d/node_modules/net-snmp.js b/node.d/node_modules/net-snmp.js
index 6fbd4e721..de5926104 100644
--- a/node.d/node_modules/net-snmp.js
+++ b/node.d/node_modules/net-snmp.js
@@ -12,7 +12,7 @@ var util = require ("util");
function _expandConstantObject (object) {
var keys = [];
- for (key in object)
+ for (var key in object)
keys.push (key);
for (var i = 0; i < keys.length; i++)
object[object[keys[i]]] = parseInt (keys[i]);
@@ -133,12 +133,9 @@ util.inherits (RequestTimedOutError, Error);
**/
function isVarbindError (varbind) {
- if (varbind.type == ObjectType.NoSuchObject
- || varbind.type == ObjectType.NoSuchInstance
- || varbind.type == ObjectType.EndOfMibView)
- return true;
- else
- return false;
+ return !!(varbind.type == ObjectType.NoSuchObject
+ || varbind.type == ObjectType.NoSuchInstance
+ || varbind.type == ObjectType.EndOfMibView);
}
function varbindError (varbind) {
@@ -216,6 +213,8 @@ function readInt (buffer) {
function readUint (buffer, isSigned) {
buffer.readByte ();
var length = buffer.readByte ();
+ var value = 0;
+ var signedBitSet = false;
if (length > 5) {
throw new RangeError ("Integer too long '" + length + "'");
@@ -225,8 +224,6 @@ function readUint (buffer, isSigned) {
length = 4;
}
- value = 0, signedBitSet = false;
-
for (var i = 0; i < length; i++) {
value *= 256;
value += buffer.readByte ();
@@ -246,10 +243,6 @@ function readUint (buffer, isSigned) {
function readUint64 (buffer) {
var value = buffer.readString (ObjectType.Counter64, true);
- if (value.length > 8)
- throw new RequestInvalidError ("64 bit unsigned integer too long '"
- + value.length + "'")
-
return value;
}
@@ -327,9 +320,6 @@ function writeUint (buffer, type, value) {
}
function writeUint64 (buffer, value) {
- if (value.length > 8)
- throw new RequestInvalidError ("64 bit unsigned integer too long '"
- + value.length + "'")
buffer.writeBuffer (value, ObjectType.Counter64);
}
@@ -381,7 +371,7 @@ function writeVarbinds (buffer, varbinds) {
}
buffer.endSequence ();
- };
+ }
buffer.endSequence ();
}
@@ -549,7 +539,7 @@ var ResponseMessage = function (buffer) {
throw new ResponseInvalidError ("Unknown PDU type '" + type
+ "' in response");
}
-}
+};
/*****************************************************************************
** Session class definition
@@ -599,7 +589,7 @@ var Session = function (target, community, options) {
this.dgram.on ("error", me.onError.bind (me));
if (this.sourceAddress || this.sourcePort)
- req.dgram.bind (this.sourcePort, this.sourceAddress);
+ this.dgram.bind (this.sourcePort, this.sourceAddress);
};
util.inherits (Session, events.EventEmitter);
@@ -607,15 +597,16 @@ util.inherits (Session, events.EventEmitter);
Session.prototype.close = function () {
this.dgram.close ();
return this;
-}
+};
Session.prototype.cancelRequests = function (error) {
+ var id;
for (id in this.reqs) {
var req = this.reqs[id];
this.unregisterRequest (req.id);
req.responseCb (error);
}
-}
+};
function _generateId () {
return Math.floor (Math.random () + Math.random () * 10000000)
@@ -645,7 +636,7 @@ Session.prototype.get = function (oids, responseCb) {
req.responseCb (null, varbinds);
}
- };
+ }
var pduVarbinds = [];
@@ -747,7 +738,7 @@ Session.prototype.getBulk = function () {
}
req.responseCb (null, varbinds);
- };
+ }
var pduVarbinds = [];
@@ -796,7 +787,7 @@ Session.prototype.getNext = function (oids, responseCb) {
req.responseCb (null, varbinds);
}
- };
+ }
var pduVarbinds = [];
@@ -813,7 +804,7 @@ Session.prototype.getNext = function (oids, responseCb) {
};
Session.prototype.inform = function () {
- var typeOrOid = arguments[0];;
+ var typeOrOid = arguments[0];
var varbinds, options = {}, responseCb;
/**
@@ -865,7 +856,7 @@ Session.prototype.inform = function () {
req.responseCb (null, varbinds);
}
- };
+ }
if (typeof typeOrOid != "string")
typeOrOid = "1.3.6.1.6.3.1.1.5." + (typeOrOid + 1);
@@ -1029,7 +1020,7 @@ Session.prototype.set = function (varbinds, responseCb) {
req.responseCb (null, varbinds);
}
- };
+ }
var pduVarbinds = [];
@@ -1049,7 +1040,7 @@ Session.prototype.set = function (varbinds, responseCb) {
Session.prototype.simpleGet = function (pduClass, feedCb, varbinds,
responseCb, options) {
- var req = {}
+ var req = {};
try {
var id = _generateId ();
@@ -1116,7 +1107,7 @@ Session.prototype.subtree = function () {
this.walk (oid, maxRepetitions, subtreeCb.bind (me, req), doneCb);
return this;
-}
+};
function tableColumnsResponseCb (req, error) {
if (error) {
@@ -1143,7 +1134,7 @@ function tableColumnsFeedCb (req, varbinds) {
return true;
}
- var oid = varbinds[i].oid.replace (req.rowOid, "")
+ var oid = varbinds[i].oid.replace (req.rowOid, "");
if (oid && oid != varbinds[i].oid) {
var match = oid.match (/^(\d+)\.(.+)$/);
if (match && match[1] > 0) {
@@ -1187,7 +1178,7 @@ Session.prototype.tableColumns = function () {
}
return this;
-}
+};
function tableResponseCb (req, error) {
if (error)
@@ -1205,7 +1196,7 @@ function tableFeedCb (req, varbinds) {
return true;
}
- var oid = varbinds[i].oid.replace (req.rowOid, "")
+ var oid = varbinds[i].oid.replace (req.rowOid, "");
if (oid && oid != varbinds[i].oid) {
var match = oid.match (/^(\d+)\.(.+)$/);
if (match && match[1] > 0) {
@@ -1243,7 +1234,7 @@ Session.prototype.table = function () {
tableResponseCb.bind (me, req));
return this;
-}
+};
Session.prototype.trap = function () {
var req = {};
@@ -1430,7 +1421,7 @@ Session.prototype.walk = function () {
this.getNext ([oid], walkCb.bind (me, req));
return this;
-}
+};
/*****************************************************************************
** Exports
@@ -1438,8 +1429,8 @@ Session.prototype.walk = function () {
exports.Session = Session;
-exports.createSession = function (target, community, version, options) {
- return new Session (target, community, version, options);
+exports.createSession = function (target, community, options) {
+ return new Session (target, community, options);
};
exports.isVarbindError = isVarbindError;