# HG changeset patch # User Luke Hoersten # Date 1591143068 18000 # Node ID 87ddaf81e63cdd76bc221797a666993f73926abc # Parent bc6c646f1814d817df958210e9012bdb876b5a8d Updated homekit door for Raspbian Buster. diff -r bc6c646f1814 -r 87ddaf81e63c README.md --- 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: "" - wpa_networks: - - ssid: "" - psk: "" - -## 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`. diff -r bc6c646f1814 -r 87ddaf81e63c ansible.cfg --- 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 diff -r bc6c646f1814 -r 87ddaf81e63c inventory/raspberrypi --- 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 diff -r bc6c646f1814 -r 87ddaf81e63c npmjs-package/package-lock.json --- /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" + } + } + } +} diff -r bc6c646f1814 -r 87ddaf81e63c npmjs-package/package.json --- /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 ", + "license": "BSD-3", + "repository": { + "type": "git", + "url": "https://github.com/lukehoersten/homekit-door.git" + }, + "dependencies": { + "hap-nodejs": "latest", + "python-shell": "latest" + } +} diff -r bc6c646f1814 -r 87ddaf81e63c npmjs-package/python/doord.py --- /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() 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"); diff -r bc6c646f1814 -r 87ddaf81e63c roles/hap-door/handlers/main.yaml --- 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 diff -r bc6c646f1814 -r 87ddaf81e63c roles/hap-door/meta/main.yaml --- 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 diff -r bc6c646f1814 -r 87ddaf81e63c roles/hap-door/tasks/main.yaml --- 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 diff -r bc6c646f1814 -r 87ddaf81e63c roles/hap-nodejs/defaults/main.yaml --- 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" diff -r bc6c646f1814 -r 87ddaf81e63c roles/hap-nodejs/handlers/main.yaml --- 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 diff -r bc6c646f1814 -r 87ddaf81e63c roles/hap-nodejs/tasks/main.yaml --- 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" diff -r bc6c646f1814 -r 87ddaf81e63c roles/hap-nodejs/templates/hap-nodejs.service.j2 --- 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 diff -r bc6c646f1814 -r 87ddaf81e63c roles/homekit-door/defaults/main.yaml --- /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 diff -r bc6c646f1814 -r 87ddaf81e63c roles/homekit-door/handlers/main.yaml --- /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 diff -r bc6c646f1814 -r 87ddaf81e63c roles/homekit-door/meta/main.yaml --- /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 diff -r bc6c646f1814 -r 87ddaf81e63c roles/homekit-door/tasks/main.yaml --- /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" diff -r bc6c646f1814 -r 87ddaf81e63c roles/homekit-door/templates/homekit-door.service.j2 --- /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 diff -r bc6c646f1814 -r 87ddaf81e63c rpi-door.yaml --- 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 diff -r bc6c646f1814 -r 87ddaf81e63c src/Door_accessory.js --- 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() {}); diff -r bc6c646f1814 -r 87ddaf81e63c src/doord.py --- 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()