diff -r bc6c646f1814 -r 87ddaf81e63c npmjs-package/src/door.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/npmjs-package/src/door.js Tue Jun 02 19:11:08 2020 -0500 @@ -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");