homebridge-smartsystem 6.7.4 → 6.8.3
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 +7 -0
- package/config.json +35 -48
- package/duotecno/logger.js +1 -1
- package/duotecno/logger.ts +1 -1
- package/duotecno/protocol.js +10 -1
- package/duotecno/protocol.ts +10 -1
- package/duotecno/types.js +19 -2
- package/duotecno/types.ts +21 -2
- package/package.json +1 -1
- package/server/HB.js +52 -14
- package/server/HB.ts +50 -11
- package/server/platform.js +11 -0
- package/server/platform.ts +11 -1
- package/server/proxy.js +257 -0
- package/server/proxy.ts +315 -0
- package/server/smartapp.js +52 -10
- package/server/smartapp.ts +55 -12
- package/server/views/link-details.ejs +12 -2
- package/server/views/nav.ejs +1 -0
- package/server/views/proxy.ejs +71 -0
- package/server/webapp.js +10 -4
- package/server/webapp.ts +10 -4
package/README.md
CHANGED
|
@@ -301,6 +301,13 @@ Homebridge UI version
|
|
|
301
301
|
- 3: do dimmers/up-downs
|
|
302
302
|
- 4: better up-down values to and from HB
|
|
303
303
|
|
|
304
|
+
|
|
305
|
+
### v6.8.0 - 08/07/2025
|
|
306
|
+
- 0: first version including the proxy
|
|
307
|
+
- 1: max/min values for hbValues
|
|
308
|
+
- 2: HB up/down -> don't respond to motor unit's, only macro
|
|
309
|
+
- 3: remember request before the login kicked in (and redirect to that one, once the login was succesful)
|
|
310
|
+
|
|
304
311
|
## Hardware
|
|
305
312
|
A Raspberry Pi that connects to a Duotecno IP Node
|
|
306
313
|
and (if configured) to a Smappee Infinity (power and plugs)
|
package/config.json
CHANGED
|
@@ -194,42 +194,6 @@
|
|
|
194
194
|
"type": "httpdim",
|
|
195
195
|
"plug": "http://192.168.0.96/light/0?brightness=$&turn=#"
|
|
196
196
|
},
|
|
197
|
-
{
|
|
198
|
-
"logicalNodeAddress": 252,
|
|
199
|
-
"logicalAddress": 105,
|
|
200
|
-
"masterAddress": "192.168.0.97",
|
|
201
|
-
"masterPort": 5001,
|
|
202
|
-
"name": "Screen Salon Top",
|
|
203
|
-
"displayName": "Screen Salon Top",
|
|
204
|
-
"extendedType": 0,
|
|
205
|
-
"nomacro": "N",
|
|
206
|
-
"nostop": "N",
|
|
207
|
-
"unitName": "Salon Top",
|
|
208
|
-
"value": 0,
|
|
209
|
-
"data": "",
|
|
210
|
-
"header": "",
|
|
211
|
-
"method": "GET",
|
|
212
|
-
"type": "somfy",
|
|
213
|
-
"plug": "1"
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
"logicalNodeAddress": 252,
|
|
217
|
-
"logicalAddress": 104,
|
|
218
|
-
"masterAddress": "192.168.0.97",
|
|
219
|
-
"masterPort": 5001,
|
|
220
|
-
"name": "Screen Tim small",
|
|
221
|
-
"displayName": "Screen Tim small",
|
|
222
|
-
"extendedType": 0,
|
|
223
|
-
"nomacro": "N",
|
|
224
|
-
"nostop": "Y",
|
|
225
|
-
"unitName": "Tim Small",
|
|
226
|
-
"value": 0,
|
|
227
|
-
"data": "",
|
|
228
|
-
"header": "",
|
|
229
|
-
"method": "GET",
|
|
230
|
-
"type": "httpupdown",
|
|
231
|
-
"plug": "2"
|
|
232
|
-
},
|
|
233
197
|
{
|
|
234
198
|
"logicalNodeAddress": 16,
|
|
235
199
|
"logicalAddress": 35,
|
|
@@ -254,8 +218,8 @@
|
|
|
254
218
|
"password": "GMTecno",
|
|
255
219
|
"links": [
|
|
256
220
|
{
|
|
257
|
-
"logicalNodeAddress":
|
|
258
|
-
"logicalAddress":
|
|
221
|
+
"logicalNodeAddress": 252,
|
|
222
|
+
"logicalAddress": 104,
|
|
259
223
|
"masterAddress": "192.168.0.97",
|
|
260
224
|
"masterPort": 5001,
|
|
261
225
|
"name": "unit",
|
|
@@ -269,7 +233,9 @@
|
|
|
269
233
|
"TargetPosition",
|
|
270
234
|
"ObstructionDetected"
|
|
271
235
|
],
|
|
272
|
-
"type": "accessory"
|
|
236
|
+
"type": "accessory",
|
|
237
|
+
"max": 100,
|
|
238
|
+
"min": 0
|
|
273
239
|
}
|
|
274
240
|
]
|
|
275
241
|
},
|
|
@@ -304,7 +270,7 @@
|
|
|
304
270
|
"masterPort": 5001,
|
|
305
271
|
"name": "<Solar Panels",
|
|
306
272
|
"displayName": "<Solar Panels",
|
|
307
|
-
"extendedType":
|
|
273
|
+
"extendedType": 0,
|
|
308
274
|
"active": "N",
|
|
309
275
|
"used": "Y",
|
|
310
276
|
"group": 0
|
|
@@ -316,7 +282,7 @@
|
|
|
316
282
|
"masterPort": 5001,
|
|
317
283
|
"name": ">Cars",
|
|
318
284
|
"displayName": ">Cars",
|
|
319
|
-
"extendedType":
|
|
285
|
+
"extendedType": 0,
|
|
320
286
|
"active": "N",
|
|
321
287
|
"used": "Y",
|
|
322
288
|
"group": 0
|
|
@@ -328,7 +294,7 @@
|
|
|
328
294
|
"masterPort": 5001,
|
|
329
295
|
"name": ">Grid",
|
|
330
296
|
"displayName": ">Grid",
|
|
331
|
-
"extendedType":
|
|
297
|
+
"extendedType": 0,
|
|
332
298
|
"active": "N",
|
|
333
299
|
"used": "Y",
|
|
334
300
|
"group": 0
|
|
@@ -340,11 +306,23 @@
|
|
|
340
306
|
"masterPort": 5001,
|
|
341
307
|
"name": ">Swimmingpool",
|
|
342
308
|
"displayName": ">Swimmingpool",
|
|
343
|
-
"extendedType":
|
|
309
|
+
"extendedType": 0,
|
|
344
310
|
"active": "N",
|
|
345
311
|
"used": "Y",
|
|
346
312
|
"group": 0
|
|
347
313
|
},
|
|
314
|
+
{
|
|
315
|
+
"logicalNodeAddress": 252,
|
|
316
|
+
"logicalAddress": 104,
|
|
317
|
+
"masterAddress": "192.168.0.97",
|
|
318
|
+
"masterPort": 5001,
|
|
319
|
+
"name": "Tim Small",
|
|
320
|
+
"displayName": "Tim Small",
|
|
321
|
+
"extendedType": 8,
|
|
322
|
+
"active": "Y",
|
|
323
|
+
"used": "Y",
|
|
324
|
+
"group": 0
|
|
325
|
+
},
|
|
348
326
|
{
|
|
349
327
|
"logicalNodeAddress": 252,
|
|
350
328
|
"logicalAddress": 7,
|
|
@@ -365,7 +343,7 @@
|
|
|
365
343
|
"name": "Garage $",
|
|
366
344
|
"displayName": "Garage ",
|
|
367
345
|
"extendedType": 8,
|
|
368
|
-
"active": "
|
|
346
|
+
"active": "Y",
|
|
369
347
|
"used": "Y",
|
|
370
348
|
"group": 0
|
|
371
349
|
},
|
|
@@ -376,7 +354,7 @@
|
|
|
376
354
|
"masterPort": 5001,
|
|
377
355
|
"name": "2|Dimmer",
|
|
378
356
|
"displayName": "Somfy Dimmer",
|
|
379
|
-
"extendedType":
|
|
357
|
+
"extendedType": 1,
|
|
380
358
|
"active": "Y",
|
|
381
359
|
"used": "Y",
|
|
382
360
|
"group": 0
|
|
@@ -388,7 +366,7 @@
|
|
|
388
366
|
"masterPort": 5001,
|
|
389
367
|
"name": "Blue LED",
|
|
390
368
|
"displayName": "Blue LED",
|
|
391
|
-
"extendedType":
|
|
369
|
+
"extendedType": 1,
|
|
392
370
|
"active": "N",
|
|
393
371
|
"used": "Y",
|
|
394
372
|
"group": 0
|
|
@@ -400,7 +378,7 @@
|
|
|
400
378
|
"masterPort": 5001,
|
|
401
379
|
"name": "Red LED",
|
|
402
380
|
"displayName": "Red LED",
|
|
403
|
-
"extendedType":
|
|
381
|
+
"extendedType": 1,
|
|
404
382
|
"active": "N",
|
|
405
383
|
"used": "Y",
|
|
406
384
|
"group": 0
|
|
@@ -480,5 +458,14 @@
|
|
|
480
458
|
"gateway2": ""
|
|
481
459
|
}
|
|
482
460
|
},
|
|
483
|
-
"p1": false
|
|
461
|
+
"p1": false,
|
|
462
|
+
"proxy": {
|
|
463
|
+
"cloudServer": "ws.duotecno.eu",
|
|
464
|
+
"cloudPort": 5098,
|
|
465
|
+
"masterAddress": "192.168.0.97",
|
|
466
|
+
"masterPort": 5001,
|
|
467
|
+
"uniqueId": "",
|
|
468
|
+
"debug": false,
|
|
469
|
+
"kind": "solo"
|
|
470
|
+
}
|
|
484
471
|
}
|
package/duotecno/logger.js
CHANGED
package/duotecno/logger.ts
CHANGED
|
@@ -10,7 +10,7 @@ export enum LogLevel { noLog = 0, log = 1, debug = 2 };
|
|
|
10
10
|
export const logSettings = {
|
|
11
11
|
"*": LogLevel.log,
|
|
12
12
|
"master": LogLevel.log,
|
|
13
|
-
"protocol": LogLevel.
|
|
13
|
+
"protocol": LogLevel.noLog,
|
|
14
14
|
"webapp": LogLevel.log,
|
|
15
15
|
"p1": LogLevel.log,
|
|
16
16
|
"shelly": LogLevel.log,
|
package/duotecno/protocol.js
CHANGED
|
@@ -790,6 +790,7 @@ exports.Protocol = {
|
|
|
790
790
|
}
|
|
791
791
|
else if (next.cmd === Rec.Motor) {
|
|
792
792
|
// motor -> boolean/status
|
|
793
|
+
// [38,0,252,104,8,0,0]
|
|
793
794
|
// 0 = stopped, 1 stopped/down, 2 = stopped/up, 3 = busy/down, 4 = busy/up
|
|
794
795
|
unit.status = next.message[6];
|
|
795
796
|
unit.value = next.message[6];
|
|
@@ -800,7 +801,8 @@ exports.Protocol = {
|
|
|
800
801
|
// = EV_UNITMACROCOMMANDO
|
|
801
802
|
// examples: On 50%: [69,0,NodeAddress,UnitAddress,6,1,0,50]
|
|
802
803
|
// Off: [69,0,NodeAddress,UnitAddress,6,0,0,0] -> don't touch dimmer value
|
|
803
|
-
//
|
|
804
|
+
// unit_type_duoswitch -> Event = 32, state 0, 1, 2
|
|
805
|
+
// STATUS (Event: 7 = dimmer, 5 = switch, on = 1, off = 0)
|
|
804
806
|
if (((next.message[4] == 7) || (next.message[4] == 5)) && (next.message[5] == 1)) {
|
|
805
807
|
// PIR ON -- override status value with "2" (our PIR ON)
|
|
806
808
|
unit.status = 2;
|
|
@@ -815,6 +817,13 @@ exports.Protocol = {
|
|
|
815
817
|
(next.message[4] === 11)) {
|
|
816
818
|
unit.value = this.makeWord(next.message, 6);
|
|
817
819
|
}
|
|
820
|
+
else if (next.message[4] === 32) {
|
|
821
|
+
// unit_type_duoswitch -> Event = 32
|
|
822
|
+
// [69,0,252,104,32,2,0,0]
|
|
823
|
+
// state = 0 -> stop, state = 1 -> up, state = 2 -> down
|
|
824
|
+
unit.value = 10 + next.message[5];
|
|
825
|
+
unit.status = next.message[5];
|
|
826
|
+
}
|
|
818
827
|
(0, logger_1.debug)("protocol", "received status - macro -> value=" + unit.value + " / status=" + unit.status);
|
|
819
828
|
kind = "M";
|
|
820
829
|
}
|
package/duotecno/protocol.ts
CHANGED
|
@@ -913,6 +913,7 @@ export const Protocol = {
|
|
|
913
913
|
|
|
914
914
|
} else if (next.cmd === Rec.Motor) {
|
|
915
915
|
// motor -> boolean/status
|
|
916
|
+
// [38,0,252,104,8,0,0]
|
|
916
917
|
// 0 = stopped, 1 stopped/down, 2 = stopped/up, 3 = busy/down, 4 = busy/up
|
|
917
918
|
unit.status = next.message[6];
|
|
918
919
|
unit.value = next.message[6];
|
|
@@ -923,8 +924,9 @@ export const Protocol = {
|
|
|
923
924
|
// = EV_UNITMACROCOMMANDO
|
|
924
925
|
// examples: On 50%: [69,0,NodeAddress,UnitAddress,6,1,0,50]
|
|
925
926
|
// Off: [69,0,NodeAddress,UnitAddress,6,0,0,0] -> don't touch dimmer value
|
|
927
|
+
// unit_type_duoswitch -> Event = 32, state 0, 1, 2
|
|
926
928
|
|
|
927
|
-
// STATUS
|
|
929
|
+
// STATUS (Event: 7 = dimmer, 5 = switch, on = 1, off = 0)
|
|
928
930
|
if (((next.message[4] == 7) || (next.message[4] == 5)) && (next.message[5] == 1)) {
|
|
929
931
|
// PIR ON -- override status value with "2" (our PIR ON)
|
|
930
932
|
unit.status = 2;
|
|
@@ -939,6 +941,13 @@ export const Protocol = {
|
|
|
939
941
|
if ((((next.message[4] === 1) || (next.message[4] === 6) || (next.message[4] === 7)) && (next.message[5] === 1)) ||
|
|
940
942
|
(next.message[4] === 11)) {
|
|
941
943
|
unit.value = this.makeWord(next.message, 6);
|
|
944
|
+
|
|
945
|
+
} else if (next.message[4] === 32) {
|
|
946
|
+
// unit_type_duoswitch -> Event = 32
|
|
947
|
+
// [69,0,252,104,32,2,0,0]
|
|
948
|
+
// state = 0 -> stop, state = 1 -> up, state = 2 -> down
|
|
949
|
+
unit.value = 10 + next.message[5];
|
|
950
|
+
unit.status = next.message[5];
|
|
942
951
|
}
|
|
943
952
|
|
|
944
953
|
debug("protocol", "received status - macro -> value=" + unit.value + " / status=" + unit.status);
|
package/duotecno/types.js
CHANGED
|
@@ -15,6 +15,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.makeInt = exports.now = exports.datetime = exports.time = exports.date = exports.watt = exports.hex = exports.two = exports.char = exports.ascii = exports.wait = exports.Sanitizers = exports.actionValueStr = exports.actionValue = exports.kEmptyBinding = exports.kEmptyLink = exports.LinkType = exports.kEmptySwitch = exports.SwitchType = exports.kEmptyRule = exports.kEmptyAction = exports.RuleType = exports.Boundaries = exports.kEmptyCommRecord = exports.WriteError = exports.kEmptySettings = exports.kEmptyNetworkConfig = exports.kEmptyGroup = exports.kEmptyScene = exports.kEmptyUnitScene = exports.kEmptyUnit = exports.UnitExtendedType = exports.UnitType = exports.UnitMotorCmd = exports.UnitState = exports.NodeType = void 0;
|
|
18
|
+
const proxy_1 = require("../server/proxy");
|
|
18
19
|
// Node types
|
|
19
20
|
var NodeType;
|
|
20
21
|
(function (NodeType) {
|
|
@@ -153,7 +154,7 @@ var LinkType;
|
|
|
153
154
|
LinkType["kNoType"] = "";
|
|
154
155
|
LinkType["kAccessory"] = "accessory";
|
|
155
156
|
})(LinkType = exports.LinkType || (exports.LinkType = {}));
|
|
156
|
-
exports.kEmptyLink = Object.assign(Object.assign({}, exports.kEmptyUnit), { type: LinkType.
|
|
157
|
+
exports.kEmptyLink = Object.assign(Object.assign({}, exports.kEmptyUnit), { type: LinkType.kNoType, max: 100, min: 0, accName: "acc", accId: "", accService: [] });
|
|
157
158
|
exports.kEmptyBinding = {
|
|
158
159
|
channel: "0", masterAddress: "0.0.0.0", masterPort: 5001, register: 0
|
|
159
160
|
};
|
|
@@ -204,6 +205,7 @@ exports.Sanitizers = {
|
|
|
204
205
|
config.shelly = config.shelly || false;
|
|
205
206
|
config.smartapp = config.smartapp || null;
|
|
206
207
|
config.system = exports.Sanitizers.system(config.system);
|
|
208
|
+
config.proxy = exports.Sanitizers.proxy(config.proxy, config.system);
|
|
207
209
|
return config;
|
|
208
210
|
},
|
|
209
211
|
homebridge: function (config) {
|
|
@@ -299,7 +301,9 @@ exports.Sanitizers = {
|
|
|
299
301
|
link.accId = aLink.accId || "";
|
|
300
302
|
link.accName = aLink.accName || "";
|
|
301
303
|
link.accService = aLink.accService || [];
|
|
302
|
-
link.type = aLink.type ||
|
|
304
|
+
link.type = aLink.type || exports.kEmptyLink.type;
|
|
305
|
+
link.max = aLink.max || exports.kEmptyLink.max;
|
|
306
|
+
link.min = aLink.min || exports.kEmptyLink.min;
|
|
303
307
|
return link;
|
|
304
308
|
},
|
|
305
309
|
switchConfig: function (aSwitch) {
|
|
@@ -358,6 +362,19 @@ exports.Sanitizers = {
|
|
|
358
362
|
b.channel = binding.channel || "0";
|
|
359
363
|
return b;
|
|
360
364
|
},
|
|
365
|
+
///////////
|
|
366
|
+
// Proxy //
|
|
367
|
+
///////////
|
|
368
|
+
proxy: function (config, system) {
|
|
369
|
+
var _a, _b;
|
|
370
|
+
const c = proxy_1.kEmptyProxy;
|
|
371
|
+
c.cloudServer = (config === null || config === void 0 ? void 0 : config.cloudServer) || proxy_1.kEmptyProxy.cloudServer;
|
|
372
|
+
c.cloudPort = (config === null || config === void 0 ? void 0 : config.cloudPort) || proxy_1.kEmptyProxy.cloudPort;
|
|
373
|
+
c.masterAddress = (config === null || config === void 0 ? void 0 : config.masterAddress) || ((_a = system === null || system === void 0 ? void 0 : system.cmasters[0]) === null || _a === void 0 ? void 0 : _a.address) || "";
|
|
374
|
+
c.masterPort = (config === null || config === void 0 ? void 0 : config.masterPort) || ((_b = system === null || system === void 0 ? void 0 : system.cmasters[0]) === null || _b === void 0 ? void 0 : _b.port) || 5001;
|
|
375
|
+
c.uniqueId = (config === null || config === void 0 ? void 0 : config.uniqueId) || proxy_1.kEmptyProxy.uniqueId;
|
|
376
|
+
return c;
|
|
377
|
+
},
|
|
361
378
|
//////////////
|
|
362
379
|
// Duotecno //
|
|
363
380
|
//////////////
|
package/duotecno/types.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// v3 - smart server version, Mar 2020
|
|
5
5
|
// v3.1 - added scenes from app version, May 2020
|
|
6
6
|
|
|
7
|
+
import { kEmptyProxy, ProxyConfig } from "../server/proxy";
|
|
7
8
|
import { Unit } from "./protocol";
|
|
8
9
|
|
|
9
10
|
// for Active=Y/N or New=X
|
|
@@ -268,13 +269,15 @@ export interface Link extends UnitDef{
|
|
|
268
269
|
accId: string;
|
|
269
270
|
accService: Array<string>; // e.g. ["On", "Brightness"], ["TargetPosition", "CurrentPosition", ...]
|
|
270
271
|
type: LinkType;
|
|
272
|
+
max?: number;
|
|
273
|
+
min?: number;
|
|
271
274
|
unit?: Unit;
|
|
272
275
|
dtValue?: number | boolean | string;
|
|
273
276
|
hbValue?: number | boolean | string
|
|
274
277
|
}
|
|
275
278
|
|
|
276
279
|
export const kEmptyLink: Link = {
|
|
277
|
-
...kEmptyUnit, type: LinkType.
|
|
280
|
+
...kEmptyUnit, type: LinkType.kNoType, max: 100, min: 0, accName: "acc", accId: "", accService: []
|
|
278
281
|
};
|
|
279
282
|
|
|
280
283
|
|
|
@@ -412,6 +415,7 @@ export const Sanitizers = {
|
|
|
412
415
|
config.shelly = config.shelly || false;
|
|
413
416
|
config.smartapp = config.smartapp || null;
|
|
414
417
|
config.system = Sanitizers.system(config.system);
|
|
418
|
+
config.proxy = Sanitizers.proxy(config.proxy, config.system);
|
|
415
419
|
|
|
416
420
|
return config;
|
|
417
421
|
},
|
|
@@ -517,7 +521,9 @@ export const Sanitizers = {
|
|
|
517
521
|
link.accId = aLink.accId || "";
|
|
518
522
|
link.accName = aLink.accName || "";
|
|
519
523
|
link.accService = aLink.accService || [];
|
|
520
|
-
link.type = aLink.type ||
|
|
524
|
+
link.type = aLink.type || kEmptyLink.type;
|
|
525
|
+
link.max = aLink.max || kEmptyLink.max;
|
|
526
|
+
link.min = aLink.min || kEmptyLink.min;
|
|
521
527
|
return link;
|
|
522
528
|
},
|
|
523
529
|
|
|
@@ -581,6 +587,19 @@ export const Sanitizers = {
|
|
|
581
587
|
return b;
|
|
582
588
|
},
|
|
583
589
|
|
|
590
|
+
///////////
|
|
591
|
+
// Proxy //
|
|
592
|
+
///////////
|
|
593
|
+
proxy: function(config?: ProxyConfig, system?: SystemConfig): ProxyConfig {
|
|
594
|
+
const c = kEmptyProxy as ProxyConfig;
|
|
595
|
+
c.cloudServer = config?.cloudServer || kEmptyProxy.cloudServer;
|
|
596
|
+
c.cloudPort = config?.cloudPort || kEmptyProxy.cloudPort;
|
|
597
|
+
c.masterAddress = config?.masterAddress || system?.cmasters[0]?.address || "";
|
|
598
|
+
c.masterPort = config?.masterPort || system?.cmasters[0]?.port || 5001;
|
|
599
|
+
c.uniqueId = config?.uniqueId || kEmptyProxy.uniqueId;
|
|
600
|
+
return c;
|
|
601
|
+
},
|
|
602
|
+
|
|
584
603
|
//////////////
|
|
585
604
|
// Duotecno //
|
|
586
605
|
//////////////
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-smartsystem",
|
|
3
3
|
"displayname": "Duotecno Bridge",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.8.3",
|
|
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",
|
package/server/HB.js
CHANGED
|
@@ -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.hbUnsubscribe = exports.hbSubscribe = exports.hbGetValue = exports.hbSetState = exports.dt2hbvalue = exports.hb2dtvalue = exports.hbLogin = exports.hbAccessories = exports.hbService = exports.hbName = void 0;
|
|
12
|
+
exports.hbUnsubscribe = exports.hbSubscribe = exports.hbStop = exports.hbGetValue = exports.hbSetState = exports.dt2hbvalue = exports.hb2dtvalue = exports.hbLogin = exports.hbAccessories = exports.hbService = exports.hbName = void 0;
|
|
13
13
|
const logger_1 = require("../duotecno/logger");
|
|
14
14
|
const HA_API_1 = require("./HA-API");
|
|
15
15
|
let gAccessories = [];
|
|
@@ -173,14 +173,15 @@ function hbLoad(value, service) {
|
|
|
173
173
|
return (value) ? 100 : 0;
|
|
174
174
|
}
|
|
175
175
|
else if (typeof value === "number") {
|
|
176
|
-
|
|
176
|
+
value = Math.round(value);
|
|
177
|
+
if (value <= 1) {
|
|
177
178
|
return 0;
|
|
178
179
|
}
|
|
179
|
-
else if (value >=
|
|
180
|
+
else if (value >= 99) {
|
|
180
181
|
return 100;
|
|
181
182
|
}
|
|
182
183
|
else {
|
|
183
|
-
return
|
|
184
|
+
return value;
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
}
|
|
@@ -217,16 +218,31 @@ function hb2dtvalue(unit, value) {
|
|
|
217
218
|
return { dtTarget, dtValue };
|
|
218
219
|
}
|
|
219
220
|
exports.hb2dtvalue = hb2dtvalue;
|
|
220
|
-
function dt2hbvalue(unit, dontChangeValue) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (unit.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
221
|
+
function dt2hbvalue(unit, dontChangeValue, min, max) {
|
|
222
|
+
// tunr into (rounded) number
|
|
223
|
+
let value = (typeof unit.value === "boolean") ? (unit.value ? max : min) : Math.round(unit.value);
|
|
224
|
+
// Virtual motor: state = 0 -> stop, state = 1 -> up, state = 2 -> down
|
|
225
|
+
// Real motor: 0 = stopped, 1 stopped/down, 2 = stopped/up, 3 = busy/down, 4 = busy/up
|
|
226
|
+
if (unit.isUpDown()) {
|
|
227
|
+
// don't send status of real motor
|
|
228
|
+
return (value == 10) ? -1 : // stop [ virtual ]
|
|
229
|
+
(value == 11) ? max : // up [ virtual ]
|
|
230
|
+
(value == 12) ? min : undefined; // down [ virtual ]
|
|
231
|
+
// return ((value === 1) || (value === 3)) ? min : // down [ motor ]
|
|
232
|
+
// ((value === 2) || (value === 4)) ? max : // up [ motor ]
|
|
233
|
+
// (value == 0) ? dontChangeValue : // no change [ motor ]
|
|
234
|
+
// (value == 10) ? -1 : // stop [ virtual ]
|
|
235
|
+
// (value == 11) ? max : min; // up/down [ virtual ]
|
|
236
|
+
}
|
|
237
|
+
else if (unit.isDimmer()) {
|
|
238
|
+
return (value <= 1) ? 0 : (value >= 99) ? 100 : value;
|
|
239
|
+
}
|
|
240
|
+
else if (unit.isSwitch() || unit.isMood()) {
|
|
241
|
+
return (value) ? max : min;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
return value;
|
|
245
|
+
}
|
|
230
246
|
}
|
|
231
247
|
exports.dt2hbvalue = dt2hbvalue;
|
|
232
248
|
function hbValue(data, service) {
|
|
@@ -276,6 +292,28 @@ function hbGetValue(server, id, service, token) {
|
|
|
276
292
|
});
|
|
277
293
|
}
|
|
278
294
|
exports.hbGetValue = hbGetValue;
|
|
295
|
+
function hbStop(server, id, service, token) {
|
|
296
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
297
|
+
// does not exist, but we'll do a getCurrentPosition + setTargetPosition to this value
|
|
298
|
+
const respBody = yield (0, HA_API_1.httpRequest)(server + "/api/accessories/" + id, 'GET', "", HA_API_1.ContentType.json, {
|
|
299
|
+
Authorization: 'Bearer ' + token
|
|
300
|
+
});
|
|
301
|
+
if (respBody && respBody.error) {
|
|
302
|
+
(0, logger_1.log)("HB", "hbGetState: " + id + " -> error: " + JSON.stringify(respBody));
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
else if (respBody && respBody.values) {
|
|
306
|
+
(0, logger_1.log)("HB", "hbStop GetState: " + id + " -> " + JSON.stringify(respBody.values));
|
|
307
|
+
const data = { value: respBody.values.CurrentPosition, characteristicType: "TargetPosition" };
|
|
308
|
+
(0, logger_1.log)("HB", "hbStop SetState: " + id + " -> " + JSON.stringify(data));
|
|
309
|
+
yield (0, HA_API_1.httpRequest)(server + "/api/accessories/" + id, 'PUT', JSON.stringify(data), HA_API_1.ContentType.json, {
|
|
310
|
+
Authorization: 'Bearer ' + token
|
|
311
|
+
});
|
|
312
|
+
return hbValue(respBody.values, service);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
exports.hbStop = hbStop;
|
|
279
317
|
function hbSubscribe(callback) {
|
|
280
318
|
if (timer) {
|
|
281
319
|
clearInterval(timer);
|
package/server/HB.ts
CHANGED
|
@@ -177,12 +177,13 @@ function hbLoad(value: number | boolean, service: Array<string>): Record<string,
|
|
|
177
177
|
if (typeof value === "boolean") {
|
|
178
178
|
return (value) ? 100 : 0;
|
|
179
179
|
} else if (typeof value === "number") {
|
|
180
|
-
|
|
180
|
+
value = Math.round(value);
|
|
181
|
+
if (value <= 1) {
|
|
181
182
|
return 0;
|
|
182
|
-
} else if (value >=
|
|
183
|
+
} else if (value >= 99) {
|
|
183
184
|
return 100;
|
|
184
185
|
} else {
|
|
185
|
-
return
|
|
186
|
+
return value;
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
189
|
}
|
|
@@ -223,16 +224,32 @@ export function hb2dtvalue(unit: Unit, value: number | boolean): {dtValue: numbe
|
|
|
223
224
|
return {dtTarget, dtValue};
|
|
224
225
|
}
|
|
225
226
|
|
|
226
|
-
export function dt2hbvalue(unit: Unit, dontChangeValue: number): number {
|
|
227
|
-
|
|
227
|
+
export function dt2hbvalue(unit: Unit, dontChangeValue: number, min: number, max: number): number {
|
|
228
|
+
// tunr into (rounded) number
|
|
229
|
+
let value = (typeof unit.value === "boolean") ? (unit.value ? max : min) : Math.round(unit.value);
|
|
228
230
|
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
231
|
+
// Virtual motor: state = 0 -> stop, state = 1 -> up, state = 2 -> down
|
|
232
|
+
// Real motor: 0 = stopped, 1 stopped/down, 2 = stopped/up, 3 = busy/down, 4 = busy/up
|
|
233
|
+
if (unit.isUpDown()) {
|
|
234
|
+
// don't send status of real motor
|
|
235
|
+
return (value == 10) ? -1 : // stop [ virtual ]
|
|
236
|
+
(value == 11) ? max : // up [ virtual ]
|
|
237
|
+
(value == 12) ? min : undefined; // down [ virtual ]
|
|
238
|
+
// return ((value === 1) || (value === 3)) ? min : // down [ motor ]
|
|
239
|
+
// ((value === 2) || (value === 4)) ? max : // up [ motor ]
|
|
240
|
+
// (value == 0) ? dontChangeValue : // no change [ motor ]
|
|
241
|
+
// (value == 10) ? -1 : // stop [ virtual ]
|
|
242
|
+
// (value == 11) ? max : min; // up/down [ virtual ]
|
|
243
|
+
|
|
244
|
+
} else if (unit.isDimmer()) {
|
|
245
|
+
return (value <= 1) ? 0 : (value >= 99) ? 100 : value;
|
|
246
|
+
|
|
247
|
+
} else if (unit.isSwitch() || unit.isMood()) {
|
|
248
|
+
return (value) ? max : min;
|
|
234
249
|
|
|
235
|
-
|
|
250
|
+
} else {
|
|
251
|
+
return value;
|
|
252
|
+
}
|
|
236
253
|
}
|
|
237
254
|
|
|
238
255
|
function hbValue(data: Record<string, any>, service: Array<string>): number {
|
|
@@ -282,6 +299,28 @@ export async function hbGetValue(server: string, id: string, service: Array<stri
|
|
|
282
299
|
};
|
|
283
300
|
}
|
|
284
301
|
|
|
302
|
+
export async function hbStop(server: string, id: string, service: Array<string>, token: string) : Promise<number | undefined> {
|
|
303
|
+
// does not exist, but we'll do a getCurrentPosition + setTargetPosition to this value
|
|
304
|
+
const respBody = await httpRequest(server + "/api/accessories/"+id, 'GET', "", ContentType.json, {
|
|
305
|
+
Authorization: 'Bearer ' + token
|
|
306
|
+
});
|
|
307
|
+
if (respBody && respBody.error) {
|
|
308
|
+
log("HB", "hbGetState: " + id + " -> error: " + JSON.stringify(respBody));
|
|
309
|
+
return undefined;
|
|
310
|
+
|
|
311
|
+
} else if (respBody && respBody.values) {
|
|
312
|
+
log("HB", "hbStop GetState: " + id + " -> " + JSON.stringify(respBody.values));
|
|
313
|
+
|
|
314
|
+
const data = {value: respBody.values.CurrentPosition, characteristicType: "TargetPosition"};
|
|
315
|
+
log("HB", "hbStop SetState: " + id + " -> " + JSON.stringify(data));
|
|
316
|
+
|
|
317
|
+
await httpRequest(server + "/api/accessories/"+id, 'PUT', JSON.stringify(data), ContentType.json, {
|
|
318
|
+
Authorization: 'Bearer ' + token
|
|
319
|
+
});
|
|
320
|
+
return hbValue(respBody.values, service);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
285
324
|
export function hbSubscribe(callback) {
|
|
286
325
|
if (timer) {
|
|
287
326
|
clearInterval(timer);
|
package/server/platform.js
CHANGED
|
@@ -30,8 +30,10 @@ const p1_1 = require("./p1");
|
|
|
30
30
|
const shelly_1 = require("./shelly");
|
|
31
31
|
const config_1 = require("../duotecno/config");
|
|
32
32
|
const fs_1 = require("fs");
|
|
33
|
+
const proxy_1 = require("./proxy");
|
|
33
34
|
class Platform extends base_1.Base {
|
|
34
35
|
constructor(logger, pConfig, api) {
|
|
36
|
+
var _a;
|
|
35
37
|
super("homebridge");
|
|
36
38
|
this.accessoryList = [];
|
|
37
39
|
this.ready = false;
|
|
@@ -109,6 +111,15 @@ class Platform extends base_1.Base {
|
|
|
109
111
|
else {
|
|
110
112
|
(0, logger_1.log)("homebridge", "platform - No SocApp configured.");
|
|
111
113
|
}
|
|
114
|
+
if (this.config.proxy && ((_a = this.config.proxy) === null || _a === void 0 ? void 0 : _a.uniqueId)) {
|
|
115
|
+
this.config.proxy.kind = "gw";
|
|
116
|
+
(0, proxy_1.setProxyConfig)(this.config.proxy);
|
|
117
|
+
(0, proxy_1.cleanStart)(true);
|
|
118
|
+
(0, logger_1.log)("homebridge", "platform - Proxy configured: " + JSON.stringify(this.config.proxy, null, 2));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
(0, logger_1.log)("homebridge", "platform - No Proxy configured.");
|
|
122
|
+
}
|
|
112
123
|
}
|
|
113
124
|
startPower(type, PowerMgr) {
|
|
114
125
|
// startup a power handler, if configured
|
package/server/platform.ts
CHANGED
|
@@ -20,7 +20,8 @@ import { Lock } from "../accessories/lock";
|
|
|
20
20
|
import { P1 } from "./p1";
|
|
21
21
|
import { Shelly } from "./shelly";
|
|
22
22
|
import { kConfigFiles, setConfig } from "../duotecno/config";
|
|
23
|
-
import {
|
|
23
|
+
import { readFileSync } from "fs";
|
|
24
|
+
import { cleanStart, setProxyConfig } from "./proxy";
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
export class Platform extends Base {
|
|
@@ -115,6 +116,15 @@ export class Platform extends Base {
|
|
|
115
116
|
} else {
|
|
116
117
|
log("homebridge", "platform - No SocApp configured.");
|
|
117
118
|
}
|
|
119
|
+
|
|
120
|
+
if (this.config.proxy && this.config.proxy?.uniqueId) {
|
|
121
|
+
this.config.proxy.kind = "gw";
|
|
122
|
+
setProxyConfig(this.config.proxy);
|
|
123
|
+
cleanStart(true);
|
|
124
|
+
log("homebridge", "platform - Proxy configured: " + JSON.stringify(this.config.proxy, null, 2));
|
|
125
|
+
} else {
|
|
126
|
+
log("homebridge", "platform - No Proxy configured.");
|
|
127
|
+
}
|
|
118
128
|
}
|
|
119
129
|
|
|
120
130
|
startPower(type: string, PowerMgr: any) {
|