|
1 const hap = require("hap-nodejs"); |
|
2 const pysh = require("python-shell"); |
|
3 |
|
4 const Accessory = hap.Accessory; |
|
5 const Characteristic = hap.Characteristic; |
|
6 const CharacteristicEventTypes = hap.CharacteristicEventTypes; |
|
7 const AccessoryEventTypes = hap.AccessoryEventTypes; |
|
8 const Service = hap.Service; |
|
9 const uuid = hap.uuid; |
|
10 |
|
11 const accessoryUuid = hap.uuid.generate("hap.accessories.doorbell-lock"); |
|
12 const accessory = new Accessory("Doorbell and Lock", accessoryUuid); |
|
13 |
|
14 const doorbellService = new Service.Doorbell("Doorbell"); |
|
15 const lockService = new Service.LockMechanism("Lock"); |
|
16 |
|
17 const lockTargetStateCharacteristic = lockService.getCharacteristic(Characteristic.LockTargetState); |
|
18 const lockCurrentStateCharacteristic = lockService.getCharacteristic(Characteristic.LockCurrentState); |
|
19 |
|
20 const doorbellSwitchCharacteristic = doorbellService.getCharacteristic(Characteristic.ProgrammableSwitchEvent); |
|
21 |
|
22 function Door() { |
|
23 this.lockTimeout = 10000; // milliseconds - 10 sec |
|
24 |
|
25 this.pyshell = new pysh.PythonShell("doord.py", { |
|
26 mode: "text", |
|
27 pythonPath: "/usr/bin/python3", |
|
28 pythonOptions: ["-u"], |
|
29 scriptPath: "python/" |
|
30 }); |
|
31 |
|
32 this.lock = () => { |
|
33 console.log("locking door"); |
|
34 this.pyshell.send("lock"); |
|
35 }; |
|
36 |
|
37 this.unlock = () => { |
|
38 console.log("unlocking door"); |
|
39 this.pyshell.send("unlock"); |
|
40 }; |
|
41 |
|
42 this.identify = () => { console.log("identify door"); }; |
|
43 |
|
44 this.listenDoorbell = (doorbellOnCallback, doorbellOffCallback) => { |
|
45 this.pyshell.on("message", (message) => { |
|
46 console.log(message); |
|
47 switch(message) { |
|
48 case "doorbell on": |
|
49 doorbellOnCallback(); |
|
50 break; |
|
51 case "doorbell off": |
|
52 doorbellOffCallback(); |
|
53 break; |
|
54 } |
|
55 }); |
|
56 }; |
|
57 } |
|
58 |
|
59 const door = new Door(); |
|
60 |
|
61 function setDoorTargetState(value) { |
|
62 switch(value) { |
|
63 case Characteristic.LockTargetState.UNSECURED: |
|
64 unlockDoor(); |
|
65 break; |
|
66 case Characteristic.LockTargetState.SECURED: |
|
67 lockDoor(); |
|
68 break; |
|
69 } |
|
70 } |
|
71 |
|
72 function unlockDoor() { |
|
73 door.unlock(); |
|
74 lockCurrentStateCharacteristic.setValue(Characteristic.LockCurrentState.UNSECURED); |
|
75 scheduleUnlockTimeout(); |
|
76 } |
|
77 |
|
78 function lockDoor() { |
|
79 door.lock(); |
|
80 lockCurrentStateCharacteristic.setValue(Characteristic.LockCurrentState.SECURED); |
|
81 } |
|
82 |
|
83 function scheduleUnlockTimeout() { |
|
84 setTimeout(() => { |
|
85 console.log("unlock timeout door"); |
|
86 lockTargetStateCharacteristic.setValue(Characteristic.LockTargetState.SECURED); |
|
87 }, door.lockTimeout); |
|
88 } |
|
89 |
|
90 door.listenDoorbell( |
|
91 () => { |
|
92 doorbellSwitchCharacteristic.setValue(Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS); |
|
93 }, |
|
94 () => {} |
|
95 ); |
|
96 |
|
97 // set initial state |
|
98 lockTargetStateCharacteristic.setValue(Characteristic.LockTargetState.SECURED); |
|
99 lockCurrentStateCharacteristic.setValue(Characteristic.LockCurrentState.SECURED); |
|
100 lockTargetStateCharacteristic.on(CharacteristicEventTypes.SET, (value, callback) => { |
|
101 setDoorTargetState(value); |
|
102 callback(); |
|
103 }); |
|
104 |
|
105 accessory.on(AccessoryEventTypes.IDENTIFY, (paired, callback) => { |
|
106 door.identify(); |
|
107 callback(); |
|
108 }); |
|
109 |
|
110 accessory.addService(doorbellService); |
|
111 accessory.addService(lockService); |
|
112 |
|
113 accessory.getService(Service.AccessoryInformation) |
|
114 .setCharacteristic(Characteristic.Manufacturer, "Raspberry Pi") |
|
115 .setCharacteristic(Characteristic.Model, "Zero W") |
|
116 .setCharacteristic(Characteristic.SerialNumber, "A1S2NASF88EW"); |
|
117 |
|
118 accessory.publish({ |
|
119 username: "C1:5D:3A:EA:54:AB", |
|
120 pincode: "031-45-154", |
|
121 category: hap.Categories.DOOR_LOCK |
|
122 }); |
|
123 |
|
124 console.log("Accessory initialized"); |