UNPKG

@tbowmo/node-red-small-timer

Version:

Small timer node for Node-RED with support for sunrise, sunset etc. timers

122 lines (121 loc) 4.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TimeCalc = void 0; const sun_and_moon_1 = require("./sun-and-moon"); const utils_1 = require("./utils"); const wholeDay = 1440; class TimeCalc extends sun_and_moon_1.SunAndMoon { constructor(latitude, longitude, wrapMidnight, startTime, endTime, startOffset, endOffset, minimumOnTime) { super(latitude, longitude); this.wrapMidnight = wrapMidnight; this.startTime = startTime; this.endTime = endTime; this.startOffset = startOffset; this.endOffset = endOffset; this.minimumOnTime = minimumOnTime; this.actualStart = 0; this.actualEnd = 0; this.lastRecalcTime = -1; this.eventCalculation(); } convertDateToTime(times) { return Object.fromEntries(Object.values(this.sunLookup) .map((key) => { if (times && (key in times)) { const t = times[key]; return t === undefined ? undefined : [key, this.getTime(t)]; } }) .filter(utils_1.isNotUndefinedOrNull)); } debug() { const sunTimes = this.convertDateToTime(this.sunTimes); const moonTimes = this.convertDateToTime(this.moonTimes); return { sunTimes, moonTimes, now: this.getTime(new Date()), actualStart: this.actualStart, actualEnd: this.actualEnd, nextStart: this.getTimeToNextStartEvent(), nextEnd: this.getTimeToNextEndEvent(), onState: this.getOnState(), operationToday: this.operationToday(), }; } setStartEndTime(startTime = this.startTime, endTime = this.endTime, startOffset = this.startOffset, endOffset = this.endOffset) { const changedProp = !(startTime === this.startTime && endTime === this.endTime && startOffset === this.startOffset && endOffset === this.endOffset); this.startTime = startTime; this.endTime = endTime; this.startOffset = startOffset; this.endOffset = endOffset; this.eventCalculation(changedProp); } getTimeToNextStartEvent(date = new Date()) { const currentTime = this.getTime(date); const nextEvent = this.actualStart - currentTime; return nextEvent >= 0 ? nextEvent : (nextEvent + wholeDay); } getTimeToNextEndEvent(date = new Date()) { const currentTime = this.getTime(date); const nextEvent = this.actualEnd - currentTime; return nextEvent >= 0 ? nextEvent : (nextEvent + wholeDay); } onTime() { const onTime = this.actualEnd - this.actualStart; if (this.wrapMidnight && onTime < 0) { return onTime + wholeDay; } return onTime; } getOnState(date = new Date()) { const currentTime = this.getTime(date); this.eventCalculation(false, date); if (this.onTime() < this.minimumOnTime) { return false; } if (this.actualEnd < this.actualStart) { return this.wrapMidnight && ((currentTime < this.actualEnd) || (currentTime > this.actualStart)); } return (currentTime > this.actualStart) && (currentTime < this.actualEnd); } operationToday() { const onTime = this.onTime(); if (onTime >= 0 && onTime < this.minimumOnTime) { return 'minimumOnTimeNotMet'; } return !this.wrapMidnight && (this.actualEnd < this.actualStart) ? 'noMidnightWrap' : 'normal'; } eventCalculation(forceUpdate = false, now = new Date()) { this.updateSunCalc(now); if (!forceUpdate && this.lastRecalcTime === now.getDate()) { return; } this.lastRecalcTime = now.getDate(); this.actualStart = this.lookupEventTime(this.startTime) + this.startOffset; this.actualEnd = this.lookupEventTime(this.endTime, this.actualStart) + this.endOffset; } getTime(date) { return date.getHours() * 60 + date.getMinutes(); } lookupEventTime(time, startTime = 0) { if (time <= wholeDay) { return time; } if (this.latitude === undefined && this.longitude === undefined) { throw new Error('Something went wrong, latitude and longitude not specified'); } if (time > 10000) { return (startTime + (time - 10000)) % wholeDay; } const lookedUptime = this.getSunOrMoonTime(time); if (!lookedUptime) { throw new Error(`Can't look up the correct time '${time}' '${startTime}'`); } return this.getTime(lookedUptime); } } exports.TimeCalc = TimeCalc;