-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcircadian.js
131 lines (111 loc) · 3.42 KB
/
circadian.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
module.exports = function(RED) {
"use strict";
var suncalc = require('suncalc');
function circadianLocation(n) {
RED.nodes.createNode(this,n);
this.name = n.name;
this.lat = n.lat;
this.lon = n.lon;
this.period = n.period;
var node = this;
function getPercent() {
const date = new Date()
const now = date.getTime();
const day = 24*60*60*1000;
const today = suncalc.getTimes(now, node.lat, node.lon);
const today_sunrise = Date.parse(today.sunrise);
const today_sunset = Date.parse(today.sunset);
const today_noon = Date.parse(today.solarNoon);
const today_midnight = Date.parse(today.nadir);
var x1, y1, x2, y2, x3, y3;
if (now < today_sunrise) {
const yesterday = suncalc.getTimes(new Date().setDate(date.getDate() - 1), node.lat, node.lon);
const yesterday_sunrise = Date.parse(yesterday.sunrise);
const yesterday_sunset = Date.parse(yesterday.sunset);
const yesterday_midnight = Date.parse(yesterday.nadir);
x1 = yesterday_sunset
y1 = 0
x2 = (today_midnight > yesterday_sunset && today_midnight < today_sunrise) ? today_midnight : yesterday_midnight
y2 = -100
x3 = today_sunrise
y3 = 0
} else if (now > today_sunset) {
const tomorrow = suncalc.getTimes(new Date().setDate(date.getDate() + 1), node.lat, node.lon);
const tomorrow_sunrise = Date.parse(tomorrow.sunrise);
const tomorrow_sunset = Date.parse(tomorrow.sunset);
const tomorrow_midnight = Date.parse(tomorrow.nadir);
x1 = today_sunset
y1 = 0
x2 = (today_midnight > today_sunset && today_midnight < tomorrow_sunrise) ? today_midnight : tomorrow_midnight
y2 = -100
x3 = tomorrow_sunrise
y3 = 0
} else {
x1 = today_sunrise
y1 = 0
x2 = today_noon
y2 = 100
x3 = today_sunset
y3 = 0
}
const a1 = -Math.pow(x1,2) + Math.pow(x2,2)
const b1 = -x1 + x2
const d1 = -y1 + y2
const a2 = -Math.pow(x2,2) + Math.pow(x3,2)
const b2 = -x2 + x3
const d2 = -y2 + y3
const bm = -(b2 / b1)
const a3 = bm * a1 + a2
const d3 = bm * d1 + d2
const a = d3 / a3
const b = (d1 - a1 * a) / b1
const c = y1 - a * Math.pow(x1,2) - b * x1
node.percent = a * Math.pow(now,2) + b * now + c
};
this.interval = setInterval(getPercent,(node.period * 60 * 1000));
getPercent();
node.on('close', function() {
clearInterval(this.interval);
});
}
RED.nodes.registerType("location", circadianLocation);
function circadianLight(n) {
RED.nodes.createNode(this,n);
this.location = RED.nodes.getNode(n.location)
this.minbr = n.minbr;
this.maxbr = n.maxbr;
this.minct = n.minct;
this.maxct = n.maxct;
this.name = n.name;
this.topic = n.topic;
var node = this;
function calcColourTemp() {
const percent = node.location.percent
var ct, bright;
if (percent > 0) {
const delta = parseFloat(node.maxct - node.minct);
const per = percent / 100;
ct = parseInt(delta * per, 10) + node.minct;
bright = node.maxbr;
} else {
ct = node.minct
const delta = parseFloat(node.maxbr - node.minbr);
const per = percent / 100 + 1;
bright = parseInt(delta * per, 10) + node.minbr;
}
node.send({
topic: node.topic,
payload: {
percent: percent | 0,
ct: ct | 0,
bright: bright | 0
}
});
};
calcColourTemp();
node.on('input', function() {
calcColourTemp();
});
};
RED.nodes.registerType("lighting", circadianLight);
}