Compare commits
12 Commits
master
...
klardotsh/
Author | SHA1 | Date | |
---|---|---|---|
|
0d168a06f4 | ||
|
b202dc77d1 | ||
|
9fc431e0a7 | ||
|
36ea0eec4e | ||
|
908da846fe | ||
|
a622239b4a | ||
|
8cb2a8b485 | ||
|
75f9d10cc7 | ||
|
2c69d0e197 | ||
|
95dcc57e76 | ||
|
317d14fdac | ||
|
41a8048775 |
4
Pipfile
4
Pipfile
@ -20,3 +20,7 @@ s3cmd = "*"
|
||||
black = "==21.6b0"
|
||||
flake8-quotes = "*"
|
||||
flake8-black = "*"
|
||||
circuitpython-stubs = "==7.0.0a6.dev195"
|
||||
pyright = "*"
|
||||
typing = "*"
|
||||
mypy = "*"
|
||||
|
321
Pipfile.lock
generated
321
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "0a04ec24d4aef6828e4f5eefa0a7d2c312f21f2b2f18c42c7004cdbe0c02bd53"
|
||||
"sha256": "cee0eeba8c8dad66dccffe0935656829132f7ca928569e3aa957f278e6e92da6"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@ -45,6 +45,13 @@
|
||||
"index": "pypi",
|
||||
"version": "==21.6b0"
|
||||
},
|
||||
"circuitpython-stubs": {
|
||||
"hashes": [
|
||||
"sha256:5963ef6b41b03e97049d48142cb23778f3e4ca841620296d7e13b00025522569"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==7.0.0a6.dev195"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a",
|
||||
@ -71,11 +78,11 @@
|
||||
},
|
||||
"flake8-black": {
|
||||
"hashes": [
|
||||
"sha256:941514149cb8b489cb17a4bb1cf18d84375db3b34381bb018de83509437931a0",
|
||||
"sha256:f26651bc10db786c03f4093414f7c9ea982ed8a244cec323c984feeffdf4c118"
|
||||
"sha256:c199844bc1b559d91195ebe8620216f21ed67f2cc1ff6884294c91a0d2492684",
|
||||
"sha256:cc080ba5b3773b69ba102b6617a00cc4ecbad8914109690cfda4d565ea435d96"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.2.1"
|
||||
"version": "==0.2.3"
|
||||
},
|
||||
"flake8-commas": {
|
||||
"hashes": [
|
||||
@ -87,11 +94,11 @@
|
||||
},
|
||||
"flake8-comprehensions": {
|
||||
"hashes": [
|
||||
"sha256:b07aef3277623db32310aa241a1cec67212b53c1d18e767d7e26d4d83aa05bf7",
|
||||
"sha256:f24be9032587127f7a5bc6d066bf755b6e66834f694383adb8a673e229c1f559"
|
||||
"sha256:4888de89248b7f7535159189ff693c77f8354f6d37a02619fa28c9921a913aa0",
|
||||
"sha256:e9a010b99aa90c05790d45281ad9953df44a4a08a1a8f6cd41f98b4fc6a268a0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.5.0"
|
||||
"version": "==3.6.1"
|
||||
},
|
||||
"flake8-isort": {
|
||||
"hashes": [
|
||||
@ -103,65 +110,66 @@
|
||||
},
|
||||
"flake8-quotes": {
|
||||
"hashes": [
|
||||
"sha256:3f1116e985ef437c130431ac92f9b3155f8f652fda7405ac22ffdfd7a9d1055e"
|
||||
"sha256:f1dd87830ed77ff2ce47fc0ee0fd87ae20e8f045355354ffbf4dcaa18d528217"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.2.0"
|
||||
"version": "==3.3.0"
|
||||
},
|
||||
"greenlet": {
|
||||
"hashes": [
|
||||
"sha256:03f28a5ea20201e70ab70518d151116ce939b412961c33827519ce620957d44c",
|
||||
"sha256:06d7ac89e6094a0a8f8dc46aa61898e9e1aec79b0f8b47b2400dd51a44dbc832",
|
||||
"sha256:06ecb43b04480e6bafc45cb1b4b67c785e183ce12c079473359e04a709333b08",
|
||||
"sha256:096cb0217d1505826ba3d723e8981096f2622cde1eb91af9ed89a17c10aa1f3e",
|
||||
"sha256:0c557c809eeee215b87e8a7cbfb2d783fb5598a78342c29ade561440abae7d22",
|
||||
"sha256:0de64d419b1cb1bfd4ea544bedea4b535ef3ae1e150b0f2609da14bbf48a4a5f",
|
||||
"sha256:14927b15c953f8f2d2a8dffa224aa78d7759ef95284d4c39e1745cf36e8cdd2c",
|
||||
"sha256:16183fa53bc1a037c38d75fdc59d6208181fa28024a12a7f64bb0884434c91ea",
|
||||
"sha256:206295d270f702bc27dbdbd7651e8ebe42d319139e0d90217b2074309a200da8",
|
||||
"sha256:22002259e5b7828b05600a762579fa2f8b33373ad95a0ee57b4d6109d0e589ad",
|
||||
"sha256:2325123ff3a8ecc10ca76f062445efef13b6cf5a23389e2df3c02a4a527b89bc",
|
||||
"sha256:258f9612aba0d06785143ee1cbf2d7361801c95489c0bd10c69d163ec5254a16",
|
||||
"sha256:3096286a6072553b5dbd5efbefc22297e9d06a05ac14ba017233fedaed7584a8",
|
||||
"sha256:3d13da093d44dee7535b91049e44dd2b5540c2a0e15df168404d3dd2626e0ec5",
|
||||
"sha256:408071b64e52192869129a205e5b463abda36eff0cebb19d6e63369440e4dc99",
|
||||
"sha256:598bcfd841e0b1d88e32e6a5ea48348a2c726461b05ff057c1b8692be9443c6e",
|
||||
"sha256:5d928e2e3c3906e0a29b43dc26d9b3d6e36921eee276786c4e7ad9ff5665c78a",
|
||||
"sha256:5f75e7f237428755d00e7460239a2482fa7e3970db56c8935bd60da3f0733e56",
|
||||
"sha256:60848099b76467ef09b62b0f4512e7e6f0a2c977357a036de602b653667f5f4c",
|
||||
"sha256:6b1d08f2e7f2048d77343279c4d4faa7aef168b3e36039cba1917fffb781a8ed",
|
||||
"sha256:70bd1bb271e9429e2793902dfd194b653221904a07cbf207c3139e2672d17959",
|
||||
"sha256:76ed710b4e953fc31c663b079d317c18f40235ba2e3d55f70ff80794f7b57922",
|
||||
"sha256:7920e3eccd26b7f4c661b746002f5ec5f0928076bd738d38d894bb359ce51927",
|
||||
"sha256:7db68f15486d412b8e2cfcd584bf3b3a000911d25779d081cbbae76d71bd1a7e",
|
||||
"sha256:8833e27949ea32d27f7e96930fa29404dd4f2feb13cce483daf52e8842ec246a",
|
||||
"sha256:944fbdd540712d5377a8795c840a97ff71e7f3221d3fddc98769a15a87b36131",
|
||||
"sha256:9a6b035aa2c5fcf3dbbf0e3a8a5bc75286fc2d4e6f9cfa738788b433ec894919",
|
||||
"sha256:9bdcff4b9051fb1aa4bba4fceff6a5f770c6be436408efd99b76fc827f2a9319",
|
||||
"sha256:a9017ff5fc2522e45562882ff481128631bf35da444775bc2776ac5c61d8bcae",
|
||||
"sha256:aa4230234d02e6f32f189fd40b59d5a968fe77e80f59c9c933384fe8ba535535",
|
||||
"sha256:ad80bb338cf9f8129c049837a42a43451fc7c8b57ad56f8e6d32e7697b115505",
|
||||
"sha256:adb94a28225005890d4cf73648b5131e885c7b4b17bc762779f061844aabcc11",
|
||||
"sha256:b3090631fecdf7e983d183d0fad7ea72cfb12fa9212461a9b708ff7907ffff47",
|
||||
"sha256:b33b51ab057f8a20b497ffafdb1e79256db0c03ef4f5e3d52e7497200e11f821",
|
||||
"sha256:b97c9a144bbeec7039cca44df117efcbeed7209543f5695201cacf05ba3b5857",
|
||||
"sha256:be13a18cec649ebaab835dff269e914679ef329204704869f2f167b2c163a9da",
|
||||
"sha256:be9768e56f92d1d7cd94185bab5856f3c5589a50d221c166cc2ad5eb134bd1dc",
|
||||
"sha256:c1580087ab493c6b43e66f2bdd165d9e3c1e86ef83f6c2c44a29f2869d2c5bd5",
|
||||
"sha256:c35872b2916ab5a240d52a94314c963476c989814ba9b519bc842e5b61b464bb",
|
||||
"sha256:c70c7dd733a4c56838d1f1781e769081a25fade879510c5b5f0df76956abfa05",
|
||||
"sha256:c767458511a59f6f597bfb0032a1c82a52c29ae228c2c0a6865cfeaeaac4c5f5",
|
||||
"sha256:c87df8ae3f01ffb4483c796fe1b15232ce2b219f0b18126948616224d3f658ee",
|
||||
"sha256:ca1c4a569232c063615f9e70ff9a1e2fee8c66a6fb5caf0f5e8b21a396deec3e",
|
||||
"sha256:cc407b68e0a874e7ece60f6639df46309376882152345508be94da608cc0b831",
|
||||
"sha256:da862b8f7de577bc421323714f63276acb2f759ab8c5e33335509f0b89e06b8f",
|
||||
"sha256:dfe7eac0d253915116ed0cd160a15a88981a1d194c1ef151e862a5c7d2f853d3",
|
||||
"sha256:ed1377feed808c9c1139bdb6a61bcbf030c236dd288d6fca71ac26906ab03ba6",
|
||||
"sha256:f42ad188466d946f1b3afc0a9e1a266ac8926461ee0786c06baac6bd71f8a6f3",
|
||||
"sha256:f92731609d6625e1cc26ff5757db4d32b6b810d2a3363b0ff94ff573e5901f6f"
|
||||
"sha256:04e1849c88aa56584d4a0a6e36af5ec7cc37993fdc1fda72b56aa1394a92ded3",
|
||||
"sha256:05e72db813c28906cdc59bd0da7c325d9b82aa0b0543014059c34c8c4ad20e16",
|
||||
"sha256:07e6d88242e09b399682b39f8dfa1e7e6eca66b305de1ff74ed9eb1a7d8e539c",
|
||||
"sha256:090126004c8ab9cd0787e2acf63d79e80ab41a18f57d6448225bbfcba475034f",
|
||||
"sha256:1796f2c283faab2b71c67e9b9aefb3f201fdfbee5cb55001f5ffce9125f63a45",
|
||||
"sha256:2f89d74b4f423e756a018832cd7a0a571e0a31b9ca59323b77ce5f15a437629b",
|
||||
"sha256:34e6675167a238bede724ee60fe0550709e95adaff6a36bcc97006c365290384",
|
||||
"sha256:3e594015a2349ec6dcceda9aca29da8dc89e85b56825b7d1f138a3f6bb79dd4c",
|
||||
"sha256:3f8fc59bc5d64fa41f58b0029794f474223693fd00016b29f4e176b3ee2cfd9f",
|
||||
"sha256:3fc6a447735749d651d8919da49aab03c434a300e9f0af1c886d560405840fd1",
|
||||
"sha256:40abb7fec4f6294225d2b5464bb6d9552050ded14a7516588d6f010e7e366dcc",
|
||||
"sha256:44556302c0ab376e37939fd0058e1f0db2e769580d340fb03b01678d1ff25f68",
|
||||
"sha256:476ba9435afaead4382fbab8f1882f75e3fb2285c35c9285abb3dd30237f9142",
|
||||
"sha256:4870b018ca685ff573edd56b93f00a122f279640732bb52ce3a62b73ee5c4a92",
|
||||
"sha256:4adaf53ace289ced90797d92d767d37e7cdc29f13bd3830c3f0a561277a4ae83",
|
||||
"sha256:4eae94de9924bbb4d24960185363e614b1b62ff797c23dc3c8a7c75bbb8d187e",
|
||||
"sha256:5317701c7ce167205c0569c10abc4bd01c7f4cf93f642c39f2ce975fa9b78a3c",
|
||||
"sha256:5c3b735ccf8fc8048664ee415f8af5a3a018cc92010a0d7195395059b4b39b7d",
|
||||
"sha256:5cde7ee190196cbdc078511f4df0be367af85636b84d8be32230f4871b960687",
|
||||
"sha256:655ab836324a473d4cd8cf231a2d6f283ed71ed77037679da554e38e606a7117",
|
||||
"sha256:6ce9d0784c3c79f3e5c5c9c9517bbb6c7e8aa12372a5ea95197b8a99402aa0e6",
|
||||
"sha256:6e0696525500bc8aa12eae654095d2260db4dc95d5c35af2b486eae1bf914ccd",
|
||||
"sha256:75ff270fd05125dce3303e9216ccddc541a9e072d4fc764a9276d44dee87242b",
|
||||
"sha256:8039f5fe8030c43cd1732d9a234fdcbf4916fcc32e21745ca62e75023e4d4649",
|
||||
"sha256:84488516639c3c5e5c0e52f311fff94ebc45b56788c2a3bfe9cf8e75670f4de3",
|
||||
"sha256:84782c80a433d87530ae3f4b9ed58d4a57317d9918dfcc6a59115fa2d8731f2c",
|
||||
"sha256:8ddb38fb6ad96c2ef7468ff73ba5c6876b63b664eebb2c919c224261ae5e8378",
|
||||
"sha256:98b491976ed656be9445b79bc57ed21decf08a01aaaf5fdabf07c98c108111f6",
|
||||
"sha256:990e0f5e64bcbc6bdbd03774ecb72496224d13b664aa03afd1f9b171a3269272",
|
||||
"sha256:9b02e6039eafd75e029d8c58b7b1f3e450ca563ef1fe21c7e3e40b9936c8d03e",
|
||||
"sha256:a11b6199a0b9dc868990456a2667167d0ba096c5224f6258e452bfbe5a9742c5",
|
||||
"sha256:a414f8e14aa7bacfe1578f17c11d977e637d25383b6210587c29210af995ef04",
|
||||
"sha256:a91ee268f059583176c2c8b012a9fce7e49ca6b333a12bbc2dd01fc1a9783885",
|
||||
"sha256:ac991947ca6533ada4ce7095f0e28fe25d5b2f3266ad5b983ed4201e61596acf",
|
||||
"sha256:b050dbb96216db273b56f0e5960959c2b4cb679fe1e58a0c3906fa0a60c00662",
|
||||
"sha256:b97a807437b81f90f85022a9dcfd527deea38368a3979ccb49d93c9198b2c722",
|
||||
"sha256:bad269e442f1b7ffa3fa8820b3c3aa66f02a9f9455b5ba2db5a6f9eea96f56de",
|
||||
"sha256:bf3725d79b1ceb19e83fb1aed44095518c0fcff88fba06a76c0891cfd1f36837",
|
||||
"sha256:c0f22774cd8294078bdf7392ac73cf00bfa1e5e0ed644bd064fdabc5f2a2f481",
|
||||
"sha256:c1862f9f1031b1dee3ff00f1027fcd098ffc82120f43041fe67804b464bbd8a7",
|
||||
"sha256:c8d4ed48eed7414ccb2aaaecbc733ed2a84c299714eae3f0f48db085342d5629",
|
||||
"sha256:cf31e894dabb077a35bbe6963285d4515a387ff657bd25b0530c7168e48f167f",
|
||||
"sha256:d15cb6f8706678dc47fb4e4f8b339937b04eda48a0af1cca95f180db552e7663",
|
||||
"sha256:dfcb5a4056e161307d103bc013478892cfd919f1262c2bb8703220adcb986362",
|
||||
"sha256:e02780da03f84a671bb4205c5968c120f18df081236d7b5462b380fd4f0b497b",
|
||||
"sha256:e2002a59453858c7f3404690ae80f10c924a39f45f6095f18a985a1234c37334",
|
||||
"sha256:e22a82d2b416d9227a500c6860cf13e74060cf10e7daf6695cbf4e6a94e0eee4",
|
||||
"sha256:e41f72f225192d5d4df81dad2974a8943b0f2d664a2a5cfccdf5a01506f5523c",
|
||||
"sha256:f253dad38605486a4590f9368ecbace95865fea0f2b66615d121ac91fd1a1563",
|
||||
"sha256:fddfb31aa2ac550b938d952bca8a87f1db0f8dc930ffa14ce05b5c08d27e7fd1"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==1.1.0"
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"ipdb": {
|
||||
"hashes": [
|
||||
@ -172,11 +180,11 @@
|
||||
},
|
||||
"ipython": {
|
||||
"hashes": [
|
||||
"sha256:9bc24a99f5d19721fb8a2d1408908e9c0520a17fff2233ffe82620847f17f1b6",
|
||||
"sha256:d513e93327cf8657d6467c81f1f894adc125334ffe0e4ddd1abbb1c78d828703"
|
||||
"sha256:0cff04bb042800129348701f7bd68a430a844e8fb193979c08f6c99f28bb735e",
|
||||
"sha256:892743b65c21ed72b806a3a602cca408520b3200b89d1924f4b3d2cdb3692362"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==7.24.1"
|
||||
"version": "==7.26.0"
|
||||
},
|
||||
"ipython-genutils": {
|
||||
"hashes": [
|
||||
@ -187,11 +195,11 @@
|
||||
},
|
||||
"isort": {
|
||||
"hashes": [
|
||||
"sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6",
|
||||
"sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"
|
||||
"sha256:9c2ea1e62d871267b78307fe511c0838ba0da28698c5732d54e2790bf3ba9899",
|
||||
"sha256:e17d6e2b81095c9db0a03a8025a957f334d6ea30b26f9ec70805411e5c7c81f2"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.8.0"
|
||||
"version": "==5.9.3"
|
||||
},
|
||||
"jedi": {
|
||||
"hashes": [
|
||||
@ -249,6 +257,35 @@
|
||||
],
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"mypy": {
|
||||
"hashes": [
|
||||
"sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9",
|
||||
"sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a",
|
||||
"sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9",
|
||||
"sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e",
|
||||
"sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2",
|
||||
"sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212",
|
||||
"sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b",
|
||||
"sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885",
|
||||
"sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150",
|
||||
"sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703",
|
||||
"sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072",
|
||||
"sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457",
|
||||
"sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e",
|
||||
"sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0",
|
||||
"sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb",
|
||||
"sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97",
|
||||
"sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8",
|
||||
"sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811",
|
||||
"sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6",
|
||||
"sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de",
|
||||
"sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504",
|
||||
"sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921",
|
||||
"sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.910"
|
||||
},
|
||||
"mypy-extensions": {
|
||||
"hashes": [
|
||||
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
|
||||
@ -263,6 +300,13 @@
|
||||
"index": "pypi",
|
||||
"version": "==0.3.1"
|
||||
},
|
||||
"nodeenv": {
|
||||
"hashes": [
|
||||
"sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b",
|
||||
"sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"
|
||||
],
|
||||
"version": "==1.6.0"
|
||||
},
|
||||
"parso": {
|
||||
"hashes": [
|
||||
"sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398",
|
||||
@ -273,10 +317,10 @@
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd",
|
||||
"sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"
|
||||
"sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a",
|
||||
"sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"
|
||||
],
|
||||
"version": "==0.8.1"
|
||||
"version": "==0.9.0"
|
||||
},
|
||||
"pexpect": {
|
||||
"hashes": [
|
||||
@ -295,11 +339,11 @@
|
||||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:08360ee3a3148bdb5163621709ee322ec34fc4375099afa4bbf751e9b7b7fa4f",
|
||||
"sha256:7089d8d2938043508aa9420ec18ce0922885304cddae87fb96eebca942299f88"
|
||||
"sha256:6076e46efae19b1e0ca1ec003ed37a933dc94b4d20f486235d436e64771dcd5c",
|
||||
"sha256:eb71d5a6b72ce6db177af4a7d4d7085b99756bf656d98ffcc4fecd36850eea6c"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.1'",
|
||||
"version": "==3.0.19"
|
||||
"markers": "python_full_version >= '3.6.2'",
|
||||
"version": "==3.0.20"
|
||||
},
|
||||
"ptyprocess": {
|
||||
"hashes": [
|
||||
@ -326,11 +370,11 @@
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f",
|
||||
"sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"
|
||||
"sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380",
|
||||
"sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==2.9.0"
|
||||
"version": "==2.10.0"
|
||||
},
|
||||
"pynvim": {
|
||||
"hashes": [
|
||||
@ -338,6 +382,14 @@
|
||||
],
|
||||
"version": "==0.4.3"
|
||||
},
|
||||
"pyright": {
|
||||
"hashes": [
|
||||
"sha256:dd8e18c54321340be44a708b6037c0b967486c32b3f492741fffdc205cb82f15",
|
||||
"sha256:e2668730cddf580e696d4a11946e740e2f5647df1eb45f7c55b7029376eac5a1"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.0.9"
|
||||
},
|
||||
"pyserial": {
|
||||
"hashes": [
|
||||
"sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb",
|
||||
@ -347,18 +399,19 @@
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
|
||||
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
|
||||
"sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
|
||||
"sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.8.1"
|
||||
"version": "==2.8.2"
|
||||
},
|
||||
"python-dotenv": {
|
||||
"hashes": [
|
||||
"sha256:dd8fe852847f4fbfadabf6183ddd4c824a9651f02d51714fa075c95561959c7d",
|
||||
"sha256:effaac3c1e58d89b3ccb4d04a40dc7ad6e0275fda25fd75ae9d323e2465e202d"
|
||||
"sha256:aae25dc1ebe97c420f50b81fb0e5c949659af713f31fdb63c749ca68748f34b1",
|
||||
"sha256:f521bc2ac9a8e03c736f62911605c5d83970021e3fa95b37d769e2bbbe9b6172"
|
||||
],
|
||||
"version": "==0.18.0"
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==0.19.0"
|
||||
},
|
||||
"python-magic": {
|
||||
"hashes": [
|
||||
@ -370,49 +423,49 @@
|
||||
},
|
||||
"regex": {
|
||||
"hashes": [
|
||||
"sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5",
|
||||
"sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79",
|
||||
"sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31",
|
||||
"sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500",
|
||||
"sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11",
|
||||
"sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14",
|
||||
"sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3",
|
||||
"sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439",
|
||||
"sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c",
|
||||
"sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82",
|
||||
"sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711",
|
||||
"sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093",
|
||||
"sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a",
|
||||
"sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb",
|
||||
"sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8",
|
||||
"sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17",
|
||||
"sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000",
|
||||
"sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d",
|
||||
"sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480",
|
||||
"sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc",
|
||||
"sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0",
|
||||
"sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9",
|
||||
"sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765",
|
||||
"sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e",
|
||||
"sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a",
|
||||
"sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07",
|
||||
"sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f",
|
||||
"sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac",
|
||||
"sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7",
|
||||
"sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed",
|
||||
"sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968",
|
||||
"sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7",
|
||||
"sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2",
|
||||
"sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4",
|
||||
"sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87",
|
||||
"sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8",
|
||||
"sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10",
|
||||
"sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29",
|
||||
"sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605",
|
||||
"sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6",
|
||||
"sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042"
|
||||
"sha256:0696eb934dee723e3292056a2c046ddb1e4dd3887685783a9f4af638e85dee76",
|
||||
"sha256:105122fa63da98d8456d5026bc6ac5a1399fd82fa6bad22c6ea641b1572c9142",
|
||||
"sha256:116c277774f84266044e889501fe79cfd293a8b4336b7a5e89b9f20f1e5a9f21",
|
||||
"sha256:12eaf0bbe568bd62e6cade7937e0bf01a2a4cef49a82f4fd204401e78409e158",
|
||||
"sha256:1401cfa4320691cbd91191ec678735c727dee674d0997b0902a5a38ad482faf5",
|
||||
"sha256:19acdb8831a4e3b03b23369db43178d8fee1f17b99c83af6cd907886f76bd9d4",
|
||||
"sha256:208851a2f8dd31e468f0b5aa6c94433975bd67a107a4e7da3bdda947c9f85e25",
|
||||
"sha256:24d68499a27b2d93831fde4a9b84ea5b19e0ab141425fbc9ab1e5b4dad179df7",
|
||||
"sha256:2778c6cb379d804e429cc8e627392909e60db5152b42c695c37ae5757aae50ae",
|
||||
"sha256:2a0a5e323cf86760784ce2b91d8ab5ea09d0865d6ef4da0151e03d15d097b24e",
|
||||
"sha256:2d9cbe0c755ab8b6f583169c0783f7278fc6b195e423b09c5a8da6f858025e96",
|
||||
"sha256:2de1429e4eeab799c168a4f6e6eecdf30fcaa389bba4039cc8a065d6b7aad647",
|
||||
"sha256:32753eda8d413ce4f208cfe01dd61171a78068a6f5d5f38ccd751e00585cdf1d",
|
||||
"sha256:3ee8ad16a35c45a5bab098e39020ecb6fec3b0e700a9d88983d35cbabcee79c8",
|
||||
"sha256:4f03fc0a25122cdcbf39136510d4ea7627f732206892db522adf510bc03b8c67",
|
||||
"sha256:4f3e36086d6631ceaf468503f96a3be0d247caef0660c9452fb1b0c055783851",
|
||||
"sha256:503c1ba0920a46a1844363725215ef44d59fcac2bd2c03ae3c59aa9d08d29bd6",
|
||||
"sha256:507861cf3d97a86fbe26ea6cc04660ae028b9e4080b8290e28b99547b4e15d89",
|
||||
"sha256:56ae6e3cf0506ec0c40b466e31f41ee7a7149a2b505ae0ee50edd9043b423d27",
|
||||
"sha256:6530b7b9505123cdea40a2301225183ca65f389bc6129f0c225b9b41680268d8",
|
||||
"sha256:6729914dd73483cd1c8aaace3ac082436fc98b0072743ac136eaea0b3811d42f",
|
||||
"sha256:7406dd2e44c7cfb4680c0a45a03264381802c67890cf506c147288f04c67177d",
|
||||
"sha256:7684016b73938ca12d160d2907d141f06b7597bd17d854e32bb7588be01afa1d",
|
||||
"sha256:7db58ad61f3f6ea393aaf124d774ee0c58806320bc85c06dc9480f5c7219c250",
|
||||
"sha256:83946ca9278b304728b637bc8d8200ab1663a79de85e47724594917aeed0e892",
|
||||
"sha256:84057cfae5676f456b03970eb78b7e182fddc80c2daafd83465a3d6ca9ff8dbf",
|
||||
"sha256:862b6164e9a38b5c495be2c2854e75fd8af12c5be4c61dc9b42d255980d7e907",
|
||||
"sha256:8ddb4f9ce6bb388ecc97b4b3eb37e786f05d7d5815e8822e0d87a3dbd7100649",
|
||||
"sha256:92eb03f47427fea452ff6956d11f5d5a3f22a048c90a0f34fa223e6badab6c85",
|
||||
"sha256:a5f3bc727fea58f21d99c22e6d4fca652dc11dbc2a1e7cfc4838cd53b2e3691f",
|
||||
"sha256:a6180dbf5945b27e9420e1b58c3cacfc79ad5278bdad3ea35109f5680fbe16d1",
|
||||
"sha256:b158f673ae6a6523f13704f70aa7e4ce875f91e379bece4362c89db18db189d5",
|
||||
"sha256:cd45b4542134de63e7b9dd653e0a2d7d47ffed9615e3637c27ca5f6b78ea68bb",
|
||||
"sha256:d2404336fd16788ea757d4218a2580de60adb052d9888031e765320be8884309",
|
||||
"sha256:db888d4fb33a2fd54b57ac55d5015e51fa849f0d8592bd799b4e47f83bd04e00",
|
||||
"sha256:dde0ac721c7c5bfa5f9fc285e811274dec3c392f2c1225f7d07ca98a8187ca84",
|
||||
"sha256:de0d06ccbc06af5bf93bddec10f4f80275c5d74ea6d28b456931f3955f58bc8c",
|
||||
"sha256:e02dad60e3e8442eefd28095e99b2ac98f2b8667167493ac6a2f3aadb5d84a17",
|
||||
"sha256:e960fe211496333b2f7e36badf4c22a919d740386681f79139ee346b403d1ca1",
|
||||
"sha256:e9700c52749cb3e90c98efd72b730c97b7e4962992fca5fbcaf1363be8e3b849",
|
||||
"sha256:ee318974a1fdacba1701bc9e552e9015788d6345416364af6fa987424ff8df53"
|
||||
],
|
||||
"version": "==2021.4.4"
|
||||
"version": "==2021.8.27"
|
||||
},
|
||||
"s3cmd": {
|
||||
"hashes": [
|
||||
@ -432,10 +485,10 @@
|
||||
},
|
||||
"testfixtures": {
|
||||
"hashes": [
|
||||
"sha256:5ec3a0dd6f71cc4c304fbc024a10cc293d3e0b852c868014b9f233203e149bda",
|
||||
"sha256:9ed31e83f59619e2fa17df053b241e16e0608f4580f7b5a9333a0c9bdcc99137"
|
||||
"sha256:0a6422737f6d89b45cdef1e2df5576f52ad0f507956002ce1020daa9f44211d6",
|
||||
"sha256:486be7b01eb71326029811878a3317b7e7994324621c0ec633c8e24499d8d5b3"
|
||||
],
|
||||
"version": "==6.17.1"
|
||||
"version": "==6.18.1"
|
||||
},
|
||||
"toml": {
|
||||
"hashes": [
|
||||
@ -453,6 +506,22 @@
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==5.0.5"
|
||||
},
|
||||
"typing": {
|
||||
"hashes": [
|
||||
"sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9",
|
||||
"sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.7.4.3"
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497",
|
||||
"sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342",
|
||||
"sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"
|
||||
],
|
||||
"version": "==3.10.0.0"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784",
|
||||
|
@ -11,3 +11,17 @@ class UnicodeMode:
|
||||
LINUX = IBUS = const(1)
|
||||
MACOS = OSX = RALT = const(2)
|
||||
WINC = const(3)
|
||||
|
||||
|
||||
TYPING_PLATFORMS = [
|
||||
'linux',
|
||||
'linux2',
|
||||
'win32',
|
||||
'cygwin',
|
||||
'msys',
|
||||
'darwin',
|
||||
'freebsd7',
|
||||
'freebsd8',
|
||||
'freebsdN',
|
||||
'openbsd6',
|
||||
]
|
||||
|
@ -1,16 +1,21 @@
|
||||
from kmk.kmk_keyboard import KMKKeyboard
|
||||
|
||||
|
||||
class InvalidExtensionEnvironment(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Extension:
|
||||
_enabled = True
|
||||
_enabled = True # type: bool
|
||||
|
||||
def enable(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
self._enabled = True
|
||||
|
||||
self.on_runtime_enable(keyboard)
|
||||
|
||||
def disable(self, keyboard):
|
||||
# type (KMKKeyboard) -> None
|
||||
self._enabled = False
|
||||
|
||||
self.on_runtime_disable(keyboard)
|
||||
@ -18,34 +23,43 @@ class Extension:
|
||||
# The below methods should be implemented by subclasses
|
||||
|
||||
def on_runtime_enable(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
raise NotImplementedError
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
raise NotImplementedError
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
raise NotImplementedError
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
'''
|
||||
Return value will be injected as an extra matrix update
|
||||
'''
|
||||
raise NotImplementedError
|
||||
|
||||
def after_matrix_scan(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
'''
|
||||
Return value will be replace matrix update if supplied
|
||||
'''
|
||||
raise NotImplementedError
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
raise NotImplementedError
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
raise NotImplementedError
|
||||
|
||||
def on_powersave_enable(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
raise NotImplementedError
|
||||
|
||||
def on_powersave_disable(self, keyboard):
|
||||
# type: (KMKKeyboard) -> None
|
||||
raise NotImplementedError
|
||||
|
@ -1,6 +1,7 @@
|
||||
'''Adds international keys'''
|
||||
from kmk.extensions import Extension
|
||||
from kmk.keys import make_key
|
||||
from kmk.kmk_keyboard import KMKKeyboard
|
||||
|
||||
|
||||
class International(Extension):
|
||||
@ -32,28 +33,37 @@ class International(Extension):
|
||||
make_key(code=152, names=('LANG9',))
|
||||
|
||||
def on_runtime_enable(self, sandbox):
|
||||
# type: (KMKKeyboard) -> None
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, sandbox):
|
||||
# type: (KMKKeyboard) -> None
|
||||
return
|
||||
|
||||
def during_bootup(self, sandbox):
|
||||
# type: (KMKKeyboard) -> None
|
||||
return
|
||||
|
||||
def before_matrix_scan(self, sandbox):
|
||||
# type: (KMKKeyboard) -> None
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, sandbox):
|
||||
# type: (KMKKeyboard) -> None
|
||||
return
|
||||
|
||||
def before_hid_send(self, sandbox):
|
||||
# type: (KMKKeyboard) -> None
|
||||
return
|
||||
|
||||
def after_hid_send(self, sandbox):
|
||||
# type: (KMKKeyboard) -> None
|
||||
return
|
||||
|
||||
def on_powersave_enable(self, sandbox):
|
||||
# type: (KMKKeyboard) -> None
|
||||
return
|
||||
|
||||
def on_powersave_disable(self, sandbox):
|
||||
# type: (KMKKeyboard) -> None
|
||||
return
|
||||
|
@ -1,11 +1,29 @@
|
||||
import sys
|
||||
from time import sleep
|
||||
|
||||
from kmk.consts import TYPING_PLATFORMS
|
||||
|
||||
if sys.platform in TYPING_PLATFORMS:
|
||||
from typing import Any, Optional
|
||||
|
||||
from kmk.keys import Key, KeyAttrDict
|
||||
from kmk.kmk_keyboard import KMKKeyboard # Avoid cyclical imports
|
||||
|
||||
|
||||
def passthrough(key, keyboard, *args, **kwargs):
|
||||
return keyboard
|
||||
|
||||
|
||||
def default_pressed(key, keyboard, KC, coord_int=None, coord_raw=None, *args, **kwargs):
|
||||
def default_pressed(
|
||||
key, # type: Key
|
||||
keyboard, # type: KMKKeyboard
|
||||
KC, # type: KeyAttrDict
|
||||
coord_int=None, # type: Optional[int]
|
||||
coord_raw=None, # type: Optional[str]
|
||||
*args, # type: Any
|
||||
**kwargs, # type: Any
|
||||
):
|
||||
# type: (...) -> KMKKeyboard
|
||||
keyboard.hid_pending = True
|
||||
|
||||
keyboard.keys_pressed.add(key)
|
||||
@ -14,8 +32,15 @@ def default_pressed(key, keyboard, KC, coord_int=None, coord_raw=None, *args, **
|
||||
|
||||
|
||||
def default_released(
|
||||
key, keyboard, KC, coord_int=None, coord_raw=None, *args, **kwargs # NOQA
|
||||
key, # type: Key
|
||||
keyboard, # type: KMKKeyboard
|
||||
KC, # type: KeyAttrDict
|
||||
coord_int=None, # type: Optional[int]
|
||||
coord_raw=None, # type: Optional[str]
|
||||
*args, # type: Any
|
||||
**kwargs, # type: Any # NOQA
|
||||
):
|
||||
# type: (...) -> KMKKeyboard
|
||||
keyboard.hid_pending = True
|
||||
keyboard.keys_pressed.discard(key)
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
import sys
|
||||
|
||||
from kmk.consts import TYPING_PLATFORMS
|
||||
from kmk.types import (
|
||||
KeySeqSleepMeta,
|
||||
LayerKeyMeta,
|
||||
@ -6,12 +9,20 @@ from kmk.types import (
|
||||
UnicodeModeKeyMeta,
|
||||
)
|
||||
|
||||
if sys.platform in TYPING_PLATFORMS:
|
||||
from typing import List, Optional
|
||||
|
||||
# Avoid cyclical imports
|
||||
from kmk.keys import Key
|
||||
|
||||
|
||||
def key_seq_sleep_validator(ms):
|
||||
# type: (float) -> KeySeqSleepMeta
|
||||
return KeySeqSleepMeta(ms)
|
||||
|
||||
|
||||
def layer_key_validator(layer, kc=None):
|
||||
# type: (int, Optional[Key]) -> LayerKeyMeta
|
||||
'''
|
||||
Validates the syntax (but not semantics) of a layer key call. We won't
|
||||
have access to the keymap here, so we can't verify much of anything useful
|
||||
@ -22,7 +33,8 @@ def layer_key_validator(layer, kc=None):
|
||||
return LayerKeyMeta(layer=layer, kc=kc)
|
||||
|
||||
|
||||
def mod_tap_validator(kc, mods=None):
|
||||
def mod_tap_validator(kc, mods):
|
||||
# type: (Key, Optional[List[Key]]) -> ModTapKeyMeta
|
||||
'''
|
||||
Validates that mod tap keys are correctly used
|
||||
'''
|
||||
@ -30,8 +42,10 @@ def mod_tap_validator(kc, mods=None):
|
||||
|
||||
|
||||
def tap_dance_key_validator(*codes):
|
||||
# type: (*Key) -> TapDanceKeyMeta
|
||||
return TapDanceKeyMeta(codes)
|
||||
|
||||
|
||||
def unicode_mode_key_validator(mode):
|
||||
# type: (int) -> UnicodeModeKeyMeta
|
||||
return UnicodeModeKeyMeta(mode)
|
||||
|
@ -1,3 +1,8 @@
|
||||
from typing import NoReturn
|
||||
|
||||
from kmk.kmk_keyboard import KMKKeyboard
|
||||
|
||||
|
||||
class InvalidExtensionEnvironment(Exception):
|
||||
pass
|
||||
|
||||
@ -12,29 +17,29 @@ class Module:
|
||||
|
||||
# The below methods should be implemented by subclasses
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
def during_bootup(self, keyboard: KMKKeyboard) -> NoReturn:
|
||||
raise NotImplementedError
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
def before_matrix_scan(self, keyboard: KMKKeyboard) -> NoReturn:
|
||||
'''
|
||||
Return value will be injected as an extra matrix update
|
||||
'''
|
||||
raise NotImplementedError
|
||||
|
||||
def after_matrix_scan(self, keyboard):
|
||||
def after_matrix_scan(self, keyboard: KMKKeyboard) -> NoReturn:
|
||||
'''
|
||||
Return value will be replace matrix update if supplied
|
||||
'''
|
||||
raise NotImplementedError
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
def before_hid_send(self, keyboard: KMKKeyboard) -> NoReturn:
|
||||
raise NotImplementedError
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
def after_hid_send(self, keyboard: KMKKeyboard) -> NoReturn:
|
||||
raise NotImplementedError
|
||||
|
||||
def on_powersave_enable(self, keyboard):
|
||||
def on_powersave_enable(self, keyboard: KMKKeyboard) -> NoReturn:
|
||||
raise NotImplementedError
|
||||
|
||||
def on_powersave_disable(self, keyboard):
|
||||
def on_powersave_disable(self, keyboard: KMKKeyboard) -> NoReturn:
|
||||
raise NotImplementedError
|
||||
|
@ -1,66 +1,89 @@
|
||||
import digitalio
|
||||
from supervisor import ticks_ms
|
||||
|
||||
from typing import Any, ClassVar, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from kmk.keys import Key
|
||||
from kmk.kmk_keyboard import KMKKeyboard
|
||||
from kmk.kmktime import ticks_ms
|
||||
from kmk.modules import Module
|
||||
|
||||
EncoderMap = Tuple[
|
||||
List[Tuple[Key, Key, int]],
|
||||
List[Tuple[Key, Key, int]],
|
||||
List[Tuple[None, None, int]],
|
||||
]
|
||||
|
||||
|
||||
class EncoderPadState:
|
||||
OFF = False
|
||||
ON = True
|
||||
OFF: bool = False
|
||||
ON: bool = True
|
||||
|
||||
|
||||
class EndcoderDirection:
|
||||
Left = False
|
||||
Right = True
|
||||
Left: bool = False
|
||||
Right: bool = True
|
||||
|
||||
|
||||
class Encoder:
|
||||
def __init__(
|
||||
self,
|
||||
pad_a,
|
||||
pad_b,
|
||||
button_pin=None,
|
||||
):
|
||||
self.pad_a = self.PreparePin(pad_a) # board pin for enc pin a
|
||||
self.pad_a_state = False
|
||||
self.pad_b = self.PreparePin(pad_b) # board pin for enc pin b
|
||||
self.pad_b_state = False
|
||||
self.button_pin = self.PreparePin(button_pin) # board pin for enc btn
|
||||
pad_a: Any,
|
||||
pad_b: Any,
|
||||
button_pin: Optional[Any] = None,
|
||||
) -> None:
|
||||
self.pad_a: Union[digitalio.DigitalInOut, None] = self.PreparePin(
|
||||
pad_a
|
||||
) # board pin for enc pin a
|
||||
self.pad_a_state: bool = False
|
||||
self.pad_b: Union[digitalio.DigitalInOut, None] = self.PreparePin(
|
||||
pad_b
|
||||
) # board pin for enc pin b
|
||||
self.pad_b_state: bool = False
|
||||
self.button_pin: Union[digitalio.DigitalInOut, None] = self.PreparePin(
|
||||
button_pin
|
||||
) # board pin for enc btn
|
||||
self.button_state = None # state of pushbutton on encoder if enabled
|
||||
self.encoder_value = 0 # clarify what this value is
|
||||
self.encoder_state = (
|
||||
self.encoder_value: int = 0 # clarify what this value is
|
||||
self.encoder_state: Tuple[bool, bool] = (
|
||||
self.pad_a_state,
|
||||
self.pad_b_state,
|
||||
) # quaderature encoder state
|
||||
self.encoder_direction = None # arbitrary, tells direction of knob
|
||||
self.last_encoder_state = None # not used yet
|
||||
self.resolution = 2 # number of keys sent per position change
|
||||
self.revolution_count = 20 # position changes per revolution
|
||||
self.has_button = False # enable/disable button functionality
|
||||
self.encoder_data = None # 6tuple containing all encoder data
|
||||
self.position_change = None # revolution count, inc/dec as knob turns
|
||||
self.last_encoder_value = 0 # not used
|
||||
self.is_inverted = False # switch to invert knob direction
|
||||
self.vel_mode = False # enable the velocity output
|
||||
self.vel_ts = None # velocity timestamp
|
||||
self.last_vel_ts = 0 # last velocity timestamp
|
||||
self.encoder_speed = None # ms per position change(4 states)
|
||||
self.encoder_map = None
|
||||
self.eps = EncoderPadState()
|
||||
self.encoder_pad_lookup = {
|
||||
self.encoder_direction: Optional[
|
||||
bool
|
||||
] = None # arbitrary, tells direction of knob
|
||||
self.last_encoder_state: Optional[Tuple[bool, bool]] = None # not used yet
|
||||
self.resolution: int = 2 # number of keys sent per position change
|
||||
self.revolution_count: int = 20 # position changes per revolution
|
||||
self.has_button: bool = False # enable/disable button functionality
|
||||
self.encoder_data: Optional[Tuple] = None # 6tuple containing all encoder data
|
||||
self.position_change: Optional[
|
||||
int
|
||||
] = None # revolution count, inc/dec as knob turns
|
||||
self.last_encoder_value: int = 0 # not used
|
||||
self.is_inverted: bool = False # switch to invert knob direction
|
||||
self.vel_mode: bool = False # enable the velocity output
|
||||
self.vel_ts: Optional[float] = None # velocity timestamp
|
||||
self.last_vel_ts: float = 0 # last velocity timestamp
|
||||
self.encoder_speed: Optional[float] = None # ms per position change(4 states)
|
||||
self.encoder_map: Optional[EncoderMap] = None
|
||||
self.eps: EncoderPadState = EncoderPadState()
|
||||
self.encoder_pad_lookup: Dict[bool, bool] = {
|
||||
False: self.eps.OFF,
|
||||
True: self.eps.ON,
|
||||
}
|
||||
self.edr = EndcoderDirection() # lookup for current encoder direction
|
||||
self.encoder_dir_lookup = {
|
||||
self.edr: EndcoderDirection = (
|
||||
EndcoderDirection()
|
||||
) # lookup for current encoder direction
|
||||
self.encoder_dir_lookup: Dict[bool, bool] = {
|
||||
False: self.edr.Left,
|
||||
True: self.edr.Right,
|
||||
}
|
||||
|
||||
def __repr__(self, idx):
|
||||
def __repr__(self, idx: int) -> str:
|
||||
return 'ENCODER_{}({})'.format(idx, self._to_dict())
|
||||
|
||||
def _to_dict(self):
|
||||
def _to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
'Encoder_State': self.encoder_state,
|
||||
'Direction': self.encoder_direction,
|
||||
@ -71,7 +94,7 @@ class Encoder:
|
||||
}
|
||||
|
||||
# adapted for CircuitPython from raspi
|
||||
def PreparePin(self, num):
|
||||
def PreparePin(self, num: Union[Any, None]) -> Union[digitalio.DigitalInOut, None]:
|
||||
if num is not None:
|
||||
pad = digitalio.DigitalInOut(num)
|
||||
pad.direction = digitalio.Direction.INPUT
|
||||
@ -81,7 +104,7 @@ class Encoder:
|
||||
return None
|
||||
|
||||
# checks encoder pins, reports encoder data
|
||||
def report(self):
|
||||
def report(self) -> Union[int, None]:
|
||||
new_encoder_state = (
|
||||
self.encoder_pad_lookup[int(self.pad_a.value)],
|
||||
self.encoder_pad_lookup[int(self.pad_b.value)],
|
||||
@ -143,14 +166,14 @@ class Encoder:
|
||||
return None
|
||||
|
||||
# invert knob direction if encoder pins are soldered backwards
|
||||
def invert_rotation(self, new, old):
|
||||
def invert_rotation(self, new: int, old: int) -> int:
|
||||
if self.is_inverted:
|
||||
return -(new - old)
|
||||
else:
|
||||
return new - old
|
||||
|
||||
# returns knob velocity as milliseconds between position changes(detents)
|
||||
def vel_report(self):
|
||||
def vel_report(self) -> float:
|
||||
self.encoder_speed = self.vel_ts - self.last_vel_ts
|
||||
self.last_vel_ts = self.vel_ts
|
||||
return self.encoder_speed
|
||||
@ -158,50 +181,54 @@ class Encoder:
|
||||
|
||||
class EncoderHandler(Module):
|
||||
|
||||
encoders = []
|
||||
debug_enabled = False # not working as inttended, do not use for now
|
||||
encoders: ClassVar[List[Encoder]] = []
|
||||
debug_enabled: ClassVar[
|
||||
bool
|
||||
] = False # not working as inttended, do not use for now
|
||||
|
||||
def __init__(self, pad_a, pad_b, encoder_map):
|
||||
self.pad_a = pad_a
|
||||
self.pad_b = pad_b
|
||||
self.encoder_count = len(self.pad_a)
|
||||
self.encoder_map = encoder_map
|
||||
def __init__(
|
||||
self, pad_a: List[Any], pad_b: List[Any], encoder_map: EncoderMap
|
||||
) -> None:
|
||||
self.pad_a: List[Any] = pad_a
|
||||
self.pad_b: List[Any] = pad_b
|
||||
self.encoder_count: int = len(self.pad_a)
|
||||
self.encoder_map: EncoderMap = encoder_map
|
||||
self.make_encoders()
|
||||
|
||||
def on_runtime_enable(self, keyboard):
|
||||
def on_runtime_enable(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def on_runtime_disable(self, keyboard):
|
||||
def on_runtime_disable(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
def during_bootup(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
def before_matrix_scan(self, keyboard: KMKKeyboard) -> Union[KMKKeyboard, None]:
|
||||
'''
|
||||
Return value will be injected as an extra matrix update
|
||||
'''
|
||||
return self.get_reports(keyboard)
|
||||
|
||||
def after_matrix_scan(self, keyboard):
|
||||
def after_matrix_scan(self, keyboard: KMKKeyboard) -> None:
|
||||
'''
|
||||
Return value will be replace matrix update if supplied
|
||||
'''
|
||||
return
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
def before_hid_send(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
def after_hid_send(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def on_powersave_enable(self, keyboard):
|
||||
def on_powersave_enable(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def on_powersave_disable(self, keyboard):
|
||||
def on_powersave_disable(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def make_encoders(self):
|
||||
def make_encoders(self) -> None:
|
||||
for i in range(self.encoder_count):
|
||||
self.encoders.append(
|
||||
Encoder(
|
||||
@ -210,7 +237,9 @@ class EncoderHandler(Module):
|
||||
)
|
||||
)
|
||||
|
||||
def send_encoder_keys(self, keyboard, encoder_key, encoder_idx):
|
||||
def send_encoder_keys(
|
||||
self, keyboard: KMKKeyboard, encoder_key: int, encoder_idx: int
|
||||
) -> KMKKeyboard:
|
||||
# position in the encoder map tuple
|
||||
encoder_resolution = 2
|
||||
for _ in range(
|
||||
@ -221,7 +250,7 @@ class EncoderHandler(Module):
|
||||
)
|
||||
return keyboard
|
||||
|
||||
def get_reports(self, keyboard):
|
||||
def get_reports(self, keyboard: KMKKeyboard) -> Union[KMKKeyboard, None]:
|
||||
for idx in range(self.encoder_count):
|
||||
if self.debug_enabled: # not working as inttended, do not use for now
|
||||
print(self.encoders[idx].__repr__(idx))
|
||||
|
@ -4,21 +4,24 @@ from supervisor import ticks_ms
|
||||
|
||||
from time import sleep
|
||||
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from kmk.handlers.stock import passthrough as handler_passthrough
|
||||
from kmk.keys import make_key
|
||||
from kmk.keys import Key, make_key
|
||||
from kmk.kmk_keyboard import KMKKeyboard
|
||||
from kmk.kmktime import check_deadline
|
||||
from kmk.modules import Module
|
||||
|
||||
|
||||
class Power(Module):
|
||||
def __init__(self, powersave_pin=None):
|
||||
self.enable = False
|
||||
def __init__(self, powersave_pin: Optional[Any] = None) -> None:
|
||||
self.enable: bool = False
|
||||
self.powersave_pin = powersave_pin # Powersave pin board object
|
||||
self._powersave_start = ticks_ms()
|
||||
self._usb_last_scan = ticks_ms() - 5000
|
||||
self._psp = None # Powersave pin object
|
||||
self._i2c = 0
|
||||
self._loopcounter = 0
|
||||
self._powersave_start: float = ticks_ms()
|
||||
self._usb_last_scan: float = ticks_ms() - 5000
|
||||
self._psp: Optional[digitalio.DigitalInOut] = None # Powersave pin object
|
||||
self._i2c: int = 0
|
||||
self._loopcounter: int = 0
|
||||
|
||||
make_key(
|
||||
names=('PS_TOG',), on_press=self._ps_tog, on_release=handler_passthrough
|
||||
@ -30,10 +33,10 @@ class Power(Module):
|
||||
names=('PS_OFF',), on_press=self._ps_disable, on_release=handler_passthrough
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return f'Power({self._to_dict()})'
|
||||
|
||||
def _to_dict(self):
|
||||
def _to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
'enable': self.enable,
|
||||
'powersave_pin': self.powersave_pin,
|
||||
@ -42,24 +45,24 @@ class Power(Module):
|
||||
'_psp': self._psp,
|
||||
}
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
def during_bootup(self, keyboard: KMKKeyboard) -> None:
|
||||
self._i2c_scan()
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
def before_matrix_scan(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard):
|
||||
def after_matrix_scan(self, keyboard: KMKKeyboard) -> None:
|
||||
if keyboard.matrix_update or keyboard.secondary_matrix_update:
|
||||
self.psave_time_reset()
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
def before_hid_send(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
def after_hid_send(self, keyboard: KMKKeyboard) -> None:
|
||||
if self.enable:
|
||||
self.psleep()
|
||||
|
||||
def on_powersave_enable(self, keyboard):
|
||||
def on_powersave_enable(self, keyboard: KMKKeyboard) -> None:
|
||||
'''Gives 10 cycles to allow other extensions to clean up before powersave'''
|
||||
if self._loopcounter > 10:
|
||||
self.enable_powersave(keyboard)
|
||||
@ -68,11 +71,11 @@ class Power(Module):
|
||||
self._loopcounter += 1
|
||||
return
|
||||
|
||||
def on_powersave_disable(self, keyboard):
|
||||
def on_powersave_disable(self, keyboard: KMKKeyboard) -> None:
|
||||
self.disable_powersave(keyboard)
|
||||
return
|
||||
|
||||
def enable_powersave(self, keyboard):
|
||||
def enable_powersave(self, keyboard: KMKKeyboard) -> None:
|
||||
'''Enables power saving features'''
|
||||
if keyboard.i2c_deinit_count >= self._i2c and self.powersave_pin:
|
||||
# Allows power save to prevent RGB drain.
|
||||
@ -88,7 +91,7 @@ class Power(Module):
|
||||
keyboard._trigger_powersave_enable = False
|
||||
return
|
||||
|
||||
def disable_powersave(self, keyboard):
|
||||
def disable_powersave(self, keyboard: KMKKeyboard) -> None:
|
||||
'''Disables power saving features'''
|
||||
if self._psp:
|
||||
self._psp.value = False
|
||||
@ -99,7 +102,7 @@ class Power(Module):
|
||||
self.enable = False
|
||||
return
|
||||
|
||||
def psleep(self):
|
||||
def psleep(self) -> None:
|
||||
'''
|
||||
Sleeps longer and longer to save power the more time in between updates.
|
||||
'''
|
||||
@ -109,10 +112,10 @@ class Power(Module):
|
||||
sleep(180 / 1000)
|
||||
return
|
||||
|
||||
def psave_time_reset(self):
|
||||
def psave_time_reset(self) -> None:
|
||||
self._powersave_start = ticks_ms()
|
||||
|
||||
def _i2c_scan(self):
|
||||
def _i2c_scan(self) -> None:
|
||||
i2c = board.I2C()
|
||||
while not i2c.try_lock():
|
||||
pass
|
||||
@ -122,28 +125,46 @@ class Power(Module):
|
||||
i2c.unlock()
|
||||
return
|
||||
|
||||
def usb_rescan_timer(self):
|
||||
def usb_rescan_timer(self) -> bool:
|
||||
return bool(check_deadline(ticks_ms(), self._usb_last_scan) > 5000)
|
||||
|
||||
def usb_time_reset(self):
|
||||
def usb_time_reset(self) -> None:
|
||||
self._usb_last_scan = ticks_ms()
|
||||
return
|
||||
|
||||
def usb_scan(self):
|
||||
def usb_scan(self) -> bool:
|
||||
# TODO Add USB detection here. Currently lies that it's connected
|
||||
# https://github.com/adafruit/circuitpython/pull/3513
|
||||
return True
|
||||
|
||||
def _ps_tog(self, key, keyboard, *args, **kwargs):
|
||||
def _ps_tog(
|
||||
self,
|
||||
key: Key,
|
||||
keyboard: KMKKeyboard,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
if self.enable:
|
||||
keyboard._trigger_powersave_disable = True
|
||||
else:
|
||||
keyboard._trigger_powersave_enable = True
|
||||
|
||||
def _ps_enable(self, key, keyboard, *args, **kwargs):
|
||||
def _ps_enable(
|
||||
self,
|
||||
key: Key,
|
||||
keyboard: KMKKeyboard,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
if not self.enable:
|
||||
keyboard._trigger_powersave_enable = True
|
||||
|
||||
def _ps_disable(self, key, keyboard, *args, **kwargs):
|
||||
def _ps_disable(
|
||||
self,
|
||||
key: Key,
|
||||
keyboard: KMKKeyboard,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
if self.enable:
|
||||
keyboard._trigger_powersave_disable = True
|
||||
|
@ -4,22 +4,26 @@ from micropython import const
|
||||
from supervisor import ticks_ms
|
||||
|
||||
from storage import getmount
|
||||
from typing import Any, List, Optional, Type, Union
|
||||
|
||||
from kmk.kmk_keyboard import KMKKeyboard
|
||||
from kmk.kmktime import check_deadline
|
||||
from kmk.matrix import intify_coordinate
|
||||
from kmk.modules import Module
|
||||
|
||||
UartBuffer = List[Optional[Union[bytes, None]]]
|
||||
|
||||
|
||||
class SplitSide:
|
||||
LEFT = const(1)
|
||||
RIGHT = const(2)
|
||||
LEFT: int = const(1)
|
||||
RIGHT: int = const(2)
|
||||
|
||||
|
||||
class SplitType:
|
||||
UART = const(1)
|
||||
I2C = const(2) # unused
|
||||
ONEWIRE = const(3) # unused
|
||||
BLE = const(4)
|
||||
UART: int = const(1)
|
||||
I2C: int = const(2) # unused
|
||||
ONEWIRE: int = const(3) # unused
|
||||
BLE: int = const(4)
|
||||
|
||||
|
||||
class Split(Module):
|
||||
@ -27,56 +31,58 @@ class Split(Module):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
split_flip=True,
|
||||
split_side=None,
|
||||
split_type=SplitType.UART,
|
||||
split_target_left=True,
|
||||
uart_interval=20,
|
||||
data_pin=None,
|
||||
data_pin2=None,
|
||||
target_left=True,
|
||||
uart_flip=True,
|
||||
debug_enabled=False,
|
||||
):
|
||||
self._is_target = True
|
||||
self._uart_buffer = []
|
||||
self.split_flip = split_flip
|
||||
self.split_side = split_side
|
||||
self.split_type = split_type
|
||||
self.split_target_left = split_target_left
|
||||
self.split_offset = None
|
||||
self.data_pin = data_pin
|
||||
self.data_pin2 = data_pin2
|
||||
self.target_left = target_left
|
||||
self.uart_flip = uart_flip
|
||||
self._is_target = True
|
||||
self._uart = None
|
||||
self._uart_interval = uart_interval
|
||||
self._debug_enabled = debug_enabled
|
||||
split_flip: bool = True,
|
||||
split_side: Optional[int] = None,
|
||||
split_type: int = SplitType.UART,
|
||||
split_target_left: bool = True,
|
||||
uart_interval: int = 20,
|
||||
data_pin: Optional[Any] = None,
|
||||
data_pin2: Optional[Any] = None,
|
||||
target_left: bool = True,
|
||||
uart_flip: bool = True,
|
||||
debug_enabled: bool = False,
|
||||
) -> None:
|
||||
self._is_target: bool = True
|
||||
self._uart_buffer: UartBuffer = []
|
||||
self.split_flip: bool = split_flip
|
||||
self.split_side: Optional[int] = split_side
|
||||
self.split_type: int = split_type
|
||||
self.split_target_left: bool = split_target_left
|
||||
self.split_offset: Optional[int] = None
|
||||
self.data_pin: Optional[Any] = data_pin
|
||||
self.data_pin2: Optional[Any] = data_pin2
|
||||
self.target_left: bool = target_left
|
||||
self.uart_flip: bool = uart_flip
|
||||
self._is_target: bool = True
|
||||
self._uart: Optional[busio.UART] = None
|
||||
self._uart_interval: int = uart_interval
|
||||
self._debug_enabled: bool = debug_enabled
|
||||
if self.split_type == SplitType.BLE:
|
||||
try:
|
||||
from adafruit_ble import BLERadio
|
||||
from adafruit_ble import BLEConnection, BLERadio
|
||||
from adafruit_ble.advertising.standard import (
|
||||
ProvideServicesAdvertisement,
|
||||
)
|
||||
from adafruit_ble.services.nordic import UARTService
|
||||
|
||||
self.ProvideServicesAdvertisement = ProvideServicesAdvertisement
|
||||
self.UARTService = UARTService
|
||||
self.ProvideServicesAdvertisement: Type[
|
||||
ProvideServicesAdvertisement
|
||||
] = ProvideServicesAdvertisement
|
||||
self.UARTService: Type[UARTService] = UARTService
|
||||
except ImportError:
|
||||
print('BLE Import error')
|
||||
return # BLE isn't supported on this platform
|
||||
self._ble = BLERadio()
|
||||
self._ble_last_scan = ticks_ms() - 5000
|
||||
self._connection_count = 0
|
||||
self._uart_connection = None
|
||||
self._advertisment = None
|
||||
self._advertising = False
|
||||
self._psave_enable = False
|
||||
self._ble: BLERadio = BLERadio()
|
||||
self._ble_last_scan: float = ticks_ms() - 5000
|
||||
self._connection_count: int = 0
|
||||
self._uart_connection: Optional[BLEConnection] = None
|
||||
self._advertisment: Optional[ProvideServicesAdvertisement] = None
|
||||
self._advertising: bool = False
|
||||
self._psave_enable: bool = False
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
def during_bootup(self, keyboard: KMKKeyboard) -> None:
|
||||
# Set up name for target side detection and BLE advertisment
|
||||
name = str(getmount('/').label)
|
||||
name: str = str(getmount('/').label)
|
||||
if self.split_type == SplitType.BLE:
|
||||
self._ble.name = name
|
||||
else:
|
||||
@ -128,7 +134,7 @@ class Split(Module):
|
||||
for cidx in range(cols_to_calc):
|
||||
keyboard.coord_mapping.append(intify_coordinate(ridx, cidx))
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
def before_matrix_scan(self, keyboard: KMKKeyboard) -> None:
|
||||
if self.split_type == SplitType.BLE:
|
||||
self._check_all_connections()
|
||||
self._receive_ble(keyboard)
|
||||
@ -139,7 +145,7 @@ class Split(Module):
|
||||
pass # Protocol needs written
|
||||
return
|
||||
|
||||
def after_matrix_scan(self, keyboard):
|
||||
def after_matrix_scan(self, keyboard: KMKKeyboard) -> None:
|
||||
if keyboard.matrix_update:
|
||||
if self.split_type == SplitType.UART and self._is_target:
|
||||
pass # explicit pass just for dev sanity...
|
||||
@ -156,28 +162,28 @@ class Split(Module):
|
||||
|
||||
return
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
def before_hid_send(self, keyboard: KMKKeyboard) -> None:
|
||||
if not self._is_target:
|
||||
keyboard.hid_pending = False
|
||||
|
||||
return
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
def after_hid_send(self, keyboard: KMKKeyboard) -> None:
|
||||
return
|
||||
|
||||
def on_powersave_enable(self, keyboard):
|
||||
def on_powersave_enable(self, keyboard: KMKKeyboard) -> None:
|
||||
if self.split_type == SplitType.BLE:
|
||||
if self._uart_connection and not self._psave_enable:
|
||||
self._uart_connection.connection_interval = self._uart_interval
|
||||
self._psave_enable = True
|
||||
|
||||
def on_powersave_disable(self, keyboard):
|
||||
def on_powersave_disable(self, keyboard: KMKKeyboard) -> None:
|
||||
if self.split_type == SplitType.BLE:
|
||||
if self._uart_connection and self._psave_enable:
|
||||
self._uart_connection.connection_interval = 11.25
|
||||
self._psave_enable = False
|
||||
|
||||
def _check_all_connections(self):
|
||||
def _check_all_connections(self) -> None:
|
||||
'''Validates the correct number of BLE connections'''
|
||||
self._connection_count = len(self._ble.connections)
|
||||
if self._is_target and self._connection_count < 2:
|
||||
@ -185,7 +191,7 @@ class Split(Module):
|
||||
elif not self._is_target and self._connection_count < 1:
|
||||
self._initiator_scan()
|
||||
|
||||
def _initiator_scan(self):
|
||||
def _initiator_scan(self) -> None:
|
||||
'''Scans for target device'''
|
||||
self._uart = None
|
||||
self._uart_connection = None
|
||||
@ -218,7 +224,7 @@ class Split(Module):
|
||||
break
|
||||
self._ble.stop_scan()
|
||||
|
||||
def _target_advertise(self):
|
||||
def _target_advertise(self) -> None:
|
||||
'''Advertises the target for the initiator to find'''
|
||||
self._ble.stop_advertising()
|
||||
if self._debug_enabled:
|
||||
@ -240,15 +246,15 @@ class Split(Module):
|
||||
break
|
||||
self._ble.stop_advertising()
|
||||
|
||||
def ble_rescan_timer(self):
|
||||
def ble_rescan_timer(self) -> bool:
|
||||
'''If true, the rescan timer is up'''
|
||||
return bool(check_deadline(ticks_ms(), self._ble_last_scan) > 5000)
|
||||
|
||||
def ble_time_reset(self):
|
||||
def ble_time_reset(self) -> None:
|
||||
'''Resets the rescan timer'''
|
||||
self._ble_last_scan = ticks_ms()
|
||||
|
||||
def _send_ble(self, update):
|
||||
def _send_ble(self, update: List) -> None:
|
||||
if self._uart:
|
||||
try:
|
||||
if not self._is_target:
|
||||
@ -266,7 +272,7 @@ class Split(Module):
|
||||
self._uart_connection = None
|
||||
self._uart = None
|
||||
|
||||
def _receive_ble(self, keyboard):
|
||||
def _receive_ble(self, keyboard: KMKKeyboard) -> None:
|
||||
if self._uart is not None and self._uart.in_waiting > 0 or self._uart_buffer:
|
||||
while self._uart.in_waiting >= 3:
|
||||
self._uart_buffer.append(self._uart.read(3))
|
||||
@ -274,7 +280,7 @@ class Split(Module):
|
||||
keyboard.secondary_matrix_update = bytearray(self._uart_buffer.pop(0))
|
||||
return
|
||||
|
||||
def _send_uart(self, update):
|
||||
def _send_uart(self, update: List) -> None:
|
||||
# Change offsets depending on where the data is going to match the correct
|
||||
# matrix location of the receiever
|
||||
if self._is_target:
|
||||
@ -291,7 +297,7 @@ class Split(Module):
|
||||
if self._uart is not None:
|
||||
self._uart.write(update)
|
||||
|
||||
def _receive_uart(self, keyboard):
|
||||
def _receive_uart(self, keyboard: KMKKeyboard) -> None:
|
||||
if self._uart is not None and self._uart.in_waiting > 0 or self._uart_buffer:
|
||||
if self._uart.in_waiting >= 60:
|
||||
# This is a dirty hack to prevent crashes in unrealistic cases
|
||||
|
34
kmk/types.py
34
kmk/types.py
@ -1,3 +1,14 @@
|
||||
import sys
|
||||
|
||||
from kmk.consts import TYPING_PLATFORMS
|
||||
|
||||
if sys.platform in TYPING_PLATFORMS:
|
||||
from typing import List, Optional, Tuple, Union
|
||||
|
||||
# Avoid cyclical imports
|
||||
from kmk.keys import ConsumerKey, Key, ModifierKey
|
||||
|
||||
|
||||
class AttrDict(dict):
|
||||
'''
|
||||
Primitive support for accessing dictionary entries in dot notation.
|
||||
@ -8,36 +19,43 @@ class AttrDict(dict):
|
||||
'''
|
||||
|
||||
def __getattr__(self, key):
|
||||
# type: (str) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
|
||||
return self[key]
|
||||
|
||||
|
||||
class LayerKeyMeta:
|
||||
def __init__(self, layer, kc=None):
|
||||
self.layer = layer
|
||||
self.kc = kc
|
||||
# type: (int, Optional[Key]) -> None
|
||||
self.layer = layer # type: int
|
||||
self.kc = kc # type: Optional[Key]
|
||||
|
||||
|
||||
class ModTapKeyMeta:
|
||||
def __init__(self, kc=None, mods=None):
|
||||
self.mods = mods
|
||||
self.kc = kc
|
||||
# type: (Optional[Key], Optional[List[Key]]) -> None
|
||||
self.mods = mods # type: Optional[List[Key]]
|
||||
self.kc = kc # type: Optional[Key]
|
||||
|
||||
|
||||
class KeySequenceMeta:
|
||||
def __init__(self, seq):
|
||||
self.seq = seq
|
||||
# type: (List[Key]) -> None
|
||||
self.seq = seq # type: List[Key]
|
||||
|
||||
|
||||
class KeySeqSleepMeta:
|
||||
def __init__(self, ms):
|
||||
self.ms = ms
|
||||
# type: (float) -> None
|
||||
self.ms = ms # type: float
|
||||
|
||||
|
||||
class UnicodeModeKeyMeta:
|
||||
def __init__(self, mode):
|
||||
self.mode = mode
|
||||
# type: (int) -> None
|
||||
self.mode = mode # type: int
|
||||
|
||||
|
||||
class TapDanceKeyMeta:
|
||||
def __init__(self, codes):
|
||||
self.codes = codes
|
||||
# type: (Tuple[Key, ...]) -> None
|
||||
self.codes = codes # type: Tuple[Key, ...]
|
||||
|
@ -22,3 +22,27 @@ exclude = '''
|
||||
| mnt
|
||||
)/
|
||||
'''
|
||||
|
||||
[tool.pyright]
|
||||
strict = ["kmk"]
|
||||
typeCheckingMode = "strict"
|
||||
include = ["kmk"]
|
||||
exclude = [
|
||||
"hardware",
|
||||
".venv",
|
||||
"user_keymaps",
|
||||
"boards",
|
||||
".git"
|
||||
]
|
||||
venvPath = ".venv"
|
||||
# stops constant reporting of missing board module etc.
|
||||
reportMissingModuleSource = false
|
||||
# reports missing typestubs allowing for a code action to
|
||||
# create new library typestubs
|
||||
reportMissingTypeStubs = true
|
||||
pythonVersion = "3.6"
|
||||
|
||||
[tool.mypy]
|
||||
exclude = "boards/|user_keymaps/"
|
||||
ignore_missing_imports = true
|
||||
python_version = "3.6"
|
||||
|
208
typings/adafruit_ble/__init__.pyi
Normal file
208
typings/adafruit_ble/__init__.pyi
Normal file
@ -0,0 +1,208 @@
|
||||
"""
|
||||
This type stub file was generated by pyright.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import _bleio
|
||||
from .services import Service
|
||||
from .advertising import Advertisement
|
||||
|
||||
"""
|
||||
|
||||
This module provides higher-level BLE (Bluetooth Low Energy) functionality,
|
||||
building on the native `_bleio` module.
|
||||
|
||||
"""
|
||||
if sys.implementation.name == "circuitpython" and sys.implementation.version[0] <= 4:
|
||||
...
|
||||
__version__ = ...
|
||||
__repo__ = ...
|
||||
class BLEConnection:
|
||||
"""
|
||||
Represents a connection to a peer BLE device.
|
||||
It acts as a map from a `Service` type to a `Service` instance for the connection.
|
||||
|
||||
:param bleio_connection _bleio.Connection: the native `_bleio.Connection` object to wrap
|
||||
|
||||
"""
|
||||
def __init__(self, bleio_connection) -> None:
|
||||
...
|
||||
|
||||
def __contains__(self, key): # -> bool:
|
||||
"""
|
||||
Allows easy testing for a particular Service class or a particular UUID
|
||||
associated with this connection.
|
||||
|
||||
Example::
|
||||
|
||||
if UARTService in connection:
|
||||
# do something
|
||||
|
||||
if StandardUUID(0x1234) in connection:
|
||||
# do something
|
||||
"""
|
||||
...
|
||||
|
||||
def __getitem__(self, key): # -> None:
|
||||
"""Return the Service for the given Service class or uuid, if any."""
|
||||
...
|
||||
|
||||
@property
|
||||
def connected(self):
|
||||
"""True if the connection to the peer is still active."""
|
||||
...
|
||||
|
||||
@property
|
||||
def paired(self):
|
||||
"""True if the paired to the peer."""
|
||||
...
|
||||
|
||||
@property
|
||||
def connection_interval(self):
|
||||
"""Time between transmissions in milliseconds. Will be multiple of 1.25ms. Lower numbers
|
||||
increase speed and decrease latency but increase power consumption.
|
||||
|
||||
When setting connection_interval, the peer may reject the new interval and
|
||||
`connection_interval` will then remain the same.
|
||||
|
||||
Apple has additional guidelines that dictate should be a multiple of 15ms except if HID
|
||||
is available. When HID is available Apple devices may accept 11.25ms intervals."""
|
||||
...
|
||||
|
||||
@connection_interval.setter
|
||||
def connection_interval(self, value): # -> None:
|
||||
...
|
||||
|
||||
def pair(self, *, bond=...):
|
||||
"""Pair to the peer to increase security of the connection."""
|
||||
...
|
||||
|
||||
def disconnect(self): # -> None:
|
||||
"""Disconnect from peer."""
|
||||
...
|
||||
|
||||
|
||||
|
||||
class BLERadio:
|
||||
"""
|
||||
BLERadio provides the interfaces for BLE advertising,
|
||||
scanning for advertisements, and connecting to peers. There may be
|
||||
multiple connections active at once.
|
||||
|
||||
It uses this library's `Advertisement` classes and the `BLEConnection` class."""
|
||||
def __init__(self, adapter=...) -> None:
|
||||
"""If no adapter is supplied, use the built-in `_bleio.adapter`.
|
||||
If no built-in adapter is available, raise `RuntimeError`.
|
||||
"""
|
||||
...
|
||||
|
||||
def start_advertising(self, advertisement, scan_response=..., interval=..., timeout=...): # -> None:
|
||||
"""
|
||||
Starts advertising the given advertisement.
|
||||
|
||||
:param buf scan_response: scan response data packet bytes.
|
||||
If ``None``, a default scan response will be generated that includes
|
||||
`BLERadio.name` and `BLERadio.tx_power`.
|
||||
:param float interval: advertising interval, in seconds
|
||||
:param int timeout: advertising timeout in seconds.
|
||||
If None, no timeout.
|
||||
|
||||
``timeout`` is not available in CircuitPython 5.x and must be `None`.
|
||||
"""
|
||||
...
|
||||
|
||||
def stop_advertising(self): # -> None:
|
||||
"""Stops advertising."""
|
||||
...
|
||||
|
||||
def start_scan(self, *advertisement_types, buffer_size=..., extended=..., timeout=..., interval=..., window=..., minimum_rssi=..., active=...): # -> Generator[Advertisement | Unknown, None, None]:
|
||||
"""
|
||||
Starts scanning. Returns an iterator of advertisement objects of the types given in
|
||||
advertisement_types. The iterator will block until an advertisement is heard or the scan
|
||||
times out.
|
||||
|
||||
If any ``advertisement_types`` are given, only Advertisements of those types are produced
|
||||
by the returned iterator. If none are given then `Advertisement` objects will be
|
||||
returned.
|
||||
|
||||
Advertisements and scan responses are filtered and returned separately.
|
||||
|
||||
:param int buffer_size: the maximum number of advertising bytes to buffer.
|
||||
:param bool extended: When True, support extended advertising packets.
|
||||
Increasing buffer_size is recommended when this is set.
|
||||
:param float timeout: the scan timeout in seconds.
|
||||
If None, will scan until `stop_scan` is called.
|
||||
:param float interval: the interval (in seconds) between the start
|
||||
of two consecutive scan windows
|
||||
Must be in the range 0.0025 - 40.959375 seconds.
|
||||
:param float window: the duration (in seconds) to scan a single BLE channel.
|
||||
window must be <= interval.
|
||||
:param int minimum_rssi: the minimum rssi of entries to return.
|
||||
:param bool active: request and retrieve scan responses for scannable advertisements.
|
||||
:return: If any ``advertisement_types`` are given,
|
||||
only Advertisements of those types are produced by the returned iterator.
|
||||
If none are given then `Advertisement` objects will be returned.
|
||||
:rtype: iterable
|
||||
"""
|
||||
...
|
||||
|
||||
def stop_scan(self): # -> None:
|
||||
"""Stops any active scan.
|
||||
|
||||
The scan results iterator will return any buffered results and then raise StopIteration
|
||||
once empty."""
|
||||
...
|
||||
|
||||
def connect(self, advertisement, *, timeout=...):
|
||||
"""
|
||||
Initiates a `BLEConnection` to the peer that advertised the given advertisement.
|
||||
|
||||
:param advertisement Advertisement: An `Advertisement` or a subclass of `Advertisement`
|
||||
:param timeout float: how long to wait for a connection
|
||||
:return: the connection to the peer
|
||||
:rtype: BLEConnection
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def connected(self): # -> bool:
|
||||
"""True if any peers are connected."""
|
||||
...
|
||||
|
||||
@property
|
||||
def connections(self): # -> tuple[None, ...]:
|
||||
"""A tuple of active `BLEConnection` objects."""
|
||||
...
|
||||
|
||||
@property
|
||||
def name(self): # -> str:
|
||||
"""The name for this device. Used in advertisements and
|
||||
as the Device Name in the Generic Access Service, available to a connected peer.
|
||||
"""
|
||||
...
|
||||
|
||||
@name.setter
|
||||
def name(self, value): # -> None:
|
||||
...
|
||||
|
||||
@property
|
||||
def tx_power(self): # -> Literal[0]:
|
||||
"""Transmit power, in dBm."""
|
||||
...
|
||||
|
||||
@tx_power.setter
|
||||
def tx_power(self, value):
|
||||
...
|
||||
|
||||
@property
|
||||
def address_bytes(self): # -> bytes:
|
||||
"""The device address, as a ``bytes()`` object of length 6."""
|
||||
...
|
||||
|
||||
@property
|
||||
def advertising(self): # -> bool:
|
||||
"""The advertising state"""
|
||||
...
|
||||
|
||||
|
||||
|
173
typings/adafruit_ble/advertising/__init__.pyi
Normal file
173
typings/adafruit_ble/advertising/__init__.pyi
Normal file
@ -0,0 +1,173 @@
|
||||
"""
|
||||
This type stub file was generated by pyright.
|
||||
"""
|
||||
|
||||
import struct
|
||||
|
||||
"""
|
||||
Advertising is the first phase of BLE where devices can broadcast
|
||||
"""
|
||||
def to_hex(seq): # -> str:
|
||||
"""Pretty prints a byte sequence as hex values."""
|
||||
...
|
||||
|
||||
def to_bytes_literal(seq): # -> str:
|
||||
"""Prints a byte sequence as a Python bytes literal that only uses hex encoding."""
|
||||
...
|
||||
|
||||
def decode_data(data, *, key_encoding=...): # -> dict[Unknown, Unknown]:
|
||||
"""Helper which decodes length encoded structures into a dictionary with the given key
|
||||
encoding."""
|
||||
...
|
||||
|
||||
def compute_length(data_dict, *, key_encoding=...): # -> int:
|
||||
"""Computes the length of the encoded data dictionary."""
|
||||
...
|
||||
|
||||
def encode_data(data_dict, *, key_encoding=...): # -> bytes:
|
||||
"""Helper which encodes dictionaries into length encoded structures with the given key
|
||||
encoding."""
|
||||
...
|
||||
|
||||
class AdvertisingDataField:
|
||||
"""Top level class for any descriptor classes that live in Advertisement or its subclasses."""
|
||||
...
|
||||
|
||||
|
||||
class AdvertisingFlag:
|
||||
"""A single bit flag within an AdvertisingFlags object."""
|
||||
def __init__(self, bit_position) -> None:
|
||||
...
|
||||
|
||||
def __get__(self, obj, cls): # -> AdvertisingFlag:
|
||||
...
|
||||
|
||||
def __set__(self, obj, value): # -> None:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class AdvertisingFlags(AdvertisingDataField):
|
||||
"""Standard advertising flags"""
|
||||
limited_discovery = ...
|
||||
general_discovery = ...
|
||||
le_only = ...
|
||||
def __init__(self, advertisement, advertising_data_type) -> None:
|
||||
...
|
||||
|
||||
def __len__(self): # -> Literal[1]:
|
||||
...
|
||||
|
||||
def __bytes__(self): # -> bytes:
|
||||
...
|
||||
|
||||
def __str__(self) -> str:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class String(AdvertisingDataField):
|
||||
"""UTF-8 encoded string in an Advertisement.
|
||||
|
||||
Not null terminated once encoded because length is always transmitted."""
|
||||
def __init__(self, *, advertising_data_type) -> None:
|
||||
...
|
||||
|
||||
def __get__(self, obj, cls): # -> String | str | None:
|
||||
...
|
||||
|
||||
def __set__(self, obj, value): # -> None:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class Struct(AdvertisingDataField):
|
||||
"""`struct` encoded data in an Advertisement."""
|
||||
def __init__(self, struct_format, *, advertising_data_type) -> None:
|
||||
...
|
||||
|
||||
def __get__(self, obj, cls): # -> Struct | Any | None:
|
||||
...
|
||||
|
||||
def __set__(self, obj, value): # -> None:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class LazyObjectField(AdvertisingDataField):
|
||||
"""Non-data descriptor useful for lazily binding a complex object to an advertisement object."""
|
||||
def __init__(self, cls, attribute_name, *, advertising_data_type, **kwargs) -> None:
|
||||
...
|
||||
|
||||
def __get__(self, obj, cls): # -> LazyObjectField | None:
|
||||
...
|
||||
|
||||
@property
|
||||
def advertising_data_type(self):
|
||||
"""Return the data type value used to indicate this field."""
|
||||
...
|
||||
|
||||
|
||||
|
||||
class Advertisement:
|
||||
"""Core Advertisement type.
|
||||
|
||||
The class attribute ``match_prefixes``, if not ``None``, is a tuple of
|
||||
bytestring prefixes to match against the multiple data structures in the advertisement.
|
||||
"""
|
||||
match_prefixes = ...
|
||||
_prefix_bytes = ...
|
||||
flags = ...
|
||||
short_name = ...
|
||||
complete_name = ...
|
||||
tx_power = ...
|
||||
appearance = ...
|
||||
def __init__(self, *, entry=...) -> None:
|
||||
"""Create an empty advertising packet or one from a ScanEntry."""
|
||||
...
|
||||
|
||||
@property
|
||||
def rssi(self): # -> None:
|
||||
"""Signal strength of the scanned advertisement. Only available on Advertisements returned
|
||||
from `BLERadio.start_scan()`. (read-only)"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def get_prefix_bytes(cls): # -> bytes | Any:
|
||||
"""Return a merged version of match_prefixes as a single bytes object,
|
||||
with length headers.
|
||||
"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def matches(cls, entry):
|
||||
"""Returns ``True`` if the given `_bleio.ScanEntry` advertisement fields
|
||||
matches all of the given prefixes in the `match_prefixes` tuple attribute.
|
||||
Subclasses may override this to match any instead of all.
|
||||
"""
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def matches_prefixes(cls, entry, *, all_):
|
||||
"""Returns ``True`` if the given `_bleio.ScanEntry` advertisement fields
|
||||
match any or all of the given prefixes in the `match_prefixes` tuple attribute.
|
||||
If ``all_`` is ``True``, all the prefixes must match. If ``all_`` is ``False``,
|
||||
returns ``True`` if at least one of the prefixes match.
|
||||
"""
|
||||
...
|
||||
|
||||
def __bytes__(self): # -> bytes:
|
||||
"""The raw packet bytes."""
|
||||
...
|
||||
|
||||
def __str__(self) -> str:
|
||||
...
|
||||
|
||||
def __len__(self): # -> int:
|
||||
...
|
||||
|
||||
def __repr__(self): # -> str:
|
||||
...
|
||||
|
||||
|
||||
|
122
typings/adafruit_ble/advertising/standard.pyi
Normal file
122
typings/adafruit_ble/advertising/standard.pyi
Normal file
@ -0,0 +1,122 @@
|
||||
"""
|
||||
This type stub file was generated by pyright.
|
||||
"""
|
||||
|
||||
from . import Advertisement, AdvertisingDataField
|
||||
|
||||
"""
|
||||
:py:mod:`~adafruit_ble.advertising.standard`
|
||||
====================================================
|
||||
|
||||
This module provides BLE standard defined advertisements. The Advertisements are single purpose
|
||||
even though multiple purposes may actually be present in a single packet.
|
||||
|
||||
"""
|
||||
__version__ = ...
|
||||
__repo__ = ...
|
||||
class BoundServiceList:
|
||||
"""Sequence-like object of Service UUID objects. It stores both standard and vendor UUIDs."""
|
||||
def __init__(self, advertisement, *, standard_services, vendor_services) -> None:
|
||||
...
|
||||
|
||||
def __contains__(self, key): # -> bool:
|
||||
...
|
||||
|
||||
def __iter__(self): # -> Iterator[Unknown]:
|
||||
...
|
||||
|
||||
def append(self, service): # -> None:
|
||||
"""Append a service to the list."""
|
||||
...
|
||||
|
||||
def extend(self, services): # -> None:
|
||||
"""Appends all services in the iterable to the list."""
|
||||
...
|
||||
|
||||
def __str__(self) -> str:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class ServiceList(AdvertisingDataField):
|
||||
"""Descriptor for a list of Service UUIDs that lazily binds a corresponding BoundServiceList."""
|
||||
def __init__(self, *, standard_services, vendor_services) -> None:
|
||||
...
|
||||
|
||||
def __get__(self, obj, cls): # -> ServiceList | tuple[()]:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class ProvideServicesAdvertisement(Advertisement):
|
||||
"""Advertise what services that the device makes available upon connection."""
|
||||
match_prefixes = ...
|
||||
services = ...
|
||||
def __init__(self, *services, entry=...) -> None:
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def matches(cls, entry):
|
||||
"""Only one kind of service list need be present in a ProvideServicesAdvertisement,
|
||||
so override the default behavior and match any prefix, not all.
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
|
||||
class SolicitServicesAdvertisement(Advertisement):
|
||||
"""Advertise what services the device would like to use over a connection."""
|
||||
match_prefixes = ...
|
||||
solicited_services = ...
|
||||
def __init__(self, *services, entry=...) -> None:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class ManufacturerData(AdvertisingDataField):
|
||||
"""Encapsulates manufacturer specific keyed data bytes. The manufacturer is identified by the
|
||||
company_id and the data is structured like an advertisement with a configurable key
|
||||
format. The order of the serialized data is determined by the order that the
|
||||
`ManufacturerDataField` attributes are set in - this can be useful for
|
||||
`match_prefixes` in an `Advertisement` sub-class."""
|
||||
def __init__(self, obj, *, advertising_data_type=..., company_id, key_encoding=...) -> None:
|
||||
...
|
||||
|
||||
def __len__(self): # -> int:
|
||||
...
|
||||
|
||||
def __bytes__(self): # -> bytes:
|
||||
...
|
||||
|
||||
def __str__(self) -> str:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class ManufacturerDataField:
|
||||
"""A single piece of data within the manufacturer specific data. The format can be repeated."""
|
||||
def __init__(self, key, value_format, field_names=...) -> None:
|
||||
...
|
||||
|
||||
def __get__(self, obj, cls): # -> ManufacturerDataField | mdf_tuple | Any | Tuple[Any, ...] | tuple[None, ...] | None:
|
||||
...
|
||||
|
||||
def __set__(self, obj, value): # -> None:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class ServiceData(AdvertisingDataField):
|
||||
"""Encapsulates service data. It is read as a memoryview which can be manipulated or set as a
|
||||
bytearray to change the size."""
|
||||
def __init__(self, service) -> None:
|
||||
...
|
||||
|
||||
def __get__(self, obj, cls): # -> ServiceData | memoryview | None:
|
||||
...
|
||||
|
||||
def __set__(self, obj, value): # -> None:
|
||||
...
|
||||
|
||||
|
||||
|
55
typings/adafruit_ble/attributes/__init__.pyi
Normal file
55
typings/adafruit_ble/attributes/__init__.pyi
Normal file
@ -0,0 +1,55 @@
|
||||
"""
|
||||
This type stub file was generated by pyright.
|
||||
"""
|
||||
|
||||
import _bleio
|
||||
|
||||
"""
|
||||
:py:mod:`~adafruit_ble.attributes`
|
||||
====================================================
|
||||
|
||||
This module provides definitions common to all kinds of BLE attributes,
|
||||
specifically characteristics and descriptors.
|
||||
|
||||
"""
|
||||
__version__ = ...
|
||||
__repo__ = ...
|
||||
class Attribute:
|
||||
"""Constants describing security levels.
|
||||
|
||||
.. data:: NO_ACCESS
|
||||
|
||||
security mode: access not allowed
|
||||
|
||||
.. data:: OPEN
|
||||
|
||||
security_mode: no security (link is not encrypted)
|
||||
|
||||
.. data:: ENCRYPT_NO_MITM
|
||||
|
||||
security_mode: unauthenticated encryption, without man-in-the-middle protection
|
||||
|
||||
.. data:: ENCRYPT_WITH_MITM
|
||||
|
||||
security_mode: authenticated encryption, with man-in-the-middle protection
|
||||
|
||||
.. data:: LESC_ENCRYPT_WITH_MITM
|
||||
|
||||
security_mode: LESC encryption, with man-in-the-middle protection
|
||||
|
||||
.. data:: SIGNED_NO_MITM
|
||||
|
||||
security_mode: unauthenticated data signing, without man-in-the-middle protection
|
||||
|
||||
.. data:: SIGNED_WITH_MITM
|
||||
|
||||
security_mode: authenticated data signing, without man-in-the-middle protection"""
|
||||
NO_ACCESS = ...
|
||||
OPEN = ...
|
||||
ENCRYPT_NO_MITM = ...
|
||||
ENCRYPT_WITH_MITM = ...
|
||||
LESC_ENCRYPT_WITH_MITM = ...
|
||||
SIGNED_NO_MITM = ...
|
||||
SIGNED_WITH_MITM = ...
|
||||
|
||||
|
120
typings/adafruit_ble/characteristics/__init__.pyi
Normal file
120
typings/adafruit_ble/characteristics/__init__.pyi
Normal file
@ -0,0 +1,120 @@
|
||||
"""
|
||||
This type stub file was generated by pyright.
|
||||
"""
|
||||
|
||||
import struct
|
||||
import _bleio
|
||||
from ..attributes import Attribute
|
||||
|
||||
"""
|
||||
|
||||
This module provides core BLE characteristic classes that are used within Services.
|
||||
|
||||
"""
|
||||
__version__ = ...
|
||||
__repo__ = ...
|
||||
class Characteristic:
|
||||
"""
|
||||
Top level Characteristic class that does basic binding.
|
||||
|
||||
:param UUID uuid: The uuid of the characteristic
|
||||
:param int properties: The properties of the characteristic,
|
||||
specified as a bitmask of these values bitwise-or'd together:
|
||||
`BROADCAST`, `INDICATE`, `NOTIFY`, `READ`, `WRITE`, `WRITE_NO_RESPONSE`.
|
||||
:param int read_perm: Specifies whether the characteristic can be read by a client,
|
||||
and if so, which security mode is required.
|
||||
Must be one of the integer values `Attribute.NO_ACCESS`, `Attribute.OPEN`,
|
||||
`Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`,
|
||||
`Attribute.LESC_ENCRYPT_WITH_MITM`,
|
||||
`Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`.
|
||||
:param int write_perm: Specifies whether the characteristic can be written by a client,
|
||||
and if so, which security mode is required. Values allowed are the same as ``read_perm``.
|
||||
:param int max_length: Maximum length in bytes of the characteristic value. The maximum allowed
|
||||
by the BLE specification is 512. On nRF, if ``fixed_length`` is ``True``, the maximum
|
||||
is 510. The default value is 20, which is the maximum
|
||||
number of data bytes that fit in a single BLE 4.x ATT packet.
|
||||
:param bool fixed_length: True if the characteristic value is of fixed length.
|
||||
:param buf initial_value: The initial value for this characteristic. If not given, will be
|
||||
filled with zeros.
|
||||
|
||||
.. data:: BROADCAST
|
||||
|
||||
property: allowed in advertising packets
|
||||
|
||||
.. data:: INDICATE
|
||||
|
||||
property: server will indicate to the client when the value is set and wait for a response
|
||||
|
||||
.. data:: NOTIFY
|
||||
|
||||
property: server will notify the client when the value is set
|
||||
|
||||
.. data:: READ
|
||||
|
||||
property: clients may read this characteristic
|
||||
|
||||
.. data:: WRITE
|
||||
|
||||
property: clients may write this characteristic; a response will be sent back
|
||||
|
||||
.. data:: WRITE_NO_RESPONSE
|
||||
|
||||
property: clients may write this characteristic; no response will be sent back"""
|
||||
BROADCAST = ...
|
||||
INDICATE = ...
|
||||
NOTIFY = ...
|
||||
READ = ...
|
||||
WRITE = ...
|
||||
WRITE_NO_RESPONSE = ...
|
||||
def __init__(self, *, uuid=..., properties=..., read_perm=..., write_perm=..., max_length=..., fixed_length=..., initial_value=...) -> None:
|
||||
...
|
||||
|
||||
def __get__(self, service, cls=...): # -> Characteristic:
|
||||
...
|
||||
|
||||
def __set__(self, service, value): # -> None:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class ComplexCharacteristic:
|
||||
"""
|
||||
Characteristic class that does complex binding where the subclass returns a full object for
|
||||
interacting with the characteristic data. The Characteristic itself will be shadowed once it
|
||||
has been bound to the corresponding instance attribute.
|
||||
"""
|
||||
def __init__(self, *, uuid=..., properties=..., read_perm=..., write_perm=..., max_length=..., fixed_length=..., initial_value=...) -> None:
|
||||
...
|
||||
|
||||
def bind(self, service):
|
||||
"""Binds the characteristic to the local Service or remote Characteristic object given."""
|
||||
...
|
||||
|
||||
def __get__(self, service, cls=...): # -> ComplexCharacteristic:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class StructCharacteristic(Characteristic):
|
||||
"""
|
||||
Data descriptor for a structure with a fixed format.
|
||||
|
||||
:param struct_format: a `struct` format string describing how to pack multiple values
|
||||
into the characteristic bytestring
|
||||
:param UUID uuid: The uuid of the characteristic
|
||||
:param int properties: see `Characteristic`
|
||||
:param int read_perm: see `Characteristic`
|
||||
:param int write_perm: see `Characteristic`
|
||||
:param buf initial_value: see `Characteristic`
|
||||
"""
|
||||
def __init__(self, struct_format, *, uuid=..., properties=..., read_perm=..., write_perm=..., initial_value=...) -> None:
|
||||
...
|
||||
|
||||
def __get__(self, obj, cls=...): # -> StructCharacteristic | Tuple[Any, ...] | None:
|
||||
...
|
||||
|
||||
def __set__(self, obj, value): # -> None:
|
||||
...
|
||||
|
||||
|
||||
|
49
typings/adafruit_ble/characteristics/stream.pyi
Normal file
49
typings/adafruit_ble/characteristics/stream.pyi
Normal file
@ -0,0 +1,49 @@
|
||||
"""
|
||||
This type stub file was generated by pyright.
|
||||
"""
|
||||
|
||||
from . import ComplexCharacteristic
|
||||
|
||||
"""
|
||||
`stream`
|
||||
====================================================
|
||||
|
||||
This module provides stream characteristics that bind readable or writable objects to the Service
|
||||
object they are on.
|
||||
|
||||
"""
|
||||
__version__ = ...
|
||||
__repo__ = ...
|
||||
class BoundWriteStream:
|
||||
"""Writes data out to the peer."""
|
||||
def __init__(self, bound_characteristic) -> None:
|
||||
...
|
||||
|
||||
def write(self, buf): # -> None:
|
||||
"""Write data from buf out to the peer."""
|
||||
...
|
||||
|
||||
|
||||
|
||||
class StreamOut(ComplexCharacteristic):
|
||||
"""Output stream from the Service server."""
|
||||
def __init__(self, *, uuid=..., timeout=..., buffer_size=..., properties=..., read_perm=..., write_perm=...) -> None:
|
||||
...
|
||||
|
||||
def bind(self, service): # -> CharacteristicBuffer | BoundWriteStream:
|
||||
"""Binds the characteristic to the given Service."""
|
||||
...
|
||||
|
||||
|
||||
|
||||
class StreamIn(ComplexCharacteristic):
|
||||
"""Input stream into the Service server."""
|
||||
def __init__(self, *, uuid=..., timeout=..., buffer_size=..., properties=..., write_perm=...) -> None:
|
||||
...
|
||||
|
||||
def bind(self, service): # -> BoundWriteStream | CharacteristicBuffer:
|
||||
"""Binds the characteristic to the given Service."""
|
||||
...
|
||||
|
||||
|
||||
|
36
typings/adafruit_ble/services/__init__.pyi
Normal file
36
typings/adafruit_ble/services/__init__.pyi
Normal file
@ -0,0 +1,36 @@
|
||||
"""
|
||||
This type stub file was generated by pyright.
|
||||
"""
|
||||
|
||||
import _bleio
|
||||
from ..characteristics import Characteristic, ComplexCharacteristic
|
||||
|
||||
"""
|
||||
|
||||
This module provides the top level Service definition.
|
||||
|
||||
"""
|
||||
__version__ = ...
|
||||
__repo__ = ...
|
||||
class Service:
|
||||
"""Top level Service class that handles the hard work of binding to a local or remote service.
|
||||
|
||||
Providers of a local service should instantiate their Service with service=None, the default.
|
||||
The local Service's characteristics will be lazily made available to clients as they are used
|
||||
locally. In other words, a characteristic won't be available to remote clients until it has
|
||||
been read or written locally.
|
||||
|
||||
To use a remote Service, get the item with the key of the Service type on the
|
||||
`BLEConnection`. For example, ``connection[UartService]`` will return the UartService
|
||||
instance for the connection's peer.
|
||||
"""
|
||||
def __init__(self, *, service=..., secondary=..., **initial_values) -> None:
|
||||
...
|
||||
|
||||
@property
|
||||
def remote(self): # -> bool:
|
||||
"""True if the service is provided by a peer and accessed remotely."""
|
||||
...
|
||||
|
||||
|
||||
|
77
typings/adafruit_ble/services/nordic.pyi
Normal file
77
typings/adafruit_ble/services/nordic.pyi
Normal file
@ -0,0 +1,77 @@
|
||||
"""
|
||||
This type stub file was generated by pyright.
|
||||
"""
|
||||
|
||||
from . import Service
|
||||
|
||||
"""
|
||||
`nordic`
|
||||
====================================================
|
||||
|
||||
This module provides Services used by Nordic Semiconductors.
|
||||
|
||||
"""
|
||||
__version__ = ...
|
||||
__repo__ = ...
|
||||
class UARTService(Service):
|
||||
"""
|
||||
Provide UART-like functionality via the Nordic NUS service.
|
||||
|
||||
:param int timeout: the timeout in seconds to wait
|
||||
for the first character and between subsequent characters.
|
||||
:param int buffer_size: buffer up to this many bytes.
|
||||
If more bytes are received, older bytes will be discarded.
|
||||
|
||||
See ``examples/ble_uart_echo_test.py`` for a usage example.
|
||||
"""
|
||||
uuid = ...
|
||||
_server_tx = ...
|
||||
_server_rx = ...
|
||||
def __init__(self, service=...) -> None:
|
||||
...
|
||||
|
||||
def read(self, nbytes=...):
|
||||
"""
|
||||
Read characters. If ``nbytes`` is specified then read at most that many bytes.
|
||||
Otherwise, read everything that arrives until the connection times out.
|
||||
Providing the number of bytes expected is highly recommended because it will be faster.
|
||||
|
||||
:return: Data read
|
||||
:rtype: bytes or None
|
||||
"""
|
||||
...
|
||||
|
||||
def readinto(self, buf, nbytes=...):
|
||||
"""
|
||||
Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
|
||||
that many bytes. Otherwise, read at most ``len(buf)`` bytes.
|
||||
|
||||
:return: number of bytes read and stored into ``buf``
|
||||
:rtype: int or None (on a non-blocking error)
|
||||
"""
|
||||
...
|
||||
|
||||
def readline(self):
|
||||
"""
|
||||
Read a line, ending in a newline character.
|
||||
|
||||
:return: the line read
|
||||
:rtype: bytes or None
|
||||
"""
|
||||
...
|
||||
|
||||
@property
|
||||
def in_waiting(self):
|
||||
"""The number of bytes in the input buffer, available to be read."""
|
||||
...
|
||||
|
||||
def reset_input_buffer(self): # -> None:
|
||||
"""Discard any unread characters in the input buffer."""
|
||||
...
|
||||
|
||||
def write(self, buf): # -> None:
|
||||
"""Write a buffer of bytes."""
|
||||
...
|
||||
|
||||
|
||||
|
48
typings/adafruit_ble/uuid/__init__.pyi
Normal file
48
typings/adafruit_ble/uuid/__init__.pyi
Normal file
@ -0,0 +1,48 @@
|
||||
"""
|
||||
This type stub file was generated by pyright.
|
||||
"""
|
||||
|
||||
import struct
|
||||
import _bleio
|
||||
|
||||
"""
|
||||
|
||||
This module provides core Unique ID (UUID) classes.
|
||||
|
||||
"""
|
||||
__version__ = ...
|
||||
__repo__ = ...
|
||||
class UUID:
|
||||
"""Top level UUID"""
|
||||
def __hash__(self) -> int:
|
||||
...
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
...
|
||||
|
||||
def __str__(self) -> str:
|
||||
...
|
||||
|
||||
def __bytes__(self): # -> bytes:
|
||||
...
|
||||
|
||||
def pack_into(self, buffer, offset=...): # -> None:
|
||||
"""Packs the UUID into the buffer at the given offset."""
|
||||
...
|
||||
|
||||
|
||||
|
||||
class StandardUUID(UUID):
|
||||
"""Standard 16-bit UUID defined by the Bluetooth SIG."""
|
||||
def __init__(self, uuid16) -> None:
|
||||
...
|
||||
|
||||
|
||||
|
||||
class VendorUUID(UUID):
|
||||
"""Vendor defined, 128-bit UUID."""
|
||||
def __init__(self, uuid128) -> None:
|
||||
...
|
||||
|
||||
|
||||
|
5
typings/micropython.pyi
Normal file
5
typings/micropython.pyi
Normal file
@ -0,0 +1,5 @@
|
||||
from typing import TypeVar
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
def const(x: T) -> T: ...
|
Loading…
Reference in New Issue
Block a user