npmjs-package/src/door.js
changeset 26 87ddaf81e63c
parent 22 00185499ed12
child 29 04bc5820407b
--- /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");