homebridge-smartsystem 6.3.4 → 6.4.2
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 +39 -34
- package/config.json +48 -56
- package/duotecno/master.js +85 -3
- package/duotecno/master.ts +88 -6
- package/duotecno/protocol.js +97 -25
- package/duotecno/protocol.ts +103 -27
- package/duotecno/types.js +8 -4
- package/duotecno/types.ts +12 -6
- package/index.spec.js +1 -0
- package/index.spec.ts +1 -0
- package/package.json +1 -1
- package/server/powerbase.js +15 -16
- package/server/powerbase.ts +19 -18
- package/server/smartapp.js +11 -6
- package/server/smartapp.ts +15 -8
- package/server/somfy.ts +4 -2
- package/server/views/master-detail.ejs +16 -0
- package/server/views/master-list.ejs +2 -0
- package/server/views/power-binding.ejs +3 -3
- package/server/views/power.ejs +3 -3
package/README.md
CHANGED
|
@@ -245,42 +245,47 @@ Homebridge UI version
|
|
|
245
245
|
added "restart plugin" to settings,
|
|
246
246
|
set lock target state to "locked"
|
|
247
247
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
248
|
+
### v6.1.0 - 15-07-2022
|
|
249
|
+
- global debug, log, err functions in types.ts
|
|
250
|
+
- split smappee.ts in PowerBase + smappee/p1/shelly
|
|
251
|
+
|
|
252
|
+
### v6.1.x - 21-07-2022 - P1 release
|
|
253
|
+
- 0: implemented P1 power meter telegram
|
|
254
|
+
- 1: bugfixes, timeout mgt, etc...
|
|
255
|
+
- 2: try fixing logfunction errors
|
|
256
|
+
- 3: reverting to console.log
|
|
257
|
+
- 4: errors when starting power mgrs from platform.ts
|
|
258
|
+
- 5: v6.1.3 changes were gone... restored them.
|
|
259
|
+
- 6: added login with pw in config + http.get with on-error
|
|
260
|
+
- 6: allow + and - in power rules expressions
|
|
261
|
+
- 7: allow NaN in bindings compare for update
|
|
262
262
|
|
|
263
263
|
### v6.2.0 - 10-08-2022 - fully use Homebridge UI (login, config)
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
264
|
+
- receive config through Platform on startup,
|
|
265
|
+
- moved all config to global variable, keep in sync through API of HB-UI
|
|
266
|
+
- implemented login page, use HB-UI api -> bearer jwt token
|
|
267
|
+
- added upgrade method from 6.1.x to v6.2.x (adding files from /home/homebridge/duotecno/config.*.json to global config.*)
|
|
268
|
+
- homebridge config is saved by UI in: /var/lib/homebridge/config.json (as well as the logfile: homebridge.log)
|
|
269
|
+
- smartapp calls Homebridge UI API to save changes
|
|
270
|
+
|
|
271
|
+
### v6.2.x - 11-08-2022 - P1 release
|
|
272
|
+
- 1 : always write config to file too (next to sending through the HB-UI API)
|
|
273
|
+
- 2: added headers to http calls from switches, dimmers and up/down's (including OH stuff)
|
|
274
|
+
- 3: fixed bug in Sanitizer of UnitConfig preventing from publishing units to homebridge
|
|
275
|
+
- 4: fixed empty name bug in unit-def / new accessory()
|
|
276
|
+
- 5: fixed bad displayNames in published units
|
|
277
|
+
- 6: power: 5% instead of 10% for power rules
|
|
278
|
+
|
|
279
|
+
### v6.3.x - 23-09-2022 - Shelly PM release
|
|
280
|
+
- 1: first test Shelly PM - allow address or addresses, example: "192.168.0.95,102.168.0.96"
|
|
281
|
+
- 2: logging now more according to debug true/false in the config file
|
|
282
|
+
- 3: power bindings now when: 5% change < 1000W, 2% change > 1000W
|
|
283
|
+
- 4: added if in set-plug if smappee not (yet) connected.
|
|
284
|
+
|
|
285
|
+
### v6.4.x - 28-11-2022 - Binding to registers
|
|
286
|
+
- 0: writing to registers
|
|
287
|
+
- 1: ask/show protocol version -> publish
|
|
288
|
+
- 2: test on firmware version, not protocol for using registers, due to bug in master firmware pre v101.x
|
|
284
289
|
|
|
285
290
|
## Hardware
|
|
286
291
|
A Raspberry Pi that connects to a Duotecno IP Node
|
package/config.json
CHANGED
|
@@ -35,17 +35,17 @@
|
|
|
35
35
|
"logicalNodeAddress": 3
|
|
36
36
|
}
|
|
37
37
|
],
|
|
38
|
-
"power":
|
|
39
|
-
"current":
|
|
38
|
+
"power": -758,
|
|
39
|
+
"current": 0
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"type": "power",
|
|
43
43
|
"channel": "7+8+9",
|
|
44
|
-
"low":
|
|
44
|
+
"low": 500,
|
|
45
45
|
"high": 10000,
|
|
46
46
|
"actions": [
|
|
47
47
|
{
|
|
48
|
-
"name": "",
|
|
48
|
+
"name": "Blue LED",
|
|
49
49
|
"value": false,
|
|
50
50
|
"masterAddress": "192.168.0.97",
|
|
51
51
|
"masterPort": 5001,
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"logicalNodeAddress": 3
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
|
-
"name": "",
|
|
56
|
+
"name": "Blue LED",
|
|
57
57
|
"value": true,
|
|
58
58
|
"masterAddress": "192.168.0.97",
|
|
59
59
|
"masterPort": 5001,
|
|
@@ -61,16 +61,14 @@
|
|
|
61
61
|
"logicalNodeAddress": 3
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
|
-
"name": "
|
|
64
|
+
"name": "--",
|
|
65
65
|
"value": true,
|
|
66
66
|
"masterAddress": "192.168.0.97",
|
|
67
67
|
"masterPort": 5001,
|
|
68
68
|
"logicalAddress": 0,
|
|
69
69
|
"logicalNodeAddress": 0
|
|
70
70
|
}
|
|
71
|
-
]
|
|
72
|
-
"power": 446,
|
|
73
|
-
"current": 1
|
|
71
|
+
]
|
|
74
72
|
},
|
|
75
73
|
{
|
|
76
74
|
"type": "power",
|
|
@@ -102,55 +100,37 @@
|
|
|
102
100
|
"logicalAddress": 0,
|
|
103
101
|
"logicalNodeAddress": 0
|
|
104
102
|
}
|
|
105
|
-
]
|
|
103
|
+
],
|
|
104
|
+
"power": 266,
|
|
105
|
+
"current": 0
|
|
106
106
|
}
|
|
107
107
|
],
|
|
108
|
-
"address": "192.168.0.
|
|
108
|
+
"address": "192.168.0.183",
|
|
109
109
|
"uid": "57e3e0d8-bb05-4b04-8662-1a9871998f3f",
|
|
110
110
|
"bindings": [
|
|
111
111
|
{
|
|
112
|
-
"
|
|
113
|
-
"logicalAddress": 102,
|
|
112
|
+
"channel": "0+1",
|
|
114
113
|
"masterAddress": "192.168.0.97",
|
|
115
114
|
"masterPort": 5001,
|
|
116
|
-
"
|
|
117
|
-
"displayName": "unit 252:102",
|
|
118
|
-
"extendedType": 0,
|
|
119
|
-
"channel": "0+1",
|
|
120
|
-
"power": 1706
|
|
115
|
+
"register": 1
|
|
121
116
|
},
|
|
122
117
|
{
|
|
123
|
-
"
|
|
124
|
-
"logicalAddress": 100,
|
|
118
|
+
"channel": "2+3",
|
|
125
119
|
"masterAddress": "192.168.0.97",
|
|
126
120
|
"masterPort": 5001,
|
|
127
|
-
"
|
|
128
|
-
"displayName": "unit 252:100",
|
|
129
|
-
"extendedType": 0,
|
|
130
|
-
"channel": "2+3",
|
|
131
|
-
"power": 2494
|
|
121
|
+
"register": 2
|
|
132
122
|
},
|
|
133
123
|
{
|
|
134
|
-
"
|
|
135
|
-
"logicalAddress": 103,
|
|
124
|
+
"channel": "4+5",
|
|
136
125
|
"masterAddress": "192.168.0.97",
|
|
137
126
|
"masterPort": 5001,
|
|
138
|
-
"
|
|
139
|
-
"displayName": "unit 252:103",
|
|
140
|
-
"extendedType": 0,
|
|
141
|
-
"channel": "4+5",
|
|
142
|
-
"power": null
|
|
127
|
+
"register": 7
|
|
143
128
|
},
|
|
144
129
|
{
|
|
145
|
-
"
|
|
146
|
-
"logicalAddress": 101,
|
|
130
|
+
"channel": "8",
|
|
147
131
|
"masterAddress": "192.168.0.97",
|
|
148
132
|
"masterPort": 5001,
|
|
149
|
-
"
|
|
150
|
-
"displayName": "unit 252:101",
|
|
151
|
-
"extendedType": 0,
|
|
152
|
-
"channel": "8",
|
|
153
|
-
"power": null
|
|
133
|
+
"register": 8
|
|
154
134
|
}
|
|
155
135
|
]
|
|
156
136
|
},
|
|
@@ -159,36 +139,33 @@
|
|
|
159
139
|
"rules": [],
|
|
160
140
|
"bindings": [
|
|
161
141
|
{
|
|
162
|
-
"
|
|
163
|
-
"logicalAddress": 102,
|
|
142
|
+
"channel": "0+1+2",
|
|
164
143
|
"masterAddress": "192.168.0.97",
|
|
165
144
|
"masterPort": 5001,
|
|
166
|
-
"
|
|
167
|
-
"displayName": "unit 252:102",
|
|
168
|
-
"extendedType": 0,
|
|
169
|
-
"channel": "0+1+2",
|
|
170
|
-
"power": null
|
|
145
|
+
"register": 11
|
|
171
146
|
},
|
|
172
147
|
{
|
|
173
|
-
"
|
|
174
|
-
"logicalAddress": 100,
|
|
148
|
+
"channel": "3+4+5",
|
|
175
149
|
"masterAddress": "192.168.0.97",
|
|
176
150
|
"masterPort": 5001,
|
|
177
|
-
"
|
|
178
|
-
"displayName": "unit 252:100",
|
|
179
|
-
"extendedType": 0,
|
|
180
|
-
"channel": "3+4+5",
|
|
181
|
-
"power": null
|
|
151
|
+
"register": 12
|
|
182
152
|
}
|
|
183
153
|
],
|
|
184
|
-
"address": "192.168.0.
|
|
154
|
+
"address": "192.168.0.206"
|
|
185
155
|
},
|
|
186
156
|
"shelly": {
|
|
187
157
|
"debug": false,
|
|
188
158
|
"address": "192.168.0.95",
|
|
189
159
|
"addresses": "192.168.0.95,192.168.0.95",
|
|
190
160
|
"rules": [],
|
|
191
|
-
"bindings": [
|
|
161
|
+
"bindings": [
|
|
162
|
+
{
|
|
163
|
+
"channel": "0+1+2+3+4+5+6+7+8",
|
|
164
|
+
"masterAddress": "192.168.0.97",
|
|
165
|
+
"masterPort": 5001,
|
|
166
|
+
"register": 5
|
|
167
|
+
}
|
|
168
|
+
]
|
|
192
169
|
},
|
|
193
170
|
"smartapp": {
|
|
194
171
|
"apiPort": 8581,
|
|
@@ -310,6 +287,21 @@
|
|
|
310
287
|
"252": " 20211003"
|
|
311
288
|
},
|
|
312
289
|
"debug": false
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"address": "192.168.0.5",
|
|
293
|
+
"port": 5005,
|
|
294
|
+
"password": "duotecno",
|
|
295
|
+
"name": "GM",
|
|
296
|
+
"active": true,
|
|
297
|
+
"nodenames": {
|
|
298
|
+
"3": "IP Server",
|
|
299
|
+
"4": "Sonos",
|
|
300
|
+
"16": "Smartbox Living",
|
|
301
|
+
"17": "Switch Living",
|
|
302
|
+
"252": " 20220925"
|
|
303
|
+
},
|
|
304
|
+
"debug": false
|
|
313
305
|
}
|
|
314
306
|
],
|
|
315
307
|
"cunits": [
|
|
@@ -450,7 +442,7 @@
|
|
|
450
442
|
"units": []
|
|
451
443
|
}
|
|
452
444
|
],
|
|
453
|
-
"debug":
|
|
445
|
+
"debug": true,
|
|
454
446
|
"settings": {
|
|
455
447
|
"network": {
|
|
456
448
|
"ip1": "1.2.3.4",
|
package/duotecno/master.js
CHANGED
|
@@ -134,6 +134,9 @@ class Master extends base_1.Base {
|
|
|
134
134
|
*/
|
|
135
135
|
constructor(system, config) {
|
|
136
136
|
super("master", types_1.Sanitizers.masterConfig(config));
|
|
137
|
+
this.protocol = 0; // major * 100 + minor
|
|
138
|
+
this.version = 0; // idem
|
|
139
|
+
this.registers = {};
|
|
137
140
|
this.resolveLogin = null;
|
|
138
141
|
this.Q = new Q_1.Q();
|
|
139
142
|
// save my eco system
|
|
@@ -150,6 +153,9 @@ class Master extends base_1.Base {
|
|
|
150
153
|
this.closing = false;
|
|
151
154
|
// incoming data
|
|
152
155
|
this.buffer = "";
|
|
156
|
+
// init to v1.00
|
|
157
|
+
this.version = 100;
|
|
158
|
+
this.protocol = 100;
|
|
153
159
|
}
|
|
154
160
|
getName() {
|
|
155
161
|
return this.config.name || "master";
|
|
@@ -360,8 +366,8 @@ class Master extends base_1.Base {
|
|
|
360
366
|
return false;
|
|
361
367
|
}
|
|
362
368
|
else {
|
|
363
|
-
|
|
364
|
-
|
|
369
|
+
// don't log all incoming (no time, no sensor status messages)
|
|
370
|
+
if ((next.cmd != protocol_1.Rec.TimeDateStatus) && (next.cmd != protocol_1.Rec.Sensor))
|
|
365
371
|
this.info("received -> " + (0, protocol_1.recName)(next.cmd) + " -> " + ((!next.message) ?
|
|
366
372
|
"--" : ((next.message instanceof Array) ? next.message.join(",") : next.message)));
|
|
367
373
|
this.Q.do();
|
|
@@ -384,6 +390,12 @@ class Master extends base_1.Base {
|
|
|
384
390
|
else if (next.cmd === protocol_1.Rec.ScheduleStatus) {
|
|
385
391
|
this.receiveSchedule(next.message);
|
|
386
392
|
}
|
|
393
|
+
else if (next.cmd === protocol_1.Rec.NodeMgtInfo) {
|
|
394
|
+
this.receiveNodeMgtInfo(next.message);
|
|
395
|
+
}
|
|
396
|
+
else if (next.cmd === protocol_1.Rec.Register) {
|
|
397
|
+
this.receiveRegister(next.message);
|
|
398
|
+
}
|
|
387
399
|
else {
|
|
388
400
|
this.info("not handled: " + next.message);
|
|
389
401
|
}
|
|
@@ -398,6 +410,10 @@ class Master extends base_1.Base {
|
|
|
398
410
|
if (this.resolveLogin) {
|
|
399
411
|
this.resolveLogin(this.isLoggedIn);
|
|
400
412
|
this.resolveLogin = null;
|
|
413
|
+
// if logged in, ask protocol version
|
|
414
|
+
if (this.isLoggedIn) {
|
|
415
|
+
this.send(protocol_1.Protocol.buildRequestNodeMgt(protocol_1.reqNodeAttributes.nodeProtocol));
|
|
416
|
+
}
|
|
401
417
|
}
|
|
402
418
|
else {
|
|
403
419
|
this.err("unexpected ConnectStatus ?");
|
|
@@ -406,7 +422,45 @@ class Master extends base_1.Base {
|
|
|
406
422
|
///////////////////
|
|
407
423
|
// Info messages //
|
|
408
424
|
///////////////////
|
|
409
|
-
|
|
425
|
+
receiveNodeMgtInfo(message) {
|
|
426
|
+
if (message[1] === protocol_1.reqNodeAttributes.isMaster) {
|
|
427
|
+
this.log("NodeMgtInfo - master " + this.getName() + " is set to master: " + message[2]);
|
|
428
|
+
}
|
|
429
|
+
else if (message[1] === protocol_1.reqNodeAttributes.nodeInfo) {
|
|
430
|
+
// should be the same as the one from the DBInfo (64)
|
|
431
|
+
this.log("NodeMgtInfo - node info for " + this.getName() + ": " + message);
|
|
432
|
+
}
|
|
433
|
+
else if (message[1] === protocol_1.reqNodeAttributes.masterSupported) {
|
|
434
|
+
this.log("NodeMgtInfo - master " + this.getName() + " can be master: " + message[2]);
|
|
435
|
+
}
|
|
436
|
+
else if (message[1] === protocol_1.reqNodeAttributes.nodeVersion) {
|
|
437
|
+
console.log("*** -> " + message);
|
|
438
|
+
this.log("NodeMgtInfo - version " + this.getName() + ", version: " + message[2] + "." + message[3]);
|
|
439
|
+
this.version = message[2] * 100 + message[3];
|
|
440
|
+
//BUG - TODO: remove
|
|
441
|
+
this.protocol = message[2] * 100 + message[3];
|
|
442
|
+
}
|
|
443
|
+
else if (message[1] === protocol_1.reqNodeAttributes.nodeProtocol) {
|
|
444
|
+
console.log("*** -> " + message);
|
|
445
|
+
this.log("NodeMgtInfo - protocol " + this.getName() + ", protocol: " + message[2] + "." + message[3]);
|
|
446
|
+
this.protocol = message[2] * 100 + message[3];
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
this.err("dropped NodeMgtInfo info message = " + message[1] + ", message: " + message);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
receiveRegister(message) {
|
|
453
|
+
const register = protocol_1.Protocol.makeWord(message, 2);
|
|
454
|
+
const value = protocol_1.Protocol.makeSigned(message, 4);
|
|
455
|
+
if ((register >= 0) && (register < 1024)) {
|
|
456
|
+
this.registers[register] = value;
|
|
457
|
+
this.log("receiveRegister(" + register + ") = " + value);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
this.err("Received register out of bound: " + register);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
receiveHeartbeat(message) {
|
|
410
464
|
this.lastHeartbeat = new Date().getTime();
|
|
411
465
|
//console.log("*HB* Received HB");
|
|
412
466
|
this.log("Received heartbeat at " + (new Date()));
|
|
@@ -486,6 +540,9 @@ class Master extends base_1.Base {
|
|
|
486
540
|
}
|
|
487
541
|
this.system.setActiveState(unit);
|
|
488
542
|
}
|
|
543
|
+
//////////////////
|
|
544
|
+
// request info //
|
|
545
|
+
//////////////////
|
|
489
546
|
fetchAllUnits(node) {
|
|
490
547
|
return __awaiter(this, void 0, void 0, function* () {
|
|
491
548
|
for (let unitInx = 0; unitInx < node.nrUnits; unitInx++) {
|
|
@@ -694,6 +751,20 @@ class Master extends base_1.Base {
|
|
|
694
751
|
this.info("get value of " + unit.node.getName() + "-" + unit.getName());
|
|
695
752
|
});
|
|
696
753
|
}
|
|
754
|
+
requestRegisterValue(register) {
|
|
755
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
756
|
+
if (this.version >= 209) {
|
|
757
|
+
yield this.send(protocol_1.Protocol.buildRegister(register));
|
|
758
|
+
this.info("request register: " + register);
|
|
759
|
+
}
|
|
760
|
+
else {
|
|
761
|
+
this.err("FC_REGISTERMAP not available before protocol v2.09");
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
/////////////////////
|
|
766
|
+
// Settings values //
|
|
767
|
+
/////////////////////
|
|
697
768
|
setUnitStatus(unit, value) {
|
|
698
769
|
return __awaiter(this, void 0, void 0, function* () {
|
|
699
770
|
const params = protocol_1.Protocol.buildSetCmd(unit.node, unit, value);
|
|
@@ -702,6 +773,17 @@ class Master extends base_1.Base {
|
|
|
702
773
|
}
|
|
703
774
|
});
|
|
704
775
|
}
|
|
776
|
+
setRegisterValue(register, value) {
|
|
777
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
778
|
+
if (this.version >= 209) {
|
|
779
|
+
yield this.send(protocol_1.Protocol.buildRegister(register, value));
|
|
780
|
+
this.info("set register: " + register + ", to: " + value);
|
|
781
|
+
}
|
|
782
|
+
else {
|
|
783
|
+
this.err("FC_REGISTERMAP not available before protocol v2.09");
|
|
784
|
+
}
|
|
785
|
+
});
|
|
786
|
+
}
|
|
705
787
|
setSensorValue(unit, value) {
|
|
706
788
|
return __awaiter(this, void 0, void 0, function* () {
|
|
707
789
|
this.info("SetSensorValue of " + unit.node.logicalAddress + "/" + unit.logicalAddress + " to " + value);
|
package/duotecno/master.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Node, Protocol, Unit, recName, Rec, TempPreset } from "./protocol";
|
|
1
|
+
import { Node, Protocol, Unit, recName, Rec, TempPreset, reqNodeAttributes } from "./protocol";
|
|
2
2
|
import { MasterConfig, WriteError, CommRecord, Message, Sanitizers } from "./types";
|
|
3
3
|
import { log, debug } from "./logger";
|
|
4
4
|
import { System } from "./system";
|
|
@@ -15,6 +15,10 @@ export class Master extends Base {
|
|
|
15
15
|
public schedule: number;
|
|
16
16
|
public date: Date;
|
|
17
17
|
public lastHeartbeat: number;
|
|
18
|
+
public protocol: number = 0; // major * 100 + minor
|
|
19
|
+
public version: number = 0; // idem
|
|
20
|
+
|
|
21
|
+
public registers: {[register: number]: number} = {};
|
|
18
22
|
|
|
19
23
|
public isOpen: boolean;
|
|
20
24
|
public isLoggedIn: boolean;
|
|
@@ -166,6 +170,10 @@ export class Master extends Base {
|
|
|
166
170
|
|
|
167
171
|
// incoming data
|
|
168
172
|
this.buffer = "";
|
|
173
|
+
|
|
174
|
+
// init to v1.00
|
|
175
|
+
this.version = 100;
|
|
176
|
+
this.protocol = 100;
|
|
169
177
|
}
|
|
170
178
|
|
|
171
179
|
getName() {
|
|
@@ -398,8 +406,8 @@ export class Master extends Base {
|
|
|
398
406
|
return false;
|
|
399
407
|
|
|
400
408
|
} else {
|
|
401
|
-
|
|
402
|
-
|
|
409
|
+
// don't log all incoming (no time, no sensor status messages)
|
|
410
|
+
if ((next.cmd != Rec.TimeDateStatus) && (next.cmd != Rec.Sensor))
|
|
403
411
|
this.info("received -> " + recName(next.cmd) + " -> " + ((!next.message) ?
|
|
404
412
|
"--" : ((next.message instanceof Array) ? next.message.join(",") : next.message)));
|
|
405
413
|
|
|
@@ -423,6 +431,12 @@ export class Master extends Base {
|
|
|
423
431
|
|
|
424
432
|
} else if (next.cmd === Rec.ScheduleStatus) {
|
|
425
433
|
this.receiveSchedule(next.message);
|
|
434
|
+
|
|
435
|
+
} else if (next.cmd === Rec.NodeMgtInfo) {
|
|
436
|
+
this.receiveNodeMgtInfo(next.message);
|
|
437
|
+
|
|
438
|
+
} else if (next.cmd === Rec.Register) {
|
|
439
|
+
this.receiveRegister(next.message);
|
|
426
440
|
|
|
427
441
|
} else {
|
|
428
442
|
this.info("not handled: " + next.message);
|
|
@@ -442,6 +456,12 @@ export class Master extends Base {
|
|
|
442
456
|
if (this.resolveLogin) {
|
|
443
457
|
this.resolveLogin(this.isLoggedIn);
|
|
444
458
|
this.resolveLogin = null;
|
|
459
|
+
|
|
460
|
+
// if logged in, ask protocol version
|
|
461
|
+
if (this.isLoggedIn) {
|
|
462
|
+
this.send(Protocol.buildRequestNodeMgt(reqNodeAttributes.nodeVersion));
|
|
463
|
+
}
|
|
464
|
+
|
|
445
465
|
} else {
|
|
446
466
|
this.err("unexpected ConnectStatus ?");
|
|
447
467
|
}
|
|
@@ -451,7 +471,46 @@ export class Master extends Base {
|
|
|
451
471
|
// Info messages //
|
|
452
472
|
///////////////////
|
|
453
473
|
|
|
454
|
-
|
|
474
|
+
receiveNodeMgtInfo(message: Message) {
|
|
475
|
+
if (message[1] === reqNodeAttributes.isMaster) {
|
|
476
|
+
this.log("NodeMgtInfo - master " + this.getName() + " is set to master: " + message[2]);
|
|
477
|
+
|
|
478
|
+
} else if (message[1] === reqNodeAttributes.nodeInfo) {
|
|
479
|
+
// should be the same as the one from the DBInfo (64)
|
|
480
|
+
this.log("NodeMgtInfo - node info for " + this.getName() + ": " + message);
|
|
481
|
+
|
|
482
|
+
} else if (message[1] === reqNodeAttributes.masterSupported) {
|
|
483
|
+
this.log("NodeMgtInfo - master " + this.getName() + " can be master: " + message[2]);
|
|
484
|
+
|
|
485
|
+
} else if (message[1] === reqNodeAttributes.nodeVersion) {
|
|
486
|
+
this.log("NodeMgtInfo - version " + this.getName() + ", version: " + message[2] + "." + message[3]);
|
|
487
|
+
this.version = message[2] * 100 + message[3];
|
|
488
|
+
console.log("*** version -> " + message + " -> " + this.version + " ***");
|
|
489
|
+
|
|
490
|
+
} else if (message[1] === reqNodeAttributes.nodeProtocol) {
|
|
491
|
+
this.log("NodeMgtInfo - protocol " + this.getName() + ", protocol: " + message[2] + "." + message[3]);
|
|
492
|
+
this.protocol = message[2] * 100 + message[3];
|
|
493
|
+
console.log("*** protocol -> " + message + " -> " + this.protocol + " ***");
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
} else {
|
|
497
|
+
this.err("dropped NodeMgtInfo info message = " + message[1] + ", message: " + message);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
receiveRegister(message: Message) {
|
|
502
|
+
const register = Protocol.makeWord(message, 2);
|
|
503
|
+
const value = Protocol.makeSigned(message, 4);
|
|
504
|
+
|
|
505
|
+
if ((register >=0) && (register < 1024)) {
|
|
506
|
+
this.registers[register] = value;
|
|
507
|
+
this.log("receiveRegister(" + register + ") = " + value);
|
|
508
|
+
} else {
|
|
509
|
+
this.err("Received register out of bound: " + register);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
receiveHeartbeat(message: Message) {
|
|
455
514
|
this.lastHeartbeat = new Date().getTime();
|
|
456
515
|
//console.log("*HB* Received HB");
|
|
457
516
|
this.log("Received heartbeat at " + (new Date()));
|
|
@@ -478,6 +537,7 @@ export class Master extends Base {
|
|
|
478
537
|
this.info("received week schedule = " + this.schedule);
|
|
479
538
|
}
|
|
480
539
|
|
|
540
|
+
|
|
481
541
|
receiveDateTime(message: Message) {
|
|
482
542
|
// 71,0,9,37,3,3,4,3,21,20 -> 09:37:03 Wednesday(3) 4 march 2120
|
|
483
543
|
this.date = new Date( (message[8]-1) * 100 + message[9], message[7]-1, message[6],
|
|
@@ -540,7 +600,9 @@ export class Master extends Base {
|
|
|
540
600
|
this.system.setActiveState(unit);
|
|
541
601
|
}
|
|
542
602
|
|
|
543
|
-
|
|
603
|
+
//////////////////
|
|
604
|
+
// request info //
|
|
605
|
+
//////////////////
|
|
544
606
|
async fetchAllUnits(node: Node) {
|
|
545
607
|
for (let unitInx=0; unitInx < node.nrUnits; unitInx++) {
|
|
546
608
|
await this.fetchUnit(node, unitInx);
|
|
@@ -755,6 +817,18 @@ export class Master extends Base {
|
|
|
755
817
|
this.info("get value of " + unit.node.getName() + "-" + unit.getName());
|
|
756
818
|
}
|
|
757
819
|
|
|
820
|
+
async requestRegisterValue(register: number) {
|
|
821
|
+
if (this.version >= 6609) {
|
|
822
|
+
await this.send(Protocol.buildRegister(register));
|
|
823
|
+
this.info("request register: " + register);
|
|
824
|
+
} else {
|
|
825
|
+
this.err("FC_REGISTERMAP not available before firmware v66.09")
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/////////////////////
|
|
830
|
+
// Settings values //
|
|
831
|
+
/////////////////////
|
|
758
832
|
async setUnitStatus(unit: Unit, value: number) {
|
|
759
833
|
const params = Protocol.buildSetCmd(unit.node, unit, value);
|
|
760
834
|
if (params.cmd) {
|
|
@@ -762,6 +836,15 @@ export class Master extends Base {
|
|
|
762
836
|
}
|
|
763
837
|
}
|
|
764
838
|
|
|
839
|
+
async setRegisterValue(register: number, value: number) {
|
|
840
|
+
if (this.version >= 6609) {
|
|
841
|
+
await this.send(Protocol.buildRegister(register, value));
|
|
842
|
+
this.info("set register: " + register + ", to: " + value);
|
|
843
|
+
} else {
|
|
844
|
+
this.err("FC_REGISTERMAP not available before firmware v66.09")
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
765
848
|
async setSensorValue(unit: Unit, value: number) {
|
|
766
849
|
this.info("SetSensorValue of " + unit.node.logicalAddress + "/" + unit.logicalAddress + " to " + value);
|
|
767
850
|
await this.send(Protocol.buildSetPreset(unit.node, unit, TempPreset.sun, Math.trunc(value / 100 / 100 / 100) % 100));
|
|
@@ -798,5 +881,4 @@ export class Master extends Base {
|
|
|
798
881
|
this.info("set temp preset of " + unit.node.getName() + "-" + unit.getName() + ": " + (inc ? "up" : "down"));
|
|
799
882
|
}
|
|
800
883
|
|
|
801
|
-
|
|
802
884
|
}
|