node-red-contrib-eskomsepush 0.0.13 → 0.0.15
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/package.json +1 -1
- package/src/nodes/eskomsepush.html +8 -1
- package/src/nodes/eskomsepush.js +70 -40
package/package.json
CHANGED
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
area: {value:""},
|
|
38
38
|
statusselect: {value:"", validate: RED.validators.regex(/^(eskom|capetown)$/)},
|
|
39
39
|
test: { value: false },
|
|
40
|
-
verbose: {value: false}
|
|
40
|
+
verbose: {value: false},
|
|
41
|
+
api_allowance_buffer: {value: 0, validate: RED.validators.regex(/^[0-9]+$/)}
|
|
41
42
|
},
|
|
42
43
|
inputs:1,
|
|
43
44
|
outputs:2,
|
|
@@ -110,6 +111,10 @@
|
|
|
110
111
|
<option value="capetown">Cape Town</option>
|
|
111
112
|
</select>
|
|
112
113
|
</div>
|
|
114
|
+
<div class="form-row">
|
|
115
|
+
<label for="node-input-api_allowance_buffer"><i class="fa fa-shopping-bag"></i> API allowance buffer</label>
|
|
116
|
+
<input type="text" id="node-input-api_allowance_buffer" placeholder="0">
|
|
117
|
+
</div>
|
|
113
118
|
<div class="form-row">
|
|
114
119
|
<label style="min-width:190px" for="node-input-test"><i class="fa fa-volume-up"></i> Use test data</label>
|
|
115
120
|
<input type="checkbox" checked id="node-input-test" style="max-width:30px">
|
|
@@ -130,6 +135,7 @@
|
|
|
130
135
|
<input type="text" id="searchAreaText" placeholder="Area" disabled />
|
|
131
136
|
<button id="searchAreaId">Search</button><br />
|
|
132
137
|
</p>
|
|
138
|
+
|
|
133
139
|
</div>
|
|
134
140
|
<div class="form-row" style="margin-bottom:0px;">
|
|
135
141
|
<input type="checkbox" checked id="node-input-verbose" style="display:inline-block; margin-left:8px; width:auto; vertical-align:top;">
|
|
@@ -158,6 +164,7 @@ see how many queries you have left.</p>
|
|
|
158
164
|
<p>First you will need a <em>licence key</em>. You can get one from <a href="https://eskomsepush.gumroad.com/l/api">here</a>, by subsribing to the Free model. Note that this is for personal use only.</p>
|
|
159
165
|
<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
166
|
<p>Then you need to fill out which status to follow. This can be either <em>National</em> (eskom) or <em>Capetown</em>.</p>
|
|
167
|
+
<p>The <i>API allowance buffer</i> allows you to reserve some daily unused API calls (so you can use your API key for other integrations too). If you don't use that, set this to _0_ (zero).</p>
|
|
161
168
|
<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
169
|
<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
170
|
|
package/src/nodes/eskomsepush.js
CHANGED
|
@@ -20,11 +20,11 @@ module.exports = function (RED) {
|
|
|
20
20
|
|
|
21
21
|
function getMinutesToAPIReset () {
|
|
22
22
|
const now = new Date()
|
|
23
|
-
const targetTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 2, 0, 0)
|
|
23
|
+
const targetTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 2, 0, 0)
|
|
24
24
|
if (now > targetTime) {
|
|
25
|
-
targetTime.setDate(targetTime.getDate() + 1)
|
|
25
|
+
targetTime.setDate(targetTime.getDate() + 1)
|
|
26
26
|
}
|
|
27
|
-
const timeDiff = targetTime - now
|
|
27
|
+
const timeDiff = targetTime - now
|
|
28
28
|
const minutesLeft = Math.floor(timeDiff / (1000 * 60))
|
|
29
29
|
|
|
30
30
|
return minutesLeft
|
|
@@ -109,7 +109,7 @@ module.exports = function (RED) {
|
|
|
109
109
|
const now = new Date()
|
|
110
110
|
|
|
111
111
|
// Check allowance every ten minutes
|
|
112
|
-
if ((msg && msg.payload === 'allowance'
|
|
112
|
+
if ((msg && msg.payload === 'allowance') || EskomSePushInfo.api.lastUpdate === null || (now.getTime() - EskomSePushInfo.api.lastUpdate.getTime()) > 600000) {
|
|
113
113
|
checkAllowance(node)
|
|
114
114
|
}
|
|
115
115
|
|
|
@@ -126,19 +126,38 @@ module.exports = function (RED) {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
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
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
// reset and divide the calls over the day. Wait at least 60 minutes between calls
|
|
130
|
+
// reduce limit by api_allowance_buffer to cater for units consumed by other API calls
|
|
131
|
+
if (node.config.verbose === true) {
|
|
132
|
+
node.warn('Minutes to API Reset: ' + getMinutesToAPIReset())
|
|
133
|
+
}
|
|
134
|
+
const allowanceRemaining = EskomSePushInfo.api.info.allowance.limit - node.config.api_allowance_buffer - EskomSePushInfo.api.info.allowance.count
|
|
135
|
+
|
|
136
|
+
if (allowanceRemaining > 0) {
|
|
137
|
+
EskomSePushInfo.calc.sleeptime = Math.round(getMinutesToAPIReset() / Math.ceil(allowanceRemaining / 2))
|
|
138
|
+
if (node.config.verbose === true) {
|
|
139
|
+
node.warn('API allowance limit: ' + EskomSePushInfo.api.info.allowance.limit)
|
|
140
|
+
node.warn('API allowance count: ' + EskomSePushInfo.api.info.allowance.count)
|
|
141
|
+
node.warn('Calculated sleeptime: ' + EskomSePushInfo.calc.sleeptime)
|
|
142
|
+
}
|
|
143
|
+
if (EskomSePushInfo.calc.sleeptime < 60) {
|
|
144
|
+
EskomSePushInfo.calc.sleeptime = 60
|
|
145
|
+
if (node.config.verbose === true) {
|
|
146
|
+
node.warn('Calculated sleeptime was less than 60. Set it to 60: ' + EskomSePushInfo.calc.sleeptime)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
133
149
|
} else {
|
|
134
|
-
EskomSePushInfo.calc.sleeptime =
|
|
150
|
+
EskomSePushInfo.calc.sleeptime = 120
|
|
151
|
+
if (node.config.verbose === true) {
|
|
152
|
+
node.warn('Set sleeptime to 120 since allowance count is low: ' + EskomSePushInfo.calc.sleeptime)
|
|
153
|
+
}
|
|
135
154
|
}
|
|
136
155
|
|
|
137
|
-
if ((
|
|
156
|
+
if ((msg && msg.payload === 'stage') || EskomSePushInfo.status.lastUpdate === null || (now.getTime() - EskomSePushInfo.status.lastUpdate) > (EskomSePushInfo.calc.sleeptime * 60000)) {
|
|
138
157
|
checkStage(node)
|
|
139
158
|
}
|
|
140
159
|
|
|
141
|
-
if ((
|
|
160
|
+
if ((msg && msg.payload === 'area') || EskomSePushInfo.area.lastUpdate === null || (now.getTime() - EskomSePushInfo.area.lastUpdate) > (EskomSePushInfo.calc.sleeptime * 60000)) {
|
|
142
161
|
checkArea(node)
|
|
143
162
|
}
|
|
144
163
|
|
|
@@ -163,10 +182,10 @@ module.exports = function (RED) {
|
|
|
163
182
|
|
|
164
183
|
// Are there any events going on?
|
|
165
184
|
if (Object.entries(EskomSePushInfo.area.info.events).length > 0) {
|
|
166
|
-
EskomSePushInfo.calc.type = 'event'
|
|
167
185
|
const EventStart = Date.parse(EskomSePushInfo.area.info.events[0].start)
|
|
168
186
|
const EventEnd = Date.parse(EskomSePushInfo.area.info.events[0].end)
|
|
169
187
|
if (now >= EventStart && now < EventEnd) {
|
|
188
|
+
EskomSePushInfo.calc.type = 'event'
|
|
170
189
|
EskomSePushInfo.calc.active = true
|
|
171
190
|
if (EskomSePushInfo.area.info.events[0].note.match(/Stage (\d+)/i)) {
|
|
172
191
|
EskomSePushInfo.calc.stage = EskomSePushInfo.area.info.events[0].note.match(/Stage (\d+)/i)[1]
|
|
@@ -187,29 +206,39 @@ module.exports = function (RED) {
|
|
|
187
206
|
// So not just like events, where they are in UTC with an offset
|
|
188
207
|
let BreakLoop = false
|
|
189
208
|
for (const dates of EskomSePushInfo.area.info.schedule.days) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
// This schedule is either active or will be next
|
|
199
|
-
if (now >= ScheduleStart) {
|
|
200
|
-
EskomSePushInfo.calc.active = true
|
|
201
|
-
EskomSePushInfo.calc.type = 'schedule'
|
|
202
|
-
EskomSePushInfo.calc.start = ScheduleStart
|
|
203
|
-
EskomSePushInfo.calc.end = ScheduleEnd
|
|
204
|
-
} else {
|
|
205
|
-
EskomSePushInfo.calc.next = {
|
|
206
|
-
type: 'schedule',
|
|
207
|
-
start: ScheduleStart,
|
|
208
|
-
end: ScheduleEnd
|
|
209
|
+
const stageIndex = EskomSePushInfo.calc.stage - 1
|
|
210
|
+
if (stageIndex >= 0 && stageIndex < dates.stages.length) {
|
|
211
|
+
if (Array.isArray(dates.stages[stageIndex])) {
|
|
212
|
+
for (const schedule of dates.stages[stageIndex]) {
|
|
213
|
+
const ScheduleStart = Date.parse(dates.date + ' ' + schedule.split('-')[0])
|
|
214
|
+
let ScheduleEnd = Date.parse(dates.date + ' ' + schedule.split('-')[1])
|
|
215
|
+
if (ScheduleEnd < ScheduleStart) {
|
|
216
|
+
ScheduleEnd += (24 * 60 * 60 * 1000)
|
|
209
217
|
}
|
|
218
|
+
if (now < ScheduleEnd) {
|
|
219
|
+
BreakLoop = true
|
|
220
|
+
// This schedule is either active or will be next
|
|
221
|
+
if (now >= ScheduleStart) {
|
|
222
|
+
EskomSePushInfo.calc.active = true
|
|
223
|
+
EskomSePushInfo.calc.type = 'schedule'
|
|
224
|
+
EskomSePushInfo.calc.start = ScheduleStart
|
|
225
|
+
EskomSePushInfo.calc.end = ScheduleEnd
|
|
226
|
+
} else {
|
|
227
|
+
EskomSePushInfo.calc.next = {
|
|
228
|
+
type: 'schedule',
|
|
229
|
+
start: ScheduleStart,
|
|
230
|
+
end: ScheduleEnd,
|
|
231
|
+
stage: EskomSePushInfo.calc.stage
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (BreakLoop) { break }
|
|
210
236
|
}
|
|
237
|
+
} else {
|
|
238
|
+
console.warn('Not an array:', dates.stages[stageIndex]) // Warning if not an array
|
|
211
239
|
}
|
|
212
|
-
|
|
240
|
+
} else {
|
|
241
|
+
console.warn('Invalid stage index:', stageIndex) // Warning if stage index is out of bounds
|
|
213
242
|
}
|
|
214
243
|
if (BreakLoop) { break }
|
|
215
244
|
}
|
|
@@ -218,6 +247,7 @@ module.exports = function (RED) {
|
|
|
218
247
|
EskomSePushInfo.calc.next.duration = (EskomSePushInfo.calc.next.end - EskomSePushInfo.calc.next.start) / 1000
|
|
219
248
|
EskomSePushInfo.calc.next.islong = EskomSePushInfo.calc.next.duration >= (4 * 3600)
|
|
220
249
|
EskomSePushInfo.calc.secondstostatechange = parseInt((EskomSePushInfo.calc.next.start - now) / 1000)
|
|
250
|
+
EskomSePushInfo.calc.next.isHigherStage = EskomSePushInfo.calc.next.stage > EskomSePushInfo.calc.stage
|
|
221
251
|
}
|
|
222
252
|
|
|
223
253
|
if (EskomSePushInfo.calc.active) {
|
|
@@ -255,16 +285,16 @@ module.exports = function (RED) {
|
|
|
255
285
|
if (EskomSePushInfo.calc.type === 'event') {
|
|
256
286
|
shape = 'dot'
|
|
257
287
|
}
|
|
258
|
-
if (
|
|
259
|
-
statusText += new Date(EskomSePushInfo.calc.start).toLocaleTimeString([], {timeStyle: 'short'})
|
|
260
|
-
statusText += ' - ' + new Date(EskomSePushInfo.calc.end).toLocaleTimeString([], {timeStyle: 'short'})
|
|
288
|
+
if (EskomSePushInfo.calc.start) {
|
|
289
|
+
statusText += new Date(EskomSePushInfo.calc.start).toLocaleTimeString([], { timeStyle: 'short' })
|
|
290
|
+
statusText += ' - ' + new Date(EskomSePushInfo.calc.end).toLocaleTimeString([], { timeStyle: 'short' })
|
|
261
291
|
}
|
|
262
292
|
} else {
|
|
263
|
-
if (new Date(EskomSePushInfo.calc.next.start).getUTCDay() !==
|
|
264
|
-
statusText += new Date(EskomSePushInfo.calc.next.start).toLocaleString([], {weekday: 'short'}) + ' '
|
|
293
|
+
if (new Date(EskomSePushInfo.calc.next.start).getUTCDay() !== now.getUTCDate) {
|
|
294
|
+
statusText += new Date(EskomSePushInfo.calc.next.start).toLocaleString([], { weekday: 'short' }) + ' '
|
|
265
295
|
}
|
|
266
|
-
statusText += new Date(EskomSePushInfo.calc.next.start).toLocaleTimeString([], {timeStyle: 'short'})
|
|
267
|
-
statusText += ' - ' + new Date(EskomSePushInfo.calc.next.end).toLocaleTimeString([], {timeStyle: 'short'})
|
|
296
|
+
statusText += new Date(EskomSePushInfo.calc.next.start).toLocaleTimeString([], { timeStyle: 'short' })
|
|
297
|
+
statusText += ' - ' + new Date(EskomSePushInfo.calc.next.end).toLocaleTimeString([], { timeStyle: 'short' })
|
|
268
298
|
}
|
|
269
299
|
|
|
270
300
|
statusText += ' (API: ' + EskomSePushInfo.api.info.allowance.count + '/' + EskomSePushInfo.api.info.allowance.limit + ')'
|
|
@@ -284,7 +314,7 @@ module.exports = function (RED) {
|
|
|
284
314
|
updateSheddingStatus(node)
|
|
285
315
|
}, 60000)
|
|
286
316
|
|
|
287
|
-
node.on('input', function(msg) {
|
|
317
|
+
node.on('input', function (msg) {
|
|
288
318
|
updateSheddingStatus(node, msg)
|
|
289
319
|
})
|
|
290
320
|
|