Updated homekit door for Raspbian Buster.
authorLuke Hoersten <luke@hoersten.org>
Tue, 02 Jun 2020 19:11:08 -0500
changeset 26 87ddaf81e63c
parent 25 bc6c646f1814
child 27 df47a99d5bfc
Updated homekit door for Raspbian Buster.
README.md
ansible.cfg
inventory/raspberrypi
npmjs-package/package-lock.json
npmjs-package/package.json
npmjs-package/python/doord.py
npmjs-package/src/door.js
roles/hap-door/handlers/main.yaml
roles/hap-door/meta/main.yaml
roles/hap-door/tasks/main.yaml
roles/hap-nodejs/defaults/main.yaml
roles/hap-nodejs/handlers/main.yaml
roles/hap-nodejs/tasks/main.yaml
roles/hap-nodejs/templates/hap-nodejs.service.j2
roles/homekit-door/defaults/main.yaml
roles/homekit-door/handlers/main.yaml
roles/homekit-door/meta/main.yaml
roles/homekit-door/tasks/main.yaml
roles/homekit-door/templates/homekit-door.service.j2
rpi-door.yaml
src/Door_accessory.js
src/doord.py
--- a/README.md	Sat Jan 11 18:09:32 2020 -0600
+++ b/README.md	Tue Jun 02 19:11:08 2020 -0500
@@ -1,27 +1,13 @@
-# Raspberry Pi Homekit Door Accessory
+# Raspberry Pi Homekit Door Lock Buzzer Accessory
 
-Using
-a
-[Raspberry Pi Zero W](https://www.raspberrypi.org/products/raspberry-pi-zero-w/) and
-[Pimoroni Automation pHAT](https://shop.pimoroni.com/products/automation-phat),
-make a simple circuit-based door lock and door bell intercom into a
-Siri-controlled HomeKit smart accessory. Siri integration is provided
-by [HAP-NodeJS](https://github.com/KhaosT/HAP-NodeJS).
+Using a [Raspberry Pi Zero W](https://www.raspberrypi.org/products/raspberry-pi-zero-w/)
+and [Pimoroni Automation pHAT](https://shop.pimoroni.com/products/automation-phat), make a simple circuit-based door
+lock and doorbell intercom into a Siri-controlled HomeKit smart accessory. Siri integration is provided
+by [HAP-NodeJS](https://github.com/homebridge/HAP-NodeJS). This package itself does not depend on Homebridge.
 
 ## Installation
 
-Installation is rather involved and handled by
-an [Ansible](https://ansible.com/) playbook.
-
-## Ansible Inventory
-
-`inventory/host_vars/raspberrypi.local.yaml`
+Installation can be handled by:
 
-    github_user: "<github user>"
-    wpa_networks:
-      - ssid: "<your ssid>"
-        psk: "<your wifi password>"
-
-## Run Ansible
-
-`ansible-playbook rpi-door.yaml`
+1. The [Ansible](https://ansible.com/) `homekit-door` role provided in the `roles` directory or
+2. By copying the `npmjs-package` to the Raspberry Pi and running `npm install`.
--- a/ansible.cfg	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-[defaults]
-inventory = inventory/
-
-[ssh_connection]
-pipelining = True
--- a/inventory/raspberrypi	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-[raspberrypi]
-raspberrypi.local ansible_user=pi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/npmjs-package/package-lock.json	Tue Jun 02 19:11:08 2020 -0500
@@ -0,0 +1,459 @@
+{
+    "name": "hap-door",
+    "version": "1.0.0",
+    "lockfileVersion": 1,
+    "requires": true,
+    "dependencies": {
+        "array-filter": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
+            "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM="
+        },
+        "array-flatten": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+            "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ=="
+        },
+        "available-typed-arrays": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz",
+            "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==",
+            "requires": {
+                "array-filter": "1.0.0"
+            }
+        },
+        "bonjour-hap": {
+            "version": "3.5.10",
+            "resolved": "https://registry.npmjs.org/bonjour-hap/-/bonjour-hap-3.5.10.tgz",
+            "integrity": "sha512-vaqa4uUST8K5rj9QGe6GaSJ+6rQ24KzgkjdyZvoTpbKBti5xL/m8H9Dp9VmPdo434OAetqU5PKAn5izucrKEBA==",
+            "requires": {
+                "array-flatten": "2.1.2",
+                "deep-equal": "2.0.3",
+                "ip": "1.1.5",
+                "multicast-dns": "7.2.2",
+                "multicast-dns-service-types": "1.1.0"
+            }
+        },
+        "debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "requires": {
+                "ms": "2.1.2"
+            }
+        },
+        "decimal.js": {
+            "version": "10.2.0",
+            "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz",
+            "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw=="
+        },
+        "deep-equal": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.3.tgz",
+            "integrity": "sha512-Spqdl4H+ky45I9ByyJtXteOm9CaIrPmnIPmOhrkKGNYWeDgCvJ8jNYVCTjChxW4FqGuZnLHADc8EKRMX6+CgvA==",
+            "requires": {
+                "es-abstract": "1.17.5",
+                "es-get-iterator": "1.1.0",
+                "is-arguments": "1.0.4",
+                "is-date-object": "1.0.2",
+                "is-regex": "1.0.5",
+                "isarray": "2.0.5",
+                "object-is": "1.1.2",
+                "object-keys": "1.1.1",
+                "object.assign": "4.1.0",
+                "regexp.prototype.flags": "1.3.0",
+                "side-channel": "1.0.2",
+                "which-boxed-primitive": "1.0.1",
+                "which-collection": "1.0.1",
+                "which-typed-array": "1.1.2"
+            }
+        },
+        "define-properties": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+            "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+            "requires": {
+                "object-keys": "1.1.1"
+            }
+        },
+        "dns-packet": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-4.2.0.tgz",
+            "integrity": "sha512-bn1AKpfkFbm0MIioOMHZ5qJzl2uypdBwI4nYNsqvhjsegBhcKJUlCrMPWLx6JEezRjxZmxhtIz/FkBEur2l8Cw==",
+            "requires": {
+                "ip": "1.1.5",
+                "safe-buffer": "5.2.1"
+            }
+        },
+        "es-abstract": {
+            "version": "1.17.5",
+            "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
+            "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
+            "requires": {
+                "es-to-primitive": "1.2.1",
+                "function-bind": "1.1.1",
+                "has": "1.0.3",
+                "has-symbols": "1.0.1",
+                "is-callable": "1.2.0",
+                "is-regex": "1.0.5",
+                "object-inspect": "1.7.0",
+                "object-keys": "1.1.1",
+                "object.assign": "4.1.0",
+                "string.prototype.trimleft": "2.1.2",
+                "string.prototype.trimright": "2.1.2"
+            }
+        },
+        "es-get-iterator": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz",
+            "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==",
+            "requires": {
+                "es-abstract": "1.17.5",
+                "has-symbols": "1.0.1",
+                "is-arguments": "1.0.4",
+                "is-map": "2.0.1",
+                "is-set": "2.0.1",
+                "is-string": "1.0.5",
+                "isarray": "2.0.5"
+            }
+        },
+        "es-to-primitive": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+            "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+            "requires": {
+                "is-callable": "1.2.0",
+                "is-date-object": "1.0.2",
+                "is-symbol": "1.0.3"
+            }
+        },
+        "fast-srp-hap": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/fast-srp-hap/-/fast-srp-hap-2.0.1.tgz",
+            "integrity": "sha512-dClwnyfRd3BZxu3KAdhvAayozq7fLazXGlDc4HAHJV1M+olqGKAT52pygXQu5UiDSHxz/WB3KRvsojqQ5zmXOA=="
+        },
+        "foreach": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+            "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
+        },
+        "function-bind": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+            "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+        },
+        "futoin-hkdf": {
+            "version": "1.3.2",
+            "resolved": "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.3.2.tgz",
+            "integrity": "sha512-3EVi3ETTyJg5PSXlxLCaUVVn0pSbDf62L3Gwxne7Uq+d8adOSNWQAad4gg7WToHkcgnCJb3Wlb1P8r4Evj4GPw=="
+        },
+        "hap-nodejs": {
+            "version": "0.7.3",
+            "resolved": "https://registry.npmjs.org/hap-nodejs/-/hap-nodejs-0.7.3.tgz",
+            "integrity": "sha512-kCPwdRizCPJk43eTSMtW2LtCh+it8rTYW7aGkhW8qFKPS4z5JQilpggvVJvdfmSy5l+L5F0/UyKwkeM/KsdrHA==",
+            "requires": {
+                "bonjour-hap": "3.5.10",
+                "debug": "4.1.1",
+                "decimal.js": "10.2.0",
+                "fast-srp-hap": "2.0.1",
+                "futoin-hkdf": "1.3.2",
+                "ip": "1.1.5",
+                "node-persist": "0.0.11",
+                "tweetnacl": "1.0.3"
+            }
+        },
+        "has": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+            "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+            "requires": {
+                "function-bind": "1.1.1"
+            }
+        },
+        "has-symbols": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+            "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
+        },
+        "ip": {
+            "version": "1.1.5",
+            "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+            "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
+        },
+        "is-arguments": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+            "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA=="
+        },
+        "is-bigint": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.0.tgz",
+            "integrity": "sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g=="
+        },
+        "is-boolean-object": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.0.1.tgz",
+            "integrity": "sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ=="
+        },
+        "is-callable": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
+            "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw=="
+        },
+        "is-date-object": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+            "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
+        },
+        "is-map": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz",
+            "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw=="
+        },
+        "is-number-object": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz",
+            "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw=="
+        },
+        "is-regex": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+            "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+            "requires": {
+                "has": "1.0.3"
+            }
+        },
+        "is-set": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz",
+            "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA=="
+        },
+        "is-string": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
+            "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ=="
+        },
+        "is-symbol": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+            "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+            "requires": {
+                "has-symbols": "1.0.1"
+            }
+        },
+        "is-typed-array": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.3.tgz",
+            "integrity": "sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ==",
+            "requires": {
+                "available-typed-arrays": "1.0.2",
+                "es-abstract": "1.17.5",
+                "foreach": "2.0.5",
+                "has-symbols": "1.0.1"
+            }
+        },
+        "is-weakmap": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
+            "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA=="
+        },
+        "is-weakset": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.1.tgz",
+            "integrity": "sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw=="
+        },
+        "isarray": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+            "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
+        },
+        "minimist": {
+            "version": "1.2.5",
+            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+            "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+        },
+        "mkdirp": {
+            "version": "0.5.5",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+            "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+            "requires": {
+                "minimist": "1.2.5"
+            }
+        },
+        "ms": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+        },
+        "multicast-dns": {
+            "version": "7.2.2",
+            "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.2.tgz",
+            "integrity": "sha512-XqSMeO8EWV/nOXOpPV8ztIpNweVfE1dSpz6SQvDPp71HD74lMXjt4m/mWB1YBMG0kHtOodxRWc5WOb/UNN1A5g==",
+            "requires": {
+                "dns-packet": "4.2.0",
+                "thunky": "1.1.0"
+            }
+        },
+        "multicast-dns-service-types": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+            "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
+        },
+        "node-persist": {
+            "version": "0.0.11",
+            "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-0.0.11.tgz",
+            "integrity": "sha1-1m66Pr72IPB5Uw+nsTB2qQZmWHQ=",
+            "requires": {
+                "mkdirp": "0.5.5",
+                "q": "1.1.2"
+            }
+        },
+        "object-inspect": {
+            "version": "1.7.0",
+            "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+            "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw=="
+        },
+        "object-is": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
+            "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
+            "requires": {
+                "define-properties": "1.1.3",
+                "es-abstract": "1.17.5"
+            }
+        },
+        "object-keys": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+            "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+        },
+        "object.assign": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+            "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+            "requires": {
+                "define-properties": "1.1.3",
+                "function-bind": "1.1.1",
+                "has-symbols": "1.0.1",
+                "object-keys": "1.1.1"
+            }
+        },
+        "python-shell": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/python-shell/-/python-shell-2.0.1.tgz",
+            "integrity": "sha512-Ys+SiCinY9JrldIJxGWd2AMQSQZLU7PFzrCWY7HTawZ73tIthFdlLLU1Y6Y40Hwdutc+TmfMe5TXNU73s07Xyg=="
+        },
+        "q": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/q/-/q-1.1.2.tgz",
+            "integrity": "sha1-Y1fikSBnAdmfGXq4TlforRlvKok="
+        },
+        "regexp.prototype.flags": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+            "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+            "requires": {
+                "define-properties": "1.1.3",
+                "es-abstract": "1.17.5"
+            }
+        },
+        "safe-buffer": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+            "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+        },
+        "side-channel": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz",
+            "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==",
+            "requires": {
+                "es-abstract": "1.17.5",
+                "object-inspect": "1.7.0"
+            }
+        },
+        "string.prototype.trimend": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
+            "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
+            "requires": {
+                "define-properties": "1.1.3",
+                "es-abstract": "1.17.5"
+            }
+        },
+        "string.prototype.trimleft": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
+            "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
+            "requires": {
+                "define-properties": "1.1.3",
+                "es-abstract": "1.17.5",
+                "string.prototype.trimstart": "1.0.1"
+            }
+        },
+        "string.prototype.trimright": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
+            "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
+            "requires": {
+                "define-properties": "1.1.3",
+                "es-abstract": "1.17.5",
+                "string.prototype.trimend": "1.0.1"
+            }
+        },
+        "string.prototype.trimstart": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
+            "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
+            "requires": {
+                "define-properties": "1.1.3",
+                "es-abstract": "1.17.5"
+            }
+        },
+        "thunky": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+            "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
+        },
+        "tweetnacl": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+            "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
+        },
+        "which-boxed-primitive": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz",
+            "integrity": "sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==",
+            "requires": {
+                "is-bigint": "1.0.0",
+                "is-boolean-object": "1.0.1",
+                "is-number-object": "1.0.4",
+                "is-string": "1.0.5",
+                "is-symbol": "1.0.3"
+            }
+        },
+        "which-collection": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
+            "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
+            "requires": {
+                "is-map": "2.0.1",
+                "is-set": "2.0.1",
+                "is-weakmap": "2.0.1",
+                "is-weakset": "2.0.1"
+            }
+        },
+        "which-typed-array": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.2.tgz",
+            "integrity": "sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ==",
+            "requires": {
+                "available-typed-arrays": "1.0.2",
+                "es-abstract": "1.17.5",
+                "foreach": "2.0.5",
+                "function-bind": "1.1.1",
+                "has-symbols": "1.0.1",
+                "is-typed-array": "1.1.3"
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/npmjs-package/package.json	Tue Jun 02 19:11:08 2020 -0500
@@ -0,0 +1,16 @@
+{
+    "name": "hap-door",
+    "version": "1.0.0",
+    "description": "A circuit-based door lock and door bell intercom for HomeKit.",
+    "main": "src/door.js",
+    "author": "Luke Hoersten <[email protected]>",
+    "license": "BSD-3",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/lukehoersten/homekit-door.git"
+    },
+    "dependencies": {
+        "hap-nodejs": "latest",
+        "python-shell": "latest"
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/npmjs-package/python/doord.py	Tue Jun 02 19:11:08 2020 -0500
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+
+import time
+import automationhat
+import sys
+
+import queue
+import threading
+
+
+def main():
+    command_queue = queue.LifoQueue()
+    read_thread = threading.Thread(target=read_loop, args=[command_queue])
+    read_thread.start()
+    run_loop(command_queue)
+
+
+def read_loop(command_queue):
+    while True:
+        command_queue.put_nowait(sys.stdin.readline().rstrip('\n'))
+
+
+def run_loop(command_queue):
+    thread_local = threading.local()
+    thread_local.doorbell_on_state = False
+
+    while True:
+        run_command(command_queue)
+        read_doorbell(thread_local)
+
+
+def run_command(command_queue):
+    try:
+        command = command_queue.get(timeout=0.5)
+    except queue.Empty:
+        pass
+    else:
+        automationhat.relay.on() if command == "unlock" else automationhat.relay.off()
+
+
+def read_doorbell(thread_local):
+    analog_value = automationhat.analog.one.read()
+    doorbell_on_state = 6.0 < analog_value and analog_value <= 6.22
+
+    if analog_value < 7.4:
+        print("doorbell analog value: {}; ringing: {}; ring range: (6.0, 6.22]".format(analog_value, doorbell_on_state))
+
+    if doorbell_on_state != thread_local.doorbell_on_state:
+        thread_local.doorbell_on_state = doorbell_on_state
+        print("doorbell on") if doorbell_on_state else print("doorbell off")
+
+
+if __name__ == "__main__":
+    main()
--- /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");
--- a/roles/hap-door/handlers/main.yaml	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
----
-
-- name: restart hap-nodejs service
-  systemd: name="hap-nodejs" state="restarted" daemon_reload="yes"
-  become: yes
--- a/roles/hap-door/meta/main.yaml	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
----
-
-dependencies:
-  - hap-nodejs
-  - automationhat
--- a/roles/hap-door/tasks/main.yaml	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
----
-
-- name: install python3 apt packages
-  become: yes
-  apt: name="python3"
-  notify: restart hap-nodejs service
-
-- name: install python-shell npm packages
-  become: yes
-  npm: name="python-shell" global="yes"
-  notify: restart hap-nodejs service
-
-- name: install door accessory
-  become: yes
-  copy:
-    src: "../../../src/Door_accessory.js"
-    dest: "{{hap_dest}}/accessories/Door_accessory.js"
-    owner: "{{hap_user}}"
-    group: "{{hap_user}}"
-  notify: restart hap-nodejs service
-
-- name: create python dir
-  become: yes
-  file:
-    path: "{{hap_dest}}/python"
-    state: "directory"
-    owner: "{{hap_user}}"
-    group: "{{hap_user}}"
-
-- name: install doord.py
-  become: yes
-  copy:
-    src: "../../../src/doord.py"
-    dest: "{{hap_dest}}/python/doord.py"
-    owner: "{{hap_user}}"
-    group: "{{hap_user}}"
-    mode: "0755"
-  notify: restart hap-nodejs service
--- a/roles/hap-nodejs/defaults/main.yaml	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
----
-
-hap_apt_packages:
-    - "libavahi-compat-libdnssd-dev"
-    - "nodejs"
-    - "npm"
-
-hap_user: "hap-nodejs"
-hap_restart_sec: 10
-hap_dir: "/home/{{hap_user}}"
-hap_src: "https://github.com/KhaosT/HAP-NodeJS/archive/master.zip"
-hap_dest: "{{hap_dir}}/HAP-NodeJS-master"
-
-hap_example_accessories:
-  - "AirConditioner_accessory.js"
-  - "Fan_accessory.js"
-  - "GarageDoorOpener_accessory.js"
-  - "Light_accessory.js"
-  - "Lock_accessory.js"
-  - "MotionSensor_accessory.js"
-  - "Outlet_accessory.js"
-  - "TemperatureSensor_accessory.js"
--- a/roles/hap-nodejs/handlers/main.yaml	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
----
-
-- name: restart hap-nodejs service
-  systemd: name="hap-nodejs" state="restarted" daemon_reload="yes"
-  become: yes
--- a/roles/hap-nodejs/tasks/main.yaml	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
----
-
-- name: create hap-nodejs user
-  become: yes
-  user:
-    name: "{{hap_user}}"
-    comment: "HAP-NodeJS"
-    groups: "spi,i2c,gpio"
-    shell: "/bin/false"
-    home: "{{hap_dir}}"
-    move_home: yes
-  notify: restart hap-nodejs service
-
-- name: install homekit apt packages
-  become: yes
-  apt: name="{{hap_apt_packages}}"
-  notify: restart hap-nodejs service
-
-- name: download and unarchive HAP-NodeJS
-  become: yes
-  become_user: "{{hap_user}}"
-  unarchive:
-    src: "{{hap_src}}"
-    dest: "{{hap_dir}}"
-    remote_src: "yes"
-    creates: "{{hap_dest}}"
-    owner: "{{hap_user}}"
-    group: "{{hap_user}}"
-  notify: restart hap-nodejs service
-
-- name: remove example accessories
-  become: yes
-  file: path="{{hap_dest}}/accessories/{{item}}" state="absent"
-  with_items: "{{hap_example_accessories}}"
-
-- name: build HAP-NodeJS
-  become: yes
-  become_user: "{{hap_user}}"
-  npm: path="{{hap_dest}}"
-
-- name: configure systemd service
-  become: yes
-  template: src="hap-nodejs.service.j2" dest="/lib/systemd/system/hap-nodejs.service"
-  notify: restart hap-nodejs service
-
-- name: ensure hap-nodejs is started
-  become: yes
-  systemd: name="hap-nodejs.service" enabled="yes" state="started"
--- a/roles/hap-nodejs/templates/hap-nodejs.service.j2	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-# {{ansible_managed}}
-
-[Unit]
-Description=HAP-NodeJS
-
-[Service]
-User={{hap_user}}
-Group={{hap_user}}
-Restart=always
-RestartSec={{hap_restart_sec}}
-
-WorkingDirectory={{hap_dest}}
-ExecStart=/usr/bin/node {{hap_dest}}/Core.js
-
-[Install]
-WantedBy=default.target
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/homekit-door/defaults/main.yaml	Tue Jun 02 19:11:08 2020 -0500
@@ -0,0 +1,10 @@
+---
+
+homekit_door_apt_packages:
+  - "python3"
+  - "nodejs"
+  - "npm"
+
+homekit_door_user: "homekit-door"
+homekit_door_dir: "/home/{{homekit_door_user}}/homekit-door"
+homekit_door_restart_sec: 10
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/homekit-door/handlers/main.yaml	Tue Jun 02 19:11:08 2020 -0500
@@ -0,0 +1,5 @@
+---
+
+- name: restart homekit-door service
+  systemd: name="homekit-door.service" state="restarted" daemon_reload="yes"
+  become: yes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/homekit-door/meta/main.yaml	Tue Jun 02 19:11:08 2020 -0500
@@ -0,0 +1,4 @@
+---
+
+dependencies:
+  - automationhat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/homekit-door/tasks/main.yaml	Tue Jun 02 19:11:08 2020 -0500
@@ -0,0 +1,41 @@
+---
+
+- name: create homekit-door user
+  become: yes
+  user:
+    name: "{{homekit_door_user}}"
+    comment: "HomeKit Door"
+    groups: "spi,i2c,gpio"
+    shell: "/bin/false"
+    move_home: yes
+  notify: restart homekit-door service
+
+- name: install homekit-door apt packages
+  become: yes
+  apt: name="{{homekit_door_apt_packages}}"
+  notify: restart homekit-door service
+
+- name: install homekit-door application dir
+  become: yes
+  copy:
+    src: "../../../npmjs-package/"
+    dest: "{{homekit_door_dir}}/"
+    owner: "{{homekit_door_user}}"
+    group: "{{homekit_door_user}}"
+    mode: "0755"
+  notify: restart homekit-door service
+
+- name: build homekit-door
+  become: yes
+  become_user: "{{homekit_door_user}}"
+  npm: path="{{homekit_door_dir}}"
+  notify: restart homekit-door service
+
+- name: configure systemd service
+  become: yes
+  template: src="homekit-door.service.j2" dest="/lib/systemd/system/homekit-door.service"
+  notify: restart homekit-door service
+
+- name: ensure homekit-door is started
+  become: yes
+  systemd: name="homekit-door.service" enabled="yes" state="started"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/roles/homekit-door/templates/homekit-door.service.j2	Tue Jun 02 19:11:08 2020 -0500
@@ -0,0 +1,16 @@
+# {{ansible_managed}}
+
+[Unit]
+Description=HomeKit Door
+
+[Service]
+User={{homekit_door_user}}
+Group={{homekit_door_user}}
+Restart=always
+RestartSec={{homekit_door_restart_sec}}
+
+WorkingDirectory={{homekit_door_dir}}
+ExecStart=/usr/bin/node {{homekit_door_dir}}/src/door.js
+
+[Install]
+WantedBy=default.target
--- a/rpi-door.yaml	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
----
-
-- hosts: raspberrypi
-  roles:
-    - rpi-base
-    - hap-door
--- a/src/Door_accessory.js	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-var Accessory = require('../').Accessory;
-var Service = require('../').Service;
-var Characteristic = require('../').Characteristic;
-var uuid = require('../').uuid;
-var PythonShell = require('python-shell');
-
-var door = exports.accessory = new Accessory('Door', uuid.generate('hap-nodejs:accessories:door'));
-door.username = 'C1:5D:3A:EA:54:AB';
-door.pincode = '031-45-154';
-
-door.getService(Service.AccessoryInformation)
-    .setCharacteristic(Characteristic.Manufacturer, 'Raspberry Pi')
-    .setCharacteristic(Characteristic.Model, 'Zero W')
-    .setCharacteristic(Characteristic.SerialNumber, 'A1S2NASF88EW');
-
-var DOOR = {
-    lockTimeout: 10000, // milliseconds - 10 sec
-
-    pyshell: new PythonShell('doord.py', {
-        mode: 'text',
-        pythonPath: '/usr/bin/python3',
-        pythonOptions: ['-u'],
-        scriptPath: 'python/'
-    }),
-
-    lock: function() {
-        console.log('locking door');
-        this.pyshell.send('lock');
-    },
-
-    unlock: function() {
-        console.log('unlocking door');
-        this.pyshell.send('unlock');
-    },
-
-    identify: function() {
-        console.log('identify door');
-    },
-
-    listenDoorbell: function(doorbellOnCallback, doorbellOffCallback) {
-        this.pyshell.on('message', function (message) {
-            console.log(message);
-            switch(message) {
-            case 'doorbell on':
-                doorbellOnCallback();
-                break;
-            case 'doorbell off':
-                doorbellOffCallback();
-                break;
-            }
-        });
-    }
-};
-
-door.on('identify', function(paired, callback) {
-    DOOR.identify();
-    callback();
-});
-
-door.addService(Service.Doorbell, 'Doorbell');
-
-door.addService(Service.LockMechanism, 'Door lock')
-    .setCharacteristic(Characteristic.LockTargetState, Characteristic.LockTargetState.SECURED) // force initial state
-    .setCharacteristic(Characteristic.LockCurrentState, Characteristic.LockCurrentState.SECURED)
-    .getCharacteristic(Characteristic.LockTargetState)
-    .on('set', function(value, callback) {
-        setDoorTargetState(value);
-        callback();
-    });
-
-function setDoorTargetState(value) {
-    switch(value) {
-    case Characteristic.LockTargetState.UNSECURED:
-        unlockDoor();
-        break;
-    case Characteristic.LockTargetState.SECURED:
-        lockDoor();
-        break;
-    }
-}
-
-function unlockDoor() {
-    DOOR.unlock();
-    door.getService(Service.LockMechanism)
-        .setCharacteristic(Characteristic.LockCurrentState,
-                           Characteristic.LockCurrentState.UNSECURED);
-    scheduleUnlockTimeout();
-}
-
-function lockDoor() {
-    DOOR.lock();
-    door.getService(Service.LockMechanism)
-        .setCharacteristic(Characteristic.LockCurrentState,
-                           Characteristic.LockCurrentState.SECURED);
-}
-
-function scheduleUnlockTimeout() {
-    setTimeout(function() {
-        console.log('unlock timeout door');
-        door.getService(Service.LockMechanism)
-            .setCharacteristic(Characteristic.LockTargetState,
-                               Characteristic.LockTargetState.SECURED);
-    }, DOOR.lockTimeout);
-}
-
-DOOR.listenDoorbell(
-    function() {
-        door.getService(Service.Doorbell)
-            .setCharacteristic(Characteristic.ProgrammableSwitchEvent,
-                               Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
-    },
-    function() {});
--- a/src/doord.py	Sat Jan 11 18:09:32 2020 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#!/usr/bin/env python3
-
-import time
-import automationhat
-import sys
-
-import queue
-import threading
-
-
-def main():
-    command_queue = queue.LifoQueue()
-    read_thread = threading.Thread(target=read_loop, args=[command_queue])
-    read_thread.start()
-    run_loop(command_queue)
-
-
-def read_loop(command_queue):
-    while True:
-        command_queue.put_nowait(sys.stdin.readline().rstrip('\n'))
-
-
-def run_loop(command_queue):
-    thread_local = threading.local()
-    thread_local.doorbell_on_state = False
-
-    while True:
-        run_command(command_queue)
-        read_doorbell(thread_local)
-
-
-def run_command(command_queue):
-    try:
-        command = command_queue.get(timeout=0.5)
-    except queue.Empty:
-        pass
-    else:
-        automationhat.relay.on() if command == "unlock" else automationhat.relay.off()
-
-
-def read_doorbell(thread_local):
-    analog_value = automationhat.analog.one.read()
-    doorbell_on_state = 6.0 < analog_value and analog_value <= 6.22
-
-    if analog_value < 7.55:
-        print("doorbell analog value: {}; ringing: {}; ring range: (6.0, 6.22]".format(analog_value, doorbell_on_state))
-
-    if doorbell_on_state != thread_local.doorbell_on_state:
-        thread_local.doorbell_on_state = doorbell_on_state
-        print("doorbell on") if doorbell_on_state else print("doorbell off")
-
-
-if __name__ == "__main__":
-    main()