UNPKG

node-red-contrib-power-saver

Version:

A module for Node-RED that you can use to turn on and off a switch based on power prices

213 lines (205 loc) 7.04 kB
const cloneDeep = require("lodash.clonedeep"); const { DateTime } = require("luxon"); const expect = require("chai").expect; const { booleanConfig, sortedIndex, firstOn, getDiffToNextOn, getSavings, countAtEnd, makeSchedule, makeScheduleFromHours, fillArray, extractPlanForDate, isSameDate, } = require("../src/utils"); const testResult = require("./data/best-save-result.json"); describe("utils", () => { it("can test boolean config", () => { expect(booleanConfig(true)).to.equal(true); expect(booleanConfig(false)).to.equal(false); expect(booleanConfig("true")).to.equal(true); expect(booleanConfig("false")).to.equal(false); expect(booleanConfig(undefined)).to.equal(false); }); it("can sortedIndex", () => { expect(sortedIndex([3, 1, 2, 4])).to.eql([3, 0, 2, 1]); }); it("returns the first on", () => { expect(firstOn([1, 2, 3], [false, false, false], 0)).to.equal(0); expect(firstOn([1, 2, 3], [true, false, false], 0)).to.equal(1); expect(firstOn([1, 2, 3], [false, true, false], 0)).to.equal(2); expect(firstOn([1, 2, 3], [false, false, true], 0)).to.equal(3); expect(firstOn([1, 2, 3], [true, true, true], 0)).to.equal(1); expect(firstOn([], [], 0)).to.equal(0); }); it("can getDiffToNextOn", () => { const values = [100, 200, 30]; expect(getDiffToNextOn(values, [false, false, false], 50)).to.eql([50, 150, -20]); expect(getDiffToNextOn(values, [false, false, true], 50)).to.eql([70, 170, -20]); expect(getDiffToNextOn(values, [false, true, false], 50)).to.eql([-100, 150, -20]); expect(getDiffToNextOn(values, [true, false, true], 50)).to.eql([70, 170, -20]); expect(getDiffToNextOn(values, [true, true, false], 50)).to.eql([-100, 150, -20]); expect(getDiffToNextOn(values, [true, true, false])).to.eql([-100, 170, 0]); }); it("calculates savings for hours off", () => { const values = [1, 10, 8, 5]; expect(getSavings(values, [true, true, true, true], 99)).to.eql([null, null, null, null]); expect(getSavings(values, [false, false, false, false], 99)).to.eql([-98, -89, -91, -94]); expect(getSavings(values, [false, true, false, true], 99)).to.eql([-9, null, 3, null]); }); it("can count at end of array", () => { expect(countAtEnd([], true)).to.equal(0); expect(countAtEnd([true], true)).to.equal(1); expect(countAtEnd([false], true)).to.equal(0); expect(countAtEnd([true], false)).to.equal(0); expect(countAtEnd([true, true], false)).to.equal(0); expect(countAtEnd([true, false], false)).to.equal(1); expect(countAtEnd([false, true], false)).to.equal(0); expect(countAtEnd([false, true], undefined)).to.equal(0); expect(countAtEnd([true, false], undefined)).to.equal(0); }); it("can make schedule", () => { const onOff = [false, false, true, true, false]; const startTimes = [ "2021-06-20T05:00:00+02:00", "2021-06-20T06:00:00+02:00", "2021-06-20T07:00:00+02:00", "2021-06-20T08:00:00+02:00", "2021-06-20T09:00:00+02:00", ]; expect(makeSchedule(onOff, startTimes)).to.eql([ { time: "2021-06-20T05:00:00+02:00", value: false, countHours: 2 }, { time: "2021-06-20T07:00:00+02:00", value: true, countHours: 2 }, { time: "2021-06-20T09:00:00+02:00", value: false, countHours: 1 }, ]); expect(makeSchedule(onOff, startTimes, true)).to.eql([ { time: "2021-06-20T05:00:00+02:00", value: false, countHours: 2 }, { time: "2021-06-20T07:00:00+02:00", value: true, countHours: 2 }, { time: "2021-06-20T09:00:00+02:00", value: false, countHours: 1 }, ]); expect(makeSchedule(onOff, startTimes, false)).to.eql([ { time: "2021-06-20T05:00:00+02:00", value: false, countHours: 2 }, // Right??? { time: "2021-06-20T07:00:00+02:00", value: true, countHours: 2 }, { time: "2021-06-20T09:00:00+02:00", value: false, countHours: 1 }, ]); }); it("can fill an array", () => { expect(fillArray(false, 0)).to.eql([]); expect(fillArray(false, 2)).to.eql([false, false]); expect(fillArray(true, 2)).to.eql([true, true]); expect(fillArray(undefined, 2)).to.eql([]); expect(fillArray(true, 0)).to.eql([]); }); it("can compare dates", () => { const date1 = "2021-06-20T01:50:00.000+02:00"; expect(isSameDate(date1, "2021-06-20T01:50:00.000+02:00")).to.equal(true); expect(isSameDate(date1, "2021-06-21T01:50:00.000+02:00")).to.equal(false); expect(isSameDate(date1, "2021-06-20")).to.equal(true); expect(isSameDate(date1, "2021-06-21")).to.equal(false); }); it("can extract plan for a date", () => { const plan = { hours: [ { price: 0.3, onOff: true, start: "2021-06-20T01:50:00.000+02:00", saving: 1, }, { price: 0.4, onOff: false, start: "2021-06-20T01:50:00.010+02:00", saving: 2, }, { price: 0.2, onOff: false, start: "2021-06-21T01:50:00.180+02:00", saving: 3, }, { price: 0.85, onOff: true, start: "2021-06-21T01:50:00.190+02:00", saving: null, }, ], schedule: [ { time: "2021-06-20T01:50:00.000+02:00", value: true, }, { time: "2021-06-21T01:50:00.020+02:00", value: false, }, { time: "2021-06-21T01:50:00.040+02:00", value: false, }, ], }; const part1 = { hours: [ { price: 0.3, onOff: true, start: "2021-06-20T01:50:00.000+02:00", saving: 1, }, { price: 0.4, onOff: false, start: "2021-06-20T01:50:00.010+02:00", saving: 2, }, ], schedule: [ { time: "2021-06-20T01:50:00.000+02:00", value: true, }, ], }; const part2 = { hours: [ { price: 0.2, onOff: false, start: "2021-06-21T01:50:00.180+02:00", saving: 3, }, { price: 0.85, onOff: true, start: "2021-06-21T01:50:00.190+02:00", saving: null, }, ], schedule: [ { time: "2021-06-21T01:50:00.020+02:00", value: false, }, { time: "2021-06-21T01:50:00.040+02:00", value: false, }, ], }; expect(extractPlanForDate(plan, "2021-06-20T01:50:00.000+02:00")).to.eql(part1); }); it("Can make schedule from hours", () => { const hours = cloneDeep(testResult.hours); const schedule = makeScheduleFromHours(hours, null); const resultToValidate = schedule.map((s) => ({ time: s.time, value: s.value })); resultToValidate.push({ time: "2021-06-20T02:50:00.470+02:00", value: false, }); expect(resultToValidate).to.eql(testResult.schedule); }); });