homebridge-smartsystem 6.1.7 → 6.2.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.
Files changed (66) hide show
  1. package/README.md +14 -0
  2. package/accessories/accessory.js +4 -4
  3. package/accessories/accessory.ts +1 -2
  4. package/accessories/dimmer.js +6 -6
  5. package/accessories/dimmer.ts +1 -1
  6. package/accessories/door.js +2 -2
  7. package/accessories/door.ts +1 -1
  8. package/accessories/garagedoor.js +5 -4
  9. package/accessories/garagedoor.ts +2 -1
  10. package/accessories/lock.js +6 -5
  11. package/accessories/lock.ts +2 -1
  12. package/accessories/mood.js +2 -1
  13. package/accessories/mood.ts +2 -1
  14. package/accessories/temperature.js +2 -2
  15. package/accessories/temperature.ts +1 -1
  16. package/accessories/windowcovering.js +8 -7
  17. package/accessories/windowcovering.ts +2 -1
  18. package/config.json +169 -228
  19. package/config.smappee.json +178 -2
  20. package/config.smartapp.json +63 -0
  21. package/duotecno/Q.js +8 -8
  22. package/duotecno/Q.ts +1 -1
  23. package/duotecno/api.js +3 -3
  24. package/duotecno/api.ts +2 -2
  25. package/duotecno/config.js +24 -23
  26. package/duotecno/config.ts +23 -16
  27. package/duotecno/logger.js +51 -0
  28. package/duotecno/logger.ts +41 -0
  29. package/duotecno/master.js +4 -6
  30. package/duotecno/master.ts +2 -4
  31. package/duotecno/protocol.js +10 -9
  32. package/duotecno/protocol.ts +2 -1
  33. package/duotecno/system.js +17 -41
  34. package/duotecno/system.ts +7 -34
  35. package/duotecno/types.js +58 -131
  36. package/duotecno/types.ts +65 -125
  37. package/index.spec.js +22 -36
  38. package/index.spec.ts +20 -33
  39. package/package.json +2 -2
  40. package/server/base.js +10 -38
  41. package/server/base.ts +9 -42
  42. package/server/p1.js +9 -8
  43. package/server/p1.ts +6 -4
  44. package/server/platform.js +66 -36
  45. package/server/platform.ts +47 -12
  46. package/server/powerbase.js +15 -55
  47. package/server/powerbase.ts +4 -50
  48. package/server/shelly.js +4 -4
  49. package/server/shelly.ts +3 -2
  50. package/server/smappee.js +9 -8
  51. package/server/smappee.ts +4 -3
  52. package/server/smartapp.js +94 -39
  53. package/server/smartapp.ts +73 -20
  54. package/server/socapp.js +6 -6
  55. package/server/socapp.ts +2 -1
  56. package/server/somfy.js +12 -12
  57. package/server/somfy.ts +1 -1
  58. package/server/support.js +13 -13
  59. package/server/support.ts +4 -4
  60. package/server/views/style.ejs +1 -0
  61. package/server/views/switch-details.ejs +15 -5
  62. package/server/webapp.js +45 -47
  63. package/server/webapp.ts +29 -38
  64. package/config.groups.json +0 -8
  65. package/config.p1-dev.json +0 -59
  66. package/config.scenes.json +0 -15
package/README.md CHANGED
@@ -257,8 +257,22 @@ Homebridge UI version
257
257
  - 4: errors when starting power mgrs from platform.ts
258
258
  - 5: v6.1.3 changes were gone... restored them.
259
259
  - 6: added login with pw in config + http.get with on-error
260
+ - 6: allow + and - in power rules expressions
260
261
  - 7: allow NaN in bindings compare for update
261
262
 
263
+ ### v6.2.0 - 10-08-2022 - fully use Homebridge UI (login, config)
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
+
275
+
262
276
  ## Hardware
263
277
  A Raspberry Pi that connects to a Duotecno IP Node
264
278
  and (if configured) to a Smappee Infinity (power and plugs)
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Accessory = void 0;
4
- const types_1 = require("../duotecno/types");
4
+ const logger_1 = require("../duotecno/logger");
5
5
  // Johan Coppieters Jan 2019
6
6
  //
7
7
  // base class for all kind of accessories on our platform
@@ -17,7 +17,7 @@ class Accessory {
17
17
  this.services.push(this.getInformationService());
18
18
  }
19
19
  makeService(service) {
20
- (0, types_1.log)("accessory", "accessory - Making service: " + this.name + ", serial: " + this.uuid_base);
20
+ (0, logger_1.log)("accessory", "accessory - Making service: " + this.name + ", serial: " + this.uuid_base);
21
21
  this.me = new service(this.name);
22
22
  return this.me;
23
23
  }
@@ -50,7 +50,7 @@ class Accessory {
50
50
  if (this.unit) {
51
51
  this.unit.reqState(unit => {
52
52
  next(null, unit.status);
53
- (0, types_1.log)("accessory", "getState was called for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
53
+ (0, logger_1.log)("accessory", "getState was called for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
54
54
  }).catch(err => next(err));
55
55
  }
56
56
  else {
@@ -61,7 +61,7 @@ class Accessory {
61
61
  if (this.unit) {
62
62
  this.unit.reqState(unit => {
63
63
  next(null, unit.value);
64
- (0, types_1.log)("accessory", "getValue was called for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.value);
64
+ (0, logger_1.log)("accessory", "getValue was called for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.value);
65
65
  }).catch(err => next(err));
66
66
  }
67
67
  else {
@@ -1,4 +1,4 @@
1
- import { log } from "../duotecno/types";
1
+ import { log } from "../duotecno/logger";
2
2
  import { Unit } from "../duotecno/protocol";
3
3
  import { API, HAP, Service } from "homebridge";
4
4
 
@@ -10,7 +10,6 @@ import { API, HAP, Service } from "homebridge";
10
10
  export class Accessory {
11
11
  homebridge: HAP; // homebridge api endpoint
12
12
  unit: Unit;
13
- config: any; // all config params
14
13
  name: string;
15
14
  uuid_base: string;
16
15
  services: Array<Service>;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Dimmer = void 0;
4
4
  const accessory_1 = require("./accessory");
5
- const types_1 = require("../duotecno/types");
5
+ const logger_1 = require("../duotecno/logger");
6
6
  // Johan Coppieters Jan 2019
7
7
  //
8
8
  // Dimmer
@@ -31,7 +31,7 @@ class Dimmer extends accessory_1.Accessory {
31
31
  if (this.unit) {
32
32
  this.unit.reqState(unit => {
33
33
  next(null, unit.value);
34
- (0, types_1.log)("accessory", "getBrightness was called for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.value);
34
+ (0, logger_1.log)("accessory", "getBrightness was called for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.value);
35
35
  }).catch(err => next(err));
36
36
  }
37
37
  else {
@@ -40,10 +40,10 @@ class Dimmer extends accessory_1.Accessory {
40
40
  }
41
41
  setPower(powerOn, next) {
42
42
  this.waitingSetPower = true;
43
- (0, types_1.log)("accessory", "setPower: *** waiting *** " + powerOn);
43
+ (0, logger_1.log)("accessory", "setPower: *** waiting *** " + powerOn);
44
44
  setTimeout(() => {
45
45
  if (!this.preventSetPower) {
46
- (0, types_1.log)("accessory", "setPower: " + powerOn);
46
+ (0, logger_1.log)("accessory", "setPower: " + powerOn);
47
47
  this.unit.setState(powerOn)
48
48
  .then(() => next())
49
49
  .catch(err => next(err));
@@ -60,9 +60,9 @@ class Dimmer extends accessory_1.Accessory {
60
60
  // crush set on/off requests, bug in homekit / homebridge
61
61
  if (this.waitingSetPower) {
62
62
  this.preventSetPower = true;
63
- (0, types_1.log)("accessory", "setBrightness -> setPower: *** cancelled ***");
63
+ (0, logger_1.log)("accessory", "setBrightness -> setPower: *** cancelled ***");
64
64
  }
65
- (0, types_1.log)("accessory", "setBrightness " + value);
65
+ (0, logger_1.log)("accessory", "setBrightness " + value);
66
66
  this.unit.setState(value)
67
67
  .then(() => next())
68
68
  .catch(err => next(err));
@@ -1,7 +1,7 @@
1
1
  import { Accessory } from "./accessory";
2
2
  import { Unit } from "../duotecno/protocol";
3
3
  import { API } from "homebridge";
4
- import { log } from "../duotecno/types";
4
+ import { log } from "../duotecno/logger";
5
5
 
6
6
  // Johan Coppieters Jan 2019
7
7
  //
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Door = void 0;
4
- const types_1 = require("../duotecno/types");
4
+ const logger_1 = require("../duotecno/logger");
5
5
  const windowcovering_1 = require("./windowcovering");
6
6
  // Johan Coppieters Jun 2020
7
7
  //
@@ -68,7 +68,7 @@ class Door extends windowcovering_1.WindowCovering {
68
68
  // in response to Duotecno status messages
69
69
  updateState() {
70
70
  const value = this.DT2HB(this.unit.status);
71
- (0, types_1.log)("accessory", "Received updateState -> Homekit Door for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
71
+ (0, logger_1.log)("accessory", "Received updateState -> Homekit Door for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
72
72
  this.me.getCharacteristic(this.homebridge.Characteristic.CurrentPosition).updateValue(value);
73
73
  }
74
74
  }
@@ -1,4 +1,4 @@
1
- import { log } from "../duotecno/types";
1
+ import { log } from "../duotecno/logger";
2
2
  import { WindowCovering } from "./windowcovering";
3
3
  import { Unit } from "../duotecno/protocol";
4
4
  import { API } from "homebridge";
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GarageDoor = void 0;
4
4
  const types_1 = require("../duotecno/types");
5
+ const logger_1 = require("../duotecno/logger");
5
6
  const accessory_1 = require("./accessory");
6
7
  // Johan Coppieters Jun 2020
7
8
  //
@@ -55,7 +56,7 @@ class GarageDoor extends accessory_1.Accessory {
55
56
  try {
56
57
  this.unit.reqState(unit => {
57
58
  const hb = this.DT2HB(unit.status);
58
- (0, types_1.log)("accessory", "Get TargetDoorState of " + this.name + " = " + unit.status + " -> " + hb);
59
+ (0, logger_1.log)("accessory", "Get TargetDoorState of " + this.name + " = " + unit.status + " -> " + hb);
59
60
  next(null, hb);
60
61
  });
61
62
  }
@@ -69,18 +70,18 @@ class GarageDoor extends accessory_1.Accessory {
69
70
  this.targetState = value;
70
71
  let cmd = this.HB2DT(value);
71
72
  if (cmd) {
72
- (0, types_1.log)("accessory", "Set TargetDoorState of " + this.name + ", value =" + value + " -> cmd=" + cmd);
73
+ (0, logger_1.log)("accessory", "Set TargetDoorState of " + this.name + ", value =" + value + " -> cmd=" + cmd);
73
74
  this.unit.setState(cmd)
74
75
  .then(() => next())
75
76
  .catch(err => next(err));
76
77
  }
77
78
  else {
78
- (0, types_1.log)("accessory", "Set TargetDoorState of " + this.name + " -> failed for : " + value);
79
+ (0, logger_1.log)("accessory", "Set TargetDoorState of " + this.name + " -> failed for : " + value);
79
80
  next(new Error("TargetDoorState of " + this.name + " -> failed"));
80
81
  }
81
82
  }
82
83
  getTargetDoorState(next) {
83
- (0, types_1.log)("accessory", "Characteristic.TargetDoorState.get was called of " + this.name + " = " + this.targetState);
84
+ (0, logger_1.log)("accessory", "Characteristic.TargetDoorState.get was called of " + this.name + " = " + this.targetState);
84
85
  next(null, this.targetState);
85
86
  }
86
87
  // in response to Duotecno status messages
@@ -1,6 +1,7 @@
1
1
  import { API } from "homebridge";
2
2
  import { Unit } from "../duotecno/protocol";
3
- import { log, UnitMotorCmd, UnitState } from "../duotecno/types";
3
+ import { UnitMotorCmd, UnitState } from "../duotecno/types";
4
+ import { log } from "../duotecno/logger";
4
5
  import { Accessory } from "./accessory";
5
6
 
6
7
  // Johan Coppieters Jun 2020
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Lock = void 0;
4
4
  const types_1 = require("../duotecno/types");
5
+ const logger_1 = require("../duotecno/logger");
5
6
  const accessory_1 = require("./accessory");
6
7
  // Johan Coppieters Jun 2020
7
8
  //
@@ -14,7 +15,7 @@ class Lock extends accessory_1.Accessory {
14
15
  constructor(homebridge, unit) {
15
16
  super(homebridge, unit);
16
17
  this.targetState = 1; // locked
17
- (0, types_1.log)("accessory", "created Lock -> " + unit.getDescription());
18
+ (0, logger_1.log)("accessory", "created Lock -> " + unit.getDescription());
18
19
  // set default for Unlocked to Locked
19
20
  if (this.unit.getType() === types_1.UnitExtendedType.kUnlocker)
20
21
  unit.setState(1);
@@ -36,7 +37,7 @@ class Lock extends accessory_1.Accessory {
36
37
  this.targetState = value;
37
38
  // unlocker is a mood, a lock is a switch
38
39
  const dtVal = (this.unit.getType() === types_1.UnitExtendedType.kUnlocker) ? -1 : value;
39
- (0, types_1.log)("accessory", "HB setting target state of lock: to " + value + " of " + this.unit.getDescription() + " (duotecno: " + dtVal + ")");
40
+ (0, logger_1.log)("accessory", "HB setting target state of lock: to " + value + " of " + this.unit.getDescription() + " (duotecno: " + dtVal + ")");
40
41
  this.unit.setState(dtVal)
41
42
  .then(() => {
42
43
  //bypass ip node update mechanism of Duotecno
@@ -45,7 +46,7 @@ class Lock extends accessory_1.Accessory {
45
46
  if (this.unit.getType() === types_1.UnitExtendedType.kUnlocker) {
46
47
  // always set to "locked" after sending the request.
47
48
  this.unit.resetTimer = setTimeout(() => {
48
- (0, types_1.log)("accessory", "Autolock for an unlocker after 2 secs of " + this.unit.getDescription());
49
+ (0, logger_1.log)("accessory", "Autolock for an unlocker after 2 secs of " + this.unit.getDescription());
49
50
  this.targetState = 1;
50
51
  this.me.getCharacteristic(this.homebridge.Characteristic.LockTargetState).updateValue(1);
51
52
  this.unit.status = 1;
@@ -57,12 +58,12 @@ class Lock extends accessory_1.Accessory {
57
58
  .catch(err => next(err));
58
59
  }
59
60
  getTarget(next) {
60
- (0, types_1.log)("accessory", "HB getting target state of lock = " + this.unit.status + " of " + this.unit.getDescription());
61
+ (0, logger_1.log)("accessory", "HB getting target state of lock = " + this.unit.status + " of " + this.unit.getDescription());
61
62
  next(null, this.targetState);
62
63
  }
63
64
  getCurrent(next) {
64
65
  this.unit.reqState(unit => {
65
- (0, types_1.log)("accessory", "HB getting current state of lock = " + this.unit.status + " of " + this.unit.getDescription());
66
+ (0, logger_1.log)("accessory", "HB getting current state of lock = " + this.unit.status + " of " + this.unit.getDescription());
66
67
  next(null, !!this.unit.status);
67
68
  });
68
69
  }
@@ -1,6 +1,7 @@
1
1
  import { API } from "homebridge";
2
2
  import { Unit } from "../duotecno/protocol";
3
- import { log, UnitExtendedType } from "../duotecno/types";
3
+ import { UnitExtendedType } from "../duotecno/types";
4
+ import { log } from "../duotecno/logger";
4
5
  import { Accessory } from "./accessory";
5
6
 
6
7
  // Johan Coppieters Jun 2020
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Mood = void 0;
4
4
  const accessory_1 = require("./accessory");
5
5
  const types_1 = require("../duotecno/types");
6
+ const logger_1 = require("../duotecno/logger");
6
7
  // Johan Coppieters Jan 2019
7
8
  //
8
9
  // Mood
@@ -22,7 +23,7 @@ class Mood extends accessory_1.Accessory {
22
23
  return [moodService];
23
24
  }
24
25
  getMood(next) {
25
- (0, types_1.log)("accessory", "getMood was called for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> false");
26
+ (0, logger_1.log)("accessory", "getMood was called for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> false");
26
27
  next(null, !!this.unit.value);
27
28
  }
28
29
  setMood(value, next) {
@@ -1,5 +1,6 @@
1
1
  import { Accessory } from "./accessory";
2
- import { log, UnitExtendedType } from "../duotecno/types";
2
+ import { UnitExtendedType } from "../duotecno/types";
3
+ import { log } from "../duotecno/logger";
3
4
  import { Unit } from "../duotecno/protocol";
4
5
  import { API } from "homebridge";
5
6
 
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Temperature = void 0;
4
4
  const accessory_1 = require("./accessory");
5
- const types_1 = require("../duotecno/types");
5
+ const logger_1 = require("../duotecno/logger");
6
6
  // Johan Coppieters Jan 2019
7
7
  //
8
8
  // Temperature Sensor
@@ -23,7 +23,7 @@ class Temperature extends accessory_1.Accessory {
23
23
  getTemperature(next) {
24
24
  if (this.unit) {
25
25
  this.unit.reqState(unit => {
26
- (0, types_1.log)("accessory", "reqState/getTemperature returned a value for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.value);
26
+ (0, logger_1.log)("accessory", "reqState/getTemperature returned a value for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.value);
27
27
  next(null, unit.value / 10.0);
28
28
  })
29
29
  .catch(err => next(err));
@@ -1,5 +1,5 @@
1
1
  import { Accessory } from "./accessory";
2
- import { log } from "../duotecno/types";
2
+ import { log } from "../duotecno/logger";
3
3
  import { Unit } from "../duotecno/protocol";
4
4
  import { API } from "homebridge";
5
5
 
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WindowCovering = void 0;
4
4
  const accessory_1 = require("./accessory");
5
5
  const types_1 = require("../duotecno/types");
6
+ const logger_1 = require("../duotecno/logger");
6
7
  // Johan Coppieters v1: Jan 2019, v2: Jun 2020
7
8
  //
8
9
  // WindowCovering
@@ -86,11 +87,11 @@ class WindowCovering extends accessory_1.Accessory {
86
87
  return 50;
87
88
  }
88
89
  getPositionState(next) {
89
- (0, types_1.log)("accessory", "get PositionState was called of " + this.name + " -> " + this.targetState);
90
+ (0, logger_1.log)("accessory", "get PositionState was called of " + this.name + " -> " + this.targetState);
90
91
  next(null, this.targetState);
91
92
  }
92
93
  getCurrentPosition(next) {
93
- (0, types_1.log)("accessory", "get CurrentPosition was called of " + this.name);
94
+ (0, logger_1.log)("accessory", "get CurrentPosition was called of " + this.name);
94
95
  this.unit.reqState(unit => {
95
96
  if (unit.status == types_1.UnitState.kOpen)
96
97
  next(null, 100);
@@ -103,7 +104,7 @@ class WindowCovering extends accessory_1.Accessory {
103
104
  setTargetPosition(value, next) {
104
105
  // homekit is giving 0-100 for windows
105
106
  // the smartbox -> 5=down, 4=up, 3=stop
106
- (0, types_1.log)("accessory", "set Characteristic.TargetPosition was called with value = " + value);
107
+ (0, logger_1.log)("accessory", "set Characteristic.TargetPosition was called with value = " + value);
107
108
  let cmd = 0;
108
109
  if (value == 100) {
109
110
  cmd = types_1.UnitMotorCmd.kOpen;
@@ -114,13 +115,13 @@ class WindowCovering extends accessory_1.Accessory {
114
115
  else {
115
116
  cmd = types_1.UnitMotorCmd.kStop;
116
117
  }
117
- (0, types_1.log)("accessory", "setUpDown, value =" + value + " -> cmd=" + cmd);
118
+ (0, logger_1.log)("accessory", "setUpDown, value =" + value + " -> cmd=" + cmd);
118
119
  this.unit.setState(cmd)
119
120
  .then(() => next())
120
121
  .catch(err => next(err));
121
122
  }
122
123
  getTargetPosition(next) {
123
- (0, types_1.log)("accessory", "get Characteristic.TargetPosition was called");
124
+ (0, logger_1.log)("accessory", "get Characteristic.TargetPosition was called");
124
125
  this.unit.reqState(unit => {
125
126
  if (this.unit.status == types_1.UnitState.kOpen)
126
127
  next(null, 100);
@@ -137,11 +138,11 @@ class WindowCovering extends accessory_1.Accessory {
137
138
  this.me.getCharacteristic(this.homebridge.Characteristic.CurrentPosition).updateValue(value);
138
139
  if (this.unit.status == types_1.UnitState.kClosing) {
139
140
  this.me.getCharacteristic(this.homebridge.Characteristic.TargetPosition).updateValue(0);
140
- (0, types_1.log)("accessory", "Setting targetposition to 0");
141
+ (0, logger_1.log)("accessory", "Setting targetposition to 0");
141
142
  }
142
143
  else if (this.unit.status == types_1.UnitState.kOpening) {
143
144
  this.me.getCharacteristic(this.homebridge.Characteristic.TargetPosition).updateValue(100);
144
- (0, types_1.log)("accessory", "Setting targetposition to 100");
145
+ (0, logger_1.log)("accessory", "Setting targetposition to 100");
145
146
  }
146
147
  }
147
148
  }
@@ -1,5 +1,6 @@
1
1
  import { Accessory } from "./accessory";
2
- import { log, UnitMotorCmd, UnitState } from "../duotecno/types";
2
+ import { UnitMotorCmd, UnitState } from "../duotecno/types";
3
+ import { log } from "../duotecno/logger";
3
4
  import { Unit } from "../duotecno/protocol";
4
5
  import { API } from "homebridge";
5
6