mirror of
https://github.com/scottbez1/smartknob.git
synced 2025-09-26 23:09:27 +08:00
Python software example (#106)
Add protobuf/cobs/crc32 framework code and a really basic python example
This commit is contained in:
parent
9431ed3971
commit
acfc85f72b
@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7-dev */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
|
||||
#include "smartknob.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7-dev */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
|
||||
#ifndef PB_PB_SMARTKNOB_PB_H_INCLUDED
|
||||
#define PB_PB_SMARTKNOB_PB_H_INCLUDED
|
||||
@ -10,10 +10,6 @@
|
||||
#endif
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _PB_RequestState {
|
||||
char dummy_field;
|
||||
} PB_RequestState;
|
||||
|
||||
typedef struct _PB_Ack {
|
||||
uint32_t nonce;
|
||||
} PB_Ack;
|
||||
@ -43,16 +39,6 @@ typedef struct _PB_SmartKnobState {
|
||||
PB_SmartKnobConfig config;
|
||||
} PB_SmartKnobState;
|
||||
|
||||
/* Message TO the Smartknob from the USB host */
|
||||
typedef struct _PB_ToSmartknob {
|
||||
uint32_t nonce;
|
||||
pb_size_t which_payload;
|
||||
union {
|
||||
PB_RequestState request_state;
|
||||
PB_SmartKnobConfig smartknob_config;
|
||||
} payload;
|
||||
} PB_ToSmartknob;
|
||||
|
||||
/* Message FROM the SmartKnob to USB host */
|
||||
typedef struct _PB_FromSmartKnob {
|
||||
pb_size_t which_payload;
|
||||
@ -63,6 +49,20 @@ typedef struct _PB_FromSmartKnob {
|
||||
} payload;
|
||||
} PB_FromSmartKnob;
|
||||
|
||||
typedef struct _PB_RequestState {
|
||||
char dummy_field;
|
||||
} PB_RequestState;
|
||||
|
||||
/* Message TO the Smartknob from the USB host */
|
||||
typedef struct _PB_ToSmartknob {
|
||||
uint32_t nonce;
|
||||
pb_size_t which_payload;
|
||||
union {
|
||||
PB_RequestState request_state;
|
||||
PB_SmartKnobConfig smartknob_config;
|
||||
} payload;
|
||||
} PB_ToSmartknob;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -100,12 +100,12 @@ extern "C" {
|
||||
#define PB_SmartKnobState_current_position_tag 1
|
||||
#define PB_SmartKnobState_sub_position_unit_tag 2
|
||||
#define PB_SmartKnobState_config_tag 3
|
||||
#define PB_ToSmartknob_nonce_tag 1
|
||||
#define PB_ToSmartknob_request_state_tag 2
|
||||
#define PB_ToSmartknob_smartknob_config_tag 3
|
||||
#define PB_FromSmartKnob_ack_tag 1
|
||||
#define PB_FromSmartKnob_log_tag 2
|
||||
#define PB_FromSmartKnob_smartknob_state_tag 3
|
||||
#define PB_ToSmartknob_nonce_tag 1
|
||||
#define PB_ToSmartknob_request_state_tag 2
|
||||
#define PB_ToSmartknob_smartknob_config_tag 3
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define PB_FromSmartKnob_FIELDLIST(X, a) \
|
||||
|
13
proto/Pipfile
Normal file
13
proto/Pipfile
Normal file
@ -0,0 +1,13 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
grpcio-tools = "*"
|
||||
protobuf = "==3.20.3"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.10"
|
160
proto/Pipfile.lock
generated
Normal file
160
proto/Pipfile.lock
generated
Normal file
@ -0,0 +1,160 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "81cf165543dd8620d62e1e5c86575e5245b7b76980809b0fbd484de2aba002cb"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.10"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"grpcio": {
|
||||
"hashes": [
|
||||
"sha256:094e64236253590d9d4075665c77b329d707b6fca864dd62b144255e199b4f87",
|
||||
"sha256:0dc5354e38e5adf2498312f7241b14c7ce3484eefa0082db4297189dcbe272e6",
|
||||
"sha256:0e1a9e1b4a23808f1132aa35f968cd8e659f60af3ffd6fb00bcf9a65e7db279f",
|
||||
"sha256:0fb93051331acbb75b49a2a0fd9239c6ba9528f6bdc1dd400ad1cb66cf864292",
|
||||
"sha256:16c71740640ba3a882f50b01bf58154681d44b51f09a5728180a8fdc66c67bd5",
|
||||
"sha256:172405ca6bdfedd6054c74c62085946e45ad4d9cec9f3c42b4c9a02546c4c7e9",
|
||||
"sha256:17ec9b13cec4a286b9e606b48191e560ca2f3bbdf3986f91e480a95d1582e1a7",
|
||||
"sha256:22b011674090594f1f3245960ced7386f6af35485a38901f8afee8ad01541dbd",
|
||||
"sha256:24ac1154c4b2ab4a0c5326a76161547e70664cd2c39ba75f00fc8a2170964ea2",
|
||||
"sha256:257478300735ce3c98d65a930bbda3db172bd4e00968ba743e6a1154ea6edf10",
|
||||
"sha256:29cb97d41a4ead83b7bcad23bdb25bdd170b1e2cba16db6d3acbb090bc2de43c",
|
||||
"sha256:2b170eaf51518275c9b6b22ccb59450537c5a8555326fd96ff7391b5dd75303c",
|
||||
"sha256:31bb6bc7ff145e2771c9baf612f4b9ebbc9605ccdc5f3ff3d5553de7fc0e0d79",
|
||||
"sha256:3c2b3842dcf870912da31a503454a33a697392f60c5e2697c91d133130c2c85d",
|
||||
"sha256:3f9b0023c2c92bebd1be72cdfca23004ea748be1813a66d684d49d67d836adde",
|
||||
"sha256:471d39d3370ca923a316d49c8aac66356cea708a11e647e3bdc3d0b5de4f0a40",
|
||||
"sha256:49d680356a975d9c66a678eb2dde192d5dc427a7994fb977363634e781614f7c",
|
||||
"sha256:4c4423ea38a7825b8fed8934d6d9aeebdf646c97e3c608c3b0bcf23616f33877",
|
||||
"sha256:506b9b7a4cede87d7219bfb31014d7b471cfc77157da9e820a737ec1ea4b0663",
|
||||
"sha256:538d981818e49b6ed1e9c8d5e5adf29f71c4e334e7d459bf47e9b7abb3c30e09",
|
||||
"sha256:59dffade859f157bcc55243714d57b286da6ae16469bf1ac0614d281b5f49b67",
|
||||
"sha256:5a6ebcdef0ef12005d56d38be30f5156d1cb3373b52e96f147f4a24b0ddb3a9d",
|
||||
"sha256:5dca372268c6ab6372d37d6b9f9343e7e5b4bc09779f819f9470cd88b2ece3c3",
|
||||
"sha256:6df3b63538c362312bc5fa95fb965069c65c3ea91d7ce78ad9c47cab57226f54",
|
||||
"sha256:6f0b89967ee11f2b654c23b27086d88ad7bf08c0b3c2a280362f28c3698b2896",
|
||||
"sha256:75e29a90dc319f0ad4d87ba6d20083615a00d8276b51512e04ad7452b5c23b04",
|
||||
"sha256:7942b32a291421460d6a07883033e392167d30724aa84987e6956cd15f1a21b9",
|
||||
"sha256:9235dcd5144a83f9ca6f431bd0eccc46b90e2c22fe27b7f7d77cabb2fb515595",
|
||||
"sha256:97d67983189e2e45550eac194d6234fc38b8c3b5396c153821f2d906ed46e0ce",
|
||||
"sha256:9ff42c5620b4e4530609e11afefa4a62ca91fa0abb045a8957e509ef84e54d30",
|
||||
"sha256:a8a0b77e992c64880e6efbe0086fe54dfc0bbd56f72a92d9e48264dcd2a3db98",
|
||||
"sha256:aacb54f7789ede5cbf1d007637f792d3e87f1c9841f57dd51abf89337d1b8472",
|
||||
"sha256:bc59f7ba87972ab236f8669d8ca7400f02a0eadf273ca00e02af64d588046f02",
|
||||
"sha256:cc2bece1737b44d878cc1510ea04469a8073dbbcdd762175168937ae4742dfb3",
|
||||
"sha256:cd3baccea2bc5c38aeb14e5b00167bd4e2373a373a5e4d8d850bd193edad150c",
|
||||
"sha256:dad6533411d033b77f5369eafe87af8583178efd4039c41d7515d3336c53b4f1",
|
||||
"sha256:e223a9793522680beae44671b9ed8f6d25bbe5ddf8887e66aebad5e0686049ef",
|
||||
"sha256:e473525c28251558337b5c1ad3fa969511e42304524a4e404065e165b084c9e4",
|
||||
"sha256:e4ef09f8997c4be5f3504cefa6b5c6cc3cf648274ce3cede84d4342a35d76db6",
|
||||
"sha256:e6dfc2b6567b1c261739b43d9c59d201c1b89e017afd9e684d85aa7a186c9f7a",
|
||||
"sha256:eacad297ea60c72dd280d3353d93fb1dcca952ec11de6bb3c49d12a572ba31dd",
|
||||
"sha256:f1158bccbb919da42544a4d3af5d9296a3358539ffa01018307337365a9a0c64",
|
||||
"sha256:f1fec3abaf274cdb85bf3878167cfde5ad4a4d97c68421afda95174de85ba813",
|
||||
"sha256:f96ace1540223f26fbe7c4ebbf8a98e3929a6aa0290c8033d12526847b291c0f",
|
||||
"sha256:fbdbe9a849854fe484c00823f45b7baab159bdd4a46075302281998cb8719df5"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.51.1"
|
||||
},
|
||||
"grpcio-tools": {
|
||||
"hashes": [
|
||||
"sha256:0119aabd9ceedfdf41b56b9fdc8284dd85a7f589d087f2694d743f346a368556",
|
||||
"sha256:072234859f6069dc43a6be8ad6b7d682f4ba1dc2e2db2ebf5c75f62eee0f6dfb",
|
||||
"sha256:0fb6c1c1e56eb26b224adc028a4204b6ad0f8b292efa28067dff273bbc8b27c4",
|
||||
"sha256:189be2a9b672300ca6845d94016bdacc052fdbe9d1ae9e85344425efae2ff8ef",
|
||||
"sha256:21ff50e321736eba22210bf9b94e05391a9ac345f26e7df16333dc75d63e74fb",
|
||||
"sha256:3c8749dca04a8d302862ceeb1dfbdd071ee13b281395975f24405a347e5baa57",
|
||||
"sha256:4fa4300b1be59b046492ed3c5fdb59760bc6433f44c08f50de900f9552ec7461",
|
||||
"sha256:516eedd5eb7af6326050bc2cfceb3a977b9cc1144f283c43cc4956905285c912",
|
||||
"sha256:51be91b7c7056ff9ee48b1eccd4a2840b0126230803a5e09dfc082a5b16a91c1",
|
||||
"sha256:5410d6b601d1404835e34466bd8aee37213489b36ee1aad2276366e265ff29d4",
|
||||
"sha256:55fdebc73fb580717656b1bafa4f8eca448726a7aa22726a6c0a7895d2f0f088",
|
||||
"sha256:6cc298fbfe584de8876a85355efbcf796dfbcfac5948c9560f5df82e79336e2a",
|
||||
"sha256:6d9753944e5a6b6b78b76ce9d2ae0fe3f748008c1849deb7fadcb64489d6553b",
|
||||
"sha256:70564521e86a0de35ea9ac6daecff10cb46860aec469af65869974807ce8e98b",
|
||||
"sha256:7307dd2408b82ea545ae63502ec03036b025f449568556ea9a056e06129a7a4e",
|
||||
"sha256:80f450272316ca0924545f488c8492649ca3aeb7044d4bf59c426dcdee527f7c",
|
||||
"sha256:84a84d601a238572d049d3108e04fe4c206536e81076d56e623bd525a1b38def",
|
||||
"sha256:8588819b22d0de3aa1951e1991cc3e4b9aa105eecf6e3e24eb0a2fc8ab958b3e",
|
||||
"sha256:8902a035708555cddbd61b5467cea127484362decc52de03f061a1a520fe90cd",
|
||||
"sha256:8a5614251c46da07549e24f417cf989710250385e9d80deeafc53a0ee7df6325",
|
||||
"sha256:8e0d74403484eb77e8df2566a64b8b0b484b5c87903678c381634dd72f252d5e",
|
||||
"sha256:92acc3e10ba2b0dcb90a88ae9fe1cc0ffba6868545207e4ff20ca95284f8e3c9",
|
||||
"sha256:9443f5c30bac449237c3cf99da125f8d6e6c01e17972bc683ee73b75dea95573",
|
||||
"sha256:9771d4d317dca029dfaca7ec9282d8afe731c18bc536ece37fd39b8a974cc331",
|
||||
"sha256:a415fbec67d4ff7efe88794cbe00cf548d0f0a5484cceffe0a0c89d47694c491",
|
||||
"sha256:a43d26714933f23de93ea0bf9c86c66a6ede709b8ca32e357f9e2181703e64ae",
|
||||
"sha256:ace0035766fe01a1b096aa050be9f0a9f98402317e7aeff8bfe55349be32a407",
|
||||
"sha256:ae56f133b05b7e5d780ef7e032dd762adad7f3dc8f64adb43ff5bfabd659f435",
|
||||
"sha256:bdbbe63f6190187de5946891941629912ac8196701ed2253fa91624a397822ec",
|
||||
"sha256:cabc8b0905cedbc3b2b7b2856334fa35cce3d4bc79ae241cacd8cca8940a5c85",
|
||||
"sha256:cb75bac0cd43858cb759ef103fe68f8c540cb58b63dda127e710228fec3007b8",
|
||||
"sha256:d18599ab572b2f15a8f3db49503272d1bb4fcabb4b4d1214ef03aca1816b20a0",
|
||||
"sha256:d18ef2adc05a8ef9e58ac46357f6d4ce7e43e077c7eda0a4425773461f9d0e6e",
|
||||
"sha256:d598ccde6338b2cfbb3124f34c95f03394209013f9b1ed4a5360a736853b1c27",
|
||||
"sha256:d77e8b1613876e0d8fd17709509d4ceba13492816426bd156f7e88a4c47e7158",
|
||||
"sha256:d886a9e052a038642b3af5d18e6f2085d1656d9788e202dc23258cf3a751e7ca",
|
||||
"sha256:d96e96ae7361aa51c9cd9c73b677b51f691f98df6086860fcc3c45852d96b0b0",
|
||||
"sha256:dcaaecdd5e847de5c1d533ea91522bf56c9e6b2dc98cdc0d45f0a1c26e846ea2",
|
||||
"sha256:e0403e095b343431195db1305248b50019ad55d3dd310254431af87e14ef83a2",
|
||||
"sha256:e20d7885a40e68a2bda92908acbabcdf3c14dd386c3845de73ba139e9df1f132",
|
||||
"sha256:e5bb396d63495667d4df42e506eed9d74fc9a51c99c173c04395fe7604c848f1",
|
||||
"sha256:e712a6d00606ad19abdeae852a7e521d6f6d0dcea843708fecf3a38be16a851e",
|
||||
"sha256:e7e7668f89fd598c5469bb58e16bfd12b511d9947ccc75aec94da31f62bc3758",
|
||||
"sha256:f0feb4f2b777fa6377e977faa89c26359d4f31953de15e035505b92f41aa6906",
|
||||
"sha256:f75973a42c710999acd419968bc79f00327e03e855bbe82c6529e003e49af660",
|
||||
"sha256:f766050e491d0b3203b6b85638015f543816a2eb7d089fc04e86e00f6de0e31d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.48.2"
|
||||
},
|
||||
"protobuf": {
|
||||
"hashes": [
|
||||
"sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7",
|
||||
"sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c",
|
||||
"sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2",
|
||||
"sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b",
|
||||
"sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050",
|
||||
"sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9",
|
||||
"sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7",
|
||||
"sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454",
|
||||
"sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480",
|
||||
"sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469",
|
||||
"sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c",
|
||||
"sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e",
|
||||
"sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db",
|
||||
"sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905",
|
||||
"sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b",
|
||||
"sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86",
|
||||
"sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4",
|
||||
"sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402",
|
||||
"sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7",
|
||||
"sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4",
|
||||
"sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99",
|
||||
"sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.20.3"
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:a7687c12b444eaac951ea87a9627c4f904ac757e7abdc5aac32833234af90378",
|
||||
"sha256:e261cdf010c11a41cb5cb5f1bf3338a7433832029f559a6a7614bd42a967c300"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==67.1.0"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
24
proto/generate_protobuf.py
Executable file → Normal file
24
proto/generate_protobuf.py
Executable file → Normal file
@ -1,11 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
if __name__ == '__main__':
|
||||
if 'PIPENV_ACTIVE' not in os.environ:
|
||||
sys.exit(f'This script should be run in a Pipenv.\n\nRun it as:\npipenv run python {os.path.basename(__file__)}')
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def run():
|
||||
SCRIPT_PATH = Path(__file__).absolute().parent
|
||||
@ -30,5 +31,20 @@ def run():
|
||||
subprocess.check_call(['python3', nanopb_generator_path, '-D', c_generated_output_path] + proto_files, cwd=proto_path)
|
||||
|
||||
|
||||
# Use nanopb's packaged protoc to generate python bindings
|
||||
protoc_path = nanopb_path / 'generator' / 'protoc'
|
||||
python_generated_output_path = REPO_ROOT / 'software' / 'python' / 'proto_gen'
|
||||
python_generated_output_path.mkdir(parents=True, exist_ok=True)
|
||||
subprocess.check_call([protoc_path, '--version'])
|
||||
subprocess.check_call([
|
||||
protoc_path,
|
||||
'--python_out',
|
||||
python_generated_output_path,
|
||||
] + proto_files, cwd=proto_path)
|
||||
|
||||
# Copy nanopb's compiled options proto
|
||||
shutil.copy2(nanopb_path / 'generator' / 'proto' / 'nanopb_pb2.py', python_generated_output_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
14
software/python/Pipfile
Normal file
14
software/python/Pipfile
Normal file
@ -0,0 +1,14 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
pyserial = "*"
|
||||
cobs = "*"
|
||||
protobuf = "==3.20.3"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.10"
|
73
software/python/Pipfile.lock
generated
Normal file
73
software/python/Pipfile.lock
generated
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "a74717fa76c8f068ed910686866d0d3ad0ef124601f1d8cf37cc0592e71d4fee"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.10"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"cobs": {
|
||||
"hashes": [
|
||||
"sha256:3f2e8ef22070c3a95ed998303b81c209dd49aaaebf45173499a1a48b8b17bb6f",
|
||||
"sha256:4625f7648e8b0ea50702cf213dcfcc0a50dc78fc6678b174f1f5e0d6fc3687c1",
|
||||
"sha256:7c4a9e246c11f48e12c1231ad5738ea927f663b7b4ffd1de0be3b1cae5bb3884",
|
||||
"sha256:991fc195f0581e456d3dd21e29df493fe9ca1b772084c26921601e48dbc34bd2",
|
||||
"sha256:b4af64be97f2a7215c3ffcd5cca26e6aa166e49cd90941efab95c76211b6710c",
|
||||
"sha256:c747c4b385f04203e1d2b767d61a69580b58c97eea7a6ed998edd42ddd9fcdc5",
|
||||
"sha256:cb573184d982edf8e7c3c08c753b765790790e7ffdca4c2ca5c258bbd9099f33",
|
||||
"sha256:d0f7e7fcad3020676feef505a0212bcd0c86549d3e4c3680f6a7c77ef599e52b",
|
||||
"sha256:d93b10b5370dc8868960aefb70adb1f73a4e6107b16918307a4aeeefd3edb8f6",
|
||||
"sha256:f68ee5e70ae6be79b424cb270835e864b86320a9fcb8048575443b658f61ee0a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"protobuf": {
|
||||
"hashes": [
|
||||
"sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7",
|
||||
"sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c",
|
||||
"sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2",
|
||||
"sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b",
|
||||
"sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050",
|
||||
"sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9",
|
||||
"sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7",
|
||||
"sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454",
|
||||
"sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480",
|
||||
"sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469",
|
||||
"sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c",
|
||||
"sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e",
|
||||
"sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db",
|
||||
"sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905",
|
||||
"sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b",
|
||||
"sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86",
|
||||
"sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4",
|
||||
"sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402",
|
||||
"sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7",
|
||||
"sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4",
|
||||
"sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99",
|
||||
"sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.20.3"
|
||||
},
|
||||
"pyserial": {
|
||||
"hashes": [
|
||||
"sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb",
|
||||
"sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.5"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
5
software/python/proto_gen/README
Normal file
5
software/python/proto_gen/README
Normal file
@ -0,0 +1,5 @@
|
||||
The files in this directory are auto-generated by the protobuf compiler.
|
||||
|
||||
They're checked into the repo to avoid the need to always re-compile them.
|
||||
|
||||
They can be regenerated by running `<repo_root>/proto/generate_protobuf.py`
|
483
software/python/proto_gen/nanopb_pb2.py
Normal file
483
software/python/proto_gen/nanopb_pb2.py
Normal file
@ -0,0 +1,483 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: nanopb.proto
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
from google.protobuf.internal import enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='nanopb.proto',
|
||||
package='',
|
||||
syntax='proto2',
|
||||
serialized_options=_b('\n\030fi.kapsi.koti.jpa.nanopb'),
|
||||
serialized_pb=_b('\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\xa4\x07\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x12\n\nmax_length\x18\x0e \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse\x12\x15\n\x06proto3\x18\x0c \x01(\x08:\x05\x66\x61lse\x12#\n\x14proto3_singular_msgs\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1d\n\x0e\x65num_to_string\x18\r \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0c\x66ixed_length\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0b\x66ixed_count\x18\x10 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0fsubmsg_callback\x18\x16 \x01(\x08:\x05\x66\x61lse\x12/\n\x0cmangle_names\x18\x11 \x01(\x0e\x32\x11.TypenameMangling:\x06M_NONE\x12(\n\x11\x63\x61llback_datatype\x18\x12 \x01(\t:\rpb_callback_t\x12\x34\n\x11\x63\x61llback_function\x18\x13 \x01(\t:\x19pb_default_field_callback\x12\x30\n\x0e\x64\x65scriptorsize\x18\x14 \x01(\x0e\x32\x0f.DescriptorSize:\x07\x44S_AUTO\x12\x1a\n\x0b\x64\x65\x66\x61ult_has\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x0f\n\x07include\x18\x18 \x03(\t\x12\x0f\n\x07\x65xclude\x18\x1a \x03(\t\x12\x0f\n\x07package\x18\x19 \x01(\t\x12\x41\n\rtype_override\x18\x1b \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x19\n\x0bsort_by_tag\x18\x1c \x01(\x08:\x04true\x12.\n\rfallback_type\x18\x1d \x01(\x0e\x32\n.FieldType:\x0b\x46T_CALLBACK*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@*Z\n\x10TypenameMangling\x12\n\n\x06M_NONE\x10\x00\x12\x13\n\x0fM_STRIP_PACKAGE\x10\x01\x12\r\n\tM_FLATTEN\x10\x02\x12\x16\n\x12M_PACKAGE_INITIALS\x10\x03*E\n\x0e\x44\x65scriptorSize\x12\x0b\n\x07\x44S_AUTO\x10\x00\x12\x08\n\x04\x44S_1\x10\x01\x12\x08\n\x04\x44S_2\x10\x02\x12\x08\n\x04\x44S_4\x10\x04\x12\x08\n\x04\x44S_8\x10\x08:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb')
|
||||
,
|
||||
dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
|
||||
|
||||
_FIELDTYPE = _descriptor.EnumDescriptor(
|
||||
name='FieldType',
|
||||
full_name='FieldType',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_DEFAULT', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_CALLBACK', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_POINTER', index=2, number=4,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_STATIC', index=3, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_IGNORE', index=4, number=3,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='FT_INLINE', index=5, number=5,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=985,
|
||||
serialized_end=1090,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_FIELDTYPE)
|
||||
|
||||
FieldType = enum_type_wrapper.EnumTypeWrapper(_FIELDTYPE)
|
||||
_INTSIZE = _descriptor.EnumDescriptor(
|
||||
name='IntSize',
|
||||
full_name='IntSize',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_DEFAULT', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_8', index=1, number=8,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_16', index=2, number=16,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_32', index=3, number=32,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='IS_64', index=4, number=64,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=1092,
|
||||
serialized_end=1160,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_INTSIZE)
|
||||
|
||||
IntSize = enum_type_wrapper.EnumTypeWrapper(_INTSIZE)
|
||||
_TYPENAMEMANGLING = _descriptor.EnumDescriptor(
|
||||
name='TypenameMangling',
|
||||
full_name='TypenameMangling',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='M_NONE', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='M_STRIP_PACKAGE', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='M_FLATTEN', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='M_PACKAGE_INITIALS', index=3, number=3,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=1162,
|
||||
serialized_end=1252,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_TYPENAMEMANGLING)
|
||||
|
||||
TypenameMangling = enum_type_wrapper.EnumTypeWrapper(_TYPENAMEMANGLING)
|
||||
_DESCRIPTORSIZE = _descriptor.EnumDescriptor(
|
||||
name='DescriptorSize',
|
||||
full_name='DescriptorSize',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_AUTO', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_1', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_2', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_4', index=3, number=4,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='DS_8', index=4, number=8,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=1254,
|
||||
serialized_end=1323,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_DESCRIPTORSIZE)
|
||||
|
||||
DescriptorSize = enum_type_wrapper.EnumTypeWrapper(_DESCRIPTORSIZE)
|
||||
FT_DEFAULT = 0
|
||||
FT_CALLBACK = 1
|
||||
FT_POINTER = 4
|
||||
FT_STATIC = 2
|
||||
FT_IGNORE = 3
|
||||
FT_INLINE = 5
|
||||
IS_DEFAULT = 0
|
||||
IS_8 = 8
|
||||
IS_16 = 16
|
||||
IS_32 = 32
|
||||
IS_64 = 64
|
||||
M_NONE = 0
|
||||
M_STRIP_PACKAGE = 1
|
||||
M_FLATTEN = 2
|
||||
M_PACKAGE_INITIALS = 3
|
||||
DS_AUTO = 0
|
||||
DS_1 = 1
|
||||
DS_2 = 2
|
||||
DS_4 = 4
|
||||
DS_8 = 8
|
||||
|
||||
NANOPB_FILEOPT_FIELD_NUMBER = 1010
|
||||
nanopb_fileopt = _descriptor.FieldDescriptor(
|
||||
name='nanopb_fileopt', full_name='nanopb_fileopt', index=0,
|
||||
number=1010, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=True, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR)
|
||||
NANOPB_MSGOPT_FIELD_NUMBER = 1010
|
||||
nanopb_msgopt = _descriptor.FieldDescriptor(
|
||||
name='nanopb_msgopt', full_name='nanopb_msgopt', index=1,
|
||||
number=1010, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=True, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR)
|
||||
NANOPB_ENUMOPT_FIELD_NUMBER = 1010
|
||||
nanopb_enumopt = _descriptor.FieldDescriptor(
|
||||
name='nanopb_enumopt', full_name='nanopb_enumopt', index=2,
|
||||
number=1010, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=True, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR)
|
||||
NANOPB_FIELD_NUMBER = 1010
|
||||
nanopb = _descriptor.FieldDescriptor(
|
||||
name='nanopb', full_name='nanopb', index=3,
|
||||
number=1010, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=True, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR)
|
||||
|
||||
|
||||
_NANOPBOPTIONS = _descriptor.Descriptor(
|
||||
name='NanoPBOptions',
|
||||
full_name='NanoPBOptions',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='max_size', full_name='NanoPBOptions.max_size', index=0,
|
||||
number=1, type=5, cpp_type=1, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='max_length', full_name='NanoPBOptions.max_length', index=1,
|
||||
number=14, type=5, cpp_type=1, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='max_count', full_name='NanoPBOptions.max_count', index=2,
|
||||
number=2, type=5, cpp_type=1, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='int_size', full_name='NanoPBOptions.int_size', index=3,
|
||||
number=7, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='type', full_name='NanoPBOptions.type', index=4,
|
||||
number=3, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='long_names', full_name='NanoPBOptions.long_names', index=5,
|
||||
number=4, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=True,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='packed_struct', full_name='NanoPBOptions.packed_struct', index=6,
|
||||
number=5, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='packed_enum', full_name='NanoPBOptions.packed_enum', index=7,
|
||||
number=10, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='skip_message', full_name='NanoPBOptions.skip_message', index=8,
|
||||
number=6, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='no_unions', full_name='NanoPBOptions.no_unions', index=9,
|
||||
number=8, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='msgid', full_name='NanoPBOptions.msgid', index=10,
|
||||
number=9, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='anonymous_oneof', full_name='NanoPBOptions.anonymous_oneof', index=11,
|
||||
number=11, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='proto3', full_name='NanoPBOptions.proto3', index=12,
|
||||
number=12, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='proto3_singular_msgs', full_name='NanoPBOptions.proto3_singular_msgs', index=13,
|
||||
number=21, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='enum_to_string', full_name='NanoPBOptions.enum_to_string', index=14,
|
||||
number=13, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='fixed_length', full_name='NanoPBOptions.fixed_length', index=15,
|
||||
number=15, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='fixed_count', full_name='NanoPBOptions.fixed_count', index=16,
|
||||
number=16, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='submsg_callback', full_name='NanoPBOptions.submsg_callback', index=17,
|
||||
number=22, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='mangle_names', full_name='NanoPBOptions.mangle_names', index=18,
|
||||
number=17, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='callback_datatype', full_name='NanoPBOptions.callback_datatype', index=19,
|
||||
number=18, type=9, cpp_type=9, label=1,
|
||||
has_default_value=True, default_value=_b("pb_callback_t").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='callback_function', full_name='NanoPBOptions.callback_function', index=20,
|
||||
number=19, type=9, cpp_type=9, label=1,
|
||||
has_default_value=True, default_value=_b("pb_default_field_callback").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='descriptorsize', full_name='NanoPBOptions.descriptorsize', index=21,
|
||||
number=20, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='default_has', full_name='NanoPBOptions.default_has', index=22,
|
||||
number=23, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='include', full_name='NanoPBOptions.include', index=23,
|
||||
number=24, type=9, cpp_type=9, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='exclude', full_name='NanoPBOptions.exclude', index=24,
|
||||
number=26, type=9, cpp_type=9, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='package', full_name='NanoPBOptions.package', index=25,
|
||||
number=25, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='type_override', full_name='NanoPBOptions.type_override', index=26,
|
||||
number=27, type=14, cpp_type=8, label=1,
|
||||
has_default_value=False, default_value=1,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='sort_by_tag', full_name='NanoPBOptions.sort_by_tag', index=27,
|
||||
number=28, type=8, cpp_type=7, label=1,
|
||||
has_default_value=True, default_value=True,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='fallback_type', full_name='NanoPBOptions.fallback_type', index=28,
|
||||
number=29, type=14, cpp_type=8, label=1,
|
||||
has_default_value=True, default_value=1,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto2',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=51,
|
||||
serialized_end=983,
|
||||
)
|
||||
|
||||
_NANOPBOPTIONS.fields_by_name['int_size'].enum_type = _INTSIZE
|
||||
_NANOPBOPTIONS.fields_by_name['type'].enum_type = _FIELDTYPE
|
||||
_NANOPBOPTIONS.fields_by_name['mangle_names'].enum_type = _TYPENAMEMANGLING
|
||||
_NANOPBOPTIONS.fields_by_name['descriptorsize'].enum_type = _DESCRIPTORSIZE
|
||||
_NANOPBOPTIONS.fields_by_name['type_override'].enum_type = google_dot_protobuf_dot_descriptor__pb2._FIELDDESCRIPTORPROTO_TYPE
|
||||
_NANOPBOPTIONS.fields_by_name['fallback_type'].enum_type = _FIELDTYPE
|
||||
DESCRIPTOR.message_types_by_name['NanoPBOptions'] = _NANOPBOPTIONS
|
||||
DESCRIPTOR.enum_types_by_name['FieldType'] = _FIELDTYPE
|
||||
DESCRIPTOR.enum_types_by_name['IntSize'] = _INTSIZE
|
||||
DESCRIPTOR.enum_types_by_name['TypenameMangling'] = _TYPENAMEMANGLING
|
||||
DESCRIPTOR.enum_types_by_name['DescriptorSize'] = _DESCRIPTORSIZE
|
||||
DESCRIPTOR.extensions_by_name['nanopb_fileopt'] = nanopb_fileopt
|
||||
DESCRIPTOR.extensions_by_name['nanopb_msgopt'] = nanopb_msgopt
|
||||
DESCRIPTOR.extensions_by_name['nanopb_enumopt'] = nanopb_enumopt
|
||||
DESCRIPTOR.extensions_by_name['nanopb'] = nanopb
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
NanoPBOptions = _reflection.GeneratedProtocolMessageType('NanoPBOptions', (_message.Message,), dict(
|
||||
DESCRIPTOR = _NANOPBOPTIONS,
|
||||
__module__ = 'nanopb_pb2'
|
||||
# @@protoc_insertion_point(class_scope:NanoPBOptions)
|
||||
))
|
||||
_sym_db.RegisterMessage(NanoPBOptions)
|
||||
|
||||
nanopb_fileopt.message_type = _NANOPBOPTIONS
|
||||
google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(nanopb_fileopt)
|
||||
nanopb_msgopt.message_type = _NANOPBOPTIONS
|
||||
google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(nanopb_msgopt)
|
||||
nanopb_enumopt.message_type = _NANOPBOPTIONS
|
||||
google_dot_protobuf_dot_descriptor__pb2.EnumOptions.RegisterExtension(nanopb_enumopt)
|
||||
nanopb.message_type = _NANOPBOPTIONS
|
||||
google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(nanopb)
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)
|
101
software/python/proto_gen/smartknob_pb2.py
Normal file
101
software/python/proto_gen/smartknob_pb2.py
Normal file
@ -0,0 +1,101 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: smartknob.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
import nanopb_pb2 as nanopb__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fsmartknob.proto\x12\x02PB\x1a\x0cnanopb.proto\"y\n\rFromSmartKnob\x12\x16\n\x03\x61\x63k\x18\x01 \x01(\x0b\x32\x07.PB.AckH\x00\x12\x16\n\x03log\x18\x02 \x01(\x0b\x32\x07.PB.LogH\x00\x12-\n\x0fsmartknob_state\x18\x03 \x01(\x0b\x32\x12.PB.SmartKnobStateH\x00\x42\t\n\x07payload\"\x14\n\x03\x41\x63k\x12\r\n\x05nonce\x18\x01 \x01(\r\"\x1a\n\x03Log\x12\x13\n\x03msg\x18\x01 \x01(\tB\x06\x92?\x03p\xff\x01\"j\n\x0eSmartKnobState\x12\x18\n\x10\x63urrent_position\x18\x01 \x01(\x05\x12\x19\n\x11sub_position_unit\x18\x02 \x01(\x02\x12#\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x13.PB.SmartKnobConfig\"\x83\x01\n\x0bToSmartknob\x12\r\n\x05nonce\x18\x01 \x01(\r\x12)\n\rrequest_state\x18\x02 \x01(\x0b\x32\x10.PB.RequestStateH\x00\x12/\n\x10smartknob_config\x18\x03 \x01(\x0b\x32\x13.PB.SmartKnobConfigH\x00\x42\t\n\x07payload\"\x8f\x02\n\x0fSmartKnobConfig\x12\x10\n\x08position\x18\x01 \x01(\x05\x12\x14\n\x0cmin_position\x18\x02 \x01(\x05\x12\x14\n\x0cmax_position\x18\x03 \x01(\x05\x12\x1e\n\x16position_width_radians\x18\x04 \x01(\x02\x12\x1c\n\x14\x64\x65tent_strength_unit\x18\x05 \x01(\x02\x12\x1d\n\x15\x65ndstop_strength_unit\x18\x06 \x01(\x02\x12\x12\n\nsnap_point\x18\x07 \x01(\x02\x12\x13\n\x04text\x18\x08 \x01(\tB\x05\x92?\x02p2\x12\x1f\n\x10\x64\x65tent_positions\x18\t \x03(\x05\x42\x05\x92?\x02\x10\x05\x12\x17\n\x0fsnap_point_bias\x18\n \x01(\x02\"\x0e\n\x0cRequestStateb\x06proto3')
|
||||
|
||||
|
||||
|
||||
_FROMSMARTKNOB = DESCRIPTOR.message_types_by_name['FromSmartKnob']
|
||||
_ACK = DESCRIPTOR.message_types_by_name['Ack']
|
||||
_LOG = DESCRIPTOR.message_types_by_name['Log']
|
||||
_SMARTKNOBSTATE = DESCRIPTOR.message_types_by_name['SmartKnobState']
|
||||
_TOSMARTKNOB = DESCRIPTOR.message_types_by_name['ToSmartknob']
|
||||
_SMARTKNOBCONFIG = DESCRIPTOR.message_types_by_name['SmartKnobConfig']
|
||||
_REQUESTSTATE = DESCRIPTOR.message_types_by_name['RequestState']
|
||||
FromSmartKnob = _reflection.GeneratedProtocolMessageType('FromSmartKnob', (_message.Message,), {
|
||||
'DESCRIPTOR' : _FROMSMARTKNOB,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PB.FromSmartKnob)
|
||||
})
|
||||
_sym_db.RegisterMessage(FromSmartKnob)
|
||||
|
||||
Ack = _reflection.GeneratedProtocolMessageType('Ack', (_message.Message,), {
|
||||
'DESCRIPTOR' : _ACK,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PB.Ack)
|
||||
})
|
||||
_sym_db.RegisterMessage(Ack)
|
||||
|
||||
Log = _reflection.GeneratedProtocolMessageType('Log', (_message.Message,), {
|
||||
'DESCRIPTOR' : _LOG,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PB.Log)
|
||||
})
|
||||
_sym_db.RegisterMessage(Log)
|
||||
|
||||
SmartKnobState = _reflection.GeneratedProtocolMessageType('SmartKnobState', (_message.Message,), {
|
||||
'DESCRIPTOR' : _SMARTKNOBSTATE,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PB.SmartKnobState)
|
||||
})
|
||||
_sym_db.RegisterMessage(SmartKnobState)
|
||||
|
||||
ToSmartknob = _reflection.GeneratedProtocolMessageType('ToSmartknob', (_message.Message,), {
|
||||
'DESCRIPTOR' : _TOSMARTKNOB,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PB.ToSmartknob)
|
||||
})
|
||||
_sym_db.RegisterMessage(ToSmartknob)
|
||||
|
||||
SmartKnobConfig = _reflection.GeneratedProtocolMessageType('SmartKnobConfig', (_message.Message,), {
|
||||
'DESCRIPTOR' : _SMARTKNOBCONFIG,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PB.SmartKnobConfig)
|
||||
})
|
||||
_sym_db.RegisterMessage(SmartKnobConfig)
|
||||
|
||||
RequestState = _reflection.GeneratedProtocolMessageType('RequestState', (_message.Message,), {
|
||||
'DESCRIPTOR' : _REQUESTSTATE,
|
||||
'__module__' : 'smartknob_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PB.RequestState)
|
||||
})
|
||||
_sym_db.RegisterMessage(RequestState)
|
||||
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
_LOG.fields_by_name['msg']._options = None
|
||||
_LOG.fields_by_name['msg']._serialized_options = b'\222?\003p\377\001'
|
||||
_SMARTKNOBCONFIG.fields_by_name['text']._options = None
|
||||
_SMARTKNOBCONFIG.fields_by_name['text']._serialized_options = b'\222?\002p2'
|
||||
_SMARTKNOBCONFIG.fields_by_name['detent_positions']._options = None
|
||||
_SMARTKNOBCONFIG.fields_by_name['detent_positions']._serialized_options = b'\222?\002\020\005'
|
||||
_FROMSMARTKNOB._serialized_start=37
|
||||
_FROMSMARTKNOB._serialized_end=158
|
||||
_ACK._serialized_start=160
|
||||
_ACK._serialized_end=180
|
||||
_LOG._serialized_start=182
|
||||
_LOG._serialized_end=208
|
||||
_SMARTKNOBSTATE._serialized_start=210
|
||||
_SMARTKNOBSTATE._serialized_end=316
|
||||
_TOSMARTKNOB._serialized_start=319
|
||||
_TOSMARTKNOB._serialized_end=450
|
||||
_SMARTKNOBCONFIG._serialized_start=453
|
||||
_SMARTKNOBCONFIG._serialized_end=724
|
||||
_REQUESTSTATE._serialized_start=726
|
||||
_REQUESTSTATE._serialized_end=740
|
||||
# @@protoc_insertion_point(module_scope)
|
46
software/python/simple_example.py
Normal file
46
software/python/simple_example.py
Normal file
@ -0,0 +1,46 @@
|
||||
import os
|
||||
import sys
|
||||
if __name__ == '__main__':
|
||||
if 'PIPENV_ACTIVE' not in os.environ:
|
||||
sys.exit(f'This script should be run in a Pipenv.\n\nRun it as:\npipenv run python {os.path.basename(__file__)}')
|
||||
|
||||
# Place imports below this line
|
||||
import logging
|
||||
import math
|
||||
|
||||
from smartknob_io import (
|
||||
ask_for_serial_port,
|
||||
smartknob_context
|
||||
)
|
||||
from proto_gen import smartknob_pb2
|
||||
|
||||
def _run_example():
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
p = ask_for_serial_port()
|
||||
with smartknob_context(p) as s:
|
||||
last_state = smartknob_pb2.SmartKnobState()
|
||||
def log_state(message):
|
||||
nonlocal last_state
|
||||
if last_state.config.SerializeToString(deterministic=True) != message.config.SerializeToString(deterministic=True):
|
||||
logging.info('State: ' + str(message))
|
||||
last_state = message
|
||||
s.add_handler('smartknob_state', log_state)
|
||||
s.request_state()
|
||||
|
||||
# Run forever, set config when enter is pressed
|
||||
while True:
|
||||
input()
|
||||
config = smartknob_pb2.SmartKnobConfig()
|
||||
config.position = 0
|
||||
config.min_position = 0
|
||||
config.max_position = 5
|
||||
config.position_width_radians = math.radians(10)
|
||||
config.detent_strength_unit = 1
|
||||
config.endstop_strength_unit = 1
|
||||
config.snap_point = 1.1
|
||||
config.text = "From Python!"
|
||||
s.set_config(config)
|
||||
|
||||
if __name__ == '__main__':
|
||||
_run_example()
|
258
software/python/smartknob_io.py
Normal file
258
software/python/smartknob_io.py
Normal file
@ -0,0 +1,258 @@
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit('This is a library file to be imported into your own python scripts. It doesn\'t do anything if run directly')
|
||||
|
||||
|
||||
from cobs import cobs
|
||||
from collections import (
|
||||
defaultdict,
|
||||
)
|
||||
from contextlib import contextmanager
|
||||
from enum import Enum
|
||||
import logging
|
||||
import os
|
||||
from queue import (
|
||||
Empty,
|
||||
Full,
|
||||
Queue,
|
||||
)
|
||||
from random import randint
|
||||
import serial
|
||||
import serial.tools.list_ports
|
||||
import sys
|
||||
from threading import (
|
||||
Thread,
|
||||
Lock,
|
||||
)
|
||||
import time
|
||||
import zlib
|
||||
|
||||
software_root = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.append(os.path.join(software_root, 'proto_gen'))
|
||||
|
||||
from proto_gen import smartknob_pb2
|
||||
|
||||
SMARTKNOB_BAUD = 921600
|
||||
|
||||
|
||||
class Smartknob(object):
|
||||
RETRY_TIMEOUT = 0.25
|
||||
|
||||
def __init__(self, serial_instance):
|
||||
self._serial = serial_instance
|
||||
self._logger = logging.getLogger('smartknob')
|
||||
self._out_q = Queue()
|
||||
self._ack_q = Queue()
|
||||
self._next_nonce = randint(0, 255)
|
||||
self._run = True
|
||||
|
||||
self._lock = Lock()
|
||||
self._message_handlers = defaultdict(list)
|
||||
|
||||
def _read_loop(self):
|
||||
self._logger.debug('Read loop started')
|
||||
buffer = b''
|
||||
while True:
|
||||
buffer += self._serial.read_until(b'\0')
|
||||
if not self._run:
|
||||
return
|
||||
|
||||
if not len(buffer):
|
||||
continue
|
||||
|
||||
if not buffer.endswith(b'\0'):
|
||||
continue
|
||||
|
||||
self._process_frame(buffer[:-1])
|
||||
buffer = b''
|
||||
|
||||
def _process_frame(self, frame):
|
||||
try:
|
||||
decoded = cobs.decode(frame)
|
||||
except cobs.DecodeError:
|
||||
self._logger.debug(f'Failed decode ({len(frame)} bytes)')
|
||||
self._logger.debug(frame)
|
||||
return
|
||||
|
||||
if len(decoded) < 4:
|
||||
return
|
||||
|
||||
payload = decoded[:-4]
|
||||
expected_crc = zlib.crc32(payload) & 0xffffffff
|
||||
provided_crc = (decoded[-1] << 24) \
|
||||
| (decoded[-2] << 16) \
|
||||
| (decoded[-3] << 8) \
|
||||
| decoded[-4]
|
||||
|
||||
if expected_crc != provided_crc:
|
||||
self._logger.debug(f'Bad CRC. expected={hex(expected_crc)}, actual={hex(provided_crc)}')
|
||||
return
|
||||
|
||||
message = smartknob_pb2.FromSmartKnob()
|
||||
message.ParseFromString(payload)
|
||||
self._logger.debug(message)
|
||||
|
||||
payload_type = message.WhichOneof('payload')
|
||||
|
||||
# If this is an ack, notify the write thread
|
||||
if payload_type == 'ack':
|
||||
nonce = message.ack.nonce
|
||||
self._ack_q.put(nonce)
|
||||
|
||||
with self._lock:
|
||||
for handler in self._message_handlers[payload_type] + self._message_handlers[None]:
|
||||
try:
|
||||
handler(getattr(message, payload_type))
|
||||
except:
|
||||
self._logger.warning(f'Unhandled exception in message handler ({payload_type})', exc_info=True)
|
||||
|
||||
def _write_loop(self):
|
||||
self._logger.debug('Write loop started')
|
||||
while True:
|
||||
data = self._out_q.get()
|
||||
# Check for shutdown
|
||||
if not self._run:
|
||||
self._logger.debug('Write loop exiting @ _out_q')
|
||||
return
|
||||
(nonce, encoded_message) = data
|
||||
|
||||
next_retry = 0
|
||||
while True:
|
||||
if time.time() >= next_retry:
|
||||
if next_retry > 0:
|
||||
self._logger.debug('Retry write...')
|
||||
self._serial.write(encoded_message)
|
||||
self._serial.write(b'\0')
|
||||
next_retry = time.time() + Smartknob.RETRY_TIMEOUT
|
||||
|
||||
try:
|
||||
latest_ack_nonce = self._ack_q.get(timeout=next_retry - time.time())
|
||||
except Empty:
|
||||
latest_ack_nonce = None
|
||||
|
||||
# Check for shutdown
|
||||
if not self._run:
|
||||
self._logger.debug('Write loop exiting @ _ack_q')
|
||||
return
|
||||
|
||||
if latest_ack_nonce == nonce:
|
||||
break
|
||||
else:
|
||||
self._logger.debug(f'Got unexpected nonce: {latest_ack_nonce}')
|
||||
|
||||
def _enqueue_message(self, message):
|
||||
nonce = self._next_nonce
|
||||
self._next_nonce += 1
|
||||
|
||||
message.nonce = nonce
|
||||
|
||||
payload = bytearray(message.SerializeToString())
|
||||
|
||||
crc = zlib.crc32(payload) & 0xffffffff
|
||||
payload.append(crc & 0xff)
|
||||
payload.append((crc >> 8) & 0xff)
|
||||
payload.append((crc >> 16) & 0xff)
|
||||
payload.append((crc >> 24) & 0xff)
|
||||
|
||||
encoded_message = cobs.encode(payload)
|
||||
|
||||
self._out_q.put((nonce, encoded_message))
|
||||
|
||||
approx_q_length = self._out_q.qsize()
|
||||
self._logger.debug(f'Out q length: {approx_q_length}')
|
||||
if approx_q_length > 10:
|
||||
self._logger.warning(f'Output queue length is high! ({approx_q_length}) Is the smartknob still connected and functional?')
|
||||
|
||||
def set_config(self, config):
|
||||
message = smartknob_pb2.ToSmartknob()
|
||||
message.smartknob_config.CopyFrom(config)
|
||||
self._enqueue_message(message)
|
||||
|
||||
def start(self):
|
||||
self.read_thread = Thread(target=self._read_loop)
|
||||
self.write_thread = Thread(target=self._write_loop)
|
||||
self.read_thread.start()
|
||||
self.write_thread.start()
|
||||
|
||||
def shutdown(self):
|
||||
self._logger.info('Shutting down...')
|
||||
self._run = False
|
||||
self.read_thread.join()
|
||||
self._logger.debug('Read thread terminated')
|
||||
self._out_q.put(None)
|
||||
self._ack_q.put(None)
|
||||
self.write_thread.join()
|
||||
self._logger.debug('Write thread terminated')
|
||||
|
||||
def add_handler(self, message_type, handler):
|
||||
with self._lock:
|
||||
self._message_handlers[message_type].append(handler)
|
||||
return lambda: self._remove_handler(message_type, handler)
|
||||
|
||||
def _remove_handler(self, message_type, handler):
|
||||
with self._lock:
|
||||
self._message_handlers[message_type].remove(handler)
|
||||
|
||||
def request_state(self):
|
||||
message = smartknob_pb2.ToSmartknob()
|
||||
message.request_state.SetInParent()
|
||||
self._enqueue_message(message)
|
||||
|
||||
def hard_reset(self):
|
||||
self._serial.setRTS(True)
|
||||
self._serial.setDTR(False)
|
||||
time.sleep(0.2)
|
||||
self._serial.setDTR(True)
|
||||
time.sleep(0.2)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def smartknob_context(serial_port, default_logging=True, wait_for_comms=True):
|
||||
with serial.Serial(serial_port, SMARTKNOB_BAUD, timeout=1.0) as ser:
|
||||
s = Smartknob(ser)
|
||||
s.start()
|
||||
|
||||
if default_logging:
|
||||
s.add_handler('log', lambda msg: s._logger.info(f'From smartknob: {msg.msg}'))
|
||||
|
||||
if wait_for_comms:
|
||||
s._logger.info('Connecting to smartknob...')
|
||||
q = Queue(1)
|
||||
def startup_handler(message):
|
||||
try:
|
||||
q.put_nowait(None)
|
||||
except Full:
|
||||
pass
|
||||
unregister = s.add_handler('smartknob_state', startup_handler)
|
||||
|
||||
s.request_state()
|
||||
q.get()
|
||||
unregister()
|
||||
s._logger.info('Connected!')
|
||||
|
||||
try:
|
||||
yield s
|
||||
finally:
|
||||
s.shutdown()
|
||||
|
||||
|
||||
def ask_for_serial_port():
|
||||
"""
|
||||
Helper function to ask which port to use via stdin
|
||||
"""
|
||||
print('Available ports:')
|
||||
ports = sorted(
|
||||
filter(
|
||||
lambda p: p.description != 'n/a',
|
||||
serial.tools.list_ports.comports(),
|
||||
),
|
||||
key=lambda p: p.device,
|
||||
)
|
||||
for i, port in enumerate(ports):
|
||||
print('[{: 2}] {} - {}'.format(i, port.device, port.description))
|
||||
print()
|
||||
value = input('Use which port? ')
|
||||
port_index = int(value)
|
||||
assert 0 <= port_index < len(ports)
|
||||
return ports[port_index].device
|
2
thirdparty/nanopb
vendored
2
thirdparty/nanopb
vendored
@ -1 +1 @@
|
||||
Subproject commit 80f9d5bcbc0da72c95d3411b642c109a14298d75
|
||||
Subproject commit b97aa657a706d3ba4a9a6ccca7043c9d6fe41cba
|
Loading…
Reference in New Issue
Block a user