From b547c47bb22431ac0afdbe72119c8b4cf3a188a2 Mon Sep 17 00:00:00 2001 From: Matt White Date: Sun, 17 Jul 2022 04:39:12 +0100 Subject: [PATCH] eye calibration process --- Pipfile | 1 + Pipfile.lock | 463 ++++++++++++++++++++++++++++-------------------- main.py | 22 ++- yuri.json | 12 ++ yuri.yaml | 1 - yuri/config.py | 65 ++++--- yuri/servos.py | 132 ++++++++++++-- yuri/speaker.py | 6 +- 8 files changed, 468 insertions(+), 234 deletions(-) create mode 100644 yuri.json delete mode 100644 yuri.yaml diff --git a/Pipfile b/Pipfile index 1140b7a..a2178c0 100644 --- a/Pipfile +++ b/Pipfile @@ -21,6 +21,7 @@ pip = "*" adafruit-pca9685 = "*" adafruit-circuitpython-servokit = "*" pyttsx3 = "*" +pydantic = "*" [dev-packages] ipython = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 22d7b14..84fb9da 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c0f2e7ed5bb5ca742531e2b3d36f1fc719a880276ce2d6ef9161e0ead77459a7" + "sha256": "7f594e5191499f64a905a9456c69ba09e90fcc1809bcddce235cb69784f7484e" }, "pipfile-spec": 6, "requires": { @@ -25,62 +25,69 @@ }, "adafruit-blinka": { "hashes": [ - "sha256:6bda326c154b93b02b6517c33f54cf7f5b10793106e91fd814e3c95a29589bf8" + "sha256:a807b3ffd1ee2e13b8513e85af84e5d973a13088ca731abe8eb27742a6903b42" ], "markers": "python_version >= '3.7'", - "version": "==6.17.0" + "version": "==8.0.2" }, "adafruit-circuitpython-bmp280": { "hashes": [ - "sha256:a1f4ca8adb68c9a889f08acbe016a5c6e59fa8879a3afe0b4b5a243915722bb3" + "sha256:895bc6fe2ff948110309a80c771a15c4e950eca221bbe0c411b597611adc01ca" ], "index": "pypi", - "version": "==3.2.9" + "version": "==3.2.15" }, "adafruit-circuitpython-busdevice": { "hashes": [ - "sha256:27049b07a3d6cdc6646bfe950ab1465604d898454b0fd9d893fd2c5294551506" + "sha256:228df23033f3259b42b998701699293a3cdfd5599fa1cfb13557ad415bab8ab5" ], - "version": "==5.1.1" + "markers": "python_version >= '3.7'", + "version": "==5.1.10" }, "adafruit-circuitpython-dotstar": { "hashes": [ - "sha256:2dd5ad15576f455d582c668a8f1049f44026a508c4116ca857f4436a6437adf0" + "sha256:2ed5f75eb3db7c5b3b461d6467ac92fbf8a9f1211dd768267d35aeb9b104f1d7" ], "index": "pypi", - "version": "==2.1.1" + "version": "==2.2.2" }, "adafruit-circuitpython-motor": { "hashes": [ - "sha256:11702cdf0025314bdb64daf580e5e49f4903460a504f66681f8a5e0beee5b324" + "sha256:d630eb6479d948578744990c1a36994f8e03cc78e92c5d4278833899328c3f6d" ], "index": "pypi", - "version": "==3.3.4" + "version": "==3.4.2" }, "adafruit-circuitpython-pca9685": { "hashes": [ - "sha256:68758316015fe2e47dfcb5acc380c7ab2ff5abdad4f358598b1a44ba07c19054" + "sha256:7b92ecc39da5afc47ea005e698a148eb1751c7ab8c9f73c1acc91eee65a26c5d" ], - "version": "==3.3.9" + "version": "==3.4.3" }, "adafruit-circuitpython-pixelbuf": { "hashes": [ - "sha256:8c6778db7c7cbf9455b617c9fe9461be1677b3faaa0a850188c40b03f070c88f" + "sha256:66e263b39d7196a17b107a194274d78971cd0d241fa0ec6cdf46694d09bf66ff" ], - "version": "==1.1.1" + "version": "==1.1.5" }, "adafruit-circuitpython-register": { "hashes": [ - "sha256:ee82a0aa94cf9dc12bc3c24b892323372d3b2e1b8b8e1cbc2498bcdea0e7dc71" + "sha256:62d67a24de825a7b14f7a6713ed77ce9e2d2bb3a6a4123aba13ba8f98d594f14" ], - "version": "==1.9.7" + "version": "==1.9.10" }, "adafruit-circuitpython-servokit": { "hashes": [ - "sha256:d8e4eb9725e8ddaaeadc50a3cfb9dfe51d499bda7f7b47ca6a3e19d4c6ea75c5" + "sha256:d302575b34560bf3a56e1dc68afefca89760f7a84f8be0a08fb0aeb414fa0ac8" ], "index": "pypi", - "version": "==1.3.6" + "version": "==1.3.10" + }, + "adafruit-circuitpython-typing": { + "hashes": [ + "sha256:30051d7f2a5eeaed67d72cbae5a627fab7be97f2dede2f47d1385d7d8dee2474" + ], + "version": "==1.7.1" }, "adafruit-gpio": { "hashes": [ @@ -98,10 +105,10 @@ }, "adafruit-platformdetect": { "hashes": [ - "sha256:593f3719580b31b3dffab0817414a3aa548ed609659ad216ceb8cf31cc51ec9b" + "sha256:f0af0e287c6e3c6e5b89b6f8f44a60bfd94cb99ec8a64f7be77b08db67ba8f6e" ], - "markers": "python_version >= '3.6'", - "version": "==3.18.0" + "markers": "python_version >= '3.7'", + "version": "==3.25.0" }, "adafruit-pureio": { "hashes": [ @@ -119,34 +126,35 @@ }, "cachetools": { "hashes": [ - "sha256:89ea6f1b638d5a73a4f9226be57ac5e4f399d22770b92355f92dcb0f7f001693", - "sha256:92971d3cb7d2a97efff7c7bb1657f21a8f5fb309a37530537c71b1774189f2d1" + "sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757", + "sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db" ], - "markers": "python_version ~= '3.5'", - "version": "==4.2.4" + "markers": "python_version ~= '3.7'", + "version": "==5.2.0" }, "certifi": { "hashes": [ - "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872", - "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569" + "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d", + "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412" ], - "version": "==2021.10.8" + "markers": "python_full_version >= '3.6.0'", + "version": "==2022.6.15" }, "charset-normalizer": { "hashes": [ - "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721", - "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c" + "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5", + "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413" ], - "markers": "python_version >= '3'", - "version": "==2.0.9" + "markers": "python_full_version >= '3.6.0'", + "version": "==2.1.0" }, "click": { "hashes": [ - "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3", - "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b" + "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", + "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" ], - "markers": "python_version >= '3.6'", - "version": "==8.0.3" + "markers": "python_version >= '3.7'", + "version": "==8.1.3" }, "flatbuffers": { "hashes": [ @@ -165,18 +173,18 @@ }, "google-auth": { "hashes": [ - "sha256:a348a50b027679cb7dae98043ac8dbcc1d7951f06d8387496071a1e05a2465c0", - "sha256:d83570a664c10b97a1dc6f8df87e5fdfff012f48f62be131e449c20dfc32630e" + "sha256:14292fa3429f2bb1e99862554cde1ee730d6840ebae067814d3d15d8549c0888", + "sha256:5a7eed0cb0e3a83989fad0b59fe1329dfc8c479543039cd6fd1e01e9adf39475" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==2.3.3" + "version": "==2.9.1" }, "google-auth-oauthlib": { "hashes": [ "sha256:3f2a6e802eebbb6fb736a370fbf3b055edcb6b52878bf2f26330b5e041316c73", "sha256:a90a072f6993f2c327067bf65270046384cda5a8ecb20b94ea9a687f1f233a7a" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==0.4.6" }, "google-pasta": { @@ -233,11 +241,10 @@ }, "gtts": { "hashes": [ - "sha256:8376d9bde85ac8cda95ea92dcd12bf31a3efe9e810edcb04437a4151cbec30d6", - "sha256:88cfaa112471867009a0450a696e5bc69cf1671fa0fa683fe17d0650023c863c" + "sha256:60f6a611ea858badcceb328544b28435b663e39898859beeb9adb2a874bc1eca" ], "index": "pypi", - "version": "==2.2.3" + "version": "==2.2.4" }, "h5py": { "hashes": [ @@ -278,16 +285,16 @@ "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" ], - "markers": "python_version >= '3'", + "markers": "python_version >= '3.5'", "version": "==3.3" }, "importlib-metadata": { "hashes": [ - "sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6", - "sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4" + "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", + "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" ], "markers": "python_version < '3.8'", - "version": "==4.10.0" + "version": "==4.12.0" }, "keras-preprocessing": { "hashes": [ @@ -298,19 +305,19 @@ }, "loguru": { "hashes": [ - "sha256:b28e72ac7a98be3d28ad28570299a393dfcd32e5e3f6a353dec94675767b6319", - "sha256:f8087ac396b5ee5f67c963b495d615ebbceac2796379599820e324419d53667c" + "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c", + "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3" ], "index": "pypi", - "version": "==0.5.3" + "version": "==0.6.0" }, "markdown": { "hashes": [ - "sha256:76df8ae32294ec39dcf89340382882dfa12975f87f45c3ed1ecdb1e8cefc7006", - "sha256:9923332318f843411e9932237530df53162e29dc7a4e2b91e35764583c46c9a3" + "sha256:08fb8465cffd03d10b9dd34a5c3fea908e20391a2a90b88d66362cb05beed186", + "sha256:3b809086bb6efad416156e00a0da66fe47618a5d6918dd688f53f40c8e4cfeff" ], - "markers": "python_version >= '3.6'", - "version": "==3.3.6" + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "numpy": { "hashes": [ @@ -349,16 +356,16 @@ "sha256:dbd18bcf4889b720ba13a27ec2f2aac1981bd41203b3a3b27ba7a33f88ae4827", "sha256:df609c82f18c5b9f6cb97271f03315ff0dbe481a2a02e56aeb1b1a985ce38e60" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==1.19.5" }, "oauthlib": { "hashes": [ - "sha256:42bf6354c2ed8c6acb54d971fce6f88193d97297e18602a3a886603f9d7730cc", - "sha256:8f0215fcc533dd8dd1bee6f4c412d4f0cd7297307d43ac61666389e3bc3198a3" + "sha256:23a8208d75b902797ea29fd31fa80a15ed9dc2c6c16fe73f5d346f83f6fa27a2", + "sha256:6db33440354787f9b7f3a6dbd4febf5d0f93758354060e802f6c06cb493022fe" ], - "markers": "python_version >= '3.6'", - "version": "==3.1.1" + "markers": "python_full_version >= '3.6.0'", + "version": "==3.2.0" }, "opt-einsum": { "hashes": [ @@ -370,11 +377,11 @@ }, "pip": { "hashes": [ - "sha256:deaf32dcd9ab821e359cd8330786bcd077604b5c5730c0b096eda46f95c24a2d", - "sha256:fd11ba3d0fdb4c07fbc5ecbba0b1b719809420f25038f8ee3cd913d3faa3033a" + "sha256:6d55b27e10f506312894a87ccc59f280136bad9061719fac9101bdad5a6bce69", + "sha256:a3edacb89022ef5258bf61852728bf866632a394da837ca49eb4303635835f17" ], "index": "pypi", - "version": "==21.3.1" + "version": "==22.1.2" }, "pocketsphinx": { "hashes": [ @@ -405,33 +412,35 @@ }, "protobuf": { "hashes": [ - "sha256:038daf4fa38a7e818dd61f51f22588d61755160a98db087a046f80d66b855942", - "sha256:28ccea56d4dc38d35cd70c43c2da2f40ac0be0a355ef882242e8586c6d66666f", - "sha256:36d90676d6f426718463fe382ec6274909337ca6319d375eebd2044e6c6ac560", - "sha256:3cd0458870ea7d1c58e948ac8078f6ba8a7ecc44a57e03032ed066c5bb318089", - "sha256:5935c8ce02e3d89c7900140a8a42b35bc037ec07a6aeb61cc108be8d3c9438a6", - "sha256:615b426a177780ce381ecd212edc1e0f70db8557ed72560b82096bd36b01bc04", - "sha256:62a8e4baa9cb9e064eb62d1002eca820857ab2138440cb4b3ea4243830f94ca7", - "sha256:655264ed0d0efe47a523e2255fc1106a22f6faab7cc46cfe99b5bae085c2a13e", - "sha256:6e8ea9173403219239cdfd8d946ed101f2ab6ecc025b0fda0c6c713c35c9981d", - "sha256:71b0250b0cfb738442d60cab68abc166de43411f2a4f791d31378590bfb71bd7", - "sha256:74f33edeb4f3b7ed13d567881da8e5a92a72b36495d57d696c2ea1ae0cfee80c", - "sha256:77d2fadcf369b3f22859ab25bd12bb8e98fb11e05d9ff9b7cd45b711c719c002", - "sha256:8b30a7de128c46b5ecb343917d9fa737612a6e8280f440874e5cc2ba0d79b8f6", - "sha256:8e51561d72efd5bd5c91490af1f13e32bcba8dab4643761eb7de3ce18e64a853", - "sha256:a529e7df52204565bcd33738a7a5f288f3d2d37d86caa5d78c458fa5fabbd54d", - "sha256:b691d996c6d0984947c4cf8b7ae2fe372d99b32821d0584f0b90277aa36982d3", - "sha256:d80f80eb175bf5f1169139c2e0c5ada98b1c098e2b3c3736667f28cbbea39fc8", - "sha256:d83e1ef8cb74009bebee3e61cc84b1c9cd04935b72bca0cbc83217d140424995", - "sha256:d8919368410110633717c406ab5c97e8df5ce93020cfcf3012834f28b1fab1ea", - "sha256:db3532d9f7a6ebbe2392041350437953b6d7a792de10e629c1e4f5a6b1fe1ac6", - "sha256:e7b24c11df36ee8e0c085e5b0dc560289e4b58804746fb487287dda51410f1e2", - "sha256:e7e8d2c20921f8da0dea277dfefc6abac05903ceac8e72839b2da519db69206b", - "sha256:e813b1c9006b6399308e917ac5d298f345d95bb31f46f02b60cd92970a9afa17", - "sha256:fd390367fc211cc0ffcf3a9e149dfeca78fecc62adb911371db0cec5c8b7472d" + "sha256:072fbc78d705d3edc7ccac58a62c4c8e0cec856987da7df8aca86e647be4e35c", + "sha256:09297b7972da685ce269ec52af761743714996b4381c085205914c41fcab59fb", + "sha256:16f519de1313f1b7139ad70772e7db515b1420d208cb16c6d7858ea989fc64a9", + "sha256:1c91ef4110fdd2c590effb5dca8fdbdcb3bf563eece99287019c4204f53d81a4", + "sha256:3112b58aac3bac9c8be2b60a9daf6b558ca3f7681c130dcdd788ade7c9ffbdca", + "sha256:36cecbabbda242915529b8ff364f2263cd4de7c46bbe361418b5ed859677ba58", + "sha256:4276cdec4447bd5015453e41bdc0c0c1234eda08420b7c9a18b8d647add51e4b", + "sha256:435bb78b37fc386f9275a7035fe4fb1364484e38980d0dd91bc834a02c5ec909", + "sha256:48ed3877fa43e22bcacc852ca76d4775741f9709dd9575881a373bd3e85e54b2", + "sha256:54a1473077f3b616779ce31f477351a45b4fef8c9fd7892d6d87e287a38df368", + "sha256:69da7d39e39942bd52848438462674c463e23963a1fdaa84d88df7fbd7e749b2", + "sha256:6cbc312be5e71869d9d5ea25147cdf652a6781cf4d906497ca7690b7b9b5df13", + "sha256:7bb03bc2873a2842e5ebb4801f5c7ff1bfbdf426f85d0172f7644fcda0671ae0", + "sha256:7ca7da9c339ca8890d66958f5462beabd611eca6c958691a8fe6eccbd1eb0c6e", + "sha256:835a9c949dc193953c319603b2961c5c8f4327957fe23d914ca80d982665e8ee", + "sha256:84123274d982b9e248a143dadd1b9815049f4477dc783bf84efe6250eb4b836a", + "sha256:8961c3a78ebfcd000920c9060a262f082f29838682b1f7201889300c1fbe0616", + "sha256:96bd766831596d6014ca88d86dc8fe0fb2e428c0b02432fd9db3943202bf8c5e", + "sha256:9df0c10adf3e83015ced42a9a7bd64e13d06c4cf45c340d2c63020ea04499d0a", + "sha256:b38057450a0c566cbd04890a40edf916db890f2818e8682221611d78dc32ae26", + "sha256:bd95d1dfb9c4f4563e6093a9aa19d9c186bf98fa54da5252531cc0d3a07977e7", + "sha256:c1068287025f8ea025103e37d62ffd63fec8e9e636246b89c341aeda8a67c934", + "sha256:c438268eebb8cf039552897d78f402d734a404f1360592fef55297285f7f953f", + "sha256:cdc076c03381f5c1d9bb1abdcc5503d9ca8b53cf0a9d31a9f6754ec9e6c8af0f", + "sha256:f358aa33e03b7a84e0d91270a4d4d8f5df6921abe99a377828839e8ed0c04e07", + "sha256:f51d5a9f137f7a2cec2d326a74b6e3fc79d635d69ffe1b036d39fc7d75430d37" ], "markers": "python_version >= '3.5'", - "version": "==3.19.1" + "version": "==3.19.4" }, "pyasn1": { "hashes": [ @@ -484,6 +493,47 @@ "index": "pypi", "version": "==0.2.11" }, + "pydantic": { + "hashes": [ + "sha256:02eefd7087268b711a3ff4db528e9916ac9aa18616da7bca69c1871d0b7a091f", + "sha256:059b6c1795170809103a1538255883e1983e5b831faea6558ef873d4955b4a74", + "sha256:0bf07cab5b279859c253d26a9194a8906e6f4a210063b84b433cf90a569de0c1", + "sha256:1542636a39c4892c4f4fa6270696902acb186a9aaeac6f6cf92ce6ae2e88564b", + "sha256:177071dfc0df6248fd22b43036f936cfe2508077a72af0933d0c1fa269b18537", + "sha256:18f3e912f9ad1bdec27fb06b8198a2ccc32f201e24174cec1b3424dda605a310", + "sha256:1dd8fecbad028cd89d04a46688d2fcc14423e8a196d5b0a5c65105664901f810", + "sha256:1ed987c3ff29fff7fd8c3ea3a3ea877ad310aae2ef9889a119e22d3f2db0691a", + "sha256:447d5521575f18e18240906beadc58551e97ec98142266e521c34968c76c8761", + "sha256:494f7c8537f0c02b740c229af4cb47c0d39840b829ecdcfc93d91dcbb0779892", + "sha256:4988c0f13c42bfa9ddd2fe2f569c9d54646ce84adc5de84228cfe83396f3bd58", + "sha256:4ce9ae9e91f46c344bec3b03d6ee9612802682c1551aaf627ad24045ce090761", + "sha256:5d93d4e95eacd313d2c765ebe40d49ca9dd2ed90e5b37d0d421c597af830c195", + "sha256:61b6760b08b7c395975d893e0b814a11cf011ebb24f7d869e7118f5a339a82e1", + "sha256:72ccb318bf0c9ab97fc04c10c37683d9eea952ed526707fabf9ac5ae59b701fd", + "sha256:79b485767c13788ee314669008d01f9ef3bc05db9ea3298f6a50d3ef596a154b", + "sha256:7eb57ba90929bac0b6cc2af2373893d80ac559adda6933e562dcfb375029acee", + "sha256:8bc541a405423ce0e51c19f637050acdbdf8feca34150e0d17f675e72d119580", + "sha256:969dd06110cb780da01336b281f53e2e7eb3a482831df441fb65dd30403f4608", + "sha256:985ceb5d0a86fcaa61e45781e567a59baa0da292d5ed2e490d612d0de5796918", + "sha256:9bcf8b6e011be08fb729d110f3e22e654a50f8a826b0575c7196616780683380", + "sha256:9ce157d979f742a915b75f792dbd6aa63b8eccaf46a1005ba03aa8a986bde34a", + "sha256:9f659a5ee95c8baa2436d392267988fd0f43eb774e5eb8739252e5a7e9cf07e0", + "sha256:a4a88dcd6ff8fd47c18b3a3709a89adb39a6373f4482e04c1b765045c7e282fd", + "sha256:a955260d47f03df08acf45689bd163ed9df82c0e0124beb4251b1290fa7ae728", + "sha256:a9af62e9b5b9bc67b2a195ebc2c2662fdf498a822d62f902bf27cccb52dbbf49", + "sha256:ae72f8098acb368d877b210ebe02ba12585e77bd0db78ac04a1ee9b9f5dd2166", + "sha256:b83ba3825bc91dfa989d4eed76865e71aea3a6ca1388b59fc801ee04c4d8d0d6", + "sha256:c11951b404e08b01b151222a1cb1a9f0a860a8153ce8334149ab9199cd198131", + "sha256:c320c64dd876e45254bdd350f0179da737463eea41c43bacbee9d8c9d1021f11", + "sha256:c8098a724c2784bf03e8070993f6d46aa2eeca031f8d8a048dff277703e6e193", + "sha256:d12f96b5b64bec3f43c8e82b4aab7599d0157f11c798c9f9c528a72b9e0b339a", + "sha256:e565a785233c2d03724c4dc55464559639b1ba9ecf091288dd47ad9c629433bd", + "sha256:f0f047e11febe5c3198ed346b507e1d010330d56ad615a7e0a89fae604065a0e", + "sha256:fe4670cb32ea98ffbf5a1262f14c3e102cccd92b1869df3bb09538158ba90fe6" + ], + "index": "pypi", + "version": "==1.9.1" + }, "pydub": { "hashes": [ "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6", @@ -494,11 +544,11 @@ }, "pyftdi": { "hashes": [ - "sha256:4ef20c246bdb0f278d283337d7a6e69cf9bdb0ead525e7ad867d9e46ad26e613", - "sha256:6e86880ec6d66389de643ca83de5d59fffea3bd334f492e12fab71a832f878a2" + "sha256:112f16ee5b2a2becb8f8df9dd40b3bba007589f34e7613024122d94bd56eb7d7", + "sha256:8df9af22077d17533d2f95b508b1d87959877627ea5dc2369056e90a3b5a232d" ], - "markers": "python_version >= '3.6'", - "version": "==0.53.3" + "markers": "python_version >= '3.7'", + "version": "==0.54.0" }, "pyserial": { "hashes": [ @@ -519,7 +569,7 @@ "sha256:2b4c7cb86dbadf044dfb9d3a4ff69fd217013dbe78a792177a3feb172449ea36", "sha256:a4cc7404a203144754164b8b40994e2849fde1cfff06b08492f12fff9d9de7b9" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==1.2.1" }, "pyyaml": { @@ -563,50 +613,56 @@ }, "requests": { "hashes": [ - "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24", - "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7" + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==2.26.0" + "markers": "python_version >= '3.7' and python_version < '4'", + "version": "==2.28.1" }, "requests-oauthlib": { "hashes": [ - "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d", - "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a", - "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc" + "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", + "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" ], - "version": "==1.3.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.3.1" }, "rpi-ws281x": { "hashes": [ - "sha256:0d1b68d2912bf56ba9078c4117720e1de29cef56af222fef64e767307ab88fda", - "sha256:689f3f4a81c70adc830694140d9de84d0dbc3b8b4ece4fc3d1ef43b2348ce9ab", - "sha256:d403bd2a45e70ec672ecc0dc2757f218d8c07401dcb2711599523e9f34c4579c" + "sha256:072eff1787e579d1710381b27c467709e3aab28ac579c7a47d7cc87398496f28", + "sha256:9c47f7f968f50abd9fe46f1f54081c6ce6b41735cc6733d59f3dc3caf7f1ac0b" ], - "version": "==4.3.1" + "version": "==4.3.4" }, "rpi.gpio": { "hashes": [ - "sha256:7424bc6c205466764f30f666c18187a0824077daf20b295c42f08aea2cb87d3f" + "sha256:15311d3b063b71dee738cd26570effc9985a952454d162937c34e08c0fc99902", + "sha256:26b2ade4bb353bbe5417a64e40b45cdf00a82f27c2d320c0dd46c59751959d77", + "sha256:29226823da8b5ccb9001d795a944f2e00924eeae583490f0bc7317581172c624", + "sha256:57b6c044ef5375a78c8dda27cdfadf329e76aa6943cd6cffbbbd345a9adf9ca5", + "sha256:77afb817b81331ce3049a4b8f94a85e41b7c404d8e56b61ac0f1eb75c3120868", + "sha256:96ea7e5bf6bf592828487bfa7d3d1d0e432d5d1682e9e33b4dab398914628fcd", + "sha256:b86b66dc02faa5461b443a1e1f0c1d209d64ab5229696f32fb3b0215e0600c8c", + "sha256:cd61c4b03c37b62bba4a5acfea9862749c33c618e0295e7e90aa4713fb373b70" ], "index": "pypi", - "version": "==0.7.0" + "version": "==0.7.1" }, "rsa": { "hashes": [ "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17", "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==4.8" }, "setuptools": { "hashes": [ - "sha256:10d6eff7fc27ada30cc87e21abf324713b7169b97af1f81f8744d66260e91d10", - "sha256:89e8cb2d5ade19e9885e56cd110f2f1e80697f7cffa048886c585fe559ebbe32" + "sha256:0d33c374d41c7863419fc8f6c10bfe25b7b498aa34164d135c622e52580c6b16", + "sha256:c04b44a57a6265fe34a4a444e965884716d34bae963119a76353434d6f18e450" ], "markers": "python_version >= '3.7'", - "version": "==60.1.1" + "version": "==63.2.0" }, "six": { "hashes": [ @@ -641,10 +697,10 @@ }, "tensorboard": { "hashes": [ - "sha256:239f78a4a8dff200ce585a030c787773a8c1184d5c159252f5f85bac4e3c3b38" + "sha256:baa727f791776f9e5841d347127720ceed4bbd59c36b40604b95fb2ae6029276" ], - "markers": "python_version >= '3.6'", - "version": "==2.7.0" + "markers": "python_full_version >= '3.6.0'", + "version": "==2.9.1" }, "tensorboard-data-server": { "hashes": [ @@ -652,14 +708,14 @@ "sha256:d8237580755e58eff68d1f3abefb5b1e39ae5c8b127cc40920f9c4fb33f4b98a", "sha256:fa8cef9be4fcae2f2363c88176638baf2da19c5ec90addb49b1cde05c95c88ee" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==0.6.1" }, "tensorboard-plugin-wit": { "hashes": [ - "sha256:2a80d1c551d741e99b2f197bb915d8a133e24adb8da1732b840041860f91183a" + "sha256:ff26bdd583d155aa951ee3b152b3d0cffae8005dc697f72b44a8e8c2a77a8cbe" ], - "version": "==1.8.0" + "version": "==1.8.1" }, "tensorflow": { "file": "https://github.com/bitsy-ai/tensorflow-arm-bin/releases/download/v2.4.0/tensorflow-2.4.0-cp37-none-linux_aarch64.whl", @@ -683,11 +739,11 @@ }, "typer": { "hashes": [ - "sha256:63c3aeab0549750ffe40da79a1b524f60e08a2cbc3126c520ebf2eeaf507f5dd", - "sha256:d81169725140423d072df464cad1ff25ee154ef381aaf5b8225352ea187ca338" + "sha256:2d5720a5e63f73eaf31edaa15f6ab87f35f0690f8ca233017d7d23d743a91d73", + "sha256:54b19e5df18654070a82f8c2aa1da456a4ac16a2a83e6dcd9f170e291c56338e" ], "index": "pypi", - "version": "==0.4.0" + "version": "==0.6.1" }, "typing-extensions": { "hashes": [ @@ -699,19 +755,19 @@ }, "urllib3": { "hashes": [ - "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece", - "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844" + "sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec", + "sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.7" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'", + "version": "==1.26.10" }, "werkzeug": { "hashes": [ - "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f", - "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a" + "sha256:1ce08e8093ed67d638d63879fd1ba3735817f7a80de3674d293f5984f25fb6e6", + "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255" ], - "markers": "python_version >= '3.6'", - "version": "==2.0.2" + "markers": "python_version >= '3.7'", + "version": "==2.1.2" }, "wheel": { "hashes": [ @@ -729,21 +785,21 @@ }, "zipp": { "hashes": [ - "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", - "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" + "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", + "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009" ], - "markers": "python_version >= '3.6'", - "version": "==3.6.0" + "markers": "python_version >= '3.7'", + "version": "==3.8.1" } }, "develop": { "astroid": { "hashes": [ - "sha256:5939cf55de24b92bda00345d4d0659d01b3c7dafb5055165c330bc7c568ba273", - "sha256:776ca0b748b4ad69c00bfe0fff38fa2d21c338e12c84aa9715ee0d473c422778" + "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b", + "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946" ], - "markers": "python_version ~= '3.6'", - "version": "==2.9.0" + "markers": "python_full_version >= '3.6.2'", + "version": "==2.11.7" }, "backcall": { "hashes": [ @@ -754,11 +810,19 @@ }, "decorator": { "hashes": [ - "sha256:7b12e7c3c6ab203a29e157335e9122cb03de9ab7264b137594103fd4a683b374", - "sha256:e59913af105b9860aa2c8d3272d9de5a56a4e608db9a2f167a8480b323d529a7" + "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", + "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" ], - "markers": "python_version >= '3.5'", - "version": "==5.1.0" + "markers": "python_version >= '3.7'", + "version": "==5.1.1" + }, + "dill": { + "hashes": [ + "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302", + "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==0.3.5.1" }, "flake8": { "hashes": [ @@ -770,11 +834,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6", - "sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4" + "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", + "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" ], "markers": "python_version < '3.8'", - "version": "==4.10.0" + "version": "==4.12.0" }, "ipdb": { "hashes": [ @@ -785,11 +849,11 @@ }, "ipython": { "hashes": [ - "sha256:cb6aef731bf708a7727ab6cde8df87f0281b1427d41e65d62d4b68934fa54e97", - "sha256:fc60ef843e0863dd4e24ab2bb5698f071031332801ecf8d1aeb4fb622056545c" + "sha256:af3bdb46aa292bce5615b1b2ebc76c2080c5f77f54bda2ec72461317273e7cd6", + "sha256:c175d2440a1caff76116eb719d40538fbb316e214eda85c5515c303aacbfb23e" ], "index": "pypi", - "version": "==7.30.1" + "version": "==7.34.0" }, "isort": { "hashes": [ @@ -890,19 +954,19 @@ }, "platformdirs": { "hashes": [ - "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca", - "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda" + "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", + "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" ], "markers": "python_version >= '3.7'", - "version": "==2.4.1" + "version": "==2.5.2" }, "prompt-toolkit": { "hashes": [ - "sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6", - "sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506" + "sha256:859b283c50bde45f5f97829f77a4674d1c1fcd88539364f1b28a37805cfd89c0", + "sha256:d8916d3f62a7b67ab353a952ce4ced6a1d2587dfe9ef8ebc30dd7c386751f289" ], "markers": "python_full_version >= '3.6.2'", - "version": "==3.0.24" + "version": "==3.0.30" }, "ptyprocess": { "hashes": [ @@ -929,27 +993,27 @@ }, "pygments": { "hashes": [ - "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380", - "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6" + "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb", + "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519" ], - "markers": "python_version >= '3.5'", - "version": "==2.10.0" + "markers": "python_version >= '3.6'", + "version": "==2.12.0" }, "pylint": { "hashes": [ - "sha256:9d945a73640e1fec07ee34b42f5669b770c759acd536ec7b16d7e4b87a9c9ff9", - "sha256:daabda3f7ed9d1c60f52d563b1b854632fd90035bcf01443e234d3dc794e3b74" + "sha256:47705453aa9dce520e123a7d51843d5f0032cbfa06870f89f00927aa1f735a4a", + "sha256:89b61867db16eefb7b3c5b84afc94081edaf11544189e2b238154677529ad69f" ], "index": "pypi", - "version": "==2.12.2" + "version": "==2.14.4" }, "setuptools": { "hashes": [ - "sha256:10d6eff7fc27ada30cc87e21abf324713b7169b97af1f81f8744d66260e91d10", - "sha256:89e8cb2d5ade19e9885e56cd110f2f1e80697f7cffa048886c585fe559ebbe32" + "sha256:0d33c374d41c7863419fc8f6c10bfe25b7b498aa34164d135c622e52580c6b16", + "sha256:c04b44a57a6265fe34a4a444e965884716d34bae963119a76353434d6f18e450" ], "markers": "python_version >= '3.7'", - "version": "==60.1.1" + "version": "==63.2.0" }, "toml": { "hashes": [ @@ -959,38 +1023,59 @@ "markers": "python_version >= '3.7'", "version": "==0.10.2" }, + "tomli": { + "hashes": [ + "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + ], + "markers": "python_version < '3.11'", + "version": "==2.0.1" + }, + "tomlkit": { + "hashes": [ + "sha256:1c5bebdf19d5051e2e1de6cf70adfc5948d47221f097fcff7a3ffc91e953eaf5", + "sha256:61901f81ff4017951119cd0d1ed9b7af31c821d6845c8c477587bbdcd5e5854e" + ], + "markers": "python_version >= '3.6' and python_version < '4.0'", + "version": "==0.11.1" + }, "traitlets": { "hashes": [ - "sha256:059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7", - "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033" + "sha256:0bb9f1f9f017aa8ec187d8b1b2a7a6626a2a1d877116baba52a129bfa124f8e2", + "sha256:65fa18961659635933100db8ca120ef6220555286949774b9cfc106f941d1c7a" ], "markers": "python_version >= '3.7'", - "version": "==5.1.1" + "version": "==5.3.0" }, "typed-ast": { "hashes": [ - "sha256:24058827d8f5d633f97223f5148a7d22628099a3d2efe06654ce872f46f07cdb", - "sha256:256115a5bc7ea9e665c6314ed6671ee2c08ca380f9d5f130bd4d2c1f5848d695", - "sha256:38cf5c642fa808300bae1281460d4f9b7617cf864d4e383054a5ef336e344d32", - "sha256:484137cab8ecf47e137260daa20bafbba5f4e3ec7fda1c1e69ab299b75fa81c5", - "sha256:4f30a2bcd8e68adbb791ce1567fdb897357506f7ea6716f6bbdd3053ac4d9471", - "sha256:591bc04e507595887160ed7aa8d6785867fb86c5793911be79ccede61ae96f4d", - "sha256:5b6ab14c56bc9c7e3c30228a0a0b54b915b1579613f6e463ba6f4eb1382e7fd4", - "sha256:5d8314c92414ce7481eee7ad42b353943679cf6f30237b5ecbf7d835519e1212", - "sha256:71dcda943a471d826ea930dd449ac7e76db7be778fcd722deb63642bab32ea3f", - "sha256:7c42707ab981b6cf4b73490c16e9d17fcd5227039720ca14abe415d39a173a30", - "sha256:9caaf2b440efb39ecbc45e2fabde809cbe56272719131a6318fd9bf08b58e2cb", - "sha256:a2b8d7007f6280e36fa42652df47087ac7b0a7d7f09f9468f07792ba646aac2d", - "sha256:a6d495c1ef572519a7bac9534dbf6d94c40e5b6a608ef41136133377bba4aa08", - "sha256:a80d84f535642420dd17e16ae25bb46c7f4c16ee231105e7f3eb43976a89670a", - "sha256:b53ae5de5500529c76225d18eeb060efbcec90ad5e030713fe8dab0fb4531631", - "sha256:b6d17f37f6edd879141e64a5db17b67488cfeffeedad8c5cec0392305e9bc775", - "sha256:c9bcad65d66d594bffab8575f39420fe0ee96f66e23c4d927ebb4e24354ec1af", - "sha256:ca9e8300d8ba0b66d140820cf463438c8e7b4cdc6fd710c059bfcfb1531d03fb", - "sha256:de4ecae89c7d8b56169473e08f6bfd2df7f95015591f43126e4ea7865928677e" + "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2", + "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1", + "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6", + "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62", + "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac", + "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d", + "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc", + "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2", + "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97", + "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35", + "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6", + "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1", + "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4", + "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c", + "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e", + "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec", + "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f", + "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72", + "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47", + "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72", + "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe", + "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6", + "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3", + "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66" ], "markers": "python_version < '3.8' and implementation_name == 'cpython'", - "version": "==1.5.1" + "version": "==1.5.4" }, "typing-extensions": { "hashes": [ @@ -1015,11 +1100,11 @@ }, "zipp": { "hashes": [ - "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", - "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" + "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", + "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009" ], - "markers": "python_version >= '3.6'", - "version": "==3.6.0" + "markers": "python_version >= '3.7'", + "version": "==3.8.1" } } } diff --git a/main.py b/main.py index eeb3d3e..3e1a92c 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,7 @@ from typing import Optional import typer +import asyncio from loguru import logger from yuri.config import Config, ConfigFactory @@ -13,7 +14,7 @@ app = typer.Typer() -DEFAULT_CONFIG_LOCATION = "yuri.yaml" +DEFAULT_CONFIG_LOCATION = "yuri.json" def get_config(config_path: Optional[str]) -> Config: @@ -54,12 +55,16 @@ def colors(seconds: int = 3, config_path: Optional[str] = None): lights.cycle_colors(seconds) +async def asay(message: str, config: Config): + servos = Servos(config) + speaker = SpeakerFactory.create(config) + await asyncio.gather(servos.eyes.blink_loop(), speaker.say(message)) + @app.command() def say(message: str, config_path: Optional[str] = None): config = get_config(config_path) - speaker = SpeakerFactory.create(config) - speaker.say(message) - + asyncio.run(asay(message, config)) + @app.command() def transcribe(config_path: Optional[str] = None): @@ -69,6 +74,15 @@ def transcribe(config_path: Optional[str] = None): transcription = listener.transcribe(audio) logger.info(transcription) +@app.command() +def calibrate(config_path: Optional[str] = None): + config = get_config(config_path) + servos = Servos(config) + speaker = SpeakerFactory.create(config) + asyncio.run(speaker.say("Let's calibrate.")) + inputs = Input(config) + servos.eyes.calibrate(inputs, config) + config.save(config_path or DEFAULT_CONFIG_LOCATION) @app.command() def repeat(config_path: Optional[str] = None): diff --git a/yuri.json b/yuri.json new file mode 100644 index 0000000..71670f9 --- /dev/null +++ b/yuri.json @@ -0,0 +1,12 @@ +{ + "listener_type": "sphinx", + "speaker_type": "google", + "left_eye": { + "neutral_x": 129.9125660837739, + "neutral_y": 100.04676697844651 + }, + "right_eye": { + "neutral_x": 80.42903619357463, + "neutral_y": 129.9125660837739 + } +} \ No newline at end of file diff --git a/yuri.yaml b/yuri.yaml deleted file mode 100644 index d73cebd..0000000 --- a/yuri.yaml +++ /dev/null @@ -1 +0,0 @@ -speaker_type: pyttsx3 diff --git a/yuri/config.py b/yuri/config.py index 16b18f5..cd25a3f 100644 --- a/yuri/config.py +++ b/yuri/config.py @@ -1,31 +1,56 @@ -from dataclasses import dataclass, field +from dataclasses import field +from pydantic.dataclasses import dataclass +from pydantic import BaseModel import board -import yaml - - -@dataclass -class Pins: - dotstar_clock: int = board.D6 - dotstar_data: int = board.D5 - button: int = board.D17 - joydown: int = board.D27 - joyleft: int = board.D22 - joyup: int = board.D23 - joyright: int = board.D24 - joyselect: int = board.D16 - -@dataclass -class Config: +import json +from typing import Optional +from loguru import logger + +Pin = board.pin.Pin + +class Pins(BaseModel): + dotstar_clock: Pin = board.D6 + dotstar_data: Pin = board.D5 + button: Pin = board.D17 + joydown: Pin = board.D27 + joyleft: Pin = board.D22 + joyup: Pin = board.D23 + joyright: Pin = board.D24 + joyselect: Pin = board.D16 + + class Config: + arbitrary_types_allowed = True + + +class Eye(BaseModel): + neutral_x: Optional[float] = None + neutral_y: Optional[float] = None + +class Config(BaseModel): listener_type: str = "sphinx" speaker_type: str = "google" - pins: Pins = field(default_factory=Pins) + pins: Pins = Pins() + left_eye: Eye = Eye() + right_eye: Eye = Eye() + + def save(self, location: str): + with open(location, "w") as config_file: + config_file.write(json.dumps(self.dict(exclude={"pins"}), indent=2)) + class ConfigFactory: @classmethod def create(cls, location: str) -> Config: with open(location) as config_file: - file_data = yaml.load(config_file, Loader=yaml.FullLoader) + obj = {} + try: + obj = json.loads(config_file.read()) + except json.JSONDecodeError: + logger.warning("error parsing config") + + config = Config.parse_obj(obj) + - return Config(**(file_data or {})) + return config diff --git a/yuri/servos.py b/yuri/servos.py index fc53522..bab89a0 100644 --- a/yuri/servos.py +++ b/yuri/servos.py @@ -1,6 +1,9 @@ import time import board import busio +import asyncio +import math +import random from typing import List from dataclasses import dataclass @@ -11,8 +14,17 @@ from adafruit_pca9685 import PCA9685 from yuri.config import Config +from yuri.input import Input +async def move(servo: Servo, target_angle: float, smoothing_factor: float = 0.80): + # Keep iterating until the target angle's reached + while not math.isclose(servo.angle, target_angle, rel_tol=0.02): + current_angle = servo.angle + smoothed_angle = (target_angle * smoothing_factor) + (current_angle * (1.0 - smoothing_factor)) + # Don't move onto the next smooth target until the current angle is achieved. + servo.angle = smoothed_angle + await asyncio.sleep(0.02) @dataclass class Eyes: @@ -25,15 +37,106 @@ class Eyes: right_y: Servo right_x: Servo - def open(self, wide: bool = False): - self.lower_lids.angle = 16 if wide else 13 - self.upper_lids.angle = 13 if wide else 10 + @property + def servos(self) -> List[Servo]: + return [ + self.upper_lids, + self.lower_lids, + self.left_y, + self.left_x, + self.right_y, + self.right_x, + ] + + def init(self, config: Config): + # Set everything to neutral + for servo in self.servos: + servo.angle = 0.5 * servo.actuation_range + + if config.left_eye.neutral_x is not None: + self.left_x.angle = config.left_eye.neutral_x + if config.left_eye.neutral_y is not None: + self.left_y.angle = config.left_eye.neutral_y + if config.right_eye.neutral_x is not None: + self.right_x.angle = config.right_eye.neutral_x + if config.right_eye.neutral_y is not None: + self.right_y.angle = config.right_eye.neutral_y + + def calibrate(self, inputs: Input, config: Config): + asyncio.run(self.open(True)) + for eye in ("left", "right"): + logger.info(f"calibrate {eye} eye") + y = getattr(self, f"{eye}_y") + x = getattr(self, f"{eye}_x") + incr = 3 + + while inputs.button.value: + logger.info(f"x:{x.angle:.2f} | y:{y.angle:.2f}") + if not inputs.joyup.value: + y.angle = min(y.angle + incr, y.actuation_range) + if not inputs.joydown.value: + y.angle = max(y.angle - incr, 0) + if not inputs.joyleft.value: + x.angle = max(x.angle - incr, 0) + if not inputs.joyright.value: + x.angle = min(x.angle + incr, x.actuation_range) + + time.sleep(0.3) + config_eye = getattr(config, f"{eye}_eye") + config_eye.neutral_x = x.angle + config_eye.neutral_y = y.angle + logger.info(f"Done calibrating {eye} eye") + + time.sleep(1.5) + + + async def open(self, wide: bool = False): + await asyncio.gather( + move(self.lower_lids, 15 if wide else 13), + move(self.upper_lids, 12 if wide else 10), + ) + + async def close(self): + await asyncio.gather( + move(self.lower_lids, 10.0), + move(self.upper_lids, 7.0), + ) + + + async def blink_loop(self): + + while True: + await self.close() + await self.open(wide=True) + await self.open() + await asyncio.sleep(random.random() * 3.0) - def close(self): - self.lower_lids.angle = 10 - self.upper_lids.angle = 7 + async def look(self): + """ + UP + self.right_y = 0 + self.left_y = 180 + + DOWN + self.right_y = 180 + self.left_y = 0 + + RIGHT + self.right_x = 0 + self.left_x = 0 + + LEFT + self.right_x = 180 + self.left_x = 180 + + """ + + + await asyncio.gather( + move(self.lower_lids, 10.0), + move(self.upper_lids, 7.0), + ) -FAST = 0.3 class Servos: @@ -45,13 +148,14 @@ def __init__(self, config: Config): self.eyes = Eyes( lower_lids=Servo(self.pca.channels[0], actuation_range=30), - right_y=Servo(self.pca.channels[1], actuation_range=30), - right_x=Servo(self.pca.channels[2], actuation_range=30), + right_y=Servo(self.pca.channels[1], actuation_range=180), + right_x=Servo(self.pca.channels[2], actuation_range=180), upper_lids=Servo(self.pca.channels[4], actuation_range=30), - left_y=Servo(self.pca.channels[5], actuation_range=30), - left_x=Servo(self.pca.channels[6], actuation_range=30), + left_y=Servo(self.pca.channels[5], actuation_range=180), + left_x=Servo(self.pca.channels[6], actuation_range=180), ) + self.eyes.init(self.config) def rotate(self): logger.info("triggering servos") @@ -64,9 +168,3 @@ def rotate(self): logger.info("done") - def smile(self): - self.eye_l.throttle = FAST - self.eye_r.throttle = FAST - time.sleep(.001) - self.eye_l.throttle = 0 - self.eye_r.throttle = 0 diff --git a/yuri/speaker.py b/yuri/speaker.py index eb01050..5e63cb9 100644 --- a/yuri/speaker.py +++ b/yuri/speaker.py @@ -16,12 +16,12 @@ def __init__(self, config: Config): self.config = config @abstractmethod - def say(self, message: str): + async def say(self, message: str): raise NotImplementedError() class GoogleSpeaker(Speaker): - def say(self, message: str): + async def say(self, message: str): logger.info("say.start", message=message) mp3_fp = BytesIO() @@ -42,7 +42,7 @@ def __init__(self, config: Config): self.engine.setProperty("voice", self.engine.getProperty("voices")[15].id) self.engine.setProperty("rate", 160) - def say(self, message: str): + async def say(self, message: str): logger.info("say.start", message=message) self.engine.say(message) self.engine.runAndWait()