diff options
-rw-r--r-- | node.d/fronius.node.js | 270 | ||||
-rw-r--r-- | tests/node.d/fronius.chart.spec.js | 91 | ||||
-rw-r--r-- | tests/node.d/fronius.parse.spec.js | 338 | ||||
-rw-r--r-- | tests/node.d/fronius.process.spec.js | 74 | ||||
-rw-r--r-- | tests/node.d/fronius.validation.spec.js | 28 |
5 files changed, 611 insertions, 190 deletions
diff --git a/node.d/fronius.node.js b/node.d/fronius.node.js index 54bae761da..8988c4fbf7 100644 --- a/node.d/fronius.node.js +++ b/node.d/fronius.node.js @@ -1,15 +1,15 @@ -'use strict'; +"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'); +var url = require("url"); +var http = require("http"); +var netdata = require("netdata"); -netdata.debug('loaded ' + __filename + ' plugin'); +netdata.debug("loaded " + __filename + " plugin"); var fronius = { name: "Fronius", @@ -39,7 +39,8 @@ var fronius = { }, // Gets the site power chart. Will be created if not existing. - getSitePowerChart: function (service, id) { + getSitePowerChart: function (service, suffix) { + var id = this.getChartId(service, suffix); var chart = fronius.charts[id]; if (fronius.isDefined(chart)) return chart; @@ -50,13 +51,13 @@ var fronius = { 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 + 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 + 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 }; @@ -67,7 +68,8 @@ var fronius = { }, // Gets the site consumption chart. Will be created if not existing. - getSiteConsumptionChart: function (service, id) { + getSiteConsumptionChart: function (service, suffix) { + var id = this.getChartId(service, suffix); var chart = fronius.charts[id]; if (fronius.isDefined(chart)) return chart; var dim = {}; @@ -75,11 +77,11 @@ var fronius = { 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 + 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 @@ -92,7 +94,8 @@ var fronius = { }, // Gets the site consumption chart. Will be created if not existing. - getSiteAutonomyChart: function (service, id) { + getSiteAutonomyChart: function (service, suffix) { + var id = this.getChartId(service, suffix); var chart = fronius.charts[id]; if (fronius.isDefined(chart)) return chart; var dim = {}; @@ -101,11 +104,11 @@ var fronius = { 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 + 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 @@ -118,21 +121,22 @@ var fronius = { }, // Gets the site energy chart for today. Will be created if not existing. - getSiteEnergyTodayChart: function (service, chartId) { + getSiteEnergyTodayChart: function (service, suffix) { + var chartId = this.getChartId(service, suffix); 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 + 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); @@ -142,21 +146,22 @@ var fronius = { }, // Gets the site energy chart for today. Will be created if not existing. - getSiteEnergyYearChart: function (service, chartId) { + getSiteEnergyYearChart: function (service, suffix) { + var chartId = this.getChartId(service, suffix); 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 + 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); @@ -167,35 +172,28 @@ var fronius = { // 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) { - + getInverterPowerChart: function (service, suffix, inverters) { + var chartId = this.getChartId(service, suffix); 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); + for (var key in inverters) { + var name = key; + if (!isNaN(key)) name = "Inverter " + key; + dim[key] = this.createBasicDimension("inverter_" + key, name, 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 + 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 + update_every: service.update_every, // the expected update frequency of the chart dimensions: dim }; chart = service.chart(chartId, chart); @@ -205,59 +203,115 @@ var fronius = { }, processResponse: function (service, content) { - var json = fronius.parseResponse(content); + var json = fronius.convertToJson(content); if (json === null) return; // add the service service.commit(); + var chartDefinitions = fronius.parseCharts(service, json); + var chartCount = chartDefinitions.length; + while (chartCount--) { + var chartObj = chartDefinitions[chartCount]; + service.begin(chartObj.chart); + var dimCount = chartObj.dimensions.length; + while (dimCount--) { + var dim = chartObj.dimensions[dimCount]; + service.set(dim.name, dim.value); + } + service.end(); + } + }, + + parseCharts: function (service, json) { var site = json.Body.Data.Site; + return [ + this.parsePowerChart(service, site), + this.parseConsumptionChart(service, site), + this.parseAutonomyChart(service, site), + this.parseEnergyTodayChart(service, site), + this.parseEnergyYearChart(service, site), + this.parseInverterChart(service, json.Body.Data.Inverters) + ]; + }, + + parsePowerChart: function (service, site) { + return this.getChart(this.getSitePowerChart(service, "power"), + [ + this.getDimension(this.powerGridId, Math.round(site.P_Grid)), + this.getDimension(this.powerPvId, Math.round(Math.max(site.P_PV, 0))), + this.getDimension(this.powerAccuId, Math.round(site.P_Akku)) + ] + ); + }, + + parseConsumptionChart: function (service, site) { + return this.getChart(this.getSiteConsumptionChart(service, "consumption"), + [this.getDimension(this.consumptionLoadId, Math.round(Math.abs(site.P_Load)))] + ); + }, - // 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)); + parseAutonomyChart: function (service, site) { 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(); + return this.getChart(this.getSiteAutonomyChart(service, "autonomy"), + [ + this.getDimension(this.autonomyId, Math.round(site.rel_Autonomy)), + this.getDimension(this.consumptionSelfId, Math.round(selfConsumption === null ? 100 : selfConsumption)) + ] + ); + }, + + parseEnergyTodayChart: function (service, site) { + return this.getChart(this.getSiteEnergyTodayChart(service, "energy.today"), + [this.getDimension(this.energyTodayId, Math.round(Math.max(site.E_Day, 0)))] + ); + }, + + parseEnergyYearChart: function (service, site) { + return this.getChart(this.getSiteEnergyYearChart(service, "energy.year"), + [this.getDimension(this.energyYearId, Math.round(Math.max(site.E_Year, 0)))] + ); + }, + + parseInverterChart: function (service, inverters) { + var dimensions = []; + for (var key in inverters) { + dimensions.push(this.getDimension(key, Math.round(inverters[key].P))); } + return this.getChart(this.getInverterPowerChart(service, "inverters.output", inverters), dimensions); + }, + + getDimension: function (name, value) { + return { + name: name, + value: value + }; + }, + + getChart: function (chart, dimensions) { + return { + chart: chart, + dimensions: dimensions + }; + }, + + getChartId: function (service, suffix) { + return "fronius_" + service.name + "." + suffix; }, - parseResponse: function (httpBody) { + convertToJson: function (httpBody) { if (httpBody === null) return null; var json = httpBody; - if (typeof httpBody !== "object") json = JSON.parse(httpBody); + // can't parse if it's already a json object, + // the check enables easier testing if the httpBody is already valid JSON. + if (typeof httpBody !== "object") { + try { + json = JSON.parse(httpBody); + } catch (error) { + netdata.error("fronius: Got a response, but it is not valid JSON. Ignoring. Error: " + error.message); + return null; + } + } return this.isResponseValid(json) ? json : null; }, @@ -274,11 +328,11 @@ var fronius = { // 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); + netdata.debug(this.name + ": " + name + ": url: " + uri + ", update_every: " + update_every); var service = netdata.service({ name: name, - request: netdata.requestFromURL('http://' + uri), + request: netdata.requestFromURL("http://" + uri), update_every: update_every, module: this }); @@ -313,7 +367,7 @@ var fronius = { }, isUndefined: function (value) { - return typeof value === 'undefined'; + return typeof value === "undefined"; }, areUndefined: function (valueArray) { @@ -325,7 +379,7 @@ var fronius = { }, isDefined: function (value) { - return typeof value !== 'undefined'; + return typeof value !== "undefined"; } }; diff --git a/tests/node.d/fronius.chart.spec.js b/tests/node.d/fronius.chart.spec.js index c9c75f9c3c..c10bbe09a7 100644 --- a/tests/node.d/fronius.chart.spec.js +++ b/tests/node.d/fronius.chart.spec.js @@ -5,17 +5,23 @@ var netdata = require("../../node.d/node_modules/netdata"); var subject = require("../../node.d/fronius.node"); var service = netdata.service({ - name: "fronius", + name: "chart", module: this }); describe("fronius chart creation", function () { + var chartPrefix = "fronius_chart."; + beforeAll(function () { // change this to enable debug log netdata.options.DEBUG = false; }); + afterAll(function () { + deleteProperties(subject.charts) + }); + it("should return a basic chart dimension", function () { var result = subject.createBasicDimension("id", "name", 2); @@ -26,10 +32,10 @@ describe("fronius chart creation", function () { }); it("should return the power chart definition", function () { - var id = "power"; - var result = subject.getSitePowerChart(service, id); + var suffix = "power"; + var result = subject.getSitePowerChart(service, suffix); - expect(result.id).toBe(id); + expect(result.id).toBe(chartPrefix + suffix); expect(result.units).toBe("W"); expect(result.type).toBe(netdata.chartTypes.area); expect(result.family).toBe("power"); @@ -41,10 +47,10 @@ describe("fronius chart creation", function () { }); it("should return the consumption chart definition", function () { - var id = "Load"; - var result = subject.getSiteConsumptionChart(service, id); + var suffix = "Load"; + var result = subject.getSiteConsumptionChart(service, suffix); - expect(result.id).toBe(id); + expect(result.id).toBe(chartPrefix + suffix); expect(result.units).toBe("W"); expect(result.type).toBe(netdata.chartTypes.area); expect(result.family).toBe("consumption"); @@ -54,10 +60,10 @@ describe("fronius chart creation", function () { }); it("should return the autonomy chart definition", function () { - var id = "Autonomy"; - var result = subject.getSiteAutonomyChart(service, id); + var suffix = "Autonomy"; + var result = subject.getSiteAutonomyChart(service, suffix); - expect(result.id).toBe(id); + expect(result.id).toBe(chartPrefix + suffix); expect(result.units).toBe("%"); expect(result.type).toBe(netdata.chartTypes.area); expect(result.family).toBe("autonomy"); @@ -68,10 +74,10 @@ describe("fronius chart creation", function () { }); it("should return the energy today chart definition", function () { - var id = "Energy today"; - var result = subject.getSiteEnergyTodayChart(service, id); + var suffix = "Energy today"; + var result = subject.getSiteEnergyTodayChart(service, suffix); - expect(result.id).toBe(id); + expect(result.id).toBe(chartPrefix + suffix); expect(result.units).toBe("kWh"); expect(result.type).toBe(netdata.chartTypes.area); expect(result.family).toBe("energy"); @@ -81,10 +87,10 @@ describe("fronius chart creation", function () { }); it("should return the energy year chart definition", function () { - var id = "Energy year"; - var result = subject.getSiteEnergyYearChart(service, id); + var suffix = "Energy year"; + var result = subject.getSiteEnergyYearChart(service, suffix); - expect(result.id).toBe(id); + expect(result.id).toBe(chartPrefix + suffix); expect(result.units).toBe("kWh"); expect(result.type).toBe(netdata.chartTypes.area); expect(result.family).toBe("energy"); @@ -93,6 +99,59 @@ describe("fronius chart creation", function () { expect(result.dimensions[subject.energyYearId].name).toBe("Year"); }); + it("should return the inverter chart definition with a single numerical inverter", function () { + var inverters = { + "1": {} + }; + var suffix = "numerical"; + var result = subject.getInverterPowerChart(service, suffix, inverters); + + expect(result.id).toBe(chartPrefix + suffix); + expect(result.units).toBe("W"); + expect(result.type).toBe(netdata.chartTypes.stacked); + expect(result.family).toBe("inverters"); + expect(result.context).toBe("fronius.inverter.output"); + expect(Object.keys(result.dimensions).length).toBe(1); + expect(result.dimensions["1"].name).toBe("Inverter 1"); + }); + + it("should return the inverter chart definition with a single alphabetical inverter", function () { + var key = "Cellar"; + var inverters = { + "Cellar": {} + }; + var suffix = "alphabetical"; + var result = subject.getInverterPowerChart(service, suffix, inverters); + + expect(result.id).toBe(chartPrefix + suffix); + expect(result.units).toBe("W"); + expect(result.type).toBe(netdata.chartTypes.stacked); + expect(result.family).toBe("inverters"); + expect(result.context).toBe("fronius.inverter.output"); + expect(Object.keys(result.dimensions).length).toBe(1); + expect(result.dimensions[key].name).toBe(key); + }); + + it("should return the inverter chart definition with multiple alphanumerical inverter", function () { + var alpha = "Cellar"; + var numerical = 1; + var inverters = { + "Cellar": {}, + "1": {} + }; + var suffix = "alphanumerical"; + var result = subject.getInverterPowerChart(service, suffix, inverters); + + expect(result.id).toBe(chartPrefix + suffix); + expect(result.units).toBe("W"); + expect(result.type).toBe(netdata.chartTypes.stacked); + expect(result.family).toBe("inverters"); + expect(result.context).toBe("fronius.inverter.output"); + expect(Object.keys(result.dimensions).length).toBe(2); + expect(result.dimensions[alpha].name).toBe(alpha); + expect(result.dimensions[numerical].name).toBe("Inverter " + numerical); + }); + it("should return the same chart definition on second call for lazy loading", function () { var first = subject.getSitePowerChart(service, "id"); var second = subject.getSitePowerChart(service, "id"); diff --git a/tests/node.d/fronius.parse.spec.js b/tests/node.d/fronius.parse.spec.js index a6f1cee305..9c371ad98a 100644 --- a/tests/node.d/fronius.parse.spec.js +++ b/tests/node.d/fronius.parse.spec.js @@ -5,63 +5,301 @@ var netdata = require("../../node.d/node_modules/netdata"); var subject = require("../../node.d/fronius.node"); var service = netdata.service({ - name: "fronius", + name: "parse", module: this }); -describe("fronius data parsing", function () { - - var fakeResponse = { - "Head" : { - "RequestArguments" : {}, - "Status" : { - "Code" : 0, - "Reason" : "", - "UserMessage" : "" - }, - "Timestamp" : "2017-07-17T16:01:04+02:00" - }, - "Body" : { - "Data" : { - "Site" : { - "Mode" : "meter", - "P_Grid" : -3430.729923, - "P_Load" : -910.270077, - "P_Akku" : null, - "P_PV" : 4341, - "rel_SelfConsumption" : 20.969133, - "rel_Autonomy" : 100, - "E_Day" : 57230, - "E_Year" : 6425915.5, - "E_Total" : 15388710, - "Meter_Location" : "grid" - }, - "Inverters" : { - "1" : { - "DT" : 123, - "P" : 4341, - "E_Day" : 57230, - "E_Year" : 6425915.5, - "E_Total" : 15388710 - } - } - } +var root = { + "Body": { + "Data": { + "Site": {}, + "Inverters": {} } - }; + } +}; - beforeAll(function () { - // change this to enable debug log - netdata.options.DEBUG = false; +describe("fronius parsing for power chart", function () { + + var site = root.Body.Data.Site; + + afterEach(function () { + deleteProperties(site); + }); + + it("should return 3000 for P_Grid when rounded", function () { + site.P_Grid = 2999.501; + var result = subject.parsePowerChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.powerGridId); + expect(result.value).toBe(3000); + }); + + it("should return -3000 for P_Grid", function () { + site.P_Grid = -3000; + var result = subject.parsePowerChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.powerGridId); + expect(result.value).toBe(-3000); + }); + + it("should return 0 for P_Grid if it is null", function () { + site.P_Grid = null; + var result = subject.parsePowerChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.powerGridId); + expect(result.value).toBe(0); + }); + + it("should return 0 for P_Grid if it is zero", function () { + site.P_Grid = 0; + var result = subject.parsePowerChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.powerGridId); + expect(result.value).toBe(0); + }); + + it("should return -100 for P_Akku", function () { + // it is unclear whether negative values are possible for p_akku (couln't test, nor any API docs found). + site.P_Akku = -100; + var result = subject.parsePowerChart(service, site).dimensions[2]; + + expect(result.name).toBe(subject.powerAccuId); + expect(result.value).toBe(-100); + }); + + it("should return 0 for P_Akku if it is null", function () { + site.P_Akku = null; + var result = subject.parsePowerChart(service, site).dimensions[2]; + + expect(result.name).toBe(subject.powerAccuId); + expect(result.value).toBe(0); + }); + + it("should return 0 for P_Akku if it is zero", function () { + site.P_Akku = 0; + var result = subject.parsePowerChart(service, site).dimensions[2]; + + expect(result.name).toBe(subject.powerAccuId); + expect(result.value).toBe(0); + }); + + it("should return 100 for P_PV", function () { + site.P_PV = 100; + var result = subject.parsePowerChart(service, site).dimensions[1]; + + expect(result.name).toBe(subject.powerPvId); + expect(result.value).toBe(100); + }); + + it("should return 0 for P_PV if it is zero", function () { + site.P_PV = 0; + var result = subject.parsePowerChart(service, site).dimensions[1]; + + expect(result.name).toBe(subject.powerPvId); + expect(result.value).toBe(0); + }); + + it("should return 0 for P_PV if it is null", function () { + site.P_PV = null; + var result = subject.parsePowerChart(service, site).dimensions[1]; + + expect(result.name).toBe(subject.powerPvId); + expect(result.value).toBe(0); + }); + + it("should return 0 for P_PV if it is negative", function () { + // solar panels shouldn't consume anything, only produce. + site.P_PV = -1; + var result = subject.parsePowerChart(service, site).dimensions[1]; + + expect(result.name).toBe(subject.powerPvId); + expect(result.value).toBe(0); + }); + +}); + +describe("fronius parsing for consumption", function () { + + var site = root.Body.Data.Site; + + afterEach(function () { + deleteProperties(site); + }); + + it("should return 1000 for P_Load when rounded", function () { + site.P_Load = 1000.499; + var result = subject.parseConsumptionChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.consumptionLoadId); + expect(result.value).toBe(1000); + }); + + it("should return absolute value for P_Load when negative", function () { + /* + with firmware 3.7.4 it is sometimes possible that negative values are returned for P_Load, + which makes absolutely no sense. There is always a device that consumes some electricity around the clock. + Best we can do is to make it a positive value, since 0 also doesn't make much sense. + This "workaround" seems to work, as there couldn't be any strange peaks observed during long-time testing. + */ + site.P_Load = -50; + var result = subject.parseConsumptionChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.consumptionLoadId); + expect(result.value).toBe(50); + }); + + it("should return 0 for P_Load if it is null", function () { + site.P_Load = null; + var result = subject.parseConsumptionChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.consumptionLoadId); + expect(result.value).toBe(0); + }); + + it("should return 0 for P_Load if it is zero", function () { + site.P_Load = 0; + var result = subject.parseConsumptionChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.consumptionLoadId); + expect(result.value).toBe(0); + }); + +}); + +describe("fronius parsing for autonomy", function () { + + var site = root.Body.Data.Site; + + afterEach(function () { + deleteProperties(site); + }); + + it("should return 100 for rel_Autonomy", function () { + site.rel_Autonomy = 100; + var result = subject.parseAutonomyChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.autonomyId); + expect(result.value).toBe(100); + }); + + it("should return 0 for rel_Autonomy if it is zero", function () { + site.rel_Autonomy = 0; + var result = subject.parseAutonomyChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.autonomyId); + expect(result.value).toBe(0); }); - it("should return a parsed value", function () { - // arrange - netdata.send = jasmine.createSpy("send"); - // act - subject.processResponse(service, fakeResponse); - var result = netdata.send.calls.argsFor(0)[0]; - // assert - expect(result).toContain("SET p_grid = -3431"); + it("should return 0 for rel_Autonomy if it is null", function () { + site.rel_Autonomy = null; + var result = subject.parseAutonomyChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.autonomyId); + expect(result.value).toBe(0); }); + it("should return 20 for rel_Autonomy if it is 20", function () { + site.rel_Autonomy = 20.1; + var result = subject.parseAutonomyChart(service, site).dimensions[0]; + + expect(result.name).toBe(subject.autonomyId); + expect(result.value).toBe(20); + }); + + it("should return 20 for rel_SelfConsumption if it is 19.5", function () { |