Skip to content

Instantly share code, notes, and snippets.

@prohazko2
Last active November 9, 2021 14:52
Show Gist options
  • Save prohazko2/16e36d200e8fd458fe649d4a95a4855d to your computer and use it in GitHub Desktop.
Save prohazko2/16e36d200e8fd458fe649d4a95a4855d to your computer and use it in GitHub Desktop.
const DAY_START = [0, 0, 0, 0];
const DAY_END = [23, 59, 59, 999];
const TZ_OFFSET = 3 * 60 * 60 * 1000;
const INIT_WITH = 230;
const TICK_VALUE = 10;
function startOfMinute(date) {
date = new Date(date || Date.now());
date.setSeconds(0);
return date;
}
function startOfHour(date) {
const start = DAY_START.concat([]);
date = new Date(date || Date.now());
start[0] = date.getHours();
date.setHours(...start);
return date;
}
function startOfDay(date) {
date = new Date(date || Date.now());
date.setHours(...DAY_START);
return date;
}
function startOfMonth(date) {
date = new Date(date || Date.now());
date = new Date(date.getFullYear(), date.getMonth(), 1);
return startOfDay(date);
}
function endOfMinute(date) {
date = new Date(date || Date.now());
date.setSeconds(59, 999);
return date;
}
function endOfHour(date) {
const end = DAY_END.concat([]);
date = new Date(date || Date.now());
end[0] = date.getHours();
date.setHours(...end);
return date;
}
function endOfDay(date) {
date = new Date(date || Date.now());
date.setHours(...DAY_END);
return date;
}
function endOfMonth(date) {
date = new Date(date || Date.now());
date = new Date(date.getFullYear(), date.getMonth() + 1, 0);
return endOfDay(date);
}
class Period {
constructor(name, base = new Date(), baseValue = 0, currentValue = 0) {
this.name = name;
this.baseDate = new Date(+base);
const { from, to } = this.at(this.baseDate);
this.from = new Date(from);
this.to = new Date(to);
this.baseValue = baseValue;
this.currentValue = baseValue || currentValue;
}
at(date = new Date()) {
switch (this.name) {
case "month":
return {
from: new Date(startOfMonth(date) - TZ_OFFSET),
to: new Date(endOfMonth(date) - TZ_OFFSET),
};
case "day":
return {
from: new Date(startOfDay(date) - TZ_OFFSET),
to: new Date(endOfDay(date) - TZ_OFFSET),
};
case "hour":
return {
from: startOfHour(+date),
to: endOfHour(+date),
};
case "minute":
return {
from: startOfMinute(+date),
to: endOfMinute(+date),
};
}
}
contains(date) {
date = new Date(date || Date.now());
return +this.from <= +date && +date <= +this.to;
}
get value() {
return this.currentValue - this.baseValue;
}
toJSON() {
return {
name: this.name,
baseDate: +this.baseDate,
baseValue: this.baseValue,
currentValue: this.currentValue,
value: this.value,
from: +this.from,
to: +this.to,
};
}
}
const PERIODS = [
new Period("month"),
new Period("day"),
new Period("hour"),
new Period("minute"),
];
function process(tick) {
if (!tick) {
return {};
}
const stored = ric.localStore.forObject.get() || {};
if (!stored.counter) {
stored.counter = INIT_WITH;
}
stored.counter += 1;
stored.value = stored.counter * TICK_VALUE;
const now = new Date();
for (const p of PERIODS) {
const current = new Period(p.name, now, stored.value);
let prev = current;
if (stored[p.name]) {
prev = new Period(
stored[p.name].name,
stored[p.name].baseDate,
stored[p.name].baseValue,
stored[p.name].currentValue
);
if (prev.contains(now)) {
current.baseValue = prev.baseValue;
}
}
stored[p.name] = current;
}
ric.localStore.forObject.set(stored);
return {
counter: stored.counter,
value: stored.value,
month: stored.month,
day: stored.day,
hour: stored.hour,
minute: stored.minute,
};
}
{
"id": "root",
"name": "m-01",
"base": "mqtt",
"active": true,
"type": "subsystem",
"children": [
{
"id": "external-software-modules",
"active": true,
"copy": true,
"type": "subsystem",
"children": []
},
{
"id": "params",
"name": "Params",
"active": true,
"type": "subsystem",
"children": [
{
"id": "server-info",
"name": "Server information",
"active": true,
"type": "subsystem",
"children": [
{
"id": "online",
"name": "Online",
"active": true,
"type": "argument",
"dataType": "boolean",
"reference": "online"
},
{
"id": "_ts",
"name": "Time",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "duration-microsecond",
"reference": "_ts"
}
]
},
{
"id": "_counter",
"name": "i18n:object_current_state",
"active": true,
"type": "subsystem",
"children": [
{
"id": "tick",
"name": "tick",
"active": true,
"type": "argument",
"dataType": "number",
"linear": true,
"reference": "tick"
},
{
"id": "counter",
"name": "counter",
"active": true,
"type": "argument",
"dataType": "number",
"linear": true
},
{
"id": "value",
"name": "value",
"active": true,
"type": "argument",
"dataType": "number",
"linear": true,
"unit": "volume-liter"
}
]
},
{
"id": "_month",
"name": "i18n:month",
"active": true,
"type": "subsystem",
"children": [
{
"id": "month.from",
"name": "i18n:begin",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "duration-millisecond"
},
{
"id": "month.to",
"name": "i18n:end",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "duration-millisecond",
"children": []
},
{
"id": "month.value",
"name": "i18n:now",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "volume-liter"
}
]
},
{
"id": "_day",
"name": "i18n:day",
"active": true,
"type": "subsystem",
"children": [
{
"id": "day.from",
"name": "i18n:begin",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "duration-millisecond"
},
{
"id": "day.to",
"name": "i18n:end",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "duration-millisecond"
},
{
"id": "day.value",
"name": "i18n:now",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "volume-liter"
}
]
},
{
"id": "_hour",
"name": "i18n:hour",
"active": true,
"type": "subsystem",
"children": [
{
"id": "hour.from",
"name": "i18n:begin",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "duration-millisecond"
},
{
"id": "hour.to",
"name": "i18n:end",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "duration-millisecond"
},
{
"id": "hour.value",
"name": "i18n:now",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "volume-liter"
}
]
},
{
"id": "_minute",
"name": "i18n:minute",
"active": true,
"type": "subsystem",
"children": [
{
"id": "minute.from",
"name": "i18n:begin",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "duration-millisecond"
},
{
"id": "minute.to",
"name": "i18n:end",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "duration-millisecond"
},
{
"id": "minute.value",
"name": "i18n:now",
"active": true,
"type": "argument",
"dataType": "number",
"unit": "volume-liter"
}
]
},
{
"id": "mqtt-last",
"name": "Last MQTT Publish",
"active": true,
"type": "subsystem",
"children": [
{
"id": "topic",
"name": "Topic",
"active": true,
"type": "argument",
"source": "state",
"dataType": "string",
"reference": "topic"
},
{
"id": "payload",
"name": "Payload",
"active": true,
"type": "argument",
"source": "state",
"dataType": "string",
"reference": "payload"
}
]
}
]
}
]
}
@prohazko2
Copy link
Author

Screenshot from 2021-11-09 15-31-56

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment