homebridge-smartsystem 6.0.7 → 6.0.10
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 +112 -2
- package/accessories/accessory.js +3 -2
- package/accessories/accessory.ts +10 -7
- package/accessories/bulb.ts +2 -1
- package/accessories/dimmer.js +1 -1
- package/accessories/dimmer.ts +3 -2
- package/accessories/door.ts +4 -2
- package/accessories/garagedoor.js +1 -1
- package/accessories/garagedoor.ts +5 -3
- package/accessories/lock.js +2 -1
- package/accessories/lock.ts +6 -4
- package/accessories/mood.js +1 -1
- package/accessories/mood.ts +3 -2
- package/accessories/switch.ts +2 -1
- package/accessories/temperature.js +1 -1
- package/accessories/temperature.ts +3 -2
- package/accessories/windowcovering.js +1 -1
- package/accessories/windowcovering.ts +3 -2
- package/duotecno/protocol.js +2 -1
- package/duotecno/protocol.ts +1 -1
- package/duotecno/types.ts +0 -1
- package/package.json +1 -1
- package/server/base.js +1 -1
- package/server/base.ts +1 -1
- package/server/smartapp.js +5 -0
- package/server/smartapp.ts +5 -0
- package/server/views/footer.ejs +1 -1
- package/server/views/nav.ejs +1 -1
- package/server/views/settings.ejs +4 -4
- package/server/webapp.js +7 -1
- package/server/webapp.ts +10 -0
package/README.md
CHANGED
|
@@ -237,7 +237,12 @@ switch =>
|
|
|
237
237
|
## v5.14.1 - todo
|
|
238
238
|
- listen on gpio pin
|
|
239
239
|
|
|
240
|
-
|
|
240
|
+
## v6.0.x - 01-07-2022
|
|
241
|
+
- .1: first version running on Homebridge UI
|
|
242
|
+
- .9: read version from package.json
|
|
243
|
+
- .10: removed "homekit" nav tab,
|
|
244
|
+
added "restart plugin" to settings,
|
|
245
|
+
set lock target state to "locked"
|
|
241
246
|
|
|
242
247
|
## Hardware
|
|
243
248
|
A Raspberry Pi that connects to a Duotecno IP Node
|
|
@@ -304,7 +309,112 @@ this $ is replaced by the value of the attached unit
|
|
|
304
309
|
Example: http://192.168.0.101/relay/0?turn=on&brightness=$
|
|
305
310
|
|
|
306
311
|
|
|
307
|
-
## How to set up a Raspberry Pi
|
|
312
|
+
## How to set up a Raspberry Pi - from V6.0 on
|
|
313
|
+
```
|
|
314
|
+
1. Setup Debian in Pi on 192.168.0.9
|
|
315
|
+
|
|
316
|
+
- download “Raspberry Pi Imager” from https://www.raspberrypi.com/software/
|
|
317
|
+
- install “Raspberry PI OS Lite 32bit” in settings: user, password, name, enable ssh, etc… in settings
|
|
318
|
+
- add “ip=192.168.0.9” to /boot/cmdline.txt (or whatever free address)
|
|
319
|
+
- put the card into a Pi and power on
|
|
320
|
+
- try to connect with ssh pi@192.168.0.9
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
2. Install Homebridge
|
|
324
|
+
|
|
325
|
+
(see instructions on https://github.com/homebridge/homebridge/wiki/Install-Homebridge-on-Raspbian)
|
|
326
|
+
|
|
327
|
+
Execute on the Pi via ssh:
|
|
328
|
+
|
|
329
|
+
# if forgotten:
|
|
330
|
+
# 1. for better security enable public key
|
|
331
|
+
mkdir ~/.ssh
|
|
332
|
+
chmod 700 ~/.ssh
|
|
333
|
+
cat "Mac/PC .ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
|
|
334
|
+
chmod 600 ~/.ssh/authorized_keys
|
|
335
|
+
rm ~/id_rsa.pub
|
|
336
|
+
|
|
337
|
+
# 2. use pi-config
|
|
338
|
+
sudo raspi-config
|
|
339
|
+
-> enable ssh
|
|
340
|
+
-> boot to cmdline
|
|
341
|
+
|
|
342
|
+
# Add Homebridge to repo’s
|
|
343
|
+
curl -sSfL https://repo.homebridge.io/KEY.gpg | sudo gpg --dearmor | sudo tee /usr/share/keyrings/homebridge.gpg > /dev/null
|
|
344
|
+
echo "deb [signed-by=/usr/share/keyrings/homebridge.gpg] https://repo.homebridge.io stable main" | sudo tee /etc/apt/sources.list.d/homebridge.list > /dev/null
|
|
345
|
+
|
|
346
|
+
# Install Homebridge
|
|
347
|
+
sudo apt-get update
|
|
348
|
+
sudo apt-get --yes install homebridge
|
|
349
|
+
sudo ln -s /opt/homebridge/bin/node /usr/bin/node
|
|
350
|
+
sudo ln -s /opt/homebridge/bin/npm /usr/bin/npm
|
|
351
|
+
|
|
352
|
+
# install smappee and mqtt
|
|
353
|
+
sudo npm install -g --force mqtt
|
|
354
|
+
sudo ln -s /opt/homebridge/bin/mqtt /usr/bin/mqtt
|
|
355
|
+
|
|
356
|
+
# connect to homebridge UI with a browser
|
|
357
|
+
http://192.168.0.9:8581
|
|
358
|
+
add user, for example: pi / pw…
|
|
359
|
+
|
|
360
|
+
# add duotecno plugin to Homebridge config
|
|
361
|
+
go to "Plugins"
|
|
362
|
+
search for "smartsystem"
|
|
363
|
+
click "install"
|
|
364
|
+
|
|
365
|
+
# or in advance:
|
|
366
|
+
cd /var/lib/homebridge
|
|
367
|
+
sudo npm install --save homebridge-smartsystem
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
# set config to:
|
|
371
|
+
{
|
|
372
|
+
"manufacturer": "Duotecno-Coppieters",
|
|
373
|
+
"name": "Duotecno",
|
|
374
|
+
"platform": "DuotecnoPlatform",
|
|
375
|
+
"smappee": true,
|
|
376
|
+
"smartapp": true,
|
|
377
|
+
"system": true,
|
|
378
|
+
"socapp": false
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
# restart Homebridge in webbrowser (right top icon)
|
|
382
|
+
|
|
383
|
+
# connect to Duotecno gateway
|
|
384
|
+
http://192.168.0.9:5002
|
|
385
|
+
add master and off you go… see "setup" a little bit higher
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
3. Various optional
|
|
389
|
+
|
|
390
|
+
Updates
|
|
391
|
+
sudo apt-get update
|
|
392
|
+
sudo apt-get install homebridge
|
|
393
|
+
sudo hb-service update-node
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
Uninstall
|
|
397
|
+
sudo apt-get remove homebridge
|
|
398
|
+
sudo rm -rf /etc/apt/sources.list.d/homebridge.list
|
|
399
|
+
sudo apt-get purge homebridge
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
4. Smappee
|
|
403
|
+
|
|
404
|
+
#find uuid
|
|
405
|
+
mqtt sub -t 'servicelocation/#' -h '192.168.0.186’ -v
|
|
406
|
+
# -> 57e3e0d8-bb05-4b04-8662-1a9871998f3f
|
|
407
|
+
|
|
408
|
+
#add uuid
|
|
409
|
+
mqtt sub -t 'servicelocation/57e3e0d8-bb05-4b04-8662-1a9871998f3f/#' -h '192.168.0.186' -v
|
|
410
|
+
|
|
411
|
+
# http://pro.smappee.net
|
|
412
|
+
# duotecno/duotecno1234
|
|
413
|
+
# 192.168.0.2
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## How to set up a Raspberry Pi - V1
|
|
308
418
|
|
|
309
419
|
### Copy SD Card
|
|
310
420
|
dump ->
|
package/accessories/accessory.js
CHANGED
|
@@ -9,9 +9,10 @@ class Accessory {
|
|
|
9
9
|
constructor(log, api, unit) {
|
|
10
10
|
this.homebridge = api.hap;
|
|
11
11
|
this.log = log; // : function(message)
|
|
12
|
-
this.unit = unit; // : Unit
|
|
12
|
+
this.unit = unit; // : Duotecno Unit
|
|
13
13
|
this.name = unit.getDisplayName();
|
|
14
14
|
this.uuid_base = unit.getSerialNr();
|
|
15
|
+
// get all services and add ours
|
|
15
16
|
this.services = this.getAccessoryServices();
|
|
16
17
|
this.services.push(this.getInformationService());
|
|
17
18
|
}
|
|
@@ -85,7 +86,7 @@ class Accessory {
|
|
|
85
86
|
}
|
|
86
87
|
updateState() {
|
|
87
88
|
this.me.getCharacteristic(this.homebridge.Characteristic.On).updateValue(this.unit.status);
|
|
88
|
-
this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> on = " + this.unit.status);
|
|
89
|
+
// this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> on = " + this.unit.status);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
exports.Accessory = Accessory;
|
package/accessories/accessory.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { LogFunction
|
|
1
|
+
import { LogFunction } from "../duotecno/types";
|
|
2
2
|
import { Unit } from "../duotecno/protocol";
|
|
3
|
+
import { API, HAP, Service } from "homebridge";
|
|
3
4
|
|
|
4
5
|
// Johan Coppieters Jan 2019
|
|
5
6
|
//
|
|
@@ -7,27 +8,29 @@ import { Unit } from "../duotecno/protocol";
|
|
|
7
8
|
// handling the homekit required services.
|
|
8
9
|
|
|
9
10
|
export class Accessory {
|
|
10
|
-
homebridge:
|
|
11
|
+
homebridge: HAP; // homebridge api endpoint
|
|
11
12
|
log: LogFunction;
|
|
12
13
|
unit: Unit;
|
|
13
14
|
config: any; // all config params
|
|
14
15
|
name: string;
|
|
15
16
|
uuid_base: string;
|
|
16
17
|
services: Array<Service>;
|
|
17
|
-
me:
|
|
18
|
+
me: Service;
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
constructor(log: LogFunction, api, unit: Unit
|
|
21
|
+
constructor(log: LogFunction, api: API, unit: Unit) {
|
|
21
22
|
this.homebridge = api.hap;
|
|
22
23
|
this.log = log; // : function(message)
|
|
23
|
-
this.unit = unit; // : Unit
|
|
24
|
+
this.unit = unit; // : Duotecno Unit
|
|
24
25
|
this.name = unit.getDisplayName();
|
|
25
26
|
this.uuid_base = unit.getSerialNr();
|
|
27
|
+
|
|
28
|
+
// get all services and add ours
|
|
26
29
|
this.services = this.getAccessoryServices();
|
|
27
30
|
this.services.push(this.getInformationService());
|
|
28
31
|
}
|
|
29
32
|
|
|
30
|
-
makeService(service:
|
|
33
|
+
makeService(service: any): Service {
|
|
31
34
|
this.log("accessory - Making service: " + this.name + ", serial: " + this.uuid_base);
|
|
32
35
|
this.me = new service(this.name);
|
|
33
36
|
return this.me;
|
|
@@ -106,7 +109,7 @@ export class Accessory {
|
|
|
106
109
|
|
|
107
110
|
updateState() {
|
|
108
111
|
this.me.getCharacteristic(this.homebridge.Characteristic.On).updateValue(this.unit.status);
|
|
109
|
-
this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> on = " + this.unit.status);
|
|
112
|
+
// this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> on = " + this.unit.status);
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
}
|
package/accessories/bulb.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Accessory } from "./accessory";
|
|
2
2
|
import { LogFunction } from "../duotecno/types";
|
|
3
3
|
import { Unit } from "../duotecno/protocol";
|
|
4
|
+
import { API } from "homebridge";
|
|
4
5
|
|
|
5
6
|
// Johan Coppieters Jan 2019
|
|
6
7
|
//
|
|
@@ -12,7 +13,7 @@ import { Unit } from "../duotecno/protocol";
|
|
|
12
13
|
|
|
13
14
|
export class Bulb extends Accessory {
|
|
14
15
|
|
|
15
|
-
constructor(log: LogFunction, homebridge, unit: Unit) {
|
|
16
|
+
constructor(log: LogFunction, homebridge: API, unit: Unit) {
|
|
16
17
|
super(log, homebridge, unit);
|
|
17
18
|
}
|
|
18
19
|
|
package/accessories/dimmer.js
CHANGED
|
@@ -68,7 +68,7 @@ class Dimmer extends accessory_1.Accessory {
|
|
|
68
68
|
}
|
|
69
69
|
updateState() {
|
|
70
70
|
this.me.getCharacteristic(this.homebridge.Characteristic.Brightness).updateValue(this.unit.value);
|
|
71
|
-
this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> Brightness = " + this.unit.value);
|
|
71
|
+
// this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> Brightness = " + this.unit.value);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
exports.Dimmer = Dimmer;
|
package/accessories/dimmer.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Accessory } from "./accessory";
|
|
2
2
|
import { LogFunction } from "../duotecno/types";
|
|
3
3
|
import { Unit } from "../duotecno/protocol";
|
|
4
|
+
import { API } from "homebridge";
|
|
4
5
|
|
|
5
6
|
// Johan Coppieters Jan 2019
|
|
6
7
|
//
|
|
@@ -14,7 +15,7 @@ export class Dimmer extends Accessory {
|
|
|
14
15
|
preventSetPower: boolean;
|
|
15
16
|
waitingSetPower: boolean;
|
|
16
17
|
|
|
17
|
-
constructor(log: LogFunction, homebridge, unit: Unit) {
|
|
18
|
+
constructor(log: LogFunction, homebridge: API, unit: Unit) {
|
|
18
19
|
super(log, homebridge, unit);
|
|
19
20
|
this.currValue = 0;
|
|
20
21
|
this.preventSetPower = false;
|
|
@@ -83,7 +84,7 @@ export class Dimmer extends Accessory {
|
|
|
83
84
|
|
|
84
85
|
updateState() {
|
|
85
86
|
this.me.getCharacteristic(this.homebridge.Characteristic.Brightness).updateValue(this.unit.value);
|
|
86
|
-
this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> Brightness = " + this.unit.value);
|
|
87
|
+
// this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> Brightness = " + this.unit.value);
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
}
|
package/accessories/door.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Accessory } from "./accessory";
|
|
2
|
-
import { UnitMotorCmd, UnitState } from "../duotecno/types";
|
|
2
|
+
import { LogFunction, UnitMotorCmd, UnitState } from "../duotecno/types";
|
|
3
3
|
import { WindowCovering } from "./windowcovering";
|
|
4
|
+
import { Unit } from "../duotecno/protocol";
|
|
5
|
+
import { API } from "homebridge";
|
|
4
6
|
|
|
5
7
|
// Johan Coppieters Jun 2020
|
|
6
8
|
//
|
|
@@ -51,7 +53,7 @@ import { WindowCovering } from "./windowcovering";
|
|
|
51
53
|
export class Door extends WindowCovering {
|
|
52
54
|
targetState;
|
|
53
55
|
|
|
54
|
-
constructor(log, homebridge, unit) {
|
|
56
|
+
constructor(log: LogFunction, homebridge: API, unit: Unit) {
|
|
55
57
|
super(log, homebridge, unit);
|
|
56
58
|
}
|
|
57
59
|
|
|
@@ -86,7 +86,7 @@ class GarageDoor extends accessory_1.Accessory {
|
|
|
86
86
|
// in response to Duotecno status messages
|
|
87
87
|
updateState() {
|
|
88
88
|
const value = this.DT2HB(this.unit.status);
|
|
89
|
-
this.log("Received updateState -> Homekit GarageDoor for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
|
|
89
|
+
// this.log("Received updateState -> Homekit GarageDoor for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
|
|
90
90
|
this.me.getCharacteristic(this.homebridge.Characteristic.CurrentDoorState).updateValue(value);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { API } from "homebridge";
|
|
2
|
+
import { Unit } from "../duotecno/protocol";
|
|
3
|
+
import { LogFunction, UnitMotorCmd, UnitState } from "../duotecno/types";
|
|
2
4
|
import { Accessory } from "./accessory";
|
|
3
5
|
|
|
4
6
|
// Johan Coppieters Jun 2020
|
|
@@ -14,7 +16,7 @@ import { Accessory } from "./accessory";
|
|
|
14
16
|
export class GarageDoor extends Accessory {
|
|
15
17
|
targetState;
|
|
16
18
|
|
|
17
|
-
constructor(log, homebridge, unit) {
|
|
19
|
+
constructor(log: LogFunction, homebridge: API, unit: Unit) {
|
|
18
20
|
super(log, homebridge, unit);
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -114,7 +116,7 @@ export class GarageDoor extends Accessory {
|
|
|
114
116
|
// in response to Duotecno status messages
|
|
115
117
|
updateState() {
|
|
116
118
|
const value = this.DT2HB(this.unit.status);
|
|
117
|
-
this.log("Received updateState -> Homekit GarageDoor for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
|
|
119
|
+
// this.log("Received updateState -> Homekit GarageDoor for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing to HB: " + value);
|
|
118
120
|
this.me.getCharacteristic(this.homebridge.Characteristic.CurrentDoorState).updateValue(value);
|
|
119
121
|
}
|
|
120
122
|
|
package/accessories/lock.js
CHANGED
|
@@ -13,6 +13,7 @@ const accessory_1 = require("./accessory");
|
|
|
13
13
|
class Lock extends accessory_1.Accessory {
|
|
14
14
|
constructor(log, homebridge, unit) {
|
|
15
15
|
super(log, homebridge, unit);
|
|
16
|
+
this.targetState = 1; // locked
|
|
16
17
|
this.log("created Lock -> " + unit.getDescription());
|
|
17
18
|
// set default for Unlocked to Locked
|
|
18
19
|
if (this.unit.getType() === types_1.UnitExtendedType.kUnlocker)
|
|
@@ -67,7 +68,7 @@ class Lock extends accessory_1.Accessory {
|
|
|
67
68
|
}
|
|
68
69
|
// in response to Duotecno status messages
|
|
69
70
|
updateState() {
|
|
70
|
-
this.log("Received updateState -> Homekit Lock for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
|
|
71
|
+
// this.log("Received updateState -> Homekit Lock for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
|
|
71
72
|
this.me.getCharacteristic(this.homebridge.Characteristic.LockCurrentState).updateValue(this.unit.status);
|
|
72
73
|
}
|
|
73
74
|
}
|
package/accessories/lock.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { API } from "homebridge";
|
|
2
|
+
import { Unit } from "../duotecno/protocol";
|
|
3
|
+
import { LogFunction, UnitExtendedType } from "../duotecno/types";
|
|
2
4
|
import { Accessory } from "./accessory";
|
|
3
5
|
|
|
4
6
|
// Johan Coppieters Jun 2020
|
|
@@ -12,9 +14,9 @@ import { Accessory } from "./accessory";
|
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
export class Lock extends Accessory {
|
|
15
|
-
targetState;
|
|
17
|
+
targetState = 1; // locked
|
|
16
18
|
|
|
17
|
-
constructor(log, homebridge, unit) {
|
|
19
|
+
constructor(log: LogFunction, homebridge: API, unit: Unit) {
|
|
18
20
|
super(log, homebridge, unit);
|
|
19
21
|
this.log("created Lock -> " + unit.getDescription());
|
|
20
22
|
|
|
@@ -86,7 +88,7 @@ export class Lock extends Accessory {
|
|
|
86
88
|
|
|
87
89
|
// in response to Duotecno status messages
|
|
88
90
|
updateState() {
|
|
89
|
-
this.log("Received updateState -> Homekit Lock for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
|
|
91
|
+
// this.log("Received updateState -> Homekit Lock for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status);
|
|
90
92
|
this.me.getCharacteristic(this.homebridge.Characteristic.LockCurrentState).updateValue(this.unit.status);
|
|
91
93
|
}
|
|
92
94
|
|
package/accessories/mood.js
CHANGED
|
@@ -50,7 +50,7 @@ class Mood extends accessory_1.Accessory {
|
|
|
50
50
|
}
|
|
51
51
|
updateState() {
|
|
52
52
|
this.me.getCharacteristic(this.homebridge.Characteristic.On).updateValue(!!this.unit.value);
|
|
53
|
-
this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> On = " + !!this.unit.value);
|
|
53
|
+
// this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> On = " + !!this.unit.value);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
exports.Mood = Mood;
|
package/accessories/mood.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Accessory } from "./accessory";
|
|
2
2
|
import { LogFunction, UnitExtendedType } from "../duotecno/types";
|
|
3
3
|
import { Unit } from "../duotecno/protocol";
|
|
4
|
+
import { API } from "homebridge";
|
|
4
5
|
|
|
5
6
|
// Johan Coppieters Jan 2019
|
|
6
7
|
//
|
|
@@ -12,7 +13,7 @@ import { Unit } from "../duotecno/protocol";
|
|
|
12
13
|
export class Mood extends Accessory {
|
|
13
14
|
myService;
|
|
14
15
|
|
|
15
|
-
constructor(log: LogFunction, homebridge, unit: Unit) {
|
|
16
|
+
constructor(log: LogFunction, homebridge: API, unit: Unit) {
|
|
16
17
|
super(log, homebridge, unit);
|
|
17
18
|
|
|
18
19
|
}
|
|
@@ -60,7 +61,7 @@ export class Mood extends Accessory {
|
|
|
60
61
|
}
|
|
61
62
|
updateState() {
|
|
62
63
|
this.me.getCharacteristic(this.homebridge.Characteristic.On).updateValue(!!this.unit.value);
|
|
63
|
-
this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> On = " + !!this.unit.value);
|
|
64
|
+
// this.log("Received status change -> update accessory -> " + this.unit.getName() + " -> On = " + !!this.unit.value);
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
}
|
package/accessories/switch.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LogFunction } from "../duotecno/types";
|
|
2
2
|
import { Accessory } from "./accessory";
|
|
3
3
|
import { Unit } from "../duotecno/protocol";
|
|
4
|
+
import { API } from "homebridge";
|
|
4
5
|
|
|
5
6
|
// Johan Coppieters Jan 2019
|
|
6
7
|
//
|
|
@@ -10,7 +11,7 @@ import { Unit } from "../duotecno/protocol";
|
|
|
10
11
|
|
|
11
12
|
export class Switch extends Accessory {
|
|
12
13
|
|
|
13
|
-
constructor(log: LogFunction, homebridge, unit: Unit) {
|
|
14
|
+
constructor(log: LogFunction, homebridge: API, unit: Unit) {
|
|
14
15
|
super(log, homebridge, unit);
|
|
15
16
|
|
|
16
17
|
}
|
|
@@ -33,7 +33,7 @@ class Temperature extends accessory_1.Accessory {
|
|
|
33
33
|
}
|
|
34
34
|
updateState() {
|
|
35
35
|
this.me.getCharacteristic(this.homebridge.Characteristic.CurrentTemperature).updateValue(this.unit.value / 10.0);
|
|
36
|
-
this.log("Received updateState -> Homekit Temperature -> " + this.unit.getName() + " -> temp = " +
|
|
36
|
+
// this.log("Received updateState -> Homekit Temperature -> " + this.unit.getName() + " -> temp = " +(<number>this.unit.value) / 10.0);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
exports.Temperature = Temperature;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Accessory } from "./accessory";
|
|
2
2
|
import { LogFunction } from "../duotecno/types";
|
|
3
3
|
import { Unit } from "../duotecno/protocol";
|
|
4
|
+
import { API } from "homebridge";
|
|
4
5
|
|
|
5
6
|
// Johan Coppieters Jan 2019
|
|
6
7
|
//
|
|
@@ -11,7 +12,7 @@ import { Unit } from "../duotecno/protocol";
|
|
|
11
12
|
|
|
12
13
|
export class Temperature extends Accessory {
|
|
13
14
|
|
|
14
|
-
constructor(log: LogFunction, homebridge, unit: Unit) {
|
|
15
|
+
constructor(log: LogFunction, homebridge: API, unit: Unit) {
|
|
15
16
|
super(log, homebridge, unit);
|
|
16
17
|
|
|
17
18
|
}
|
|
@@ -41,7 +42,7 @@ export class Temperature extends Accessory {
|
|
|
41
42
|
|
|
42
43
|
updateState() {
|
|
43
44
|
this.me.getCharacteristic(this.homebridge.Characteristic.CurrentTemperature).updateValue((<number>this.unit.value) / 10.0);
|
|
44
|
-
this.log("Received updateState -> Homekit Temperature -> " + this.unit.getName() + " -> temp = " +(<number>this.unit.value) / 10.0);
|
|
45
|
+
// this.log("Received updateState -> Homekit Temperature -> " + this.unit.getName() + " -> temp = " +(<number>this.unit.value) / 10.0);
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
}
|
|
@@ -133,7 +133,7 @@ class WindowCovering extends accessory_1.Accessory {
|
|
|
133
133
|
// called in response to Duotecno status update
|
|
134
134
|
updateState() {
|
|
135
135
|
const value = this.DT2HB(this.unit.status);
|
|
136
|
-
this.log("Received updateState -> Homekit WindowCovering for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing: " + value);
|
|
136
|
+
// this.log("Received updateState -> Homekit WindowCovering for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing: " + value);
|
|
137
137
|
this.me.getCharacteristic(this.homebridge.Characteristic.CurrentPosition).updateValue(value);
|
|
138
138
|
if (this.unit.status == types_1.UnitState.kClosing) {
|
|
139
139
|
this.me.getCharacteristic(this.homebridge.Characteristic.TargetPosition).updateValue(0);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Accessory } from "./accessory";
|
|
2
2
|
import { LogFunction, UnitMotorCmd, UnitState } from "../duotecno/types";
|
|
3
3
|
import { Unit } from "../duotecno/protocol";
|
|
4
|
+
import { API } from "homebridge";
|
|
4
5
|
|
|
5
6
|
// Johan Coppieters v1: Jan 2019, v2: Jun 2020
|
|
6
7
|
//
|
|
@@ -58,7 +59,7 @@ import { Unit } from "../duotecno/protocol";
|
|
|
58
59
|
export class WindowCovering extends Accessory {
|
|
59
60
|
targetState;
|
|
60
61
|
|
|
61
|
-
constructor(log: LogFunction, homebridge, unit: Unit) {
|
|
62
|
+
constructor(log: LogFunction, homebridge: API, unit: Unit) {
|
|
62
63
|
super(log, homebridge, unit);
|
|
63
64
|
this.targetState = 0; // down or closed by default ??
|
|
64
65
|
|
|
@@ -159,7 +160,7 @@ export class WindowCovering extends Accessory {
|
|
|
159
160
|
// called in response to Duotecno status update
|
|
160
161
|
updateState() {
|
|
161
162
|
const value = this.DT2HB(this.unit.status);
|
|
162
|
-
this.log("Received updateState -> Homekit WindowCovering for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing: " + value);
|
|
163
|
+
// this.log("Received updateState -> Homekit WindowCovering for " + this.unit.node.getName() + " - " + this.unit.getName() + " -> " + this.unit.status + " / " + this.unit.value + " -> passing: " + value);
|
|
163
164
|
|
|
164
165
|
this.me.getCharacteristic(this.homebridge.Characteristic.CurrentPosition).updateValue(value);
|
|
165
166
|
|
package/duotecno/protocol.js
CHANGED
|
@@ -447,7 +447,8 @@ exports.Protocol = {
|
|
|
447
447
|
emitter: null,
|
|
448
448
|
setLogger(logger, debug) {
|
|
449
449
|
this.logger = logger;
|
|
450
|
-
|
|
450
|
+
if (debug)
|
|
451
|
+
this.debugger = debug;
|
|
451
452
|
},
|
|
452
453
|
setEmitter(emitter) {
|
|
453
454
|
this.emitter = emitter;
|
package/duotecno/protocol.ts
CHANGED
|
@@ -525,7 +525,7 @@ export const Protocol = {
|
|
|
525
525
|
|
|
526
526
|
setLogger(logger: LogFunction, debug?: LogFunction) {
|
|
527
527
|
this.logger = logger;
|
|
528
|
-
this.debugger = debug
|
|
528
|
+
if (debug) this.debugger = debug;
|
|
529
529
|
},
|
|
530
530
|
setEmitter(emitter: EventEmitter) {
|
|
531
531
|
this.emitter = emitter;
|
package/duotecno/types.ts
CHANGED
|
@@ -273,7 +273,6 @@ export interface SmappeeConfig extends BaseConfig {
|
|
|
273
273
|
// coming from Homebridge or from unit tests
|
|
274
274
|
export type LogFunction = (message: any, ...optionalParams: any[]) => void;
|
|
275
275
|
// needed as return objects to Homebridge
|
|
276
|
-
export type Service = new (nodeName: string) => any;
|
|
277
276
|
|
|
278
277
|
|
|
279
278
|
export interface Bridge {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-smartsystem",
|
|
3
3
|
"displayname": "Duotecno Bridge",
|
|
4
|
-
"version": "6.0.
|
|
4
|
+
"version": "6.0.10",
|
|
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/base.js
CHANGED
|
@@ -6,7 +6,7 @@ const protocol_1 = require("../duotecno/protocol");
|
|
|
6
6
|
const types_1 = require("../duotecno/types");
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
8
|
const os_1 = require("os");
|
|
9
|
-
const kConfigFiles = (0, os_1.homedir)() + "/
|
|
9
|
+
const kConfigFiles = (0, os_1.homedir)() + "/duotecno";
|
|
10
10
|
if (!(0, fs_1.existsSync)(kConfigFiles))
|
|
11
11
|
(0, fs_1.mkdirSync)(kConfigFiles);
|
|
12
12
|
///////////////
|
package/server/base.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { LogFunction, now, Sanitizers } from "../duotecno/types";
|
|
|
6
6
|
import { existsSync, mkdirSync } from "fs";
|
|
7
7
|
import { homedir } from "os";
|
|
8
8
|
|
|
9
|
-
const kConfigFiles = homedir() + "/
|
|
9
|
+
const kConfigFiles = homedir() + "/duotecno";
|
|
10
10
|
if (! existsSync(kConfigFiles)) mkdirSync(kConfigFiles);
|
|
11
11
|
|
|
12
12
|
|
package/server/smartapp.js
CHANGED
|
@@ -211,8 +211,13 @@ class SmartApp extends webapp_1.WebApp {
|
|
|
211
211
|
config = this.scrapeSettings(context);
|
|
212
212
|
this.write("settings", config);
|
|
213
213
|
}
|
|
214
|
+
else if (context.action === "restart") {
|
|
215
|
+
context.request = "restart";
|
|
216
|
+
return this.doRestart(false);
|
|
217
|
+
}
|
|
214
218
|
else if (context.action === "install") {
|
|
215
219
|
config = this.scrapeSettings(context);
|
|
220
|
+
context.request = "install";
|
|
216
221
|
this.write("settings", config);
|
|
217
222
|
this.writeDHCP(context, config);
|
|
218
223
|
}
|
package/server/smartapp.ts
CHANGED
|
@@ -227,8 +227,13 @@ export class SmartApp extends WebApp {
|
|
|
227
227
|
config = this.scrapeSettings(context);
|
|
228
228
|
this.write("settings", config);
|
|
229
229
|
|
|
230
|
+
} else if (context.action === "restart") {
|
|
231
|
+
context.request = "restart";
|
|
232
|
+
return this.doRestart(false)
|
|
233
|
+
|
|
230
234
|
} else if (context.action === "install") {
|
|
231
235
|
config = this.scrapeSettings(context);
|
|
236
|
+
context.request = "install";
|
|
232
237
|
this.write("settings", config);
|
|
233
238
|
this.writeDHCP(context, config);
|
|
234
239
|
|
package/server/views/footer.ejs
CHANGED
package/server/views/nav.ejs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="nav-wrapper">
|
|
3
3
|
<a href="/index.html" target=_blank class="brand-logo hide-on-small-only" >Duotecno</a>
|
|
4
4
|
<ul id="nav-mobile" class="right">
|
|
5
|
-
|
|
5
|
+
<!-- li <%= (request === "homekit") ? 'class="active"' : '' %></li><a href="/homekit">Homekit</a></li -->
|
|
6
6
|
<li <%= (request === "masters") ? 'class="active"' : '' %></li><a href="/masters">Masters</a></li>
|
|
7
7
|
<li <%= (request === "services") ? 'class="active"' : '' %></li><a href="/services">Services</a></li>
|
|
8
8
|
<% if (hasSmappee) { %><li <%= (request === "smappee") ? 'class="active"' : '' %></li><a href="/smappee">Smappee</a></li><% } %>
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
<form method="POST" action="/settings">
|
|
18
18
|
<input type="hidden" name="daction" value="save">
|
|
19
19
|
<h1>
|
|
20
|
-
|
|
21
|
-
<button class="right btn waves-effect waves-light" type="submit" name="action" value="
|
|
22
|
-
<button class="right btn waves-effect waves-light" type="submit" name="action" value="
|
|
23
|
-
<button class="right btn waves-effect waves-light" type="submit" name="action" value="
|
|
20
|
+
Settings<button class="right btn waves-effect waves-light" type="submit" name="action" value="reset">Reset to DHCP</button>
|
|
21
|
+
<button class="right btn waves-effect waves-light" type="submit" name="action" value="install">Install IP Settings</button>
|
|
22
|
+
<button class="right btn waves-effect waves-light" type="submit" name="action" value="reboot">Reboot PI</button>
|
|
23
|
+
<button class="right btn waves-effect waves-light" type="submit" name="action" value="restart">Restart Homebridge</button>
|
|
24
24
|
</h1>
|
|
25
25
|
|
|
26
26
|
<div class="row">
|
package/server/webapp.js
CHANGED
|
@@ -12,7 +12,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
12
12
|
});
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.WebApp = exports.Context = exports.single = void 0;
|
|
15
|
+
exports.WebApp = exports.Context = exports.kVersion = exports.single = void 0;
|
|
16
16
|
const ejs = require("ejs");
|
|
17
17
|
const http = require("http");
|
|
18
18
|
const fs = require("fs");
|
|
@@ -30,6 +30,8 @@ function single(val) {
|
|
|
30
30
|
return (val instanceof Array) ? val[0] : val;
|
|
31
31
|
}
|
|
32
32
|
exports.single = single;
|
|
33
|
+
exports.kVersion = require("../package.json").version;
|
|
34
|
+
console.log("stolen version: " + exports.kVersion);
|
|
33
35
|
///////////////////
|
|
34
36
|
// Context Class //
|
|
35
37
|
///////////////////
|
|
@@ -61,6 +63,10 @@ class Context {
|
|
|
61
63
|
this.res = res;
|
|
62
64
|
// can be used for sending different answers
|
|
63
65
|
this.jsonrequest = !!(((_a = req.headers['content-type']) === null || _a === void 0 ? void 0 : _a.toLowerCase().indexOf('application/json')) > -1);
|
|
66
|
+
// helpers for ejs
|
|
67
|
+
this.today = new Date();
|
|
68
|
+
this.year = this.today.getFullYear();
|
|
69
|
+
this.version = exports.kVersion;
|
|
64
70
|
this.nums = [0, 0, 0];
|
|
65
71
|
// check short urls with numbers a parts
|
|
66
72
|
const p1 = parseInt(this.request);
|
package/server/webapp.ts
CHANGED
|
@@ -54,6 +54,8 @@ export function single(val: string | Array<string>): string {
|
|
|
54
54
|
return (val instanceof Array) ? val[0] : val;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
export const kVersion = require("../package.json").version;
|
|
58
|
+
console.log("stolen version: " + kVersion);
|
|
57
59
|
|
|
58
60
|
///////////////////
|
|
59
61
|
// Context Class //
|
|
@@ -70,6 +72,9 @@ export class Context {
|
|
|
70
72
|
res: http.ServerResponse; // from http request
|
|
71
73
|
jsonrequest: boolean; // from http request
|
|
72
74
|
message = ""; // display if not empty
|
|
75
|
+
today: Date;
|
|
76
|
+
year: number;
|
|
77
|
+
version: string;
|
|
73
78
|
|
|
74
79
|
time = types.time;
|
|
75
80
|
hex = types.hex;
|
|
@@ -102,6 +107,11 @@ export class Context {
|
|
|
102
107
|
// can be used for sending different answers
|
|
103
108
|
this.jsonrequest = !!(req.headers['content-type']?.toLowerCase().indexOf('application/json')> -1);
|
|
104
109
|
|
|
110
|
+
// helpers for ejs
|
|
111
|
+
this.today = new Date();
|
|
112
|
+
this.year = this.today.getFullYear();
|
|
113
|
+
this.version = kVersion;
|
|
114
|
+
|
|
105
115
|
this.nums = [0,0,0];
|
|
106
116
|
// check short urls with numbers a parts
|
|
107
117
|
const p1 = parseInt(this.request);
|