Skip to content

Instantly share code, notes, and snippets.

@mrizvic
Last active October 23, 2022 18:00
Show Gist options
  • Save mrizvic/f8c6b1db1bd815d49d76657cf6977e4a to your computer and use it in GitHub Desktop.
Save mrizvic/f8c6b1db1bd815d49d76657cf6977e4a to your computer and use it in GitHub Desktop.
Function for node-red which determines properties like holiday, business day, weekend, etc at the moment when incoming message is received. It contains Slovenian conditions to determine those properties.
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* github.com/mrizvic wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. M.Rizvic
* ----------------------------------------------------------------------------
## This function will pass incoming message to multiple outputs based on following conditions:
## output 1 - unconditional
## output 2 - if its holiday
## output 3 - if its business day
## output 4 - if its weeekend
## output 5 - if its leap year
## output 6 - if its high tariff time regarding energy consumption
## output 7 - if its low tariff time regarding energy consumption
## Holidays are defined in a matter of if..else if sentences as shown below in USER SPECIFIC DATES section. Some holidays are variable and must be calculated each time (e.g. easter)
## Some properties will be appended to original message in case some would like to use them. Below is an example:
_msgid: "78a5e9f0.a318e8"
topic: ""
payload: "power on"
date: "2017-02-23T15:59:59.401Z"
tariff: "vt"
holiday: false
businessday: true
weekend: false
weekday: 4
leapyear: false
properties: "tariff=vt,holiday=false,businessday=true,weekend=false,weekday=4,leapyear=false"
weekday numbers are in range from 1 to 7 where is 1 for monday, 2 for tuesday, ... and 7 for sunday
tariff can be 'vt' (high tariff) or 'mt' (low tariff)
*/
// take current timestamp
var date = new Date();
var getEasterDate = function(year) {
var a = year % 19;
var b = Math.floor(year / 100);
var c = year % 100;
var d = Math.floor(b / 4);
var e = b % 4;
var f = Math.floor((b + 8) / 25);
var g = Math.floor((b - f + 1) / 3);
var h = (19 * a + b - d - g + 15) % 30;
var i = Math.floor(c / 4);
var k = c % 4;
var l = (32 + 2 * e + 2 * i - h - k) % 7;
var m = Math.floor((a + 11 * h + 22 * l) / 451);
var n0 = (h + l + 7 * m + 114);
var n = Math.floor(n0 / 31) - 1;
var p = n0 % 31 + 1;
var date = new Date(year,n,p);
return date;
};
Date.prototype.addDays = function(days)
{
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
};
var weekday = date.getDay();
if (weekday === 0) { weekday = 7; }
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
var hour = date.getHours();
var isHoliday = false;
var holidayString = "";
var isLeapYear = new Date(year, 1, 29).getMonth() == 1;
// sunday or saturday
var isWeekend = (weekday > 5);
var isBusinessDay = ! isWeekend;
// USER SPECIFIC DATES - BEGIN
// calculate some variable holiday dates
// EASTER SUNDAY
var easterDate = getEasterDate(year);
var ed1 = easterDate.getDate();
var em1 = easterDate.getMonth() + 1;
// EASTER MONDAY
var easterMonday = easterDate.addDays(1);
var ed2 = easterMonday.getDate();
var em2 = easterMonday.getMonth() + 1;
// BINKOSTNA NEDELJA = (EASTER SUNDAY + 49) - 50 DAN PO VELIKI NOCI
var binkost1 = easterDate.addDays(49);
var bd1 = binkost1.getDate();
var bm1 = binkost1.getMonth() + 1;
// BINKOSTNI PONEDELJEK
var binkost2 = easterDate.addDays(50);
var bd2 = binkost2.getDate();
var bm2 = binkost2.getMonth() + 1;
// PUSTNA NEDELJA IN PUSTNI TOREK
var pn = easterDate.addDays(-49);
var pnd = pn.getDate();
var pnm = pn.getMonth() + 1;
var pt = easterDate.addDays(-47);
var ptd = pt.getDate();
var ptm = pt.getMonth() + 1;
// set date specific properties
if ( (month == 1) && (day == 1) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Novo leto"; }
else if ( (month == 1) && (day == 2) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Novo leto"; }
else if ( (month == 2) && (day == 8) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Prešernov dan"; }
else if ( (month == pnm) && (day == pnd) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Pustna nedelja"; }
else if ( (month == ptm) && (day == ptd) ) { isHoliday = true; isBusinessDay = isBusinessDay && true; holidayString = "Pustni torek"; }
else if ( (month == em1) && (day == ed1) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Velika noč"; }
else if ( (month == em2) && (day == ed2) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Velikončni ponedeljek"; }
else if ( (month == 4) && (day == 27) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Dan boja proti okupatorju"; }
else if ( (month == 5) && (day == 1) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Praznik dela"; }
else if ( (month == 5) && (day == 2) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Praznik dela"; }
else if ( (month == bm1) && (day == bd1) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Binkoštna nedelja"; }
else if ( (month == bm2) && (day == bd2) ) { isHoliday = true; isBusinessDay = isBusinessDay && true; holidayString = "Binkoštni ponedeljek"; }
else if ( (month == 6) && (day == 8) ) { isHoliday = true; isBusinessDay = isBusinessDay && true; holidayString = "Dan Primoža Trubarja";}
else if ( (month == 6) && (day == 25) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Dan državnosti"; }
else if ( (month == 8) && (day == 15) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Marijino vnebovzetje"; }
else if ( (month == 8) && (day == 17) ) { isHoliday = true; isBusinessDay = isBusinessDay && true; holidayString = "Združitev prekmurskih Slovencev z matičnim narodom";}
else if ( (month == 9) && (day == 15) ) { isHoliday = true; isBusinessDay = isBusinessDay && true; holidayString = "Vrnitev Primorske k matični domovini";}
else if ( (month == 10) && (day == 25) ) { isHoliday = true; isBusinessDay = isBusinessDay && true; holidayString = "Dan suverenosti"; }
else if ( (month == 10) && (day == 31) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Dan reformacije"; }
else if ( (month == 11) && (day == 1) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Dan spomina na mrtve"; }
else if ( (month == 11) && (day == 23) ) { isHoliday = true; isBusinessDay = isBusinessDay && true; holidayString = "Dan Rudolfa Maistra"; }
else if ( (month == 12) && (day == 25) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Božič"; }
else if ( (month == 12) && (day == 26) ) { isHoliday = true; isBusinessDay = isBusinessDay && false; holidayString = "Dan samostojnosti in enotnosti"; }
// USER SPECIFIC DATES - END
// determine energy consumption tariff
// low tariff if not business day or between 22:00 and 06:00
var mt = ! isBusinessDay || (hour >= 22) || (hour < 6);
var vt = ! mt;
var tariff = mt ? "mt" : "vt";
// preserve original message
var result = msg;
msg.date = date;
// add our properties
result.tariff = tariff;
result.holiday = isHoliday;
result.businessday = isBusinessDay;
result.weekend = isWeekend;
result.weekday = weekday;
result.leapyear = isLeapYear;
if (holidayString.length > 0) {
result.holiday_name = holidayString;
}
// generate string of properties so one could
// parse using switch node
result.properties = '';
result.properties += 'tariff=' + tariff + ',';
result.properties += 'holiday=' + isHoliday + ',';
result.properties += 'businessday=' + isBusinessDay + ',';
result.properties += 'weekend=' + isWeekend + ',';
result.properties += 'weekday=' + weekday + ',';
result.properties += 'leapyear=' + isLeapYear;
// generate conditional outputs
msg1 = result;
msg2 = isHoliday ? result : null;
msg3 = isBusinessDay ? result : null;
msg4 = isWeekend ? result : null;
msg5 = isLeapYear ? result : null;
msg6 = vt ? result : null;
msg7 = mt ? result : null;
return [ msg1, msg2, msg3, msg4, msg5, msg6, msg7 ];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment