homebridge-smartsystem 6.5.0 → 6.7.0
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 +41 -33
- package/duotecno/api.ts +2 -0
- package/duotecno/types.js +34 -11
- package/duotecno/types.ts +103 -49
- package/package.json +4 -2
- package/server/HA-API.js +125 -0
- package/server/HA-API.ts +99 -0
- package/server/HB.js +169 -0
- package/server/HB.ts +161 -0
- package/server/platform.ts +1 -1
- package/server/powerbase.ts +1 -1
- package/server/smartapp.js +204 -95
- package/server/smartapp.ts +220 -85
- package/server/views/link-details.ejs +109 -0
- package/server/views/link-list.ejs +58 -0
- package/server/views/nav.ejs +1 -0
- package/server/views/scripts.ejs +6 -0
- package/server/views/switch-details.ejs +4 -3
- package/server/webapp.js +2 -2
- package/server/webapp.ts +2 -2
package/README.md
CHANGED
|
@@ -287,6 +287,13 @@ Homebridge UI version
|
|
|
287
287
|
- 1: ask/show protocol version -> publish
|
|
288
288
|
- 2 & 3: test on protocol version, not firmware for using registers, due to bug in master firmware pre v101.x
|
|
289
289
|
|
|
290
|
+
### v6.5.0 - 18-05-2025 - Homebridge 2.0
|
|
291
|
+
- 0: published
|
|
292
|
+
|
|
293
|
+
### v6.6.0 - 21-05-2025 - OpenHAB
|
|
294
|
+
- 0: Extra "Switch" type openHAB, uses username/password to ask for a token
|
|
295
|
+
|
|
296
|
+
|
|
290
297
|
## Hardware
|
|
291
298
|
A Raspberry Pi that connects to a Duotecno IP Node
|
|
292
299
|
and (if configured) to a Smappee Infinity (power and plugs)
|
package/config.json
CHANGED
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
}
|
|
135
135
|
]
|
|
136
136
|
},
|
|
137
|
-
"
|
|
137
|
+
"p11": {
|
|
138
138
|
"debug": false,
|
|
139
139
|
"rules": [],
|
|
140
140
|
"bindings": [
|
|
@@ -247,27 +247,25 @@
|
|
|
247
247
|
"method": "GET",
|
|
248
248
|
"type": "smappee",
|
|
249
249
|
"plug": "1"
|
|
250
|
-
}
|
|
250
|
+
}
|
|
251
|
+
],
|
|
252
|
+
"debug": false,
|
|
253
|
+
"username": "pi",
|
|
254
|
+
"password": "GMTecno",
|
|
255
|
+
"links": [
|
|
251
256
|
{
|
|
252
257
|
"logicalNodeAddress": 3,
|
|
253
|
-
"logicalAddress":
|
|
258
|
+
"logicalAddress": 30,
|
|
254
259
|
"masterAddress": "192.168.0.97",
|
|
255
260
|
"masterPort": 5001,
|
|
256
|
-
"name": "
|
|
257
|
-
"displayName": "
|
|
261
|
+
"name": "Blue LEDje",
|
|
262
|
+
"displayName": "Blue LEDje",
|
|
258
263
|
"extendedType": 0,
|
|
259
|
-
"
|
|
260
|
-
"
|
|
261
|
-
"
|
|
262
|
-
"value": 0,
|
|
263
|
-
"data": "b=2",
|
|
264
|
-
"header": "{\"a\":101, \"b\": \"hallo\"}",
|
|
265
|
-
"method": "PUT",
|
|
266
|
-
"type": "http",
|
|
267
|
-
"plug": "http://localhost:3001/api/demo/haha?set=#B"
|
|
264
|
+
"accId": "986b901a30d92cb7bd0205be90f65786c2d87c9a95d8a0a60cb4c048deda5ce6",
|
|
265
|
+
"accName": "Tim Klein",
|
|
266
|
+
"type": "accessory"
|
|
268
267
|
}
|
|
269
|
-
]
|
|
270
|
-
"debug": false
|
|
268
|
+
]
|
|
271
269
|
},
|
|
272
270
|
"system": {
|
|
273
271
|
"language": "EN",
|
|
@@ -290,21 +288,6 @@
|
|
|
290
288
|
"252": " 20211003"
|
|
291
289
|
},
|
|
292
290
|
"debug": false
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
"address": "192.168.0.5",
|
|
296
|
-
"port": 5005,
|
|
297
|
-
"password": "duotecno",
|
|
298
|
-
"name": "GM",
|
|
299
|
-
"active": true,
|
|
300
|
-
"nodenames": {
|
|
301
|
-
"3": "IP Server",
|
|
302
|
-
"4": "Sonos",
|
|
303
|
-
"16": "Smartbox Living",
|
|
304
|
-
"17": "Switch Living",
|
|
305
|
-
"252": " 20220925"
|
|
306
|
-
},
|
|
307
|
-
"debug": false
|
|
308
291
|
}
|
|
309
292
|
],
|
|
310
293
|
"cunits": [
|
|
@@ -368,6 +351,18 @@
|
|
|
368
351
|
"used": "Y",
|
|
369
352
|
"group": 0
|
|
370
353
|
},
|
|
354
|
+
{
|
|
355
|
+
"logicalNodeAddress": 3,
|
|
356
|
+
"logicalAddress": 31,
|
|
357
|
+
"masterAddress": "192.168.0.97",
|
|
358
|
+
"masterPort": 5001,
|
|
359
|
+
"name": "2|Dimmer",
|
|
360
|
+
"displayName": "Somfy Dimmer",
|
|
361
|
+
"extendedType": 0,
|
|
362
|
+
"active": "Y",
|
|
363
|
+
"used": "Y",
|
|
364
|
+
"group": 0
|
|
365
|
+
},
|
|
371
366
|
{
|
|
372
367
|
"logicalNodeAddress": 3,
|
|
373
368
|
"logicalAddress": 30,
|
|
@@ -375,7 +370,19 @@
|
|
|
375
370
|
"masterPort": 5001,
|
|
376
371
|
"name": "Blue LED",
|
|
377
372
|
"displayName": "Blue LED",
|
|
378
|
-
"extendedType":
|
|
373
|
+
"extendedType": 0,
|
|
374
|
+
"active": "N",
|
|
375
|
+
"used": "Y",
|
|
376
|
+
"group": 0
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"logicalNodeAddress": 3,
|
|
380
|
+
"logicalAddress": 29,
|
|
381
|
+
"masterAddress": "192.168.0.97",
|
|
382
|
+
"masterPort": 5001,
|
|
383
|
+
"name": "Red LED",
|
|
384
|
+
"displayName": "Red LED",
|
|
385
|
+
"extendedType": 0,
|
|
379
386
|
"active": "N",
|
|
380
387
|
"used": "Y",
|
|
381
388
|
"group": 0
|
|
@@ -454,5 +461,6 @@
|
|
|
454
461
|
"ip2": "",
|
|
455
462
|
"gateway2": ""
|
|
456
463
|
}
|
|
457
|
-
}
|
|
464
|
+
},
|
|
465
|
+
"p1": false
|
|
458
466
|
}
|
package/duotecno/api.ts
CHANGED
package/duotecno/types.js
CHANGED
|
@@ -14,7 +14,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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.
|
|
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
18
|
// Node types
|
|
19
19
|
var NodeType;
|
|
20
20
|
(function (NodeType) {
|
|
@@ -126,6 +126,13 @@ var RuleType;
|
|
|
126
126
|
RuleType["kWater"] = "water";
|
|
127
127
|
})(RuleType = exports.RuleType || (exports.RuleType = {}));
|
|
128
128
|
;
|
|
129
|
+
exports.kEmptyAction = Object.assign(Object.assign({}, exports.kEmptyUnit), { value: false });
|
|
130
|
+
;
|
|
131
|
+
exports.kEmptyRule = {
|
|
132
|
+
type: "power", channel: "0", low: 30, high: 900,
|
|
133
|
+
actions: [Object.assign(Object.assign({}, exports.kEmptyUnit), { value: false }), Object.assign(Object.assign({}, exports.kEmptyUnit), { value: 50 }), Object.assign(Object.assign({}, exports.kEmptyUnit), { value: true })]
|
|
134
|
+
};
|
|
135
|
+
// Switches
|
|
129
136
|
var SwitchType;
|
|
130
137
|
(function (SwitchType) {
|
|
131
138
|
SwitchType["kNoType"] = "";
|
|
@@ -139,18 +146,17 @@ var SwitchType;
|
|
|
139
146
|
SwitchType["kOhUpDown"] = "oupdown";
|
|
140
147
|
SwitchType["kSomfy"] = "somfy";
|
|
141
148
|
})(SwitchType = exports.SwitchType || (exports.SwitchType = {}));
|
|
142
|
-
;
|
|
149
|
+
exports.kEmptySwitch = Object.assign(Object.assign({}, exports.kEmptyUnit), { plug: 0, type: SwitchType.kNoType, unitName: "", name: "", data: "", method: "GET", header: "", username: "", password: "", nomacro: "N", nostop: "N" });
|
|
150
|
+
// Links
|
|
151
|
+
var LinkType;
|
|
152
|
+
(function (LinkType) {
|
|
153
|
+
LinkType["kNoType"] = "";
|
|
154
|
+
LinkType["kAccessory"] = "accessory";
|
|
155
|
+
})(LinkType = exports.LinkType || (exports.LinkType = {}));
|
|
156
|
+
exports.kEmptyLink = Object.assign(Object.assign({}, exports.kEmptyUnit), { type: LinkType.kAccessory, accName: "acc", accId: "" });
|
|
143
157
|
exports.kEmptyBinding = {
|
|
144
158
|
channel: "0", masterAddress: "0.0.0.0", masterPort: 5001, register: 0
|
|
145
159
|
};
|
|
146
|
-
exports.kEmptyAction = Object.assign(Object.assign({}, exports.kEmptyUnit), { value: false });
|
|
147
|
-
;
|
|
148
|
-
exports.kEmptyRule = {
|
|
149
|
-
type: "power", channel: "0", low: 30, high: 900,
|
|
150
|
-
actions: [Object.assign(Object.assign({}, exports.kEmptyUnit), { value: false }), Object.assign(Object.assign({}, exports.kEmptyUnit), { value: 50 }), Object.assign(Object.assign({}, exports.kEmptyUnit), { value: true })]
|
|
151
|
-
};
|
|
152
|
-
;
|
|
153
|
-
exports.kEmptySwitch = Object.assign(Object.assign({}, exports.kEmptyUnit), { plug: 0, type: SwitchType.kNoType, unitName: "", name: "", data: "", method: "GET", header: "", nomacro: "N", nostop: "N" });
|
|
154
160
|
;
|
|
155
161
|
;
|
|
156
162
|
;
|
|
@@ -248,9 +254,13 @@ exports.Sanitizers = {
|
|
|
248
254
|
config.port = config.port || 5002;
|
|
249
255
|
config.switches = config.switches || [];
|
|
250
256
|
config.switches = config.switches.map(sw => exports.Sanitizers.switchConfig(sw));
|
|
257
|
+
config.links = config.links || [];
|
|
258
|
+
config.links = config.links.map(sw => exports.Sanitizers.linkConfig(sw));
|
|
251
259
|
config.debug = config.debug || false;
|
|
252
260
|
config.apiHost = config.apiHost || "localhost";
|
|
253
261
|
config.apiPort = config.apiPort || 8581;
|
|
262
|
+
config.username = config.username || "admin";
|
|
263
|
+
config.password = config.password || "";
|
|
254
264
|
return config;
|
|
255
265
|
},
|
|
256
266
|
powerbase: function (config) {
|
|
@@ -284,6 +294,13 @@ exports.Sanitizers = {
|
|
|
284
294
|
cfg.addresses = (config === null || config === void 0 ? void 0 : config.addresses) || "";
|
|
285
295
|
return cfg;
|
|
286
296
|
},
|
|
297
|
+
linkConfig: function (aLink) {
|
|
298
|
+
const link = exports.Sanitizers.unitDef(aLink);
|
|
299
|
+
link.accId = aLink.accId || "";
|
|
300
|
+
link.accName = aLink.accName || "";
|
|
301
|
+
link.type = aLink.type || LinkType.kNoType;
|
|
302
|
+
return link;
|
|
303
|
+
},
|
|
287
304
|
switchConfig: function (aSwitch) {
|
|
288
305
|
const sw = exports.Sanitizers.unitDef(aSwitch);
|
|
289
306
|
sw.nomacro = aSwitch.nomacro || "N";
|
|
@@ -308,6 +325,12 @@ exports.Sanitizers = {
|
|
|
308
325
|
type: aSwitch.type, plug: aSwitch.plug,
|
|
309
326
|
data: aSwitch.data, method: aSwitch.method, header: aSwitch.header });
|
|
310
327
|
},
|
|
328
|
+
makeLinkConfig: function (aLink) {
|
|
329
|
+
return exports.Sanitizers.linkConfig({ name: aLink.name, unitName: aLink.unitName,
|
|
330
|
+
masterAddress: aLink.masterAddress, masterPort: aLink.masterPort,
|
|
331
|
+
logicalAddress: aLink.logicalAddress, logicalNodeAddress: aLink.logicalNodeAddress,
|
|
332
|
+
accName: aLink.accName, accId: aLink.accId, type: aLink.type });
|
|
333
|
+
},
|
|
311
334
|
ruleConfig(rule) {
|
|
312
335
|
rule = Object.assign({}, rule);
|
|
313
336
|
rule.channel = rule.channel || "0";
|
|
@@ -496,7 +519,7 @@ function char(ascii) {
|
|
|
496
519
|
}
|
|
497
520
|
exports.char = char;
|
|
498
521
|
function two(n) {
|
|
499
|
-
return (n < 10) ? ("0" + n) : n.toString();
|
|
522
|
+
return (+n < 10) ? ("0" + n) : n.toString();
|
|
500
523
|
}
|
|
501
524
|
exports.two = two;
|
|
502
525
|
function hex(n) {
|
package/duotecno/types.ts
CHANGED
|
@@ -193,37 +193,17 @@ export const kEmptyCommRecord = { status: false, cmd: -1, message: [-1,0,0], res
|
|
|
193
193
|
export enum Boundaries {kLow = 0, kMid = 1, kHigh = 2};
|
|
194
194
|
export enum RuleType {kPower = "power", kCurrent = "current", kWater = "water"};
|
|
195
195
|
|
|
196
|
-
export enum SwitchType {
|
|
197
|
-
kNoType = "",
|
|
198
|
-
kSmappee = "smappee",
|
|
199
|
-
kRF = "RF",
|
|
200
|
-
kHTTPSwitch = "http",
|
|
201
|
-
kHTTPDimmer = "httpdim",
|
|
202
|
-
kHTTPUpDown = "httpupdown",
|
|
203
|
-
kOhSwitch = "oswitch",
|
|
204
|
-
kOhDimmer = "odimmer",
|
|
205
|
-
kOhUpDown = "oupdown",
|
|
206
|
-
kSomfy = "somfy"
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
export interface Binding {
|
|
211
|
-
masterAddress: string;
|
|
212
|
-
masterPort: number;
|
|
213
|
-
register: number;
|
|
214
|
-
channel: string;
|
|
215
|
-
value?: number;
|
|
216
|
-
}
|
|
217
|
-
export const kEmptyBinding: Binding = {
|
|
218
|
-
channel: "0", masterAddress: "0.0.0.0", masterPort: 5001, register: 0
|
|
219
|
-
} as const;
|
|
220
196
|
|
|
221
197
|
|
|
198
|
+
///////////
|
|
199
|
+
// Rules //
|
|
200
|
+
///////////
|
|
222
201
|
export interface Action extends UnitDef {
|
|
223
202
|
value: number | boolean;
|
|
224
203
|
}
|
|
225
|
-
export const kEmptyAction: Action = {
|
|
226
|
-
|
|
204
|
+
export const kEmptyAction: Action = {
|
|
205
|
+
...kEmptyUnit, value: false
|
|
206
|
+
} as const;
|
|
227
207
|
|
|
228
208
|
export interface Rule {
|
|
229
209
|
type: string;
|
|
@@ -239,41 +219,78 @@ export const kEmptyRule: Rule = {
|
|
|
239
219
|
actions: [{...kEmptyUnit, value: false}, {...kEmptyUnit, value: 50}, {...kEmptyUnit, value: true}]
|
|
240
220
|
};
|
|
241
221
|
|
|
222
|
+
|
|
223
|
+
// Switches
|
|
224
|
+
|
|
225
|
+
export enum SwitchType {
|
|
226
|
+
kNoType = "",
|
|
227
|
+
kSmappee = "smappee",
|
|
228
|
+
kRF = "RF",
|
|
229
|
+
kHTTPSwitch = "http",
|
|
230
|
+
kHTTPDimmer = "httpdim",
|
|
231
|
+
kHTTPUpDown = "httpupdown",
|
|
232
|
+
kOhSwitch = "oswitch",
|
|
233
|
+
kOhDimmer = "odimmer",
|
|
234
|
+
kOhUpDown = "oupdown",
|
|
235
|
+
kSomfy = "somfy"
|
|
236
|
+
}
|
|
237
|
+
|
|
242
238
|
export interface Switch extends UnitDef {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
239
|
+
unitName: string;
|
|
240
|
+
type: SwitchType;
|
|
241
|
+
plug: number | string;
|
|
242
|
+
data: string;
|
|
243
|
+
header: string;
|
|
244
|
+
method: string;
|
|
245
|
+
username?: string;
|
|
246
|
+
password?: string;
|
|
250
247
|
unit?: Unit;
|
|
251
|
-
status?: number | boolean
|
|
252
|
-
value?: number | boolean | string
|
|
248
|
+
status?: number | boolean;
|
|
249
|
+
value?: number | boolean | string;
|
|
253
250
|
nomacro: string;
|
|
254
251
|
nostop: string;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export const kEmptySwitch: Switch = {
|
|
255
|
+
...kEmptyUnit, plug: 0, type: SwitchType.kNoType, unitName: "", name: "", data: "", method: "GET",
|
|
256
|
+
header: "", username: "", password: "", nomacro: "N", nostop: "N"
|
|
257
|
+
} as const;
|
|
258
258
|
|
|
259
259
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
switches: Array<Switch>;
|
|
260
|
+
// Links
|
|
261
|
+
export enum LinkType {
|
|
262
|
+
kNoType = "",
|
|
263
|
+
kAccessory = "accessory"
|
|
265
264
|
}
|
|
266
265
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
266
|
+
export interface Link extends UnitDef{
|
|
267
|
+
accName: string;
|
|
268
|
+
accId: string;
|
|
269
|
+
type: LinkType;
|
|
270
|
+
unit?: Unit;
|
|
271
|
+
status?: number | boolean;
|
|
272
|
+
value?: number | boolean | string
|
|
272
273
|
}
|
|
273
274
|
|
|
275
|
+
export const kEmptyLink: Link = {
|
|
276
|
+
...kEmptyUnit, type: LinkType.kAccessory, accName: "acc", accId: ""
|
|
277
|
+
} as const;
|
|
278
|
+
|
|
279
|
+
|
|
274
280
|
///////////
|
|
275
281
|
// Power //
|
|
276
282
|
///////////
|
|
283
|
+
export interface Binding {
|
|
284
|
+
masterAddress: string;
|
|
285
|
+
masterPort: number;
|
|
286
|
+
register: number;
|
|
287
|
+
channel: string;
|
|
288
|
+
value?: number;
|
|
289
|
+
}
|
|
290
|
+
export const kEmptyBinding: Binding = {
|
|
291
|
+
channel: "0", masterAddress: "0.0.0.0", masterPort: 5001, register: 0
|
|
292
|
+
} as const;
|
|
293
|
+
|
|
277
294
|
export interface PowerBaseConfig extends BaseConfig {
|
|
278
295
|
address: string;
|
|
279
296
|
rules: Array<Rule>;
|
|
@@ -288,6 +305,24 @@ export interface ShellyConfig extends PowerBaseConfig {
|
|
|
288
305
|
addresses: string;
|
|
289
306
|
}
|
|
290
307
|
|
|
308
|
+
|
|
309
|
+
/////////////////////
|
|
310
|
+
// Smartapp config //
|
|
311
|
+
/////////////////////
|
|
312
|
+
export interface BaseConfig {
|
|
313
|
+
debug?: boolean;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export interface SmartAppConfig extends BaseConfig {
|
|
317
|
+
port: number;
|
|
318
|
+
apiHost: string;
|
|
319
|
+
apiPort: number;
|
|
320
|
+
username: string; password: string;
|
|
321
|
+
switches: Array<Switch>;
|
|
322
|
+
links: Array<Link>;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
291
326
|
////////////////
|
|
292
327
|
// Homebridge //
|
|
293
328
|
////////////////
|
|
@@ -430,9 +465,13 @@ export const Sanitizers = {
|
|
|
430
465
|
config.port = config.port || 5002;
|
|
431
466
|
config.switches = config.switches || [];
|
|
432
467
|
config.switches = config.switches.map(sw => Sanitizers.switchConfig(sw));
|
|
468
|
+
config.links = config.links || [];
|
|
469
|
+
config.links = config.links.map(sw => Sanitizers.linkConfig(sw));
|
|
433
470
|
config.debug = config.debug || false;
|
|
434
471
|
config.apiHost = config.apiHost || "localhost";
|
|
435
472
|
config.apiPort = config.apiPort || 8581;
|
|
473
|
+
config.username = config.username || "admin";
|
|
474
|
+
config.password = config.password || "";
|
|
436
475
|
|
|
437
476
|
return config;
|
|
438
477
|
},
|
|
@@ -472,6 +511,14 @@ export const Sanitizers = {
|
|
|
472
511
|
return cfg;
|
|
473
512
|
},
|
|
474
513
|
|
|
514
|
+
linkConfig: function(aLink): Link {
|
|
515
|
+
const link = <Link>Sanitizers.unitDef(aLink);
|
|
516
|
+
link.accId = aLink.accId || "";
|
|
517
|
+
link.accName = aLink.accName || "";
|
|
518
|
+
link.type = aLink.type || LinkType.kNoType;
|
|
519
|
+
return link;
|
|
520
|
+
},
|
|
521
|
+
|
|
475
522
|
switchConfig: function(aSwitch): Switch {
|
|
476
523
|
const sw = <Switch>Sanitizers.unitDef(aSwitch);
|
|
477
524
|
sw.nomacro = aSwitch.nomacro || "N";
|
|
@@ -499,6 +546,13 @@ export const Sanitizers = {
|
|
|
499
546
|
data: aSwitch.data, method: aSwitch.method, header: aSwitch.header });
|
|
500
547
|
},
|
|
501
548
|
|
|
549
|
+
makeLinkConfig: function(aLink): Link {
|
|
550
|
+
return Sanitizers.linkConfig({ name: aLink.name, unitName: aLink.unitName,
|
|
551
|
+
masterAddress: aLink.masterAddress, masterPort: aLink.masterPort,
|
|
552
|
+
logicalAddress: aLink.logicalAddress, logicalNodeAddress: aLink.logicalNodeAddress,
|
|
553
|
+
accName: aLink.accName, accId: aLink.accId, type: aLink.type });
|
|
554
|
+
},
|
|
555
|
+
|
|
502
556
|
ruleConfig(rule): Rule {
|
|
503
557
|
rule = {... rule};
|
|
504
558
|
rule.channel = rule.channel || "0";
|
|
@@ -700,7 +754,7 @@ export function char(ascii: number): string {
|
|
|
700
754
|
|
|
701
755
|
|
|
702
756
|
export function two(n: number | string) {
|
|
703
|
-
return (n < 10) ? ("0" + n) : n.toString();
|
|
757
|
+
return (+n < 10) ? ("0" + n) : n.toString();
|
|
704
758
|
}
|
|
705
759
|
export function hex(n: number): string {
|
|
706
760
|
n = Math.floor(n);
|
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.7.0",
|
|
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",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"proxy",
|
|
24
24
|
"duotecno",
|
|
25
25
|
"homebridge",
|
|
26
|
-
"homebridge-plugin"
|
|
26
|
+
"homebridge-plugin",
|
|
27
|
+
"openHAB",
|
|
28
|
+
"Somfy"
|
|
27
29
|
],
|
|
28
30
|
"repository": {
|
|
29
31
|
"type": "git",
|
package/server/HA-API.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.httpRequest = exports.ContentType = void 0;
|
|
13
|
+
const logger_1 = require("../duotecno/logger");
|
|
14
|
+
const http = require("http");
|
|
15
|
+
//////////////////////////////////
|
|
16
|
+
// Home Assistant API //
|
|
17
|
+
// and other http based APIs //
|
|
18
|
+
//////////////////////////////////
|
|
19
|
+
var ContentType;
|
|
20
|
+
(function (ContentType) {
|
|
21
|
+
ContentType[ContentType["form"] = 0] = "form";
|
|
22
|
+
ContentType[ContentType["plain"] = 1] = "plain";
|
|
23
|
+
ContentType[ContentType["none"] = 2] = "none";
|
|
24
|
+
ContentType[ContentType["json"] = 3] = "json";
|
|
25
|
+
})(ContentType = exports.ContentType || (exports.ContentType = {}));
|
|
26
|
+
;
|
|
27
|
+
function httpRequest(url, method = "GET", formdata = "", contentType = ContentType.form, header = "") {
|
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
if (url.indexOf("://") === -1)
|
|
30
|
+
url = "http://" + url;
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
try {
|
|
33
|
+
// const data = querystring.stringify(formdata);
|
|
34
|
+
const options = { method };
|
|
35
|
+
if (formdata) {
|
|
36
|
+
if (contentType === ContentType.form) {
|
|
37
|
+
options.headers = {
|
|
38
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
39
|
+
'Content-Length': Buffer.byteLength(formdata)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
else if (contentType === ContentType.plain) {
|
|
43
|
+
options.headers = {
|
|
44
|
+
'Content-Type': 'text/plain',
|
|
45
|
+
'Accept': 'application/json'
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
else if (contentType === ContentType.json) {
|
|
49
|
+
options.headers = {
|
|
50
|
+
'Content-Type': 'application/json',
|
|
51
|
+
'Accept': '*/*'
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
;
|
|
56
|
+
// header provide as string or object
|
|
57
|
+
if (header) {
|
|
58
|
+
if (!options.headers)
|
|
59
|
+
options.headers = {};
|
|
60
|
+
if (typeof header === "string") {
|
|
61
|
+
if (header.substring(0, 1) === "{") {
|
|
62
|
+
try {
|
|
63
|
+
options.headers = Object.assign(Object.assign({}, options.headers), JSON.parse(header));
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
(0, logger_1.err)("smartapp", "error parsing :" + header + " -> " + JSON.stringify(e));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const s = header.split(":");
|
|
71
|
+
options.headers[s[0]] = s[1];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// header is an object
|
|
76
|
+
options.headers = Object.assign(Object.assign({}, options.headers), header);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
(0, logger_1.debug)("smartapp", "Sending to " + url + " with options: " + JSON.stringify(options));
|
|
80
|
+
const req = http.request(url, options, res => {
|
|
81
|
+
let resp = "";
|
|
82
|
+
// res.setEncoding('utf8');
|
|
83
|
+
res.on('error', error => {
|
|
84
|
+
(0, logger_1.log)("smartapp", "The request to " + url + ", error: " + (error ? error.message : "unknown"));
|
|
85
|
+
reject(error);
|
|
86
|
+
});
|
|
87
|
+
res.on('data', chunk => {
|
|
88
|
+
resp += chunk;
|
|
89
|
+
});
|
|
90
|
+
res.on('end', () => {
|
|
91
|
+
// try to make something out of it...
|
|
92
|
+
try {
|
|
93
|
+
const x = JSON.parse(resp);
|
|
94
|
+
if ((x.type === "Buffer") && x.data)
|
|
95
|
+
x.data = x.data.toString();
|
|
96
|
+
(0, logger_1.debug)("smartapp", "http " + method + " -> " + res.statusCode + ": " + url + " = " + JSON.stringify(x).substring(0, 200) + "...");
|
|
97
|
+
resolve(x);
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
(0, logger_1.err)("smartapp", "http " + method + " -> " + res.statusCode + ": " + url + " = " + resp);
|
|
101
|
+
resolve({ status: "NOK", result: resp });
|
|
102
|
+
}
|
|
103
|
+
;
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
if (formdata) {
|
|
107
|
+
req.write(formdata);
|
|
108
|
+
}
|
|
109
|
+
req.on("error", (e) => {
|
|
110
|
+
(0, logger_1.log)("smartapp", "The request to " + url + ", error: " + (e ? e.message : "unknown"));
|
|
111
|
+
});
|
|
112
|
+
req.on("timeout", (e) => {
|
|
113
|
+
(0, logger_1.log)("smartapp", "The request to " + url + ", timeout: " + (e ? e.message : "unknown"));
|
|
114
|
+
});
|
|
115
|
+
req.end();
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
(0, logger_1.log)("smartapp", "** http error ** " + (e ? e.message : "unknown") + " **");
|
|
119
|
+
reject(e);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
exports.httpRequest = httpRequest;
|
|
125
|
+
//# sourceMappingURL=HA-API.js.map
|