homebridge-smartsystem 6.8.7 → 6.8.9

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 CHANGED
@@ -302,15 +302,17 @@ Homebridge UI version
302
302
  - 4: better up-down values to and from HB
303
303
 
304
304
 
305
- ### v6.8.0 - 08/07/2025
305
+ ### v6.8.x - 08/07/2025
306
306
  - 0: first version including the proxy
307
307
  - 1: max/min values for hbValues
308
308
  - 2: HB up/down -> don't respond to motor unit's, only macro
309
309
  - 3: remember request before the login kicked in (and redirect to that one, once the login was succesful)
310
310
  - 4: now using only TCP sockets to the server
311
311
  - 5: making it more robust / inline with repo-service version
312
- - 6: removed double error handlers on cloudSocket
313
- - 7: restart if no free connections
312
+ - 6: 26 aug / removed double error handlers on cloudSocket
313
+ - 7: 28 aug / restart if no free connections
314
+ - 8: 28 aug / less logging (through logConfig) for device set/get functions
315
+ - 9: corrected reading the local config file + dump it in the logs
314
316
 
315
317
  ## Hardware
316
318
  A Raspberry Pi that connects to a Duotecno IP Node
@@ -86,7 +86,7 @@ class Accessory {
86
86
  }
87
87
  updateState() {
88
88
  this.me.getCharacteristic(this.homebridge.Characteristic.On).updateValue(this.unit.status);
89
- // log("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> on = " + this.unit.status);
89
+ (0, logger_1.log)("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> on = " + this.unit.status);
90
90
  }
91
91
  }
92
92
  exports.Accessory = Accessory;
@@ -107,7 +107,7 @@ export class Accessory {
107
107
 
108
108
  updateState() {
109
109
  this.me.getCharacteristic(this.homebridge.Characteristic.On).updateValue(this.unit.status);
110
- // log("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> on = " + this.unit.status);
110
+ log("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> on = " + this.unit.status);
111
111
  }
112
112
 
113
113
  }
@@ -69,7 +69,7 @@ class Dimmer extends accessory_1.Accessory {
69
69
  }
70
70
  updateState() {
71
71
  this.me.getCharacteristic(this.homebridge.Characteristic.Brightness).updateValue(this.unit.value);
72
- // log("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> Brightness = " + this.unit.value);
72
+ (0, logger_1.log)("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> Brightness = " + this.unit.value);
73
73
  }
74
74
  }
75
75
  exports.Dimmer = Dimmer;
@@ -84,7 +84,7 @@ export class Dimmer extends Accessory {
84
84
 
85
85
  updateState() {
86
86
  this.me.getCharacteristic(this.homebridge.Characteristic.Brightness).updateValue(this.unit.value);
87
- // log("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> Brightness = " + this.unit.value);
87
+ log("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> Brightness = " + this.unit.value);
88
88
  }
89
89
 
90
90
  }
@@ -10,7 +10,6 @@ const accessory_1 = require("./accessory");
10
10
  // - has security, so when opening you need to authenticate
11
11
  // - TargetDoorState -> Characteristic.CurrentDoorState.OPEN, .STOPPED, .CLOSED
12
12
  //
13
- //
14
13
  class GarageDoor extends accessory_1.Accessory {
15
14
  constructor(homebridge, unit) {
16
15
  super(homebridge, unit);
@@ -50,7 +49,7 @@ class GarageDoor extends accessory_1.Accessory {
50
49
  else if (state == this.homebridge.Characteristic.CurrentDoorState.STOPPED)
51
50
  return types_1.UnitMotorCmd.kStop;
52
51
  else
53
- return 0;
52
+ return null;
54
53
  }
55
54
  getDoorState(next) {
56
55
  try {
@@ -87,7 +86,7 @@ class GarageDoor extends accessory_1.Accessory {
87
86
  // in response to Duotecno status messages
88
87
  updateState() {
89
88
  const value = this.DT2HB(this.unit.status);
90
- // log("accessory", "Received updateState -> Homekit GarageDoor for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
89
+ (0, logger_1.log)("accessory", "Received updateState -> Homekit GarageDoor for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
91
90
  this.me.getCharacteristic(this.homebridge.Characteristic.CurrentDoorState).updateValue(value);
92
91
  }
93
92
  }
@@ -10,7 +10,6 @@ import { Accessory } from "./accessory";
10
10
  // - has security, so when opening you need to authenticate
11
11
  // - TargetDoorState -> Characteristic.CurrentDoorState.OPEN, .STOPPED, .CLOSED
12
12
  //
13
- //
14
13
 
15
14
 
16
15
 
@@ -61,7 +60,7 @@ export class GarageDoor extends Accessory {
61
60
  return this.homebridge.Characteristic.CurrentDoorState.STOPPED; // ????
62
61
  }
63
62
 
64
- HB2DT(state): UnitMotorCmd {
63
+ HB2DT(state): UnitMotorCmd | null {
65
64
  if (state == this.homebridge.Characteristic.CurrentDoorState.OPEN)
66
65
  return UnitMotorCmd.kOpen;
67
66
 
@@ -72,8 +71,7 @@ export class GarageDoor extends Accessory {
72
71
  return UnitMotorCmd.kStop;
73
72
 
74
73
  else
75
- return 0;
76
-
74
+ return null;
77
75
  }
78
76
 
79
77
  getDoorState(next) {
@@ -117,7 +115,7 @@ export class GarageDoor extends Accessory {
117
115
  // in response to Duotecno status messages
118
116
  updateState() {
119
117
  const value = this.DT2HB(this.unit.status);
120
- // log("accessory", "Received updateState -> Homekit GarageDoor for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
118
+ log("accessory", "Received updateState -> Homekit GarageDoor for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
121
119
  this.me.getCharacteristic(this.homebridge.Characteristic.CurrentDoorState).updateValue(value);
122
120
  }
123
121
 
@@ -69,7 +69,7 @@ class Lock extends accessory_1.Accessory {
69
69
  }
70
70
  // in response to Duotecno status messages
71
71
  updateState() {
72
- // log("accessory", "Received updateState -> Homekit Lock for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
72
+ (0, logger_1.log)("accessory", "Received updateState -> Homekit Lock for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
73
73
  this.me.getCharacteristic(this.homebridge.Characteristic.LockCurrentState).updateValue(this.unit.status);
74
74
  }
75
75
  }
@@ -89,7 +89,7 @@ export class Lock extends Accessory {
89
89
 
90
90
  // in response to Duotecno status messages
91
91
  updateState() {
92
- // log("accessory", "Received updateState -> Homekit Lock for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
92
+ log("accessory", "Received updateState -> Homekit Lock for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
93
93
  this.me.getCharacteristic(this.homebridge.Characteristic.LockCurrentState).updateValue(this.unit.status);
94
94
  }
95
95
 
@@ -51,7 +51,7 @@ class Mood extends accessory_1.Accessory {
51
51
  }
52
52
  updateState() {
53
53
  this.me.getCharacteristic(this.homebridge.Characteristic.On).updateValue(!!this.unit.value);
54
- // log("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> On = " + !!this.unit.value);
54
+ (0, logger_1.log)("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> On = " + !!this.unit.value);
55
55
  }
56
56
  }
57
57
  exports.Mood = Mood;
@@ -62,7 +62,7 @@ export class Mood extends Accessory {
62
62
  }
63
63
  updateState() {
64
64
  this.me.getCharacteristic(this.homebridge.Characteristic.On).updateValue(!!this.unit.value);
65
- // log("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> On = " + !!this.unit.value);
65
+ log("accessory", "Received status change -> update accessory -> " + this.unit.getName() + " -> On = " + !!this.unit.value);
66
66
  }
67
67
 
68
68
  }
@@ -34,7 +34,7 @@ class Temperature extends accessory_1.Accessory {
34
34
  }
35
35
  updateState() {
36
36
  this.me.getCharacteristic(this.homebridge.Characteristic.CurrentTemperature).updateValue(this.unit.value / 10.0);
37
- // log("accessory", "Received updateState -> Homekit Temperature -> " + this.unit.getName() + " -> temp = " +(<number>this.unit.value) / 10.0);
37
+ (0, logger_1.log)("accessory", "Received updateState -> Homekit Temperature -> " + this.unit.getName() + " -> temp = " + this.unit.value / 10.0);
38
38
  }
39
39
  }
40
40
  exports.Temperature = Temperature;
@@ -42,7 +42,7 @@ export class Temperature extends Accessory {
42
42
 
43
43
  updateState() {
44
44
  this.me.getCharacteristic(this.homebridge.Characteristic.CurrentTemperature).updateValue((<number>this.unit.value) / 10.0);
45
- // log("accessory", "Received updateState -> Homekit Temperature -> " + this.unit.getName() + " -> temp = " +(<number>this.unit.value) / 10.0);
45
+ log("accessory", "Received updateState -> Homekit Temperature -> " + this.unit.getName() + " -> temp = " +(<number>this.unit.value) / 10.0);
46
46
  }
47
47
 
48
48
  }
@@ -134,7 +134,7 @@ class WindowCovering extends accessory_1.Accessory {
134
134
  // called in response to Duotecno status update
135
135
  updateState() {
136
136
  const value = this.DT2HB(this.unit.status);
137
- // log("accessory", "Received updateState -> Homekit WindowCovering for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing: " + value);
137
+ (0, logger_1.log)("accessory", "Received updateState -> Homekit WindowCovering for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing: " + value);
138
138
  this.me.getCharacteristic(this.homebridge.Characteristic.CurrentPosition).updateValue(value);
139
139
  if (this.unit.status == types_1.UnitState.kClosing) {
140
140
  this.me.getCharacteristic(this.homebridge.Characteristic.TargetPosition).updateValue(0);
@@ -161,7 +161,7 @@ export class WindowCovering extends Accessory {
161
161
  // called in response to Duotecno status update
162
162
  updateState() {
163
163
  const value = this.DT2HB(this.unit.status);
164
- // log("accessory", "Received updateState -> Homekit WindowCovering for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing: " + value);
164
+ log("accessory", "Received updateState -> Homekit WindowCovering for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing: " + value);
165
165
 
166
166
  this.me.getCharacteristic(this.homebridge.Characteristic.CurrentPosition).updateValue(value);
167
167
 
@@ -16,6 +16,7 @@ exports.logSettings = {
16
16
  "*": LogLevel.log,
17
17
  "master": LogLevel.log,
18
18
  "protocol": LogLevel.noLog,
19
+ "accessory": LogLevel.noLog,
19
20
  "webapp": LogLevel.log,
20
21
  "p1": LogLevel.log,
21
22
  "shelly": LogLevel.log,
@@ -11,6 +11,7 @@ export const logSettings = {
11
11
  "*": LogLevel.log,
12
12
  "master": LogLevel.log,
13
13
  "protocol": LogLevel.noLog,
14
+ "accessory": LogLevel.noLog,
14
15
  "webapp": LogLevel.log,
15
16
  "p1": LogLevel.log,
16
17
  "shelly": LogLevel.log,
package/duotecno/types.ts CHANGED
@@ -17,7 +17,7 @@ export enum NodeType { kNoNode = 0, kStandardNode = 1, kGatewayNode = 4, kModemN
17
17
 
18
18
  // States
19
19
  export enum UnitState { kOpening = 4, kClosing = 3, kOpen = 2, kClosed = 1, kStopped = 0 };
20
- export enum UnitMotorCmd { kClose = 5, kOpen = 4, kStop = 3};
20
+ export enum UnitMotorCmd { kClose = 5, kOpen = 4, kStop = 3 };
21
21
 
22
22
  export enum UnitType {
23
23
  kNoType = 0, kDimmer = 1, kSwitch = 2, kInput = 3,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "homebridge-smartsystem",
3
3
  "displayname": "Duotecno Bridge",
4
- "version": "6.8.7",
4
+ "version": "6.8.9",
5
5
  "description": "SmartServer (Proxy TCP sockets to the cloud, Smappee MQTT, Duotecno IP Nodes, Homekit interface)",
6
6
  "main": "index.js",
7
7
  "author": "Johan Coppieters",
package/server/proxy.js CHANGED
@@ -13,6 +13,7 @@ exports.kEmptyProxy = {
13
13
  debug: false,
14
14
  kind: "solo" // default running under PM2 or other process manager -> don't restart yourself
15
15
  };
16
+ const config = Object.assign({}, exports.kEmptyProxy);
16
17
  function setProxyConfig(c) {
17
18
  // set the proxy config
18
19
  if (c) {
@@ -24,19 +25,17 @@ function setProxyConfig(c) {
24
25
  config.debug = !!c.debug;
25
26
  config.kind = c.kind || exports.kEmptyProxy.kind;
26
27
  }
27
- else {
28
- config = Object.assign({}, exports.kEmptyProxy);
29
- }
30
28
  return config;
31
29
  }
32
30
  exports.setProxyConfig = setProxyConfig;
33
- let config;
34
31
  try {
35
- setProxyConfig(require('../config-proxy.json'));
32
+ const configPath = require.resolve('../config-proxy.json');
33
+ console.log(`Using config file at: ${configPath}`);
34
+ setProxyConfig(require(configPath));
36
35
  }
37
36
  catch (e) {
38
37
  setProxyConfig();
39
- console.log("No config-proxy.json found, using default values from homebridge or other.");
38
+ log("No config-proxy.json found, using default values from homebridge or other.");
40
39
  }
41
40
  let connectionChecker = null;
42
41
  const gCloudConnections = [];
@@ -102,15 +101,19 @@ function cleanStart(restart = false) {
102
101
  }
103
102
  if (restart) {
104
103
  if (config.uniqueId) {
104
+ log(`[PROXY] → [CLOUD] Starting proxy with config: ${JSON.stringify(config, null, 2)}`);
105
105
  makeNewCloudConnection(config.masterAddress, config.masterPort, config.cloudServer, config.cloudPort, config.uniqueId);
106
- // check every 5 second for a free connection
106
+ // check every 10 second for a free connection
107
107
  connectionChecker = setInterval(() => {
108
108
  const freeConnection = gCloudConnections.find((ctx) => (!ctx.deviceSocket) && ctx.cloudSocket && (ctx.cloudSocket.readyState === 'open'));
109
- if (!freeConnection) {
109
+ if (freeConnection) {
110
+ log(`[PROXY] → [CLOUD] Found free connection #${freeConnection.uniqueId} to the Cloud -> we're still ok.`);
111
+ }
112
+ else {
110
113
  error(`[PROXY] → [CLOUD] No free connections available, restarting proxy. ***************************`);
111
114
  cleanStart(true);
112
115
  }
113
- }, 5000);
116
+ }, 10 * 1000);
114
117
  }
115
118
  else {
116
119
  log(`[PROXY] → [CLOUD] Not restarting, no unique ID configured, not starting the proxy.`);
@@ -309,8 +312,10 @@ function restart() {
309
312
  // Graceful shutdown handler
310
313
  function handleShutdown(signal) {
311
314
  log(`[PROXY] → [SYSTEM] Received ${signal}, shutting down gracefully...`);
312
- if (connectionChecker)
315
+ if (connectionChecker) {
313
316
  clearInterval(connectionChecker);
317
+ connectionChecker = null;
318
+ }
314
319
  // Close all cloud connections
315
320
  gCloudConnections.forEach(ctx => ctx.cleanupSockets());
316
321
  gCloudConnections.splice(0, gCloudConnections.length);
package/server/proxy.ts CHANGED
@@ -26,6 +26,8 @@ export const kEmptyProxy: ProxyConfig = {
26
26
  kind: "solo" // default running under PM2 or other process manager -> don't restart yourself
27
27
  }
28
28
 
29
+ const config = {...kEmptyProxy};
30
+
29
31
  export function setProxyConfig(c?: ProxyConfig): ProxyConfig {
30
32
  // set the proxy config
31
33
  if (c) {
@@ -36,22 +38,23 @@ export function setProxyConfig(c?: ProxyConfig): ProxyConfig {
36
38
  config.uniqueId = c.uniqueId || kEmptyProxy.uniqueId;
37
39
  config.debug = !!c.debug;
38
40
  config.kind = c.kind || kEmptyProxy.kind;
39
- } else {
40
- config = {...kEmptyProxy};
41
41
  }
42
42
  return config;
43
43
  }
44
44
 
45
- let config: ProxyConfig;
45
+
46
46
  try {
47
- setProxyConfig(require('../config-proxy.json'));
47
+ const configPath = require.resolve('../config-proxy.json');
48
+ console.log(`Using config file at: ${configPath}`);
49
+ setProxyConfig(require(configPath));
50
+
48
51
  } catch (e) {
49
52
  setProxyConfig();
50
- console.log("No config-proxy.json found, using default values from homebridge or other.");
53
+ log("No config-proxy.json found, using default values from homebridge or other.");
51
54
  }
52
55
 
53
56
 
54
- let connectionChecker: NodeJS.Timer | null = null;
57
+ let connectionChecker: NodeJS.Timeout | null = null;
55
58
 
56
59
  const gCloudConnections: Array<Context> = [];
57
60
  const kDebug = config.debug || false; // enable debug mode from config
@@ -130,18 +133,21 @@ export function cleanStart(restart: boolean = false) {
130
133
 
131
134
  if (restart) {
132
135
  if (config.uniqueId) {
136
+ log(`[PROXY] → [CLOUD] Starting proxy with config: ${JSON.stringify(config, null, 2)}`);
133
137
  makeNewCloudConnection(config.masterAddress, config.masterPort, config.cloudServer, config.cloudPort, config.uniqueId);
134
138
 
135
- // check every 5 second for a free connection
139
+ // check every 10 second for a free connection
136
140
  connectionChecker = setInterval(() => {
137
141
  const freeConnection = gCloudConnections.find((ctx: Context) =>
138
142
  (!ctx.deviceSocket) && ctx.cloudSocket && (ctx.cloudSocket.readyState === 'open')
139
143
  );
140
- if (!freeConnection) {
144
+ if (freeConnection) {
145
+ log(`[PROXY] → [CLOUD] Found free connection #${freeConnection.uniqueId} to the Cloud -> we're still ok.`);
146
+ } else {
141
147
  error(`[PROXY] → [CLOUD] No free connections available, restarting proxy. ***************************`);
142
148
  cleanStart(true);
143
149
  }
144
- }, 5000);
150
+ }, 10 * 1000);
145
151
 
146
152
  } else {
147
153
  log(`[PROXY] → [CLOUD] Not restarting, no unique ID configured, not starting the proxy.`);
@@ -385,7 +391,10 @@ function restart() {
385
391
  function handleShutdown(signal: string) {
386
392
  log(`[PROXY] → [SYSTEM] Received ${signal}, shutting down gracefully...`);
387
393
 
388
- if (connectionChecker)clearInterval(connectionChecker);
394
+ if (connectionChecker) {
395
+ clearInterval(connectionChecker);
396
+ connectionChecker = null;
397
+ }
389
398
 
390
399
  // Close all cloud connections
391
400
  gCloudConnections.forEach(ctx => ctx.cleanupSockets());