node-red-contrib-eskomsepush 0.0.8 → 0.0.10
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.
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: "[BUG]"
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Describe the bug**
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
**To Reproduce**
|
|
14
|
+
Steps to reproduce the behavior:
|
|
15
|
+
1. Using node '...'
|
|
16
|
+
2. Click on '....'
|
|
17
|
+
3. See error
|
|
18
|
+
|
|
19
|
+
**Expected behavior**
|
|
20
|
+
A clear and concise description of what you expected to happen.
|
|
21
|
+
|
|
22
|
+
**Screenshots**
|
|
23
|
+
If applicable, add screenshots to help explain your problem.
|
|
24
|
+
|
|
25
|
+
**Flow**
|
|
26
|
+
If applicable, add a flow to help explain your problem.
|
|
27
|
+
|
|
28
|
+
**Software (please complete the following information):**
|
|
29
|
+
- node-red-contrib-eskomsepush version:
|
|
30
|
+
|
|
31
|
+
**Additional context**
|
|
32
|
+
Add any other context about the problem here.
|
|
33
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea for the EskomSePush node
|
|
4
|
+
title: "[Feature]"
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
12
|
+
|
|
13
|
+
**Describe the solution you'd like**
|
|
14
|
+
A clear and concise description of what you want to happen.
|
|
15
|
+
|
|
16
|
+
**Describe alternatives you've considered**
|
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
|
18
|
+
|
|
19
|
+
**Additional context**
|
|
20
|
+
Add any other context or screenshots about the feature request here.
|
|
21
|
+
|
package/README.md
CHANGED
|
@@ -20,7 +20,9 @@ The node has been made to work well together with the [@victronenergy/node-red-c
|
|
|
20
20
|
|
|
21
21
|
You can find the example flow for this via importing the [victron-minsoc-stage-based.json](examples/victron-minsoc-stage-based.json) file.
|
|
22
22
|
|
|
23
|
-
### Configuration
|
|
23
|
+
### Installation & Configuration
|
|
24
|
+
|
|
25
|
+
Install the node from within Node-RED from the menu: Manage pallete -> Install (tab) -> Search for "eskom" and click "install".
|
|
24
26
|
|
|
25
27
|
First you will need a _licence key_. You can get one from [here](https://eskomsepush.gumroad.com/l/api), by subscribing to the Free model. Note that this is for personal use only.
|
|
26
28
|
|
|
@@ -106,6 +108,10 @@ The status will show the situation regarding the API calls and when the next
|
|
|
106
108
|
shedding wil start or end. It also shows the count of API calls that have been
|
|
107
109
|
done and how many are left. This updates every 10 minutes.
|
|
108
110
|
|
|
111
|
+
The red color status can be either filled (dot) or not (ring). In case of a dot,
|
|
112
|
+
the load schedding is because of an _event_. When it is a ring, it is caused by
|
|
113
|
+
a matching _schedule_.
|
|
114
|
+
|
|
109
115
|
### Documentation
|
|
110
116
|
|
|
111
117
|
Documentation for the API can be found [here](https://documenter.getpostman.com/view/1296288/UzQuNk3E)
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
|
+
function checkForValidLicense() {
|
|
3
|
+
var licensekey = $('#node-input-licensekey').val();
|
|
4
|
+
|
|
5
|
+
var regexValidator = RED.validators.regex(/^[0-9A-F\-]{35}$/)
|
|
6
|
+
var isValid = regexValidator(licensekey)
|
|
7
|
+
|
|
8
|
+
if (isValid) {
|
|
9
|
+
document.getElementById("searchAreaText").disabled = false
|
|
10
|
+
$.ajax({
|
|
11
|
+
url: '/eskomsepush/api',
|
|
12
|
+
method: 'GET',
|
|
13
|
+
data: {
|
|
14
|
+
token: licensekey,
|
|
15
|
+
},
|
|
16
|
+
success: function(response) {
|
|
17
|
+
$('#api_info').text(response.allowance.count + '/' + response.allowance.limit)
|
|
18
|
+
if (response.allowance.count >= response.allowance.limit) {
|
|
19
|
+
document.getElementById("searchAreaText").disabled = true
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
error: function(error) {
|
|
23
|
+
node.warn(error)
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
} else {
|
|
27
|
+
document.getElementById("searchAreaText").disabled = true
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
2
31
|
RED.nodes.registerType('eskomsepush',{
|
|
3
32
|
category: 'network',
|
|
4
33
|
color: '#ffffff',
|
|
@@ -7,7 +36,8 @@
|
|
|
7
36
|
licensekey: {value:"", validate: RED.validators.regex(/^[0-9A-F\-]{35}$/)},
|
|
8
37
|
area: {value:""},
|
|
9
38
|
statusselect: {value:"", validate: RED.validators.regex(/^(eskom|capetown)$/)},
|
|
10
|
-
test: { value: false }
|
|
39
|
+
test: { value: false },
|
|
40
|
+
verbose: {value: false}
|
|
11
41
|
},
|
|
12
42
|
inputs:0,
|
|
13
43
|
outputs:2,
|
|
@@ -16,53 +46,48 @@
|
|
|
16
46
|
return this.name||"EskomSePush API";
|
|
17
47
|
},
|
|
18
48
|
oneditprepare: function oneditprepare() {
|
|
49
|
+
checkForValidLicense()
|
|
19
50
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var licensekey = document.getElementById("node-input-licensekey");
|
|
27
|
-
|
|
28
|
-
if (!RED.validators.regex(licensekey.value, /^[0-9A-F\-]{35}$/)) {
|
|
29
|
-
return
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (input.value.length >= 5) {
|
|
33
|
-
dropdown.innerHTML = "";
|
|
51
|
+
$("button#searchAreaId").on("click", function() {
|
|
52
|
+
var licensekey = $("#node-input-licensekey").val()
|
|
53
|
+
var regexValidator = RED.validators.regex(/^[0-9A-F\-]{35}$/)
|
|
54
|
+
var isValid = regexValidator(licensekey)
|
|
55
|
+
var search = $("input#searchAreaText").val()
|
|
56
|
+
var arealist = ''
|
|
34
57
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
if (isValid && search != '') {
|
|
59
|
+
$.ajax({
|
|
60
|
+
url: '/eskomsepush/search',
|
|
61
|
+
method: 'GET',
|
|
62
|
+
data: {
|
|
63
|
+
token: licensekey,
|
|
64
|
+
search
|
|
65
|
+
},
|
|
66
|
+
success: function(response) {
|
|
67
|
+
for (var i = 0; i < response.areas.length; i++) {
|
|
68
|
+
arealist += '<li id="' + response.areas[i].id + '">' + response.areas[i].name +
|
|
69
|
+
', '+ response.areas[i].region + '</li>'
|
|
70
|
+
}
|
|
71
|
+
$('#list-areas').html(arealist)
|
|
72
|
+
$('#list-areas li').on('click', function() {
|
|
73
|
+
$('#node-input-area').val($(this).attr("id"))
|
|
74
|
+
$('#node-input-name').val($(this).text().split(',')[0])
|
|
75
|
+
})
|
|
76
|
+
checkForValidLicense()
|
|
77
|
+
},
|
|
78
|
+
error: function(error) {
|
|
79
|
+
node.warn(error)
|
|
80
|
+
}
|
|
81
|
+
})
|
|
52
82
|
}
|
|
53
83
|
})
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
dropdown.style.display = "none";
|
|
84
|
+
|
|
85
|
+
$("#node-input-licensekey").on("input", function() {
|
|
86
|
+
checkForValidLicense()
|
|
58
87
|
});
|
|
59
|
-
input.addEventListener("focusout", function() {
|
|
60
|
-
dropdown.style.display = "none"
|
|
61
|
-
})
|
|
62
|
-
} else {
|
|
63
|
-
dropdown.style.display = "none";
|
|
64
88
|
}
|
|
65
|
-
}
|
|
89
|
+
});
|
|
90
|
+
|
|
66
91
|
</script>
|
|
67
92
|
|
|
68
93
|
<script type="text/html" data-template-name="eskomsepush">
|
|
@@ -75,13 +100,8 @@
|
|
|
75
100
|
<input type="password" id="node-input-licensekey" placeholder="License key" required>
|
|
76
101
|
</div>
|
|
77
102
|
<div class="form-row">
|
|
78
|
-
<label for="node-input-area"><i class="fa fa-tag"></i> Area</label>
|
|
79
|
-
<input type="text" id="node-input-area" placeholder="Area
|
|
80
|
-
<select id="areaDropdown" style="display: none;"></select>
|
|
81
|
-
</div>
|
|
82
|
-
<div class="form-row">
|
|
83
|
-
<label style="min-width:190px" for="node-input-test"><i class="fa fa-volume-up"></i> Use test data</label>
|
|
84
|
-
<input type="checkbox" checked id="node-input-test" style="max-width:30px">
|
|
103
|
+
<label for="node-input-area"><i class="fa fa-tag"></i> Area id</label>
|
|
104
|
+
<input type="text" id="node-input-area" placeholder="Area id">
|
|
85
105
|
</div>
|
|
86
106
|
<div class="form-row">
|
|
87
107
|
<label for="node-input-statusselect"><i class="fa fa-location-arrow"></i> Status select</label>
|
|
@@ -90,6 +110,31 @@
|
|
|
90
110
|
<option value="capetown">Cape Town</option>
|
|
91
111
|
</select>
|
|
92
112
|
</div>
|
|
113
|
+
<div class="form-row">
|
|
114
|
+
<label style="min-width:190px" for="node-input-test"><i class="fa fa-volume-up"></i> Use test data</label>
|
|
115
|
+
<input type="checkbox" checked id="node-input-test" style="max-width:30px">
|
|
116
|
+
</div>
|
|
117
|
+
<div class="form-tips">
|
|
118
|
+
<p>In order to fill out the properties, you will need to add the correct license key, which can be
|
|
119
|
+
obtained <a href="https://eskomsepush.gumroad.com/l/api">here</a>. Apart from that, the
|
|
120
|
+
<em>Aread id</em> needs to be filled out. The search form below can help you to obtain that.<br />
|
|
121
|
+
Once you have a valid licence key filled out in the form, a query willl be done, checking
|
|
122
|
+
how many credits you have left. If you have credits left, the form
|
|
123
|
+
can be used to search for the needed area id. <strong>Each search will cost you 5 credits.</strong>
|
|
124
|
+
</p>
|
|
125
|
+
|
|
126
|
+
<ul id="list-areas"></ul>
|
|
127
|
+
|
|
128
|
+
<p>
|
|
129
|
+
Queries left: <span id="api_info">unknown/unknown</span><br />
|
|
130
|
+
<input type="text" id="searchAreaText" placeholder="Area" disabled />
|
|
131
|
+
<button id="searchAreaId">Search</button><br />
|
|
132
|
+
</p>
|
|
133
|
+
</div>
|
|
134
|
+
<div class="form-row" style="margin-bottom:0px;">
|
|
135
|
+
<input type="checkbox" checked id="node-input-verbose" style="display:inline-block; margin-left:8px; width:auto; vertical-align:top;">
|
|
136
|
+
<label style="min-width:390px" for="node-input-verbose"><i class="fa fa-power"></i> Verbose: add extra logging when running</label>
|
|
137
|
+
</div>
|
|
93
138
|
</script>
|
|
94
139
|
|
|
95
140
|
<script type="text/html" data-help-name="eskomsepush">
|
|
@@ -111,8 +156,7 @@ see how many queries you have left.</p>
|
|
|
111
156
|
<h3 id="configuration">Configuration</h3>
|
|
112
157
|
|
|
113
158
|
<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>
|
|
114
|
-
<p>Next you need to insert the correct area. Once
|
|
115
|
-
key.</p>
|
|
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>
|
|
116
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>
|
|
117
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>
|
|
118
162
|
|
|
@@ -122,47 +166,53 @@ key.</p>
|
|
|
122
166
|
|
|
123
167
|
<pre>
|
|
124
168
|
{
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
|
|
140
|
-
|
|
169
|
+
"payload": false,
|
|
170
|
+
"LoadShedding": {
|
|
171
|
+
"schedule": {
|
|
172
|
+
"next": {
|
|
173
|
+
"start": 1684267200000,
|
|
174
|
+
"end": 1684276200000,
|
|
175
|
+
"type": "schedule",
|
|
176
|
+
"duration": 9000,
|
|
177
|
+
"islong": false
|
|
178
|
+
},
|
|
179
|
+
"active": false
|
|
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
|
|
141
197
|
},
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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)"
|
|
147
205
|
},
|
|
148
|
-
"
|
|
149
|
-
|
|
150
|
-
"stage":"5",
|
|
151
|
-
"statusselect":"capetown",
|
|
152
|
-
"api":{
|
|
153
|
-
"count":12,
|
|
154
|
-
"limit":50,
|
|
155
|
-
"lastStatusUpdate":"Mon May 08 2023 13:34:30 GMT+0200 (Central European Summer Time)",
|
|
156
|
-
"lastScheduleUpdate":"Mon May 08 2023 13:34:30 GMT+0200 (Central European Summer Time)"
|
|
157
|
-
},
|
|
158
|
-
"_msgid":"6e77b593b7f9eda4"
|
|
159
|
-
}
|
|
206
|
+
"_msgid": "dfa429a93a16472d"
|
|
207
|
+
}
|
|
160
208
|
</pre>
|
|
161
209
|
|
|
162
|
-
<p>The <tt>start</tt> and <tt>end</tt> objects contain the time as unix timestamp in the Javascript format (milliseconds after the epoch)
|
|
210
|
+
<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.LoadShedding.next.islong</code> value is boolean and will be <em>true</em> if the
|
|
212
|
+
shedding lasts 4 hours or longer.</p>
|
|
163
213
|
|
|
164
214
|
<p>The second output shows <code>msg.stage</code> and <code>msg.schedule</code>, containing the latest information as retrieved from the API.
|
|
165
|
-
This output is mainly useful when writing your own functions and logic.</p>
|
|
215
|
+
This output is mainly useful when debugging or writing your own functions and logic.</p>
|
|
166
216
|
|
|
167
217
|
<h3 id="status">Status</h3>
|
|
168
218
|
|
|
@@ -170,9 +220,29 @@ This output is mainly useful when writing your own functions and logic.</p>
|
|
|
170
220
|
It also shows the count of API calls that have been done and
|
|
171
221
|
how many are left. This updates every 10 minutes.</p>
|
|
172
222
|
|
|
223
|
+
<p>
|
|
224
|
+
The yellow color status can be either filled (dot) or not (ring). In case of a dot,
|
|
225
|
+
the load schedding is because of an <em>event</em>. When it is a ring, it is caused by
|
|
226
|
+
a matching <em>schedule</em>.
|
|
227
|
+
</p>
|
|
228
|
+
|
|
229
|
+
<div id="legend">
|
|
230
|
+
<ul>
|
|
231
|
+
<li><svg class="bullet" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect x="5" y="5" width="9" height="9" rx="2" ry="2" stroke-width="3" fill="#fff" stroke="#5a8"></rect>
|
|
232
|
+
</svg> - grid available, working properly</li>
|
|
233
|
+
<li><svg class="bullet" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect x="5" y="5" width="9" height="9" rx="2" ry="2" stroke-width="3" fill="#F9DF31" stroke="#F9DF31"></rect>
|
|
234
|
+
</svg> - no grid, load shedding because of an <strong>event</strong></li>
|
|
235
|
+
<li><svg class="bullet" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect x="5" y="5" width="9" height="9" rx="2" ry="2" stroke-width="3" fill="#fff" stroke="#F9DF31"></rect>
|
|
236
|
+
</svg> - no grid, load shedding because of a <strong>schedule</strong></li>
|
|
237
|
+
<li><svg class="bullet" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect x="5" y="5" width="9" height="9" rx="2" ry="2" stroke-width="3" fill="#fff" stroke="#c00"></rect>
|
|
238
|
+
</svg> - ran out of API calls</li>
|
|
239
|
+
</ul>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
173
242
|
<h1 id="documentation">Documentation</h1>
|
|
174
|
-
<p>Documentation for the API can be found <a href="https://documenter.getpostman.com/view/1296288/UzQuNk3E">here</a></p>
|
|
175
243
|
|
|
244
|
+
<p>The GitHub site for the node can be found <a href="https://github.com/dirkjanfaber/node-red-contrib-eskomsepush">here</a>, while the documentation for the API can be found <a href="https://documenter.getpostman.com/view/1296288/UzQuNk3E">here</a>.
|
|
245
|
+
For issues and/or suggestions for improving the node, please use the <a href="https://github.com/dirkjanfaber/node-red-contrib-eskomsepush/issues">issue tracker</a>.</p>
|
|
176
246
|
</script>
|
|
177
247
|
|
|
178
248
|
<style>
|
|
@@ -183,4 +253,24 @@ select#areaDropdown {
|
|
|
183
253
|
position: absolute;
|
|
184
254
|
left: 120px;
|
|
185
255
|
}
|
|
256
|
+
#list-areas li {
|
|
257
|
+
cursor: pointer;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
#legend ul {
|
|
261
|
+
list-style: none;
|
|
262
|
+
padding: 0;
|
|
263
|
+
}
|
|
264
|
+
#legend li {
|
|
265
|
+
margin-bottom: 10px;
|
|
266
|
+
position: relative;
|
|
267
|
+
padding-left: 25px;
|
|
268
|
+
}
|
|
269
|
+
.bullet {
|
|
270
|
+
position: absolute;
|
|
271
|
+
top: 2px;
|
|
272
|
+
left: 0;
|
|
273
|
+
width: 35px;
|
|
274
|
+
height: 35px;
|
|
275
|
+
}
|
|
186
276
|
</style>
|
package/src/nodes/eskomsepush.js
CHANGED
|
@@ -10,17 +10,20 @@ module.exports = function (RED) {
|
|
|
10
10
|
let lastStageUpdate = new Date()
|
|
11
11
|
let lastScheduleUpdate = new Date()
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
function updateStatus(node) {
|
|
13
|
+
function updateStatus (node) {
|
|
15
14
|
let fill = 'green'
|
|
16
15
|
let shape = 'ring'
|
|
17
16
|
let statusText = ''
|
|
17
|
+
|
|
18
|
+
if (node.config.verbose === true) {
|
|
19
|
+
node.warn('Running function updateStatus')
|
|
20
|
+
}
|
|
18
21
|
if (Stage && Stage.status && Stage.status[node.config.statusselect].stage) {
|
|
19
|
-
statusText += 'Stage '+Stage.status[node.config.statusselect].stage
|
|
22
|
+
statusText += 'Stage ' + (Stage.active || Stage.status[node.config.statusselect].stage)
|
|
20
23
|
}
|
|
21
24
|
if (LoadShedding && LoadShedding.active && LoadShedding.next && LoadShedding.next.end) {
|
|
22
25
|
statusText += ' - ' + new Date(LoadShedding.next.end).toLocaleTimeString()
|
|
23
|
-
fill = '
|
|
26
|
+
fill = 'yellow'
|
|
24
27
|
if (LoadShedding.type === 'event') {
|
|
25
28
|
shape = 'dot'
|
|
26
29
|
}
|
|
@@ -32,7 +35,7 @@ module.exports = function (RED) {
|
|
|
32
35
|
if (EskomSePushAPI) {
|
|
33
36
|
statusText += ` (API: ${EskomSePushAPI.allowance.count}/${EskomSePushAPI.allowance.limit})`
|
|
34
37
|
if (EskomSePushAPI.allowance.count >= EskomSePushAPI.allowance.limit) {
|
|
35
|
-
fill = 'red'
|
|
38
|
+
fill = 'red'
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
node.status({
|
|
@@ -43,6 +46,10 @@ module.exports = function (RED) {
|
|
|
43
46
|
function checkAllowance (node) {
|
|
44
47
|
const options = {}
|
|
45
48
|
const headers = { token: node.config.licensekey }
|
|
49
|
+
|
|
50
|
+
if (node.config.verbose === true) {
|
|
51
|
+
node.warn('Running function checkAllowance')
|
|
52
|
+
}
|
|
46
53
|
axios.get('https://developer.sepush.co.za/business/2.0/api_allowance',
|
|
47
54
|
{ params: options, headers }).then(function (response) {
|
|
48
55
|
EskomSePushAPI = response.data
|
|
@@ -56,6 +63,10 @@ module.exports = function (RED) {
|
|
|
56
63
|
function checkStage (node) {
|
|
57
64
|
const options = {}
|
|
58
65
|
const headers = { token: node.config.licensekey }
|
|
66
|
+
|
|
67
|
+
if (node.config.verbose === true) {
|
|
68
|
+
node.warn('Running function checkStage')
|
|
69
|
+
}
|
|
59
70
|
axios.get('https://developer.sepush.co.za/business/2.0/status',
|
|
60
71
|
{ params: options, headers }).then(function (response) {
|
|
61
72
|
Stage = response.data
|
|
@@ -70,6 +81,10 @@ module.exports = function (RED) {
|
|
|
70
81
|
const options = { id: node.config.area }
|
|
71
82
|
const headers = { token: node.config.licensekey }
|
|
72
83
|
const url = 'https://developer.sepush.co.za/business/2.0/area'
|
|
84
|
+
|
|
85
|
+
if (node.config.verbose === true) {
|
|
86
|
+
node.warn('Running function checkSchedule')
|
|
87
|
+
}
|
|
73
88
|
if (node.config.test) {
|
|
74
89
|
options.test = 'current'
|
|
75
90
|
}
|
|
@@ -87,6 +102,9 @@ module.exports = function (RED) {
|
|
|
87
102
|
function updateSheddingStatus (node) {
|
|
88
103
|
const now = new Date()
|
|
89
104
|
|
|
105
|
+
if (node.config.verbose === true) {
|
|
106
|
+
node.warn('Running function updateSheddingStatus')
|
|
107
|
+
}
|
|
90
108
|
if (EskomSePushAPI === null || (now.getTime() - lastStatusUpdate.getTime()) > 600000) {
|
|
91
109
|
checkAllowance(node)
|
|
92
110
|
lastStatusUpdate = now
|
|
@@ -112,7 +130,7 @@ module.exports = function (RED) {
|
|
|
112
130
|
}
|
|
113
131
|
|
|
114
132
|
if (Stage && Schedule && EskomSePushAPI) {
|
|
115
|
-
|
|
133
|
+
let stage = Stage.status[node.config.statusselect].stage
|
|
116
134
|
const nowtime = now.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' })
|
|
117
135
|
LoadShedding = {
|
|
118
136
|
schedule: {
|
|
@@ -125,20 +143,40 @@ module.exports = function (RED) {
|
|
|
125
143
|
},
|
|
126
144
|
checked: nowtime
|
|
127
145
|
}
|
|
128
|
-
|
|
146
|
+
|
|
147
|
+
if (!Array.isArray(Schedule.schedule.days[0].stages[stage])) {
|
|
148
|
+
node.warn(`No schedule defined for stage ${stage}`)
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
for (const schedule of Schedule.schedule.days[0].stages[stage]) {
|
|
129
153
|
if (nowtime >= schedule.split('-')[0] && nowtime <= schedule.split('-')[1]) {
|
|
130
154
|
LoadShedding.schedule = {
|
|
131
155
|
active: true
|
|
132
156
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
157
|
+
if (schedule.split('-')[0] < schedule.split('-')[1]) {
|
|
158
|
+
LoadShedding.schedule.next = {
|
|
159
|
+
start: Date.parse(Schedule.schedule.days[0].date + ' ' + schedule.split('-')[0]),
|
|
160
|
+
end: Date.parse(Schedule.schedule.days[0].date + ' ' + schedule.split('-')[1])
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
LoadShedding.schedule.next = {
|
|
164
|
+
start: Date.parse(Schedule.schedule.days[0].date + ' ' + schedule.split('-')[0]),
|
|
165
|
+
end: Date.parse(Schedule.schedule.days[1].date + ' ' + schedule.split('-')[1])
|
|
166
|
+
}
|
|
136
167
|
}
|
|
137
168
|
}
|
|
138
169
|
if (nowtime < schedule.split('-')[0]) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
170
|
+
if (schedule.split('-')[0] < schedule.split('-')[1]) {
|
|
171
|
+
LoadShedding.schedule.next = {
|
|
172
|
+
start: Date.parse(Schedule.schedule.days[0].date + ' ' + schedule.split('-')[0]),
|
|
173
|
+
end: Date.parse(Schedule.schedule.days[0].date + ' ' + schedule.split('-')[1])
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
LoadShedding.schedule.next = {
|
|
177
|
+
start: Date.parse(Schedule.schedule.days[0].date + ' ' + schedule.split('-')[0]),
|
|
178
|
+
end: Date.parse(Schedule.schedule.days[1].date + ' ' + schedule.split('-')[1])
|
|
179
|
+
}
|
|
142
180
|
}
|
|
143
181
|
}
|
|
144
182
|
}
|
|
@@ -155,6 +193,12 @@ module.exports = function (RED) {
|
|
|
155
193
|
}
|
|
156
194
|
if (now >= LoadShedding.event.next.start && now < LoadShedding.event.next.end) {
|
|
157
195
|
LoadShedding.event.active = true
|
|
196
|
+
if (Schedule.events[0].note.match(/Stage (\d+)/i)) {
|
|
197
|
+
stage = Schedule.events[0].note.match(/Stage (\d+)/i)[1]
|
|
198
|
+
Stage.active = stage
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
Stage.active = stage
|
|
158
202
|
}
|
|
159
203
|
|
|
160
204
|
if (!LoadShedding.schedule | !LoadShedding.schedule.next ||
|
|
@@ -172,6 +216,9 @@ module.exports = function (RED) {
|
|
|
172
216
|
LoadShedding.next.type = 'event'
|
|
173
217
|
}
|
|
174
218
|
|
|
219
|
+
LoadShedding.next.duration = (LoadShedding.next.end - LoadShedding.next.start) / 1000
|
|
220
|
+
LoadShedding.next.islong = LoadShedding.next.duration >= (4 * 3600)
|
|
221
|
+
|
|
175
222
|
LoadShedding.active = (LoadShedding.schedule.active || LoadShedding.event.active)
|
|
176
223
|
if (LoadShedding.schedule.active) {
|
|
177
224
|
LoadShedding.type = 'schedule'
|
|
@@ -243,4 +290,23 @@ module.exports = function (RED) {
|
|
|
243
290
|
return res.send({ error: error.message })
|
|
244
291
|
})
|
|
245
292
|
})
|
|
293
|
+
RED.httpNode.get('/eskomsepush/api', (req, res) => {
|
|
294
|
+
if (!req.query.token) {
|
|
295
|
+
res.setHeader('Content-Type', 'application/json')
|
|
296
|
+
return res.send('invalid')
|
|
297
|
+
}
|
|
298
|
+
const headers = {
|
|
299
|
+
token: req.query.token
|
|
300
|
+
}
|
|
301
|
+
const options = {}
|
|
302
|
+
|
|
303
|
+
res.setHeader('Content-Type', 'application/json')
|
|
304
|
+
axios.get('https://developer.sepush.co.za/business/2.0/api_allowance',
|
|
305
|
+
{ params: options, headers }).then(function (response) {
|
|
306
|
+
return res.send(response.data)
|
|
307
|
+
})
|
|
308
|
+
.catch(error => {
|
|
309
|
+
return res.send({ error: error.message })
|
|
310
|
+
})
|
|
311
|
+
})
|
|
246
312
|
}
|