From 4a7f13ec6c0fd59bed009f31b62674f279a58213 Mon Sep 17 00:00:00 2001 From: Luke Hoersten Date: Tue, 2 Jun 2020 19:11:08 -0500 Subject: Updated homekit door for Raspbian Buster. --- npmjs-package/src/door.js | 124 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 npmjs-package/src/door.js (limited to 'npmjs-package/src/door.js') diff --git a/npmjs-package/src/door.js b/npmjs-package/src/door.js new file mode 100644 index 0000000..b521805 --- /dev/null +++ b/npmjs-package/src/door.js @@ -0,0 +1,124 @@ +const hap = require("hap-nodejs"); +const pysh = require("python-shell"); + +const Accessory = hap.Accessory; +const Characteristic = hap.Characteristic; +const CharacteristicEventTypes = hap.CharacteristicEventTypes; +const AccessoryEventTypes = hap.AccessoryEventTypes; +const Service = hap.Service; +const uuid = hap.uuid; + +const accessoryUuid = hap.uuid.generate("hap.accessories.doorbell-lock"); +const accessory = new Accessory("Doorbell and Lock", accessoryUuid); + +const doorbellService = new Service.Doorbell("Doorbell"); +const lockService = new Service.LockMechanism("Lock"); + +const lockTargetStateCharacteristic = lockService.getCharacteristic(Characteristic.LockTargetState); +const lockCurrentStateCharacteristic = lockService.getCharacteristic(Characteristic.LockCurrentState); + +const doorbellSwitchCharacteristic = doorbellService.getCharacteristic(Characteristic.ProgrammableSwitchEvent); + +function Door() { + this.lockTimeout = 10000; // milliseconds - 10 sec + + this.pyshell = new pysh.PythonShell("doord.py", { + mode: "text", + pythonPath: "/usr/bin/python3", + pythonOptions: ["-u"], + scriptPath: "python/" + }); + + this.lock = () => { + console.log("locking door"); + this.pyshell.send("lock"); + }; + + this.unlock = () => { + console.log("unlocking door"); + this.pyshell.send("unlock"); + }; + + this.identify = () => { console.log("identify door"); }; + + this.listenDoorbell = (doorbellOnCallback, doorbellOffCallback) => { + this.pyshell.on("message", (message) => { + console.log(message); + switch(message) { + case "doorbell on": + doorbellOnCallback(); + break; + case "doorbell off": + doorbellOffCallback(); + break; + } + }); + }; +} + +const door = new Door(); + +function setDoorTargetState(value) { + switch(value) { + case Characteristic.LockTargetState.UNSECURED: + unlockDoor(); + break; + case Characteristic.LockTargetState.SECURED: + lockDoor(); + break; + } +} + +function unlockDoor() { + door.unlock(); + lockCurrentStateCharacteristic.setValue(Characteristic.LockCurrentState.UNSECURED); + scheduleUnlockTimeout(); +} + +function lockDoor() { + door.lock(); + lockCurrentStateCharacteristic.setValue(Characteristic.LockCurrentState.SECURED); +} + +function scheduleUnlockTimeout() { + setTimeout(() => { + console.log("unlock timeout door"); + lockTargetStateCharacteristic.setValue(Characteristic.LockTargetState.SECURED); + }, door.lockTimeout); +} + +door.listenDoorbell( + () => { + doorbellSwitchCharacteristic.setValue(Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS); + }, + () => {} +); + +// set initial state +lockTargetStateCharacteristic.setValue(Characteristic.LockTargetState.SECURED); +lockCurrentStateCharacteristic.setValue(Characteristic.LockCurrentState.SECURED); +lockTargetStateCharacteristic.on(CharacteristicEventTypes.SET, (value, callback) => { + setDoorTargetState(value); + callback(); +}); + +accessory.on(AccessoryEventTypes.IDENTIFY, (paired, callback) => { + door.identify(); + callback(); +}); + +accessory.addService(doorbellService); +accessory.addService(lockService); + +accessory.getService(Service.AccessoryInformation) + .setCharacteristic(Characteristic.Manufacturer, "Raspberry Pi") + .setCharacteristic(Characteristic.Model, "Zero W") + .setCharacteristic(Characteristic.SerialNumber, "A1S2NASF88EW"); + +accessory.publish({ + username: "C1:5D:3A:EA:54:AB", + pincode: "031-45-154", + category: hap.Categories.DOOR_LOCK +}); + +console.log("Accessory initialized"); -- cgit v1.2.3