nodejs-poolcontroller 7.3.1 → 7.6.1
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/.eslintrc.json +44 -44
- package/.github/ISSUE_TEMPLATE/bug_report.md +52 -52
- package/CONTRIBUTING.md +74 -74
- package/Changelog +215 -195
- package/Dockerfile +17 -17
- package/Gruntfile.js +40 -40
- package/LICENSE +661 -661
- package/README.md +191 -186
- package/app.ts +2 -0
- package/config/Config.ts +27 -2
- package/config/VersionCheck.ts +33 -14
- package/config copy.json +299 -299
- package/controller/Constants.ts +88 -0
- package/controller/Equipment.ts +2459 -2225
- package/controller/Errors.ts +180 -157
- package/controller/Lockouts.ts +437 -0
- package/controller/State.ts +364 -79
- package/controller/boards/BoardFactory.ts +45 -45
- package/controller/boards/EasyTouchBoard.ts +2653 -2489
- package/controller/boards/IntelliCenterBoard.ts +4230 -3973
- package/controller/boards/IntelliComBoard.ts +63 -63
- package/controller/boards/IntelliTouchBoard.ts +241 -167
- package/controller/boards/NixieBoard.ts +1675 -1105
- package/controller/boards/SystemBoard.ts +4697 -3201
- package/controller/comms/Comms.ts +222 -10
- package/controller/comms/messages/Messages.ts +13 -9
- package/controller/comms/messages/config/ChlorinatorMessage.ts +13 -4
- package/controller/comms/messages/config/CircuitGroupMessage.ts +6 -0
- package/controller/comms/messages/config/CircuitMessage.ts +0 -0
- package/controller/comms/messages/config/ConfigMessage.ts +0 -0
- package/controller/comms/messages/config/CoverMessage.ts +1 -0
- package/controller/comms/messages/config/CustomNameMessage.ts +30 -30
- package/controller/comms/messages/config/EquipmentMessage.ts +4 -0
- package/controller/comms/messages/config/ExternalMessage.ts +53 -33
- package/controller/comms/messages/config/FeatureMessage.ts +8 -1
- package/controller/comms/messages/config/GeneralMessage.ts +8 -0
- package/controller/comms/messages/config/HeaterMessage.ts +14 -28
- package/controller/comms/messages/config/IntellichemMessage.ts +4 -1
- package/controller/comms/messages/config/OptionsMessage.ts +38 -2
- package/controller/comms/messages/config/PumpMessage.ts +4 -20
- package/controller/comms/messages/config/RemoteMessage.ts +4 -0
- package/controller/comms/messages/config/ScheduleMessage.ts +347 -331
- package/controller/comms/messages/config/SecurityMessage.ts +1 -0
- package/controller/comms/messages/config/ValveMessage.ts +13 -3
- package/controller/comms/messages/status/ChlorinatorStateMessage.ts +2 -3
- package/controller/comms/messages/status/EquipmentStateMessage.ts +79 -25
- package/controller/comms/messages/status/HeaterStateMessage.ts +86 -53
- package/controller/comms/messages/status/IntelliChemStateMessage.ts +445 -386
- package/controller/comms/messages/status/IntelliValveStateMessage.ts +35 -35
- package/controller/comms/messages/status/PumpStateMessage.ts +0 -0
- package/controller/comms/messages/status/VersionMessage.ts +0 -0
- package/controller/nixie/Nixie.ts +162 -160
- package/controller/nixie/NixieEquipment.ts +103 -103
- package/controller/nixie/bodies/Body.ts +120 -117
- package/controller/nixie/bodies/Filter.ts +135 -135
- package/controller/nixie/chemistry/ChemController.ts +2498 -2395
- package/controller/nixie/chemistry/Chlorinator.ts +314 -313
- package/controller/nixie/circuits/Circuit.ts +248 -210
- package/controller/nixie/heaters/Heater.ts +649 -441
- package/controller/nixie/pumps/Pump.ts +661 -599
- package/controller/nixie/schedules/Schedule.ts +257 -256
- package/controller/nixie/valves/Valve.ts +170 -170
- package/defaultConfig.json +286 -271
- package/issue_template.md +51 -51
- package/logger/DataLogger.ts +448 -433
- package/logger/Logger.ts +0 -0
- package/package.json +56 -54
- package/tsconfig.json +25 -25
- package/web/Server.ts +522 -31
- package/web/bindings/influxDB.json +1022 -894
- package/web/bindings/mqtt.json +654 -543
- package/web/bindings/mqttAlt.json +684 -574
- package/web/bindings/rulesManager.json +54 -54
- package/web/bindings/smartThings-Hubitat.json +31 -31
- package/web/bindings/valveRelays.json +20 -20
- package/web/bindings/vera.json +25 -25
- package/web/interfaces/baseInterface.ts +136 -136
- package/web/interfaces/httpInterface.ts +124 -122
- package/web/interfaces/influxInterface.ts +245 -240
- package/web/interfaces/mqttInterface.ts +475 -464
- package/web/services/config/Config.ts +181 -152
- package/web/services/config/ConfigSocket.ts +0 -0
- package/web/services/state/State.ts +118 -7
- package/web/services/state/StateSocket.ts +18 -1
- package/web/services/utilities/Utilities.ts +42 -42
|
@@ -15,6 +15,8 @@ You should have received a copy of the GNU Affero General Public License
|
|
|
15
15
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
16
|
*/
|
|
17
17
|
import * as express from "express";
|
|
18
|
+
import * as extend from "extend";
|
|
19
|
+
|
|
18
20
|
import { state, ICircuitState, LightGroupState, ICircuitGroupState, ChemicalDoseState } from "../../../controller/State";
|
|
19
21
|
import { sys } from "../../../controller/Equipment";
|
|
20
22
|
import { utils } from '../../../controller/Constants';
|
|
@@ -79,7 +81,21 @@ export class StateRoute {
|
|
|
79
81
|
catch (err) { next(err); }
|
|
80
82
|
|
|
81
83
|
});
|
|
82
|
-
app.
|
|
84
|
+
app.get('/state/chemController/:id/doseLog/ph', async (req, res, next) => {
|
|
85
|
+
try {
|
|
86
|
+
let schem = state.chemControllers.getItemById(parseInt(req.params.id));
|
|
87
|
+
let filter = req.body || {};
|
|
88
|
+
let dh = await DataLogger.readFromEndAsync(`chemDosage_${schem.ph.chemType}.log`, ChemicalDoseState, (lineNumber: number, entry: ChemicalDoseState, arr: ChemicalDoseState[]): boolean => {
|
|
89
|
+
if (entry.id !== schem.id) return false;
|
|
90
|
+
if (typeof filter.lines !== 'undefined' && filter.lines <= arr.length) return false;
|
|
91
|
+
if (typeof filter.date !== 'undefined' && entry.end < filter.date) return false;
|
|
92
|
+
return true;
|
|
93
|
+
});
|
|
94
|
+
return res.status(200).send(dh);
|
|
95
|
+
}
|
|
96
|
+
catch (err) { next(err); }
|
|
97
|
+
});
|
|
98
|
+
app.search('/state/chemController/:id/doseLog/ph', async (req, res, next) => {
|
|
83
99
|
try {
|
|
84
100
|
let schem = state.chemControllers.getItemById(parseInt(req.params.id));
|
|
85
101
|
let filter = req.body || {};
|
|
@@ -93,6 +109,34 @@ export class StateRoute {
|
|
|
93
109
|
}
|
|
94
110
|
catch (err) { next(err); }
|
|
95
111
|
});
|
|
112
|
+
app.get('/state/chemController/:id/doseLog/orp', async (req, res, next) => {
|
|
113
|
+
try {
|
|
114
|
+
let schem = state.chemControllers.getItemById(parseInt(req.params.id));
|
|
115
|
+
let filter = req.body || {};
|
|
116
|
+
let dh = await DataLogger.readFromEndAsync(`chemDosage_orp.log`, ChemicalDoseState, (lineNumber: number, entry: ChemicalDoseState, arr: ChemicalDoseState[]): boolean => {
|
|
117
|
+
if (entry.id !== schem.id) return false;
|
|
118
|
+
if (typeof filter.lines !== 'undefined' && filter.lines <= arr.length) return false;
|
|
119
|
+
if (typeof filter.date !== 'undefined' && entry.end < filter.date) return false;
|
|
120
|
+
return true;
|
|
121
|
+
});
|
|
122
|
+
return res.status(200).send(dh);
|
|
123
|
+
}
|
|
124
|
+
catch (err) { next(err); }
|
|
125
|
+
});
|
|
126
|
+
app.search('/state/chemController/:id/doseLog/orp', async (req, res, next) => {
|
|
127
|
+
try {
|
|
128
|
+
let schem = state.chemControllers.getItemById(parseInt(req.params.id));
|
|
129
|
+
let filter = req.body || {};
|
|
130
|
+
let dh = DataLogger.readFromEnd(`chemDosage_orp.log`, ChemicalDoseState, (lineNumber: number, entry: ChemicalDoseState, arr: ChemicalDoseState[]): boolean => {
|
|
131
|
+
if (entry.id !== schem.id) return;
|
|
132
|
+
if (typeof filter.lines !== 'undefined' && filter.lines <= arr.length) return false;
|
|
133
|
+
if (typeof filter.date !== 'undefined' && entry.end < filter.date) return false;
|
|
134
|
+
return true;
|
|
135
|
+
});
|
|
136
|
+
return res.status(200).send(dh);
|
|
137
|
+
}
|
|
138
|
+
catch (err) { next(err); }
|
|
139
|
+
});
|
|
96
140
|
app.put('/state/chemController/cancelDosing', async (req, res, next) => {
|
|
97
141
|
try {
|
|
98
142
|
let schem = await sys.board.chemControllers.cancelDosingAsync(req.body);
|
|
@@ -109,7 +153,7 @@ export class StateRoute {
|
|
|
109
153
|
});
|
|
110
154
|
|
|
111
155
|
app.get('/state/chlorinator/:id', (req, res) => {
|
|
112
|
-
res.status(200).send(state.chlorinators.getItemById(parseInt(req.params.id, 10)).
|
|
156
|
+
res.status(200).send(state.chlorinators.getItemById(parseInt(req.params.id, 10), false).getExtended());
|
|
113
157
|
});
|
|
114
158
|
app.get('/state/circuit/:id', (req, res) => {
|
|
115
159
|
res.status(200).send(state.circuits.getItemById(parseInt(req.params.id, 10)).get());
|
|
@@ -170,7 +214,44 @@ export class StateRoute {
|
|
|
170
214
|
return res.status(200).send(theme.get(true));
|
|
171
215
|
}
|
|
172
216
|
catch (err) { next(err); }
|
|
173
|
-
});
|
|
217
|
+
});
|
|
218
|
+
app.put('/state/light/setTheme', async (req, res, next) => {
|
|
219
|
+
try {
|
|
220
|
+
let theme = await state.circuits.setLightThemeAsync(parseInt(req.body.id, 10), sys.board.valueMaps.lightThemes.encode(req.body.theme));
|
|
221
|
+
return res.status(200).send(theme.get(true));
|
|
222
|
+
}
|
|
223
|
+
catch (err) { next(err); }
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
app.put('/state/light/runCommand', async (req, res, next) => {
|
|
227
|
+
try {
|
|
228
|
+
let slight = await sys.board.circuits.runLightCommandAsync(req.body);
|
|
229
|
+
return res.status(200).send(slight.get(true));
|
|
230
|
+
}
|
|
231
|
+
catch (err) { next(err); }
|
|
232
|
+
});
|
|
233
|
+
app.put('/state/light/:id/colorHold', async (req, res, next) => {
|
|
234
|
+
try {
|
|
235
|
+
let slight = await sys.board.circuits.runLightCommandAsync({ id: parseInt(req.params.id, 10), command: 'colorhold' });
|
|
236
|
+
return res.status(200).send(slight.get(true));
|
|
237
|
+
}
|
|
238
|
+
catch (err) { next(err); }
|
|
239
|
+
});
|
|
240
|
+
app.put('/state/light/:id/colorRecall', async (req, res, next) => {
|
|
241
|
+
try {
|
|
242
|
+
let slight = await sys.board.circuits.runLightCommandAsync({ id: parseInt(req.params.id, 10), command: 'colorecall' });
|
|
243
|
+
return res.status(200).send(slight.get(true));
|
|
244
|
+
}
|
|
245
|
+
catch (err) { next(err); }
|
|
246
|
+
});
|
|
247
|
+
app.put('/state/light/:id/lightThumper', async (req, res, next) => {
|
|
248
|
+
try {
|
|
249
|
+
let slight = await sys.board.circuits.runLightCommandAsync({ id: parseInt(req.params.id, 10), command: 'lightthumper' });
|
|
250
|
+
return res.status(200).send(slight.get(true));
|
|
251
|
+
}
|
|
252
|
+
catch (err) { next(err); }
|
|
253
|
+
});
|
|
254
|
+
|
|
174
255
|
/* app.put('/state/intellibrite/setTheme', (req, res) => {
|
|
175
256
|
let id = sys.board.equipmentIds.circuitGroups.start;
|
|
176
257
|
if (typeof req.body.theme !== 'undefined') id = parseInt(req.body.id, 10);
|
|
@@ -229,7 +310,7 @@ export class StateRoute {
|
|
|
229
310
|
if (typeof req.body.heatSetpoint !== 'undefined' && !isNaN(parseInt(req.body.heatSetpoint, 10)))
|
|
230
311
|
await sys.board.bodies.setHeatSetpointAsync(body, parseInt(req.body.heatSetpoint, 10));
|
|
231
312
|
else if (typeof req.body.setPoint !== 'undefined' && !isNaN(parseInt(req.body.setPoint, 10)))
|
|
232
|
-
await sys.board.bodies.setHeatSetpointAsync(body, parseInt(req.body.
|
|
313
|
+
await sys.board.bodies.setHeatSetpointAsync(body, parseInt(req.body.setpoint, 10));
|
|
233
314
|
let tbody = state.temps.bodies.getItemById(body.id);
|
|
234
315
|
return res.status(200).send(tbody.get(true));
|
|
235
316
|
} catch (err) { next(err); }
|
|
@@ -286,27 +367,57 @@ export class StateRoute {
|
|
|
286
367
|
}
|
|
287
368
|
catch (err) { next(err); }
|
|
288
369
|
});
|
|
370
|
+
app.put('/state/lightGroup/runCommand', async (req, res, next) => {
|
|
371
|
+
try {
|
|
372
|
+
let sgroup = await sys.board.circuits.runLightGroupCommandAsync(req.body);
|
|
373
|
+
return res.status(200).send(sgroup.get(true));
|
|
374
|
+
}
|
|
375
|
+
catch (err) { next(err); }
|
|
376
|
+
});
|
|
289
377
|
app.put('/state/lightGroup/:id/colorSync', async (req, res, next) => {
|
|
290
378
|
try {
|
|
291
|
-
let sgroup = await sys.board.circuits.sequenceLightGroupAsync(parseInt(req.params.id, 10), '
|
|
379
|
+
let sgroup = await sys.board.circuits.sequenceLightGroupAsync(parseInt(req.params.id, 10), 'colorsync');
|
|
292
380
|
return res.status(200).send(sgroup.get(true));
|
|
293
381
|
}
|
|
294
382
|
catch (err) { next(err); }
|
|
295
383
|
});
|
|
296
384
|
app.put('/state/lightGroup/:id/colorSet', async (req, res, next) => {
|
|
297
385
|
try {
|
|
298
|
-
let sgroup = await sys.board.circuits.sequenceLightGroupAsync(parseInt(req.params.id, 10), '
|
|
386
|
+
let sgroup = await sys.board.circuits.sequenceLightGroupAsync(parseInt(req.params.id, 10), 'colorset');
|
|
299
387
|
return res.status(200).send(sgroup.get(true));
|
|
300
388
|
}
|
|
301
389
|
catch (err) { next(err); }
|
|
302
390
|
});
|
|
303
391
|
app.put('/state/lightGroup/:id/colorSwim', async (req, res, next) => {
|
|
304
392
|
try {
|
|
305
|
-
let sgroup = await sys.board.circuits.sequenceLightGroupAsync(parseInt(req.params.id, 10), '
|
|
393
|
+
let sgroup = await sys.board.circuits.sequenceLightGroupAsync(parseInt(req.params.id, 10), 'colorswim');
|
|
394
|
+
return res.status(200).send(sgroup.get(true));
|
|
395
|
+
}
|
|
396
|
+
catch (err) { next(err); }
|
|
397
|
+
});
|
|
398
|
+
app.put('/state/lightGroup/:id/colorHold', async (req, res, next) => {
|
|
399
|
+
try {
|
|
400
|
+
let sgroup = await sys.board.circuits.runLightGroupCommandAsync({ id: parseInt(req.params.id, 10), command: 'colorhold' });
|
|
401
|
+
return res.status(200).send(sgroup.get(true));
|
|
402
|
+
}
|
|
403
|
+
catch (err) { next(err); }
|
|
404
|
+
});
|
|
405
|
+
app.put('/state/lightGroup/:id/colorRecall', async (req, res, next) => {
|
|
406
|
+
try {
|
|
407
|
+
let sgroup = await sys.board.circuits.runLightGroupCommandAsync({ id: parseInt(req.params.id, 10), command: 'colorrecall' });
|
|
408
|
+
return res.status(200).send(sgroup.get(true));
|
|
409
|
+
}
|
|
410
|
+
catch (err) { next(err); }
|
|
411
|
+
});
|
|
412
|
+
app.put('/state/lightGroup/:id/lightThumper', async (req, res, next) => {
|
|
413
|
+
try {
|
|
414
|
+
let sgroup = await sys.board.circuits.runLightGroupCommandAsync({ id: parseInt(req.params.id, 10), command: 'lightthumper' });
|
|
306
415
|
return res.status(200).send(sgroup.get(true));
|
|
307
416
|
}
|
|
308
417
|
catch (err) { next(err); }
|
|
309
418
|
});
|
|
419
|
+
|
|
420
|
+
|
|
310
421
|
app.get('/state/emitAll', (req, res) => {
|
|
311
422
|
res.status(200).send(state.emitAllEquipmentChanges());
|
|
312
423
|
});
|
|
@@ -74,6 +74,7 @@ export class StateSocket {
|
|
|
74
74
|
}
|
|
75
75
|
catch (err) { logger.error(err); }
|
|
76
76
|
});
|
|
77
|
+
|
|
77
78
|
sock.on('/chlorinator', async (data: any) => {
|
|
78
79
|
try {
|
|
79
80
|
data = JSON.parse(data);
|
|
@@ -99,6 +100,22 @@ export class StateSocket {
|
|
|
99
100
|
}
|
|
100
101
|
catch (err) { logger.error(err); }
|
|
101
102
|
});
|
|
103
|
+
sock.on('/filter', async (data: any) => {
|
|
104
|
+
try {
|
|
105
|
+
data = JSON.parse(data);
|
|
106
|
+
let id = parseInt(data.id, 10);
|
|
107
|
+
let filter = sys.filters.find(elem => elem.id === id);
|
|
108
|
+
if (typeof filter !== 'undefined' && filter.isActive && !isNaN(filter.id)) {
|
|
109
|
+
let sfilter = state.filters.getItemById(filter.id, filter.isActive)
|
|
110
|
+
let pu = sys.board.valueMaps.pressureUnits.transform(filter.pressureUnits);
|
|
111
|
+
if (typeof data.pressure !== 'undefined')
|
|
112
|
+
await sys.board.filters.setFilterPressure(filter.id, data.pressure, data.pressureUnits || pu.name);
|
|
113
|
+
sfilter.emitEquipmentChange();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
} catch (err) { logger.error(err); }
|
|
118
|
+
});
|
|
102
119
|
sock.on('/chemController', async (data: any) => {
|
|
103
120
|
try {
|
|
104
121
|
//console.log(`chemController: ${data}`);
|
|
@@ -144,7 +161,7 @@ export class StateSocket {
|
|
|
144
161
|
if (typeof data.orpTank.units === 'string') scontroller.orp.tank.units = controller.orp.tank.units = data.orpTank.units;
|
|
145
162
|
}
|
|
146
163
|
|
|
147
|
-
// Need to build this out to include the type of controller. If this is
|
|
164
|
+
// Need to build this out to include the type of controller. If this is REM Chem we
|
|
148
165
|
// will send the whole rest of the nut over to it. Intellichem will only let us
|
|
149
166
|
// set specific values.
|
|
150
167
|
if (controller.type === 3) {
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
/* nodejs-poolController. An application to control pool equipment.
|
|
2
|
-
Copyright (C) 2016, 2017, 2018, 2019, 2020. Russell Goldin, tagyoureit. russ.goldin@gmail.com
|
|
3
|
-
|
|
4
|
-
This program is free software: you can redistribute it and/or modify
|
|
5
|
-
it under the terms of the GNU Affero General Public License as
|
|
6
|
-
published by the Free Software Foundation, either version 3 of the
|
|
7
|
-
License, or (at your option) any later version.
|
|
8
|
-
|
|
9
|
-
This program is distributed in the hope that it will be useful,
|
|
10
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
-
GNU Affero General Public License for more details.
|
|
13
|
-
|
|
14
|
-
You should have received a copy of the GNU Affero General Public License
|
|
15
|
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
-
*/
|
|
17
|
-
import * as express from 'express';
|
|
18
|
-
import { SsdpServer} from '../../Server';
|
|
19
|
-
import { state } from "../../../controller/State";
|
|
20
|
-
import { sys } from "../../../controller/Equipment";
|
|
21
|
-
|
|
22
|
-
const extend = require("extend");
|
|
23
|
-
export class UtilitiesRoute {
|
|
24
|
-
|
|
25
|
-
public static initRoutes(app: express.Application) {
|
|
26
|
-
app.get('/device', function(req, res) {
|
|
27
|
-
// there's got to be a better way to get this than instantiating SsdpServer() again.
|
|
28
|
-
// RKS: There was I made the function static.
|
|
29
|
-
let xml = SsdpServer.deviceXML();
|
|
30
|
-
res.status(200).set('Content-Type', 'text/xml').send(xml);
|
|
31
|
-
});
|
|
32
|
-
app.get('/extended/:section', (req, res) => {
|
|
33
|
-
let cfg = sys.getSection(req.params.section);
|
|
34
|
-
let st = state.getState(req.params.section);
|
|
35
|
-
let arr = [];
|
|
36
|
-
for (let i = 0; i < cfg.length; i++){
|
|
37
|
-
let p = extend(true, {}, cfg[i], st.find(s => s.id === cfg[i].id));
|
|
38
|
-
arr.push(p);
|
|
39
|
-
}
|
|
40
|
-
return res.status(200).send(arr);
|
|
41
|
-
});
|
|
42
|
-
}
|
|
1
|
+
/* nodejs-poolController. An application to control pool equipment.
|
|
2
|
+
Copyright (C) 2016, 2017, 2018, 2019, 2020. Russell Goldin, tagyoureit. russ.goldin@gmail.com
|
|
3
|
+
|
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU Affero General Public License as
|
|
6
|
+
published by the Free Software Foundation, either version 3 of the
|
|
7
|
+
License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU Affero General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
import * as express from 'express';
|
|
18
|
+
import { SsdpServer} from '../../Server';
|
|
19
|
+
import { state } from "../../../controller/State";
|
|
20
|
+
import { sys } from "../../../controller/Equipment";
|
|
21
|
+
|
|
22
|
+
const extend = require("extend");
|
|
23
|
+
export class UtilitiesRoute {
|
|
24
|
+
|
|
25
|
+
public static initRoutes(app: express.Application) {
|
|
26
|
+
app.get('/device', function(req, res) {
|
|
27
|
+
// there's got to be a better way to get this than instantiating SsdpServer() again.
|
|
28
|
+
// RKS: There was I made the function static.
|
|
29
|
+
let xml = SsdpServer.deviceXML();
|
|
30
|
+
res.status(200).set('Content-Type', 'text/xml').send(xml);
|
|
31
|
+
});
|
|
32
|
+
app.get('/extended/:section', (req, res) => {
|
|
33
|
+
let cfg = sys.getSection(req.params.section);
|
|
34
|
+
let st = state.getState(req.params.section);
|
|
35
|
+
let arr = [];
|
|
36
|
+
for (let i = 0; i < cfg.length; i++){
|
|
37
|
+
let p = extend(true, {}, cfg[i], st.find(s => s.id === cfg[i].id));
|
|
38
|
+
arr.push(p);
|
|
39
|
+
}
|
|
40
|
+
return res.status(200).send(arr);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
43
|
}
|