spikeble 0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. spikeble-0.1/.gitignore +5 -0
  2. spikeble-0.1/LICENSE +13 -0
  3. spikeble-0.1/PKG-INFO +126 -0
  4. spikeble-0.1/README.md +93 -0
  5. spikeble-0.1/pyproject.toml +65 -0
  6. spikeble-0.1/spikeble/__init__.py +71 -0
  7. spikeble-0.1/spikeble/_lib/cobs.py +125 -0
  8. spikeble-0.1/spikeble/_lib/connection.py +22 -0
  9. spikeble-0.1/spikeble/_lib/crc.py +11 -0
  10. spikeble-0.1/spikeble/_lib/enumeration.py +79 -0
  11. spikeble-0.1/spikeble/_lib/messages.py +290 -0
  12. spikeble-0.1/spikeble/_lib/readme +2 -0
  13. spikeble-0.1/spikeble/_utils.py +8 -0
  14. spikeble-0.1/spikeble/micropython/app/__init__.py +3 -0
  15. spikeble-0.1/spikeble/micropython/app/bargraph.py +24 -0
  16. spikeble-0.1/spikeble/micropython/app/display.py +39 -0
  17. spikeble-0.1/spikeble/micropython/app/linegraph.py +39 -0
  18. spikeble-0.1/spikeble/micropython/app/music.py +51 -0
  19. spikeble-0.1/spikeble/micropython/app/sound.py +18 -0
  20. spikeble-0.1/spikeble/micropython/color/__init__.py +14 -0
  21. spikeble-0.1/spikeble/micropython/color_matrix/__init__.py +18 -0
  22. spikeble-0.1/spikeble/micropython/color_sensor/__init__.py +16 -0
  23. spikeble-0.1/spikeble/micropython/device/__init__.py +27 -0
  24. spikeble-0.1/spikeble/micropython/distance_sensor/__init__.py +30 -0
  25. spikeble-0.1/spikeble/micropython/force_sensor/__init__.py +65 -0
  26. spikeble-0.1/spikeble/micropython/hub/__init__.py +13 -0
  27. spikeble-0.1/spikeble/micropython/hub/button.py +37 -0
  28. spikeble-0.1/spikeble/micropython/hub/light.py +38 -0
  29. spikeble-0.1/spikeble/micropython/hub/light_matrix.py +249 -0
  30. spikeble-0.1/spikeble/micropython/hub/motion_sensor.py +142 -0
  31. spikeble-0.1/spikeble/micropython/hub/port.py +25 -0
  32. spikeble-0.1/spikeble/micropython/hub/sound.py +74 -0
  33. spikeble-0.1/spikeble/micropython/motor/__init__.py +398 -0
  34. spikeble-0.1/spikeble/micropython/motor_pair/__init__.py +555 -0
  35. spikeble-0.1/spikeble/micropython/orientation/__init__.py +12 -0
  36. spikeble-0.1/spikeble/micropython/runloop/__init__.py +85 -0
  37. spikeble-0.1/spikeble/spike.py +243 -0
@@ -0,0 +1,5 @@
1
+ __pycache__/
2
+ .venv*
3
+ local/
4
+ .vscode/
5
+ dist/
spikeble-0.1/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2025 Michael Gross
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
spikeble-0.1/PKG-INFO ADDED
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.4
2
+ Name: spikeble
3
+ Version: 0.1
4
+ Summary: BLE interface for running Micropython on LEGO SPIKE devices
5
+ Project-URL: Homepage, https://github.com/MGross21/spikeble
6
+ Project-URL: Repository, https://github.com/MGross21/spikeble
7
+ Project-URL: Issues, https://github.com/MGross21/spikeble/issues
8
+ Author-email: Michael Gross <MGross21@users.noreply.github.com>
9
+ License: Copyright 2025 Michael Gross
10
+
11
+ Licensed under the Apache License, Version 2.0 (the "License");
12
+ you may not use this file except in compliance with the License.
13
+ You may obtain a copy of the License at
14
+
15
+ http://www.apache.org/licenses/LICENSE-2.0
16
+
17
+ Unless required by applicable law or agreed to in writing, software
18
+ distributed under the License is distributed on an "AS IS" BASIS,
19
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ See the License for the specific language governing permissions and
21
+ limitations under the License.
22
+ License-File: LICENSE
23
+ Keywords: ble,bluetooth,lego,robotics,spike
24
+ Classifier: License :: OSI Approved :: MIT License
25
+ Classifier: Operating System :: OS Independent
26
+ Classifier: Programming Language :: Python :: 3
27
+ Classifier: Programming Language :: Python :: 3 :: Only
28
+ Classifier: Topic :: Software Development :: Libraries
29
+ Classifier: Topic :: System :: Hardware
30
+ Requires-Python: >=3.11
31
+ Requires-Dist: bleak>=1.0.0
32
+ Description-Content-Type: text/markdown
33
+
34
+ <h1 align="center">
35
+ <img src="https://raw.githubusercontent.com/MGross21/spikeble/main/assets/spikeble_logo.png" alt="spikeble logo" width="300" />
36
+ </h1>
37
+ <p align="center">
38
+ <sub>(pronounced "spike-able")</sub>
39
+ <br>
40
+ <img src="https://raw.githubusercontent.com/MGross21/spikeble/main/assets/lego_spike.png" alt="Lego Spike"/>
41
+ </p>
42
+
43
+ ## Installation
44
+
45
+ *From PyPI:*
46
+
47
+ ```console
48
+ pip install spikeble
49
+ ```
50
+
51
+ *From GitHub:*
52
+
53
+ ```console
54
+ pip install git+https://github.com/MGross21/spikeble.git
55
+ ```
56
+
57
+ > **⚠️ Warning:**
58
+ > It is **highly recommended** to install and use this library within a Python virtual environment. Installing `spikeble` will expose all MicroPython modules (such as `app`, `color`, `color_matrix`, `color_sensor`, `device`, `distance_sensor`, `force_sensor`, `hub`, `motor`, `motor_pair`, `orientation`, and `runloop`) as direct imports in your environment. Using a virtual environment prevents conflicts with other Python projects and keeps your global Python installation clean.
59
+ >
60
+ > <details>
61
+ > <summary><strong>Making a Python Virtual Environment</strong></summary>
62
+ >
63
+ > ```bash
64
+ > python -m venv .venv
65
+ >
66
+ > # Activate the virtual environment
67
+ > # On Windows:
68
+ > venv\Scripts\activate
69
+ >
70
+ > # On macOS/Linux:
71
+ > source venv/bin/activate
72
+ > ```
73
+ >
74
+ > Once activated, you can install `spikeble` and other dependencies.
75
+ >
76
+ > </details>
77
+
78
+ ## Running Code on SPIKE
79
+
80
+ To enable auto-complete for MicroPython APIs, place all MicroPython imports inside your `main()` function.
81
+ Use the template below as a starting point for your SPIKE code:
82
+
83
+ ```python
84
+ import spikeble
85
+ import asyncio
86
+
87
+ def main():
88
+ # from app import sound, bargraph, display, linegraph, music
89
+ import color
90
+ import color_matrix
91
+ import color_sensor
92
+ import device
93
+ import distance_sensor
94
+ import force_sensor
95
+ from hub import port, button, light, light_matrix, motion_sensor, sound
96
+ import motor
97
+ import motor_pair
98
+ import orientation
99
+ import runloop
100
+
101
+ ### Insert Your Code Here ###
102
+
103
+ if __name__ == "__main__":
104
+ asyncio.run(spikeble.run(main))
105
+ ```
106
+
107
+ > **Note:**
108
+ > As of `SPIKE™ Firmware v1.8.149` and `RPC v1.0.47`, using `import app` or `from app import ...` will result in an import error. The `app` module is currently disabled until further notice.
109
+
110
+ ### Other Send Methods
111
+
112
+ You can also run code on the SPIKE using the following methods:
113
+
114
+ ```python
115
+ spikeble.run_file("path/to/your_script.py")
116
+ ```
117
+
118
+ ```python
119
+ spikeble.run_str("print('Hello from SPIKE!')")
120
+ ```
121
+
122
+ ## Documentation
123
+
124
+ - [MicroPython Docs](https://spike.legoeducation.com/prime/modal/help/lls-help-python)
125
+ - [Communication Protocol](https://github.com/LEGO/spike-prime-docs)
126
+ <!-- - [Spike 3 Python Docs (Unofficial)](https://tuftsceeo.github.io/SPIKEPythonDocs/SPIKE3.html) -->
spikeble-0.1/README.md ADDED
@@ -0,0 +1,93 @@
1
+ <h1 align="center">
2
+ <img src="https://raw.githubusercontent.com/MGross21/spikeble/main/assets/spikeble_logo.png" alt="spikeble logo" width="300" />
3
+ </h1>
4
+ <p align="center">
5
+ <sub>(pronounced "spike-able")</sub>
6
+ <br>
7
+ <img src="https://raw.githubusercontent.com/MGross21/spikeble/main/assets/lego_spike.png" alt="Lego Spike"/>
8
+ </p>
9
+
10
+ ## Installation
11
+
12
+ *From PyPI:*
13
+
14
+ ```console
15
+ pip install spikeble
16
+ ```
17
+
18
+ *From GitHub:*
19
+
20
+ ```console
21
+ pip install git+https://github.com/MGross21/spikeble.git
22
+ ```
23
+
24
+ > **⚠️ Warning:**
25
+ > It is **highly recommended** to install and use this library within a Python virtual environment. Installing `spikeble` will expose all MicroPython modules (such as `app`, `color`, `color_matrix`, `color_sensor`, `device`, `distance_sensor`, `force_sensor`, `hub`, `motor`, `motor_pair`, `orientation`, and `runloop`) as direct imports in your environment. Using a virtual environment prevents conflicts with other Python projects and keeps your global Python installation clean.
26
+ >
27
+ > <details>
28
+ > <summary><strong>Making a Python Virtual Environment</strong></summary>
29
+ >
30
+ > ```bash
31
+ > python -m venv .venv
32
+ >
33
+ > # Activate the virtual environment
34
+ > # On Windows:
35
+ > venv\Scripts\activate
36
+ >
37
+ > # On macOS/Linux:
38
+ > source venv/bin/activate
39
+ > ```
40
+ >
41
+ > Once activated, you can install `spikeble` and other dependencies.
42
+ >
43
+ > </details>
44
+
45
+ ## Running Code on SPIKE
46
+
47
+ To enable auto-complete for MicroPython APIs, place all MicroPython imports inside your `main()` function.
48
+ Use the template below as a starting point for your SPIKE code:
49
+
50
+ ```python
51
+ import spikeble
52
+ import asyncio
53
+
54
+ def main():
55
+ # from app import sound, bargraph, display, linegraph, music
56
+ import color
57
+ import color_matrix
58
+ import color_sensor
59
+ import device
60
+ import distance_sensor
61
+ import force_sensor
62
+ from hub import port, button, light, light_matrix, motion_sensor, sound
63
+ import motor
64
+ import motor_pair
65
+ import orientation
66
+ import runloop
67
+
68
+ ### Insert Your Code Here ###
69
+
70
+ if __name__ == "__main__":
71
+ asyncio.run(spikeble.run(main))
72
+ ```
73
+
74
+ > **Note:**
75
+ > As of `SPIKE™ Firmware v1.8.149` and `RPC v1.0.47`, using `import app` or `from app import ...` will result in an import error. The `app` module is currently disabled until further notice.
76
+
77
+ ### Other Send Methods
78
+
79
+ You can also run code on the SPIKE using the following methods:
80
+
81
+ ```python
82
+ spikeble.run_file("path/to/your_script.py")
83
+ ```
84
+
85
+ ```python
86
+ spikeble.run_str("print('Hello from SPIKE!')")
87
+ ```
88
+
89
+ ## Documentation
90
+
91
+ - [MicroPython Docs](https://spike.legoeducation.com/prime/modal/help/lls-help-python)
92
+ - [Communication Protocol](https://github.com/LEGO/spike-prime-docs)
93
+ <!-- - [Spike 3 Python Docs (Unofficial)](https://tuftsceeo.github.io/SPIKEPythonDocs/SPIKE3.html) -->
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27", "hatch-vcs>=0.4"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "spikeble"
7
+ description = "BLE interface for running Micropython on LEGO SPIKE devices"
8
+ readme = "README.md"
9
+ requires-python = ">=3.11"
10
+ license = { file = "LICENSE" }
11
+ authors = [{ name = "Michael Gross", email = "MGross21@users.noreply.github.com" }]
12
+ keywords = ["lego", "spike", "ble", "bluetooth", "robotics"]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3 :: Only",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Topic :: Software Development :: Libraries",
19
+ "Topic :: System :: Hardware",
20
+ ]
21
+ dependencies = ["bleak>=1.0.0"]
22
+ dynamic = ["version"]
23
+
24
+ [project.urls]
25
+ Homepage = "https://github.com/MGross21/spikeble"
26
+ Repository = "https://github.com/MGross21/spikeble"
27
+ Issues = "https://github.com/MGross21/spikeble/issues"
28
+
29
+ [tool.hatch.version]
30
+ source = "vcs"
31
+ fallback-version = "0.0.0"
32
+ raw-options = { local_scheme = "no-local-version" }
33
+
34
+ [tool.hatch.build.targets.wheel]
35
+ packages = ["spikeble"]
36
+ include = ["spikeble/py.typed"]
37
+
38
+ # Expose MicroPython folders as top-level install packages
39
+ [tool.hatch.build.targets.wheel.force-include]
40
+ "spikeble/micropython/app" = "app"
41
+ "spikeble/micropython/color" = "color"
42
+ "spikeble/micropython/color_matrix" = "color_matrix"
43
+ "spikeble/micropython/color_sensor" = "color_sensor"
44
+ "spikeble/micropython/device" = "device"
45
+ "spikeble/micropython/distance_sensor" = "distance_sensor"
46
+ "spikeble/micropython/force_sensor" = "force_sensor"
47
+ "spikeble/micropython/hub" = "hub"
48
+ "spikeble/micropython/motor" = "motor"
49
+ "spikeble/micropython/motor_pair" = "motor_pair"
50
+ "spikeble/micropython/orientation" = "orientation"
51
+ "spikeble/micropython/runloop" = "runloop"
52
+
53
+ [tool.hatch.build.targets.sdist]
54
+ include = ["/spikeble", "/README.md", "/LICENSE*", "/pyproject.toml"]
55
+
56
+ # ---- Tooling ---------------------------------------------------------------
57
+
58
+ [tool.ruff]
59
+ target-version = "py311"
60
+ line-length = 80
61
+ lint.select = ["E", "F", "I", "UP", "B", "C4", "SIM"]
62
+
63
+ [tool.pytest.ini_options]
64
+ addopts = "-ra -q"
65
+ testpaths = ["tests"]
@@ -0,0 +1,71 @@
1
+ from typing import Callable
2
+
3
+ async def run_fn(
4
+ program: Callable[[], None],
5
+ *,
6
+ slot: int = 0,
7
+ stay_connected: bool = False,
8
+ ):
9
+ """Run a Python function on the SPIKE Prime hub."""
10
+ from .spike import logger
11
+ from ._utils import fn_to_string
12
+ try:
13
+ # call function and see if any front-side errors trigger
14
+ program()
15
+ except Exception as e:
16
+ logger.error(f"Error occurred while running program: {e}")
17
+ await run_str(
18
+ fn_to_string(program),
19
+ slot=slot,
20
+ name=program.__name__ + ".py",
21
+ stay_connected=stay_connected
22
+ )
23
+
24
+ run = run_fn # shorthand alias default
25
+
26
+ async def run_file(
27
+ program_path: str,
28
+ *,
29
+ slot: int = 0,
30
+ stay_connected: bool = False,
31
+ ):
32
+ """Run a Python file on the SPIKE Prime hub."""
33
+ from .spike import logger
34
+ from pathlib import Path
35
+ if not Path(program_path).exists():
36
+ logger.error(f"File not found: {program_path}")
37
+ return
38
+
39
+ program_str = Path(program_path).read_text()
40
+ try:
41
+ compile(program_str, program_path, "exec")
42
+ except Exception as e:
43
+ logger.error(f"Error compiling {program_path}: {e}")
44
+ return
45
+ await run_str(
46
+ program_str,
47
+ slot=slot,
48
+ name=Path(program_path).name,
49
+ stay_connected=stay_connected
50
+ )
51
+
52
+ async def run_str(
53
+ program_str: str,
54
+ *,
55
+ slot: int = 0,
56
+ name: str = "program.py",
57
+ stay_connected: bool = False,
58
+ ):
59
+ """Run a Python string as code on the SPIKE Prime hub."""
60
+ from .spike import Spike
61
+ async with Spike(timeout=10, slot=slot) as hub:
62
+ await hub.get_info()
63
+ await hub.enable_notifications()
64
+ await hub.clear_slot()
65
+ await hub.upload_program(program_str.encode("utf-8"), name=name)
66
+ await hub.start_program()
67
+ if stay_connected:
68
+ try:
69
+ await hub.run_until_disconnect()
70
+ except KeyboardInterrupt:
71
+ await hub.disconnect()
@@ -0,0 +1,125 @@
1
+ """
2
+ Example implementation of the Consistent Overhead Byte Stuffing (COBS) algorithm
3
+ used by the SPIKE™ Prime BLE protocol.
4
+
5
+ This implementation prioritizes readability and simplicity over performance and
6
+ should be used for educational purposes only.
7
+ """
8
+
9
+ DELIMITER = 0x02
10
+ """Delimiter used to mark end of frame"""
11
+
12
+ NO_DELIMITER = 0xFF
13
+ """Code word indicating no delimiter in block"""
14
+
15
+ COBS_CODE_OFFSET = DELIMITER
16
+ """Offset added to code word"""
17
+
18
+ MAX_BLOCK_SIZE = 84
19
+ """Maximum block size (incl. code word)"""
20
+
21
+ XOR = 3
22
+ """XOR mask for encoding"""
23
+
24
+
25
+ # Source: https://lego.github.io/spike-prime-docs/encoding.html#cobs-encode
26
+ def encode(data: bytes):
27
+ """
28
+ Encode data using COBS algorithm, such that no delimiters are present.
29
+ """
30
+ buffer = bytearray()
31
+ code_index = block = 0
32
+
33
+ def begin_block():
34
+ """Append code word to buffer and update code_index and block"""
35
+ nonlocal code_index, block
36
+ code_index = len(buffer) # index of incomplete code word
37
+ buffer.append(NO_DELIMITER) # updated later if delimiter is encountered
38
+ block = 1 # no. of bytes in block (incl. code word)
39
+
40
+ begin_block()
41
+ for byte in data:
42
+ if byte > DELIMITER:
43
+ # non-delimeter value, write as-is
44
+ buffer.append(byte)
45
+ block += 1
46
+
47
+ if byte <= DELIMITER or block > MAX_BLOCK_SIZE:
48
+ # block completed because size limit reached or delimiter found
49
+ if byte <= DELIMITER:
50
+ # reason for block completion is delimiter
51
+ # update code word to reflect block size
52
+ delimiter_base = byte * MAX_BLOCK_SIZE
53
+ block_offset = block + COBS_CODE_OFFSET
54
+ buffer[code_index] = delimiter_base + block_offset
55
+ # begin new block
56
+ begin_block()
57
+
58
+ # update final code word
59
+ buffer[code_index] = block + COBS_CODE_OFFSET
60
+
61
+ return buffer
62
+
63
+
64
+ # Source: https://lego.github.io/spike-prime-docs/encoding.html#cobs-decode
65
+ def decode(data: bytes):
66
+ """
67
+ Decode data using COBS algorithm.
68
+ """
69
+ buffer = bytearray()
70
+
71
+ def unescape(code: int):
72
+ """Decode code word, returning value and block size"""
73
+ if code == 0xFF:
74
+ # no delimiter in block
75
+ return None, MAX_BLOCK_SIZE + 1
76
+ value, block = divmod(code - COBS_CODE_OFFSET, MAX_BLOCK_SIZE)
77
+ if block == 0:
78
+ # maximum block size ending with delimiter
79
+ block = MAX_BLOCK_SIZE
80
+ value -= 1
81
+ return value, block
82
+
83
+ value, block = unescape(data[0])
84
+ for byte in data[1:]: # first byte already processed
85
+ block -= 1
86
+ if block > 0:
87
+ buffer.append(byte)
88
+ continue
89
+
90
+ # block completed
91
+ if value is not None:
92
+ buffer.append(value)
93
+
94
+ value, block = unescape(byte)
95
+
96
+ return buffer
97
+
98
+
99
+ # Source: https://lego.github.io/spike-prime-docs/encoding.html#cobs-pack
100
+ def pack(data: bytes):
101
+ """
102
+ Encode and frame data for transmission.
103
+ """
104
+ buffer = encode(data)
105
+
106
+ # XOR buffer to remove problematic ctrl+C
107
+ for i in range(len(buffer)):
108
+ buffer[i] ^= XOR
109
+
110
+ # add delimiter
111
+ buffer.append(DELIMITER)
112
+ return bytes(buffer)
113
+
114
+
115
+ # Source: https://lego.github.io/spike-prime-docs/encoding.html#cobs-unpack
116
+ def unpack(frame: bytes):
117
+ """
118
+ Unframe and decode frame.
119
+ """
120
+ start = 0
121
+ if frame[0] == 0x01: # unused priority byte
122
+ start += 1
123
+ # unframe and XOR
124
+ unframed = bytes(map(lambda x: x ^ XOR, frame[start:-1]))
125
+ return bytes(decode(unframed))
@@ -0,0 +1,22 @@
1
+ class UUID:
2
+ """
3
+ The LEGO SPIKE Prime Hub exposes a BLE GATT service with two characteristics:
4
+ - RX: for receiving data (from the hub's perspective)
5
+ - TX: for transmitting data (from the hub's perspective)
6
+ """
7
+
8
+ _BASE = "0000FD02"
9
+ _TAIL = "1000-8000-00805F9B34FB"
10
+ SERVICE = f"{_BASE}-0000-{_TAIL}"
11
+ RX = f"{_BASE}-0001-{_TAIL}"
12
+ TX = f"{_BASE}-0002-{_TAIL}"
13
+
14
+
15
+ class Hardware:
16
+ MAC_ADDR = "3C:E4:B0:AB:D3:3A"
17
+
18
+
19
+ class Name:
20
+ HINTS = ["SPIKE", "Spike", "Prime", "Hub", "Lego"] + [
21
+ str(i) for i in range(1, 100)
22
+ ]
@@ -0,0 +1,11 @@
1
+ from binascii import crc32 as _crc32
2
+
3
+
4
+ def crc(data: bytes, seed=0, align=4):
5
+ """
6
+ Calculate the CRC32 of data with an optional seed and alignment.
7
+ """
8
+ remainder = len(data) % align
9
+ if remainder:
10
+ data += b"\x00" * (align - remainder)
11
+ return _crc32(data, seed)
@@ -0,0 +1,79 @@
1
+ from enum import IntEnum, unique
2
+
3
+
4
+ @unique
5
+ class Color(IntEnum):
6
+ BLACK = 0x00
7
+ MAGENTA = 0x01
8
+ PURPLE = 0x02
9
+ BLUE = 0x03
10
+ AZURE = 0x04
11
+ TURQUOISE = 0x05
12
+ GREEN = 0x06
13
+ YELLOW = 0x07
14
+ ORANGE = 0x08
15
+ RED = 0x09
16
+ WHITE = 0x0A
17
+ NONE = 0xFF
18
+
19
+
20
+ @unique
21
+ class HubPort(IntEnum):
22
+ A = 0x00
23
+ B = 0x01
24
+ C = 0x02
25
+ D = 0x03
26
+ E = 0x04
27
+ F = 0x05
28
+
29
+
30
+ @unique
31
+ class HubFace(IntEnum):
32
+ TOP = 0x00
33
+ FRONT = 0x01
34
+ RIGHT = 0x02
35
+ BOTTOM = 0x03
36
+ BACK = 0x04
37
+ LEFT = 0x05
38
+
39
+
40
+ @unique
41
+ class ProgramAction(IntEnum):
42
+ START = 0x00
43
+ STOP = 0x01
44
+
45
+
46
+ @unique
47
+ class ResponseStatus(IntEnum):
48
+ ACKNOWLEDGED = 0x00
49
+ NOT_ACKNOWLEDGED = 0x01
50
+
51
+
52
+ @unique
53
+ class MotorEndState(IntEnum):
54
+ """
55
+ Smart coast/brake: methods of stopping a motor that compensate for inaccuracies when following commands.
56
+ """
57
+
58
+ COAST = 0x00
59
+ BRAKE = 0x01
60
+ HOLD = 0x02
61
+ CONTINUE = 0x03
62
+ COAST_SMART = 0x04
63
+ BRAKE_SMART = 0x05
64
+ DEFAULT = 0xFF
65
+
66
+
67
+ @unique
68
+ class MotorMoveDirection(IntEnum):
69
+ CLOCKWISE = 0x00
70
+ COUNTERCLOCKWISE = 0x01
71
+ SHORTEST_PATH = 0x02
72
+ LONGEST_PATH = 0x03
73
+
74
+
75
+ @unique
76
+ class MotorDeviceType(IntEnum):
77
+ MEDIUM = 0x30
78
+ LARGE = 0x31
79
+ SMALL = 0x41