node-red-contrib-eskomsepush 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -34
- package/img/eskomsepush-configuration.png +0 -0
- package/img/eskomsepush-flow.png +0 -0
- package/package.json +1 -1
- package/src/nodes/eskomsepush.html +46 -41
- package/src/nodes/eskomsepush.js +31 -17
- package/test/three-anchor-bay.js +26 -0
package/README.md
CHANGED
|
@@ -53,6 +53,18 @@ Then you need to fill out which status to follow. This can be either _National_
|
|
|
53
53
|
|
|
54
54
|
If the _test_ checkbox has been selected, test data for the specified area will be fetched instead of the actual schedule. This is useful when debugging.
|
|
55
55
|
|
|
56
|
+
### Inputs
|
|
57
|
+
|
|
58
|
+
The input side is not needed in most cases. The node will output its status every ten minutes and won't update the information it gets from the API more often. The input node however can be used to overrule this behaviour. When inserting a timestamp, the node will output the latest information it got and re-calculate all fields.
|
|
59
|
+
|
|
60
|
+
There are also special strings that can be injected as payload to force updates:
|
|
61
|
+
|
|
62
|
+
- `allowance` - for retrieving the latest API count values
|
|
63
|
+
- `stage` - for retrieving the latest active load shedding stage
|
|
64
|
+
- `area` - for retrieving the latest schedule information
|
|
65
|
+
|
|
66
|
+
So usually there is no reason to connect anything to the input. It is only needed if you want to have more control over the node.
|
|
67
|
+
|
|
56
68
|
### Outputs
|
|
57
69
|
|
|
58
70
|
The note has two outputs. In most cases, the first (upper) output will be used.
|
|
@@ -61,46 +73,34 @@ The first output of the node outputs a boolean value and some related data. When
|
|
|
61
73
|
|
|
62
74
|
```
|
|
63
75
|
{
|
|
64
|
-
"payload":false,
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"type":"schedule"
|
|
71
|
-
},
|
|
72
|
-
"active":false
|
|
73
|
-
},
|
|
74
|
-
"event":{
|
|
75
|
-
"next":{
|
|
76
|
-
"start":1683561600000,
|
|
77
|
-
"end":1683570600000
|
|
78
|
-
},
|
|
79
|
-
"active":false
|
|
80
|
-
},
|
|
81
|
-
"checked":"13:35",
|
|
82
|
-
"next":{
|
|
83
|
-
"start":1683561600000,
|
|
84
|
-
"end":1683570600000,
|
|
85
|
-
"type":"schedule"
|
|
86
|
-
},
|
|
87
|
-
"active":false
|
|
76
|
+
"payload": false,
|
|
77
|
+
"stage": "0",
|
|
78
|
+
"statusselect": "capetown",
|
|
79
|
+
"api": {
|
|
80
|
+
"count": 30,
|
|
81
|
+
"limit": 50
|
|
88
82
|
},
|
|
89
|
-
"
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
|
|
83
|
+
"calc": {
|
|
84
|
+
"sleeptime": "58",
|
|
85
|
+
"stage": "0",
|
|
86
|
+
"active": false,
|
|
87
|
+
"type": "event",
|
|
88
|
+
"next": {
|
|
89
|
+
"type": "schedule",
|
|
90
|
+
"start": 1686830400000,
|
|
91
|
+
"end": 1686839400000,
|
|
92
|
+
"duration": 9000,
|
|
93
|
+
"islong": false
|
|
94
|
+
},
|
|
95
|
+
"secondstostatechange": 84912
|
|
96
96
|
},
|
|
97
|
-
"
|
|
97
|
+
"_msgid": "9fa5d503c47f083e"
|
|
98
98
|
}
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
The
|
|
101
|
+
The _start_ and _end_ objects contain the time as unix timestamp in the Javascript format (milliseconds after the epoch), while the duration is in seconds. The `msg.calc.next.islong` value is boolean and will be _true_ if the shedding lasts 4 hours or longer.
|
|
102
102
|
|
|
103
|
-
The second output shows `msg.stage` and `msg.schedule`, containing the latest information as retrieved from the API. This output is mainly useful when writing your own functions and logic.
|
|
103
|
+
The second output shows `msg.stage` and `msg.schedule`, containing the latest information as retrieved from the API, with the lastUpdate field added. This output is mainly useful when debugging or writing your own functions and logic.
|
|
104
104
|
|
|
105
105
|
### Status
|
|
106
106
|
|
|
Binary file
|
package/img/eskomsepush-flow.png
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
test: { value: false },
|
|
40
40
|
verbose: {value: false}
|
|
41
41
|
},
|
|
42
|
-
inputs:
|
|
42
|
+
inputs:1,
|
|
43
43
|
outputs:2,
|
|
44
44
|
icon: "eskomsepush.svg",
|
|
45
45
|
label: function() {
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
<ul id="list-areas"></ul>
|
|
127
127
|
|
|
128
128
|
<p>
|
|
129
|
-
Queries
|
|
129
|
+
Queries used: <span id="api_info">unknown/unknown</span><br />
|
|
130
130
|
<input type="text" id="searchAreaText" placeholder="Area" disabled />
|
|
131
131
|
<button id="searchAreaId">Search</button><br />
|
|
132
132
|
</p>
|
|
@@ -159,60 +159,65 @@ see how many queries you have left.</p>
|
|
|
159
159
|
<p>Next you need to insert the correct area. Once a valid license is filled out, the API can be used for searching the correct area id. Do note that this will cost some of the daily queries. If you don't want that and you already know the id of the area, fill out the area id manually.</p>
|
|
160
160
|
<p>Then you need to fill out which status to follow. This can be either <em>National</em> (eskom) or <em>Capetown</em>.</p>
|
|
161
161
|
<p>If the <em>test</em> checkbox has been selected, test data for the area will be fetched instead of the actual schedule. This is useful when debugging.</p>
|
|
162
|
+
<p>The <em>verbose</em> checkbox will give some additional <tt>node.warn()</tt> messages, appearing in the debug tab. This is also useful when debugging.</p>
|
|
163
|
+
|
|
164
|
+
<h3 id=""inputs">Inputs</h3>
|
|
165
|
+
|
|
166
|
+
<p>
|
|
167
|
+
The input side is not needed in most cases. The node will output its status every ten minutes and won't update the information it gets from the API more
|
|
168
|
+
often. The input node however can be used to overrule this behaviour. When inserting a timestamp, the node will output the latest information it got and
|
|
169
|
+
re-calculate all fields.
|
|
170
|
+
</p>
|
|
171
|
+
|
|
172
|
+
<p>There are also special strings that can be injected as payload to force updates:
|
|
173
|
+
<ul>
|
|
174
|
+
<li><code>allowance</code> - for retrieving the latest API count values</li>
|
|
175
|
+
<li><code>stage</code> - for retrieving the latest active load shedding stage</li>
|
|
176
|
+
<li><code>area</code> - for retrieving the latest schedule information</li>
|
|
177
|
+
</ul>
|
|
178
|
+
</p>
|
|
179
|
+
|
|
180
|
+
<p>
|
|
181
|
+
So usually there is no reason to connect anything to the input. It is only needed if you want to have more control over the node.
|
|
182
|
+
</p>
|
|
162
183
|
|
|
163
184
|
<h3 id="outputs">Outputs</h3>
|
|
164
185
|
|
|
165
186
|
<p>The first output of the node outputs a boolean value. When load shedding is active, the <code>msg.payload</code> will be <em>true</em>, otherwise it will be <em>false</em>. It also outputs some extra values:</p>
|
|
166
187
|
|
|
167
188
|
<pre>
|
|
168
|
-
{
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
|
|
174
|
-
|
|
189
|
+
{
|
|
190
|
+
"payload": false,
|
|
191
|
+
"stage": "0",
|
|
192
|
+
"statusselect": "capetown",
|
|
193
|
+
"api": {
|
|
194
|
+
"count": 30,
|
|
195
|
+
"limit": 50
|
|
196
|
+
},
|
|
197
|
+
"calc": {
|
|
198
|
+
"sleeptime": "58",
|
|
199
|
+
"stage": "0",
|
|
200
|
+
"active": false,
|
|
201
|
+
"type": "event",
|
|
202
|
+
"next": {
|
|
175
203
|
"type": "schedule",
|
|
204
|
+
"start": 1686830400000,
|
|
205
|
+
"end": 1686839400000,
|
|
176
206
|
"duration": 9000,
|
|
177
207
|
"islong": false
|
|
208
|
+
},
|
|
209
|
+
"secondstostatechange": 84912
|
|
178
210
|
},
|
|
179
|
-
"
|
|
180
|
-
|
|
181
|
-
"event": {
|
|
182
|
-
"next": {
|
|
183
|
-
"start": 1684267200000,
|
|
184
|
-
"end": 1684276200000
|
|
185
|
-
},
|
|
186
|
-
"active": false
|
|
187
|
-
},
|
|
188
|
-
"checked": "15:38",
|
|
189
|
-
"next": {
|
|
190
|
-
"start": 1684267200000,
|
|
191
|
-
"end": 1684276200000,
|
|
192
|
-
"type": "schedule",
|
|
193
|
-
"duration": 9000,
|
|
194
|
-
"islong": false
|
|
195
|
-
},
|
|
196
|
-
"active": false
|
|
197
|
-
},
|
|
198
|
-
"stage": "3",
|
|
199
|
-
"statusselect": "capetown",
|
|
200
|
-
"api": {
|
|
201
|
-
"count": 45,
|
|
202
|
-
"limit": 50,
|
|
203
|
-
"lastStatusUpdate": "Tue May 16 2023 15:38:15 GMT+0200 (Central European Summer Time)",
|
|
204
|
-
"lastScheduleUpdate": "Tue May 16 2023 15:38:15 GMT+0200 (Central European Summer Time)"
|
|
205
|
-
},
|
|
206
|
-
"_msgid": "dfa429a93a16472d"
|
|
207
|
-
}
|
|
211
|
+
"_msgid": "9fa5d503c47f083e"
|
|
212
|
+
}
|
|
208
213
|
</pre>
|
|
209
214
|
|
|
210
215
|
<p>The <tt>start</tt> and <tt>end</tt> objects contain the time as unix timestamp in the Javascript format (milliseconds after the epoch),
|
|
211
|
-
while the <tt>duration</tt> is in seconds. The <code>msg.
|
|
216
|
+
while the <tt>duration</tt> is in seconds. The <code>msg.calc.next.islong</code> value is boolean and will be <em>true</em> if the
|
|
212
217
|
shedding lasts 4 hours or longer.</p>
|
|
213
218
|
|
|
214
|
-
<p>The second output shows <code>msg.stage</code> and <code>msg.schedule</code>, containing the latest information as retrieved from the API
|
|
215
|
-
This output is mainly useful when debugging or writing your own functions and logic.</p>
|
|
219
|
+
<p>The second output shows <code>msg.stage</code> and <code>msg.schedule</code>, containing the latest information as retrieved from the API,
|
|
220
|
+
with the <tt>lastUpdate</tt> field added. This output is mainly useful when debugging or writing your own functions and logic.</p>
|
|
216
221
|
|
|
217
222
|
<h3 id="status">Status</h3>
|
|
218
223
|
|
package/src/nodes/eskomsepush.js
CHANGED
|
@@ -18,10 +18,13 @@ module.exports = function (RED) {
|
|
|
18
18
|
calc: {}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
function
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
21
|
+
function getMinutesToAPIReset () {
|
|
22
|
+
const now = new Date()
|
|
23
|
+
const targetTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 2, 0, 0);
|
|
24
|
+
if (now > targetTime) {
|
|
25
|
+
targetTime.setDate(targetTime.getDate() + 1);
|
|
26
|
+
}
|
|
27
|
+
const timeDiff = targetTime - now;
|
|
25
28
|
const minutesLeft = Math.floor(timeDiff / (1000 * 60))
|
|
26
29
|
|
|
27
30
|
return minutesLeft
|
|
@@ -102,11 +105,11 @@ module.exports = function (RED) {
|
|
|
102
105
|
})
|
|
103
106
|
}
|
|
104
107
|
|
|
105
|
-
function updateSheddingStatus (node) {
|
|
108
|
+
function updateSheddingStatus (node, msg) {
|
|
106
109
|
const now = new Date()
|
|
107
110
|
|
|
108
111
|
// Check allowance every ten minutes
|
|
109
|
-
if (EskomSePushInfo.api.lastUpdate === null || (now.getTime() - EskomSePushInfo.api.lastUpdate.getTime()) > 600000) {
|
|
112
|
+
if ((msg && msg.payload === 'allowance' ) || EskomSePushInfo.api.lastUpdate === null || (now.getTime() - EskomSePushInfo.api.lastUpdate.getTime()) > 600000) {
|
|
110
113
|
checkAllowance(node)
|
|
111
114
|
}
|
|
112
115
|
|
|
@@ -122,19 +125,20 @@ module.exports = function (RED) {
|
|
|
122
125
|
return
|
|
123
126
|
}
|
|
124
127
|
|
|
125
|
-
// Fetching actual information takes 2 calls, so calculate how long the
|
|
126
|
-
//
|
|
128
|
+
// Fetching actual information takes 2 calls, so calculate how long until the next API count
|
|
129
|
+
// reset and divide the calls over the day. Wait at least 10 minutes between calls
|
|
127
130
|
if ((EskomSePushInfo.api.info.allowance.limit - EskomSePushInfo.api.info.allowance.count) > 0) {
|
|
128
|
-
EskomSePushInfo.calc.sleeptime = (
|
|
131
|
+
EskomSePushInfo.calc.sleeptime = (getMinutesToAPIReset() / ((EskomSePushInfo.api.info.allowance.limit - EskomSePushInfo.api.info.allowance.count) / 2)).toFixed(0)
|
|
132
|
+
if (EskomSePushInfo.calc.sleeptime < 10) { EskomSePushInfo.calc.sleeptime = 10 }
|
|
129
133
|
} else {
|
|
130
134
|
EskomSePushInfo.calc.sleeptime = 30
|
|
131
135
|
}
|
|
132
136
|
|
|
133
|
-
if (EskomSePushInfo.status.lastUpdate === null || (now.getTime() - EskomSePushInfo.status.lastUpdate) > (EskomSePushInfo.calc.sleeptime * 60000)) {
|
|
137
|
+
if (( msg && msg.payload === 'stage' ) || EskomSePushInfo.status.lastUpdate === null || (now.getTime() - EskomSePushInfo.status.lastUpdate) > (EskomSePushInfo.calc.sleeptime * 60000)) {
|
|
134
138
|
checkStage(node)
|
|
135
139
|
}
|
|
136
140
|
|
|
137
|
-
if (EskomSePushInfo.area.lastUpdate === null || (now.getTime() - EskomSePushInfo.area.lastUpdate) > (EskomSePushInfo.calc.sleeptime * 60000)) {
|
|
141
|
+
if (( msg && msg.payload === 'area' ) || EskomSePushInfo.area.lastUpdate === null || (now.getTime() - EskomSePushInfo.area.lastUpdate) > (EskomSePushInfo.calc.sleeptime * 60000)) {
|
|
138
142
|
checkArea(node)
|
|
139
143
|
}
|
|
140
144
|
|
|
@@ -183,7 +187,10 @@ module.exports = function (RED) {
|
|
|
183
187
|
for (const dates of EskomSePushInfo.area.info.schedule.days) {
|
|
184
188
|
for (const schedule of dates.stages[EskomSePushInfo.calc.stage]) {
|
|
185
189
|
const ScheduleStart = Date.parse(dates.date + ' ' + schedule.split('-')[0])
|
|
186
|
-
|
|
190
|
+
let ScheduleEnd = Date.parse(dates.date + ' ' + schedule.split('-')[1])
|
|
191
|
+
if (ScheduleEnd < ScheduleStart) {
|
|
192
|
+
ScheduleEnd += (24 * 60 * 60 * 1000)
|
|
193
|
+
}
|
|
187
194
|
if (now < ScheduleEnd) {
|
|
188
195
|
BreakLoop = true
|
|
189
196
|
// This schedule is either active or will be next
|
|
@@ -239,18 +246,21 @@ module.exports = function (RED) {
|
|
|
239
246
|
// And update the status
|
|
240
247
|
let fill = 'green'
|
|
241
248
|
let shape = 'ring'
|
|
242
|
-
let statusText = 'Stage ' + EskomSePushInfo.calc.stage
|
|
249
|
+
let statusText = 'Stage ' + EskomSePushInfo.calc.stage + ': '
|
|
243
250
|
|
|
244
251
|
if (EskomSePushInfo.calc.active) {
|
|
245
252
|
fill = 'yellow'
|
|
246
253
|
if (EskomSePushInfo.calc.type === 'event') {
|
|
247
254
|
shape = 'dot'
|
|
248
255
|
}
|
|
249
|
-
statusText +=
|
|
250
|
-
statusText += ' - ' + new Date(EskomSePushInfo.calc.end).toLocaleTimeString()
|
|
256
|
+
statusText += new Date(EskomSePushInfo.calc.start).toLocaleTimeString([], {timeStyle: 'short'})
|
|
257
|
+
statusText += ' - ' + new Date(EskomSePushInfo.calc.end).toLocaleTimeString([], {timeStyle: 'short'})
|
|
251
258
|
} else {
|
|
252
|
-
|
|
253
|
-
|
|
259
|
+
if (new Date(EskomSePushInfo.calc.next.start).getUTCDay() !== now.getUTCDate) {
|
|
260
|
+
statusText += new Date(EskomSePushInfo.calc.next.start).toLocaleString([], {weekday: 'short'}) + ' '
|
|
261
|
+
}
|
|
262
|
+
statusText += new Date(EskomSePushInfo.calc.next.start).toLocaleTimeString([], {timeStyle: 'short'})
|
|
263
|
+
statusText += ' - ' + new Date(EskomSePushInfo.calc.next.end).toLocaleTimeString([], {timeStyle: 'short'})
|
|
254
264
|
}
|
|
255
265
|
|
|
256
266
|
statusText += ' (API: ' + EskomSePushInfo.api.info.allowance.count + '/' + EskomSePushInfo.api.info.allowance.limit + ')'
|
|
@@ -270,6 +280,10 @@ module.exports = function (RED) {
|
|
|
270
280
|
updateSheddingStatus(node)
|
|
271
281
|
}, 60000)
|
|
272
282
|
|
|
283
|
+
node.on('input', function(msg) {
|
|
284
|
+
updateSheddingStatus(node, msg)
|
|
285
|
+
})
|
|
286
|
+
|
|
273
287
|
node.on('close', function () {
|
|
274
288
|
clearInterval(intervalId)
|
|
275
289
|
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const EskomSePushInfo = { stage: { lastUpdate: '2023-06-16T07:18:37.847Z', info: { status: { capetown: { name: 'Cape Town', next_stages: [{ stage: '1', stage_start_timestamp: '2023-06-16T16:00:00+02:00' }, { stage: '0', stage_start_timestamp: '2023-06-17T00:00:00+02:00' }, { stage: '1', stage_start_timestamp: '2023-06-17T16:00:00+02:00' }, { stage: '0', stage_start_timestamp: '2023-06-18T00:00:00+02:00' }, { stage: '1', stage_start_timestamp: '2023-06-18T16:00:00+02:00' }], stage: '0', stage_updated: '2023-06-16T00:00:00.742510+02:00' }, eskom: { name: 'Eskom', next_stages: [{ stage: '3', stage_start_timestamp: '2023-06-16T16:00:00+02:00' }, { stage: '0', stage_start_timestamp: '2023-06-17T00:00:00+02:00' }, { stage: '3', stage_start_timestamp: '2023-06-17T16:00:00+02:00' }, { stage: '0', stage_start_timestamp: '2023-06-18T00:00:00+02:00' }, { stage: '3', stage_start_timestamp: '2023-06-18T16:00:00+02:00' }], stage: '0', stage_updated: '2023-06-16T00:00:00.742510+02:00' } } } }, schedule: { lastUpdate: '2023-06-16T07:18:38.957Z', info: { events: [{ end: '2023-06-17T00:30:00+02:00', note: 'Stage 1', start: '2023-06-16T22:00:00+02:00' }], info: { name: 'Helderberg Village (3)', region: 'City of Cape Town' }, schedule: { days: [{ date: '2023-06-16', name: 'Friday', stages: [['22:00-00:30'], ['06:00-08:30', '22:00-00:30'], ['06:00-08:30', '22:00-00:30'], ['06:00-08:30', '14:00-16:30', '22:00-00:30'], ['06:00-08:30', '14:00-16:30', '22:00-00:30'], ['06:00-08:30', '12:00-16:30', '22:00-00:30'], ['04:00-08:30', '12:00-16:30', '22:00-00:30'], ['04:00-08:30', '12:00-16:30', '20:00-00:30']] }, { date: '2023-06-17', name: 'Saturday', stages: [['04:00-06:30'], ['04:00-06:30', '20:00-22:30'], ['04:00-06:30', '12:00-14:30', '20:00-22:30'], ['04:00-06:30', '12:00-14:30', '20:00-22:30'], ['02:00-06:30', '12:00-14:30', '20:00-22:30'], ['02:00-06:30', '12:00-14:30', '18:00-22:30'], ['02:00-06:30', '10:00-14:30', '18:00-22:30'], ['02:00-06:30', '10:00-14:30', '18:00-22:30']] }, { date: '2023-06-18', name: 'Sunday', stages: [['12:00-14:30'], ['12:00-14:30'], ['12:00-14:30', '20:00-22:30'], ['04:00-06:30', '12:00-14:30', '20:00-22:30'], ['04:00-06:30', '10:00-14:30', '20:00-22:30'], ['04:00-06:30', '10:00-14:30', '20:00-22:30'], ['04:00-06:30', '10:00-14:30', '18:00-22:30'], ['02:00-06:30', '10:00-14:30', '18:00-22:30']] }, { date: '2023-06-19', name: 'Monday', stages: [['20:00-22:30'], ['04:00-06:30', '20:00-22:30'], ['04:00-06:30', '20:00-22:30'], ['04:00-06:30', '12:00-14:30', '20:00-22:30'], ['04:00-06:30', '12:00-14:30', '18:00-22:30'], ['02:00-06:30', '12:00-14:30', '18:00-22:30'], ['02:00-06:30', '12:00-14:30', '18:00-22:30'], ['02:00-06:30', '10:00-14:30', '18:00-22:30']] }, { date: '2023-06-20', name: 'Tuesday', stages: [[], ['12:00-14:30'], ['04:00-06:30', '12:00-14:30'], ['04:00-06:30', '12:00-14:30', '20:00-22:30'], ['04:00-06:30', '12:00-14:30', '20:00-22:30'], ['04:00-06:30', '10:00-14:30', '20:00-22:30'], ['02:00-06:30', '10:00-14:30', '20:00-22:30'], ['02:00-06:30', '10:00-14:30', '18:00-22:30']] }, { date: '2023-06-21', name: 'Wednesday', stages: [['02:00-04:30'], ['02:00-04:30', '18:00-20:30'], ['02:00-04:30', '10:00-12:30', '18:00-20:30'], ['02:00-04:30', '10:00-12:30', '18:00-20:30'], ['00:00-04:30', '10:00-12:30', '18:00-20:30'], ['00:00-04:30', '10:00-12:30', '16:00-20:30'], ['00:00-04:30', '08:00-12:30', '16:00-20:30'], ['00:00-04:30', '08:00-12:30', '16:00-20:30']] }, { date: '2023-06-22', name: 'Thursday', stages: [['10:00-12:30'], ['10:00-12:30'], ['10:00-12:30', '18:00-20:30'], ['02:00-04:30', '10:00-12:30', '18:00-20:30'], ['02:00-04:30', '08:00-12:30', '18:00-20:30'], ['02:00-04:30', '08:00-12:30', '18:00-20:30'], ['02:00-04:30', '08:00-12:30', '16:00-20:30'], ['00:00-04:30', '08:00-12:30', '16:00-20:30']] }], source: 'https://www.capetown.gov.za/loadshedding/' } } }, _msgid: 'e5eceed861704158' }
|
|
2
|
+
|
|
3
|
+
const now = new Date()
|
|
4
|
+
let BreakLoop = false
|
|
5
|
+
for (const dates of EskomSePushInfo.schedule.info.schedule.days) {
|
|
6
|
+
for (const schedule of dates.stages['0']) {
|
|
7
|
+
const ScheduleStart = Date.parse(dates.date + ' ' + schedule.split('-')[0])
|
|
8
|
+
let ScheduleEnd = Date.parse(dates.date + ' ' + schedule.split('-')[1])
|
|
9
|
+
if (ScheduleEnd < ScheduleStart) {
|
|
10
|
+
ScheduleEnd += (24 * 60 * 60 * 1000)
|
|
11
|
+
}
|
|
12
|
+
console.log('check: ' + new Date(ScheduleEnd))
|
|
13
|
+
if (now < new Date(ScheduleEnd)) {
|
|
14
|
+
BreakLoop = true
|
|
15
|
+
// This schedule is either active or will be next
|
|
16
|
+
if (now >= ScheduleStart) {
|
|
17
|
+
console.log('match')
|
|
18
|
+
} else {
|
|
19
|
+
console.log('next found')
|
|
20
|
+
console.log(new Date(ScheduleStart).toLocaleString())
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (BreakLoop) { break }
|
|
24
|
+
}
|
|
25
|
+
if (BreakLoop) { break }
|
|
26
|
+
}
|