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.
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.Protocol = exports.Unit = exports.Node = exports.recName = exports.Rec = exports.TempPreset = exports.cmdName = void 0;
12
+ exports.Protocol = exports.Unit = exports.Node = exports.recName = exports.Rec = exports.TempPreset = exports.cmdName = exports.reqNodeAttributes = void 0;
13
13
  const types_1 = require("./types");
14
14
  const logger_1 = require("./logger");
15
15
  // Duotecno master IP protocol implementation
@@ -19,21 +19,29 @@ const logger_1 = require("./logger");
19
19
  // Mar 2019 - v2 - rewrite to support multiple masters
20
20
  //
21
21
  // Dec 2019 - v3 - for app side only
22
+ // May-Nov 2021 - v4 - changes for pro-app
23
+ // Nov 2022 - Register and merge with gateway
22
24
  ///////////////////////////
23
25
  // Commands + attributes //
24
26
  ///////////////////////////
25
27
  var Cmd;
26
28
  (function (Cmd) {
27
29
  Cmd[Cmd["SetSensorValue"] = 7] = "SetSensorValue";
30
+ Cmd[Cmd["Internal"] = 9] = "Internal";
31
+ Cmd[Cmd["SetBasicAudio"] = 159] = "SetBasicAudio";
32
+ Cmd[Cmd["SetExtendedAudio"] = 208] = "SetExtendedAudio";
33
+ Cmd[Cmd["SetAVMatrix"] = 202] = "SetAVMatrix";
28
34
  Cmd[Cmd["SetSwitch"] = 163] = "SetSwitch";
29
35
  Cmd[Cmd["SetDimmer"] = 162] = "SetDimmer";
30
36
  Cmd[Cmd["SetControl"] = 168] = "SetControl";
31
37
  Cmd[Cmd["SetMotor"] = 182] = "SetMotor";
32
38
  Cmd[Cmd["SetSensor"] = 136] = "SetSensor";
39
+ Cmd[Cmd["SetDateTime"] = 170] = "SetDateTime";
33
40
  Cmd[Cmd["Login"] = 214] = "Login";
34
41
  Cmd[Cmd["Heartbeat"] = 215] = "Heartbeat";
35
42
  Cmd[Cmd["DatabaseInfo"] = 209] = "DatabaseInfo";
36
43
  Cmd[Cmd["SetSchedule"] = 217] = "SetSchedule";
44
+ Cmd[Cmd["Register"] = 224] = "Register";
37
45
  })(Cmd || (Cmd = {}));
38
46
  // for Set Switch/Dimmer/Control
39
47
  const reqDim = 3;
@@ -49,6 +57,16 @@ const reqUnitInfo = 2;
49
57
  const reqUnitStatus = 3;
50
58
  // for Schedule
51
59
  const reqSchedule = 218;
60
+ // for versions et al
61
+ const reqNodeManagement = 220;
62
+ var reqNodeAttributes;
63
+ (function (reqNodeAttributes) {
64
+ reqNodeAttributes[reqNodeAttributes["masterSupported"] = 0] = "masterSupported";
65
+ reqNodeAttributes[reqNodeAttributes["isMaster"] = 4] = "isMaster";
66
+ reqNodeAttributes[reqNodeAttributes["nodeInfo"] = 5] = "nodeInfo";
67
+ reqNodeAttributes[reqNodeAttributes["nodeVersion"] = 6] = "nodeVersion";
68
+ reqNodeAttributes[reqNodeAttributes["nodeProtocol"] = 7] = "nodeProtocol";
69
+ })(reqNodeAttributes = exports.reqNodeAttributes || (exports.reqNodeAttributes = {}));
52
70
  function cmdName(cmd) {
53
71
  return Cmd[cmd] || "cmd" + cmd;
54
72
  }
@@ -80,6 +98,8 @@ var Rec;
80
98
  Rec[Rec["TimeDateStatus"] = 71] = "TimeDateStatus";
81
99
  Rec[Rec["HeartbeatStatus"] = 72] = "HeartbeatStatus";
82
100
  Rec[Rec["ScheduleStatus"] = 73] = "ScheduleStatus";
101
+ Rec[Rec["NodeMgtInfo"] = 74] = "NodeMgtInfo";
102
+ Rec[Rec["Register"] = 77] = "Register";
83
103
  // return info from recDBInfo
84
104
  Rec[Rec["Info"] = 64] = "Info";
85
105
  // return info from reqUnitStatus
@@ -151,8 +171,8 @@ class Unit {
151
171
  this.extendedType = this.extendedType || this.calcExtendedType();
152
172
  this.name = this.name || this.getSerialNr();
153
173
  // delete the "<" and ">" for power meters
154
- if (this.extendedType === types_1.UnitExtendedType.kPower)
155
- this.name = this.name.substring(1);
174
+ // if (this.extendedType === UnitExtendedType.kPower)
175
+ // this.name = this.name.substring(1);
156
176
  // make a name for homekit, without the | but add § is 'specials' to add "sfeer", etc...
157
177
  // if the display name is empty make a N[nodeAdr]-U[unitAdr] name.
158
178
  // delete all type modifiers ( $, * and ! )
@@ -229,11 +249,12 @@ class Unit {
229
249
  case types_1.UnitType.kDimmer: return "03|" + name;
230
250
  case types_1.UnitType.kSwitch: return "04|" + name;
231
251
  case types_1.UnitType.kMood: return "09|" + name;
232
- case types_1.UnitType.kInput: return "11|" + name;
252
+ case types_1.UnitType.kInput: return "10|" + name;
253
+ // case UnitType.kPower: return "11|" + name;
233
254
  case types_1.UnitType.kExtendedAudio: "12|" + name;
234
- case types_1.UnitType.kAudio: return "12|" + name;
235
- case types_1.UnitType.kAV: return "13|" + name;
236
- case types_1.UnitType.kVideo: return "14|" + name;
255
+ case types_1.UnitType.kAudio: return "13|" + name;
256
+ case types_1.UnitType.kAV: return "14|" + name;
257
+ case types_1.UnitType.kVideo: return "15|" + name;
237
258
  case types_1.UnitType.kIRTX: return "19|" + name;
238
259
  default: return "99|" + name;
239
260
  }
@@ -280,9 +301,9 @@ class Unit {
280
301
  //////////////////
281
302
  // Temp / Power //
282
303
  //////////////////
283
- if ((this.type === types_1.UnitType.kTemperature) &&
284
- ((this.name[0] === "<") || (this.name[0] === ">")))
285
- return types_1.UnitExtendedType.kPower;
304
+ //if ((this.type === UnitType.kTemperature) &&
305
+ // ((this.name[0] === "<") || (this.name[0] === ">")))
306
+ // return UnitExtendedType.kPower;
286
307
  /////////////
287
308
  // Up/Down //
288
309
  /////////////
@@ -472,12 +493,55 @@ exports.Protocol = {
472
493
  .map(val => String.fromCharCode(val))
473
494
  .join("");
474
495
  },
496
+ makeWord: function (arr, at) {
497
+ return arr[at + 0] * 256 + arr[at + 1];
498
+ },
499
+ makeSignedWord: function (arr, at) {
500
+ if (arr[at + 0] > 127)
501
+ return (arr[at + 0] - 255) * 256 +
502
+ (arr[at + 1] - 255) - 1;
503
+ else
504
+ return arr[at + 0] * 256 + arr[at + 1];
505
+ },
475
506
  makeLong: function (arr, at) {
476
507
  return arr[at + 0] * 256 * 256 * 256 +
477
508
  arr[at + 1] * 256 * 256 +
478
509
  arr[at + 2] * 256 +
479
510
  arr[at + 3];
480
511
  },
512
+ makeSigned: function (arr, at) {
513
+ if (arr[at + 0] > 127)
514
+ return (arr[at + 0] - 255) * 256 * 256 * 256 +
515
+ (arr[at + 1] - 255) * 256 * 256 +
516
+ (arr[at + 2] - 255) * 256 +
517
+ (arr[at + 3] - 255) - 1;
518
+ else
519
+ return arr[at + 0] * 256 * 256 * 256 +
520
+ arr[at + 1] * 256 * 256 +
521
+ arr[at + 2] * 256 +
522
+ arr[at + 3];
523
+ },
524
+ signedToArray: function (value) {
525
+ if (value < 0)
526
+ return [256 + Math.floor(value / 256 / 256 / 256),
527
+ 256 + Math.floor(value / 256 / 256) % 256,
528
+ 256 + Math.floor(value / 256) % 256,
529
+ 256 + Math.floor(value) % 256];
530
+ else
531
+ return [Math.floor(value / 256 / 256 / 256),
532
+ Math.floor(value / 256 / 256) % 256,
533
+ Math.floor(value / 256) % 256,
534
+ Math.floor(value) % 256];
535
+ },
536
+ signedWordToArray: function (value) {
537
+ if (value < 0)
538
+ return [256 + Math.floor(value / 256) % 256, 256 + Math.floor(value) % 256];
539
+ else
540
+ return [Math.floor(value / 256) % 256, Math.floor(value) % 256];
541
+ },
542
+ wordToArray: function (value) {
543
+ return [Math.floor(value / 256) % 256, Math.floor(value) % 256];
544
+ },
481
545
  isStatus: function (cmd) {
482
546
  return (cmd === Rec.Mood) ||
483
547
  (cmd === Rec.Dimmer) ||
@@ -529,8 +593,8 @@ exports.Protocol = {
529
593
  socket.write(data + String.fromCharCode(10));
530
594
  return types_1.WriteError.writeOK;
531
595
  }
532
- catch (err) {
533
- (0, logger_1.log)("protocol", "error sending through socket " + err.message);
596
+ catch (e) {
597
+ (0, logger_1.err)("protocol", "error sending through socket " + e.message);
534
598
  return types_1.WriteError.writeFatal;
535
599
  }
536
600
  }
@@ -609,6 +673,9 @@ exports.Protocol = {
609
673
  buildRequestSchedule() {
610
674
  return [reqSchedule, 0];
611
675
  },
676
+ buildRequestNodeMgt(method = reqNodeAttributes.nodeProtocol) {
677
+ return [reqNodeManagement, method];
678
+ },
612
679
  getCmdAndMethod: function (unit, value) {
613
680
  switch (unit.type) {
614
681
  case types_1.UnitType.kDimmer:
@@ -656,10 +723,10 @@ exports.Protocol = {
656
723
  return [Cmd.SetSensor, 13, node.logicalAddress, unit.logicalAddress, preset];
657
724
  },
658
725
  buildSetSensor(node, unit, value) {
659
- return [Cmd.SetSensorValue, 10, node.logicalAddress, unit.logicalAddress, types_1.UnitType.kTemperature, Math.floor(value / 256), value % 256];
726
+ return [Cmd.SetSensorValue, 10, node.logicalAddress, unit.logicalAddress, types_1.UnitType.kTemperature, ...this.wordToArray(value)];
660
727
  },
661
728
  buildSetPreset(node, unit, preset, value) {
662
- return [Cmd.SetSensor, 1, node.logicalAddress, unit.logicalAddress, preset, Math.floor(value / 256), value % 256];
729
+ return [Cmd.SetSensor, 1, node.logicalAddress, unit.logicalAddress, preset, ...this.wordToArray(value)];
663
730
  },
664
731
  buildIncDecPreset(node, unit, inc) {
665
732
  return [Cmd.SetSensor, (inc) ? 5 : 6, node.logicalAddress, unit.logicalAddress];
@@ -671,6 +738,16 @@ exports.Protocol = {
671
738
  buildSendSchedule(schedule) {
672
739
  return [Cmd.SetSchedule, 0, Math.max(0, Math.min(3, schedule))];
673
740
  },
741
+ buildRegister(register, value) {
742
+ if (typeof value != "undefined") {
743
+ // set register
744
+ return [Cmd.Register, 1, ...this.wordToArray(register), ...this.signedToArray(value)];
745
+ }
746
+ else {
747
+ // get register
748
+ return [Cmd.Register, 2, ...this.wordToArray(register)];
749
+ }
750
+ },
674
751
  ///////////////////
675
752
  // Received info //
676
753
  ///////////////////
@@ -678,13 +755,13 @@ exports.Protocol = {
678
755
  let kind = "-";
679
756
  if (next.cmd === Rec.Sensor) {
680
757
  // sensor -> value
681
- unit.value = next.message[9] * 256 + next.message[10]; // 10x current temperature
758
+ unit.value = this.makeWord(next.message, 9); // 10x current temperature
682
759
  unit.status = next.message[7]; // 0=idle, 1=heating, 2=cooling
683
760
  unit.preset = (next.message[6]) ? next.message[8] : -1; // 0=sun, 1=half sun, 2=moon, 3=half moon, -1 = off
684
- unit.sun = next.message[11] * 256 + next.message[12]; // 10x temperature
685
- unit.hsun = next.message[13] * 256 + next.message[14]; // 10x temperature
686
- unit.moon = next.message[15] * 256 + next.message[16]; // 10x temperature
687
- unit.hmoon = next.message[17] * 256 + next.message[18]; // 10x temperature
761
+ unit.sun = this.makeWord(next.message, 11); // 10x temperature
762
+ unit.hsun = this.makeWord(next.message, 13); // 10x temperature
763
+ unit.moon = this.makeWord(next.message, 15); // 10x temperature
764
+ unit.hmoon = this.makeWord(next.message, 17); // 10x temperature
688
765
  (0, logger_1.debug)("protocol", "received status - " + unit.getDisplayName() + ", temperature = " + unit.value / 10.0 + ", sun = " + unit.sun);
689
766
  kind = "S";
690
767
  // Dimmers, switches and moods have
@@ -737,16 +814,11 @@ exports.Protocol = {
737
814
  // only change dim value when state = 1 (ON, PIR ON, DIM STOP) for Dimmers and IRTX + for any setpoint event
738
815
  if ((((next.message[4] === 1) || (next.message[4] === 6) || (next.message[4] === 7)) && (next.message[5] === 1)) ||
739
816
  (next.message[4] === 11)) {
740
- unit.value = next.message[6] * 256 + next.message[7];
817
+ unit.value = this.makeWord(next.message, 6);
741
818
  }
742
819
  (0, logger_1.debug)("protocol", "received status - macro -> value=" + unit.value + " / status=" + unit.status);
743
820
  kind = "M";
744
821
  }
745
- // clear the timer to turn the mood off again.
746
- //if (unit.resetTimer) {
747
- // clearInterval(unit.resetTimer);
748
- // unit.resetTimer = null;
749
- //}
750
822
  this.alertSubscriber(unit);
751
823
  this.emitter.emit('update', unit, kind);
752
824
  },
@@ -1,5 +1,5 @@
1
1
  import { CommRecord, Message, Sanitizers, NodeInfo, UnitInfo, DBInfo, WriteError, hex, NodeType, UnitType, UnitExtendedType, UnitState, two } from "./types";
2
- import { debug, log } from "./logger";
2
+ import { debug, log, err } from "./logger";
3
3
  import { Master } from "./master";
4
4
  import { SmartSocket } from "./smartsocket";
5
5
  import { EventEmitter } from "events";
@@ -11,6 +11,8 @@ import { EventEmitter } from "events";
11
11
  // Mar 2019 - v2 - rewrite to support multiple masters
12
12
  //
13
13
  // Dec 2019 - v3 - for app side only
14
+ // May-Nov 2021 - v4 - changes for pro-app
15
+ // Nov 2022 - Register and merge with gateway
14
16
 
15
17
 
16
18
  ///////////////////////////
@@ -18,15 +20,25 @@ import { EventEmitter } from "events";
18
20
  ///////////////////////////
19
21
  enum Cmd {
20
22
  SetSensorValue = 7,
23
+ Internal = 9, // smartsystem defined (not Duotecno)
24
+
25
+ SetBasicAudio = 159,
26
+ SetExtendedAudio = 208,
27
+ SetAVMatrix = 202,
28
+
21
29
  SetSwitch = 163,
22
30
  SetDimmer = 162,
23
31
  SetControl = 168,
24
32
  SetMotor = 182,
25
33
  SetSensor = 136,
34
+
35
+ SetDateTime = 170,
36
+
26
37
  Login = 214,
27
38
  Heartbeat = 215,
28
39
  DatabaseInfo = 209,
29
- SetSchedule = 217
40
+ SetSchedule = 217,
41
+ Register = 224
30
42
  }
31
43
 
32
44
  // for Set Switch/Dimmer/Control
@@ -47,6 +59,16 @@ const reqUnitStatus = 3;
47
59
  // for Schedule
48
60
  const reqSchedule = 218;
49
61
 
62
+ // for versions et al
63
+ const reqNodeManagement = 220;
64
+ export enum reqNodeAttributes {
65
+ masterSupported = 0,
66
+ isMaster = 4,
67
+ nodeInfo = 5,
68
+ nodeVersion = 6,
69
+ nodeProtocol = 7
70
+ }
71
+
50
72
 
51
73
  export function cmdName(cmd: number | string) {
52
74
  return Cmd[cmd] || "cmd"+cmd;
@@ -88,6 +110,8 @@ export enum Rec {
88
110
  TimeDateStatus = 71,
89
111
  HeartbeatStatus = 72,
90
112
  ScheduleStatus = 73,
113
+ NodeMgtInfo = 74,
114
+ Register = 77,
91
115
 
92
116
  // return info from recDBInfo
93
117
  Info = 64,
@@ -207,8 +231,8 @@ export class Unit {
207
231
  this.name = this.name || this.getSerialNr();
208
232
 
209
233
  // delete the "<" and ">" for power meters
210
- if (this.extendedType === UnitExtendedType.kPower)
211
- this.name = this.name.substring(1);
234
+ // if (this.extendedType === UnitExtendedType.kPower)
235
+ // this.name = this.name.substring(1);
212
236
 
213
237
  // make a name for homekit, without the | but add § is 'specials' to add "sfeer", etc...
214
238
  // if the display name is empty make a N[nodeAdr]-U[unitAdr] name.
@@ -290,12 +314,14 @@ export class Unit {
290
314
  case UnitType.kDimmer: return "03|" + name;
291
315
  case UnitType.kSwitch: return "04|" + name;
292
316
  case UnitType.kMood: return "09|" + name;
293
- case UnitType.kInput: return "11|" + name;
317
+ case UnitType.kInput: return "10|" + name;
318
+ // case UnitType.kPower: return "11|" + name;
294
319
  case UnitType.kExtendedAudio: "12|" + name;
295
- case UnitType.kAudio: return "12|" + name;
296
- case UnitType.kAV: return "13|" + name;
297
- case UnitType.kVideo: return "14|" + name;
320
+ case UnitType.kAudio: return "13|" + name;
321
+ case UnitType.kAV: return "14|" + name;
322
+ case UnitType.kVideo: return "15|" + name;
298
323
  case UnitType.kIRTX: return "19|" + name;
324
+
299
325
  default: return "99|" + name;
300
326
  }
301
327
  }
@@ -347,9 +373,9 @@ export class Unit {
347
373
  //////////////////
348
374
  // Temp / Power //
349
375
  //////////////////
350
- if ((this.type === UnitType.kTemperature) &&
351
- ((this.name[0] === "<") || (this.name[0] === ">")))
352
- return UnitExtendedType.kPower;
376
+ //if ((this.type === UnitType.kTemperature) &&
377
+ // ((this.name[0] === "<") || (this.name[0] === ">")))
378
+ // return UnitExtendedType.kPower;
353
379
 
354
380
 
355
381
  /////////////
@@ -552,12 +578,55 @@ export const Protocol = {
552
578
  .join("");
553
579
  },
554
580
 
581
+ makeWord: function(arr: Array<number>, at: number) {
582
+ return arr[at+0] * 256 + arr[at+1];
583
+ },
584
+ makeSignedWord: function(arr: Array<number>, at: number) {
585
+ if (arr[at+0] > 127)
586
+ return (arr[at+0]-255) * 256 +
587
+ (arr[at+1]-255) - 1;
588
+ else
589
+ return arr[at+0] * 256 + arr[at+1];
590
+ },
555
591
  makeLong: function(arr: Array<number>, at: number) {
556
592
  return arr[at+0] * 256 * 256 * 256 +
557
593
  arr[at+1] * 256 * 256 +
558
594
  arr[at+2] * 256 +
559
595
  arr[at+3];
560
596
  },
597
+ makeSigned: function(arr: Array<number>, at: number) {
598
+ if (arr[at+0] > 127)
599
+ return (arr[at+0]-255) * 256 * 256 * 256 +
600
+ (arr[at+1]-255) * 256 * 256 +
601
+ (arr[at+2]-255) * 256 +
602
+ (arr[at+3]-255) - 1;
603
+ else
604
+ return arr[at+0] * 256 * 256 * 256 +
605
+ arr[at+1] * 256 * 256 +
606
+ arr[at+2] * 256 +
607
+ arr[at+3];
608
+ },
609
+ signedToArray: function(value: number) {
610
+ if (value < 0)
611
+ return [256 + Math.floor(value / 256 / 256 / 256),
612
+ 256 + Math.floor(value / 256 / 256) % 256,
613
+ 256 + Math.floor(value / 256) % 256,
614
+ 256 + Math.floor(value) % 256]
615
+ else
616
+ return [Math.floor(value / 256 / 256 / 256),
617
+ Math.floor(value / 256 / 256) % 256,
618
+ Math.floor(value / 256) % 256,
619
+ Math.floor(value) % 256];
620
+ },
621
+ signedWordToArray: function(value: number) {
622
+ if (value < 0)
623
+ return [256 + Math.floor(value / 256) % 256, 256 + Math.floor(value) % 256];
624
+ else
625
+ return [Math.floor(value / 256) % 256, Math.floor(value) % 256];
626
+ },
627
+ wordToArray: function(value: number) {
628
+ return [Math.floor(value / 256) % 256, Math.floor(value) % 256];
629
+ },
561
630
 
562
631
  isStatus: function(cmd: number): boolean {
563
632
  return (cmd === Rec.Mood) ||
@@ -617,8 +686,8 @@ export const Protocol = {
617
686
  socket.write(data+String.fromCharCode(10));
618
687
  return WriteError.writeOK;
619
688
 
620
- } catch(err) {
621
- log("protocol", "error sending through socket " + err.message);
689
+ } catch(e) {
690
+ err("protocol", "error sending through socket " + e.message);
622
691
  return WriteError.writeFatal;
623
692
  }
624
693
  } else {
@@ -715,6 +784,9 @@ export const Protocol = {
715
784
  buildRequestSchedule(): Message {
716
785
  return [reqSchedule, 0];
717
786
  },
787
+ buildRequestNodeMgt(method = reqNodeAttributes.nodeProtocol): Message {
788
+ return [reqNodeManagement, method];
789
+ },
718
790
 
719
791
  getCmdAndMethod: function(unit: Unit, value: number | boolean): CmdSet {
720
792
  switch (unit.type) {
@@ -771,10 +843,10 @@ export const Protocol = {
771
843
  return [Cmd.SetSensor, 13, node.logicalAddress, unit.logicalAddress, preset];
772
844
  },
773
845
  buildSetSensor(node: Node, unit: Unit, value: number): Message {
774
- return [Cmd.SetSensorValue, 10, node.logicalAddress, unit.logicalAddress, UnitType.kTemperature, Math.floor(value / 256), value % 256];
846
+ return [Cmd.SetSensorValue, 10, node.logicalAddress, unit.logicalAddress, UnitType.kTemperature, ...this.wordToArray(value)];
775
847
  },
776
848
  buildSetPreset(node: Node, unit: Unit, preset: number, value: number): Message {
777
- return [Cmd.SetSensor, 1, node.logicalAddress, unit.logicalAddress, preset, Math.floor(value / 256), value % 256];
849
+ return [Cmd.SetSensor, 1, node.logicalAddress, unit.logicalAddress, preset, ...this.wordToArray(value)];
778
850
  },
779
851
  buildIncDecPreset(node: Node, unit: Unit, inc: boolean): Message {
780
852
  return [Cmd.SetSensor, (inc) ? 5 : 6, node.logicalAddress, unit.logicalAddress];
@@ -788,6 +860,16 @@ export const Protocol = {
788
860
  return [Cmd.SetSchedule, 0, Math.max(0, Math.min(3, schedule))];
789
861
  },
790
862
 
863
+ buildRegister(register: number, value?: number) {
864
+ if (typeof value != "undefined") {
865
+ // set register
866
+ return [Cmd.Register, 1, ...this.wordToArray(register), ...this.signedToArray(value)];
867
+ } else {
868
+ // get register
869
+ return [Cmd.Register, 2, ...this.wordToArray(register)];
870
+ }
871
+ },
872
+
791
873
  ///////////////////
792
874
  // Received info //
793
875
  ///////////////////
@@ -796,13 +878,13 @@ export const Protocol = {
796
878
 
797
879
  if (next.cmd === Rec.Sensor) {
798
880
  // sensor -> value
799
- unit.value = next.message[9]*256 + next.message[10]; // 10x current temperature
881
+ unit.value = this.makeWord(next.message, 9); // 10x current temperature
800
882
  unit.status = next.message[7]; // 0=idle, 1=heating, 2=cooling
801
883
  unit.preset = (next.message[6]) ? next.message[8] : -1; // 0=sun, 1=half sun, 2=moon, 3=half moon, -1 = off
802
- unit.sun = next.message[11]*256 + next.message[12]; // 10x temperature
803
- unit.hsun = next.message[13]*256 + next.message[14]; // 10x temperature
804
- unit.moon = next.message[15]*256 + next.message[16]; // 10x temperature
805
- unit.hmoon = next.message[17]*256 + next.message[18]; // 10x temperature
884
+ unit.sun = this.makeWord(next.message, 11); // 10x temperature
885
+ unit.hsun = this.makeWord(next.message, 13); // 10x temperature
886
+ unit.moon = this.makeWord(next.message, 15); // 10x temperature
887
+ unit.hmoon = this.makeWord(next.message, 17); // 10x temperature
806
888
  debug("protocol", "received status - " + unit.getDisplayName() + ", temperature = " + <number>unit.value / 10.0 + ", sun = " + unit.sun);
807
889
  kind = "S";
808
890
 
@@ -858,19 +940,13 @@ export const Protocol = {
858
940
  // only change dim value when state = 1 (ON, PIR ON, DIM STOP) for Dimmers and IRTX + for any setpoint event
859
941
  if ((((next.message[4] === 1) || (next.message[4] === 6) || (next.message[4] === 7)) && (next.message[5] === 1)) ||
860
942
  (next.message[4] === 11)) {
861
- unit.value = next.message[6]*256 + next.message[7];
943
+ unit.value = this.makeWord(next.message, 6);
862
944
  }
863
945
 
864
946
  debug("protocol", "received status - macro -> value=" + unit.value + " / status=" + unit.status);
865
947
  kind = "M";
866
948
  }
867
949
 
868
- // clear the timer to turn the mood off again.
869
- //if (unit.resetTimer) {
870
- // clearInterval(unit.resetTimer);
871
- // unit.resetTimer = null;
872
- //}
873
-
874
950
  this.alertSubscriber(unit);
875
951
  this.emitter.emit('update', unit, kind);
876
952
  },
package/duotecno/types.js CHANGED
@@ -140,7 +140,9 @@ var SwitchType;
140
140
  SwitchType["kSomfy"] = "somfy";
141
141
  })(SwitchType = exports.SwitchType || (exports.SwitchType = {}));
142
142
  ;
143
- exports.kEmptyBinding = Object.assign({ channel: "0" }, exports.kEmptyUnit);
143
+ exports.kEmptyBinding = {
144
+ channel: "0", masterAddress: "0.0.0.0", masterPort: 5001, register: 0
145
+ };
144
146
  exports.kEmptyAction = Object.assign(Object.assign({}, exports.kEmptyUnit), { value: false });
145
147
  ;
146
148
  exports.kEmptyRule = {
@@ -325,9 +327,11 @@ exports.Sanitizers = {
325
327
  return rule;
326
328
  },
327
329
  bindingConfig(binding) {
328
- const b = exports.Sanitizers.unitDef(Object.assign({}, binding));
329
- b.channel = binding.channel || "0";
330
- b.power = binding.power || NaN;
330
+ const b = Object.assign({}, exports.kEmptyBinding);
331
+ b.masterAddress = binding.masterAddress || '',
332
+ b.register = binding.register || 0,
333
+ b.masterPort = binding.masterPort || 5001,
334
+ b.channel = binding.channel || "0";
331
335
  return b;
332
336
  },
333
337
  //////////////
package/duotecno/types.ts CHANGED
@@ -207,19 +207,24 @@ export enum SwitchType {
207
207
  };
208
208
 
209
209
 
210
- export interface Binding extends UnitDef {
210
+ export interface Binding {
211
+ masterAddress: string;
212
+ masterPort: number;
213
+ register: number;
211
214
  channel: string;
212
- power?: number;
215
+ value?: number;
213
216
  }
214
217
  export const kEmptyBinding: Binding = {
215
- channel: "0", ...kEmptyUnit
218
+ channel: "0", masterAddress: "0.0.0.0", masterPort: 5001, register: 0
216
219
  } as const;
217
220
 
221
+
218
222
  export interface Action extends UnitDef {
219
223
  value: number | boolean;
220
224
  }
221
225
  export const kEmptyAction: Action = { ...kEmptyUnit, value: false } as const;
222
226
 
227
+
223
228
  export interface Rule {
224
229
  type: string;
225
230
  channel: string;
@@ -512,10 +517,11 @@ export const Sanitizers = {
512
517
  },
513
518
 
514
519
  bindingConfig(binding): Binding {
515
- const b = <Binding>Sanitizers.unitDef({... binding});
516
-
520
+ const b = <Binding>{... kEmptyBinding};
521
+ b.masterAddress = binding.masterAddress || '',
522
+ b.register = binding.register || 0,
523
+ b.masterPort = binding.masterPort || 5001,
517
524
  b.channel = binding.channel || "0";
518
- b.power = binding.power || NaN;
519
525
  return b;
520
526
  },
521
527
 
package/index.spec.js CHANGED
@@ -23,6 +23,7 @@ try {
23
23
  const configStr = configBuf.toString();
24
24
  const config = JSON.parse(configStr);
25
25
  (0, logger_1.debug)("spec", config);
26
+ config.debug = true;
26
27
  const platform = new platform_1.Platform(console, config, { registerPlatformAccessories: adder });
27
28
  }
28
29
  catch (err) {
package/index.spec.ts CHANGED
@@ -33,6 +33,7 @@ try {
33
33
  const configStr = configBuf.toString();
34
34
  const config = JSON.parse(configStr);
35
35
  debug("spec", config);
36
+ config.debug = true;
36
37
 
37
38
  const platform = new Platform(console, config, <API>{registerPlatformAccessories: adder});
38
39
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "homebridge-smartsystem",
3
3
  "displayname": "Duotecno Bridge",
4
- "version": "6.3.4",
4
+ "version": "6.4.2",
5
5
  "description": "SmartServer (Proxy Websockets to TCP sockets, Smappee MQTT, Duotecno IP Nodes, Homekit interface)",
6
6
  "main": "index.js",
7
7
  "author": "Johan Coppieters",
@@ -114,19 +114,19 @@ class PowerBase extends base_1.Base {
114
114
  // for all bindings
115
115
  this.bindings.forEach(b => {
116
116
  const power = this.evalPower(b.channel);
117
- if (this.significant(power, b.power)) {
118
- (0, logger_1.debug)("power", "APPLY to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name +
119
- " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) +
120
- " > threshold: 5% =" + Math.abs(b.power * 0.05) + " > threshold: 2% =" + Math.abs(b.power * 0.02));
117
+ if (this.significant(power, b.value)) {
118
+ (0, logger_1.debug)("power", "APPLY to " + b.channel + " = " + b.value + " -> " + power + " for " + b.register +
119
+ "): difference: " + Math.abs(b.value - power) +
120
+ " > threshold: 5% =" + Math.abs(b.value * 0.05) + " > threshold: 2% =" + Math.abs(b.value * 0.02));
121
121
  this.applyBinding(b, power)
122
- .then(value => {
123
- b.power = value;
124
- // debug("power", "set unit " + b.name + " to " + value);
122
+ .then(power => {
123
+ b.value = power;
124
+ (0, logger_1.debug)("power", "set register " + b.register + " to " + power);
125
125
  })
126
126
  .catch((e) => (0, logger_1.err)(this.type, e.message || e));
127
127
  // } else {
128
- // debug("power", "DONT to " + b.channel + " = " + b.power + " -> " + power + " for " + b.name +
129
- // " (" + b.logicalNodeAddress + ";" + b.logicalAddress + "): difference: " + Math.abs(b.power - power) +
128
+ // debug("power", "DONT to " + b.channel + " = " + b.power + " -> " + power + " for " + b.register +
129
+ // " : difference: " + Math.abs(b.power - power) +
130
130
  // " > threshold: 5% =" + Math.abs(b.power * 0.05) + " > threshold: 2% =" + Math.abs(b.power * 0.02));
131
131
  }
132
132
  });
@@ -134,15 +134,14 @@ class PowerBase extends base_1.Base {
134
134
  }
135
135
  applyBinding(binding, value) {
136
136
  return __awaiter(this, void 0, void 0, function* () {
137
- const unit = this.system.findUnit(this.system.findMaster(binding.masterAddress, binding.masterPort), binding.logicalNodeAddress, binding.logicalAddress);
138
- if (unit) {
139
- if (!isNaN(value))
140
- yield unit.setSensorValue(Math.abs(value));
137
+ const master = this.system.findMaster(binding.masterAddress, binding.masterPort);
138
+ if (master) {
139
+ yield master.setRegisterValue(binding.register, value);
141
140
  return value;
142
141
  }
143
- else if ((binding.logicalNodeAddress != 0) || (binding.logicalAddress != 0)) {
144
- throw new Error("***** UNIT NOT FOUND for binding value " + value + " to " + binding.masterAddress + " - " + binding.logicalNodeAddress + ";" + binding.logicalAddress + " *****");
145
- }
142
+ else if ((!binding.masterAddress) || (binding.register)) {
143
+ throw new Error("***** MASTER NOT FOUND for binding for value " + value + " to " + binding.masterAddress + ":" + binding.masterPort + " - register = " + binding.register + " *****");
144
+ } // else empty binding -> no error
146
145
  });
147
146
  }
148
147
  /////////////////////