1414After connecting, programs SHOULD read the Software Revision characteristic of
1515the Device Information Service to determine the Pybricks protocol version. This
1616version can be used to determine the capabilities of the device.
17+
18+ Additional information about the Pybricks Profile can be found at
19+ _`https://github.com/pybricks/technical-info/blob/master/pybricks-ble-profile.md`.
1720"""
1821
1922from enum import IntEnum , IntFlag
@@ -30,12 +33,22 @@ def _pybricks_uuid(short: int) -> str:
3033PYBRICKS_SERVICE_UUID = _pybricks_uuid (0x0001 )
3134"""The Pybricks GATT service UUID."""
3235
33- PYBRICKS_CONTROL_UUID = _pybricks_uuid (0x0002 )
34- """The Pybricks control GATT characteristic UUID.
36+ PYBRICKS_COMMAND_EVENT_UUID = _pybricks_uuid (0x0002 )
37+ """The Pybricks command/event GATT characteristic UUID.
38+
39+ Commands are written to this characteristic and events are received via notifications.
40+
41+ See :class:`Command` and :class:`Event`.
3542
3643.. availability:: Since Pybricks protocol v1.0.0.
3744"""
3845
46+ PYBRICKS_HUB_CAPABILITIES_UUID = _pybricks_uuid (0x0003 )
47+ """The Pybricks hub capabilities GATT characteristic UUID.
48+
49+ .. availability:: Since Pybricks protocol v1.2.0.
50+ """
51+
3952PYBRICKS_PROTOCOL_VERSION = semver .VersionInfo (1 , 1 , 0 )
4053"""The minimum required Pybricks protocol version supported by this library."""
4154
@@ -55,6 +68,89 @@ class Command(IntEnum):
5568 .. availability:: Since Pybricks protocol v1.0.0.
5669 """
5770
71+ START_USER_PROGRAM = 1
72+ """
73+ Requests that the user program should be started.
74+
75+ Hub responds with :attr:`CommandError.BUSY` if a user program is currently running.
76+
77+ .. availability:: Since Pybricks protocol v1.2.0.
78+ """
79+
80+ START_REPL = 2
81+ """
82+ Requests that the interactive REPL should be started.
83+
84+ Hub responds with :attr:`CommandError.INVALID_COMMAND` if the hub does not support the REPL.
85+ Hub responds with :attr:`CommandError.BUSY` if a user program is currently running.
86+
87+ .. availability:: Since Pybricks protocol v1.2.0.
88+ """
89+
90+ WRITE_USER_PROGRAM_META = 3
91+ """
92+ Requests to write user program metadata.
93+
94+ Parameters:
95+ size: The size of the user program in bytes (32-bit unsigned integer).
96+
97+ Hub responds with :attr:`CommandError.BUSY` if a user program is currently running.
98+
99+ .. availability:: Since Pybricks protocol v1.2.0.
100+ """
101+
102+ COMMAND_WRITE_USER_RAM = 4
103+ """
104+ Requests to write data to user RAM.
105+
106+ Parameters:
107+ offset: The offset from the base user RAM address (32-bit unsigned integer).
108+ payload: The data to write to this address (0 to ``max_char_size`` - 5 bytes).
109+
110+ Hub responds with :attr:`CommandError.VALUE_NOT_ALLOWED` if the offset and size exceeded the user RAM area.
111+ Hub responds with :attr:`CommandError.BUSY` if a user program is currently running.
112+
113+ .. availability:: Since Pybricks protocol v1.2.0.
114+ """
115+
116+
117+ class CommandError (IntEnum ):
118+ """
119+ GATT Attribute error codes that can be sent in response to command write requests.
120+ """
121+
122+ # NB: these values are standard BLE protocol values (i.e. Table 3.4 in v5.3 core specification)
123+
124+ INVALID_HANDLE = 0x01
125+ """
126+ The attribute handle given was not valid on this server.
127+ """
128+ NOT_SUPPORTED = 0x06
129+ """
130+ Attribute server does not support the request received from the client.
131+ """
132+ VALUE_NOT_ALLOWED = 0x13
133+ """
134+ The attribute parameter value was not allowed.
135+ """
136+
137+ # NB: these values are limited to 0x80 – 0x9F as required by the Bluetooth
138+ # spec (i.e. Table 3.4 in v5.3 core specification)
139+
140+ INVALID_COMMAND = 0x80
141+ """
142+ An invalid command was requested.
143+
144+ .. availability:: Since Pybricks protocol v1.2.0.
145+ """
146+
147+ BUSY = 0x81
148+ """
149+ The command cannot be completed now because the required resources are busy.
150+
151+ .. availability:: Since Pybricks protocol v1.2.0.
152+ """
153+
58154
59155class Event (IntEnum ):
60156 """Event for Pybricks BLE protocol.
@@ -118,11 +214,52 @@ class StatusFlag(IntFlag):
118214 """
119215
120216 SHUTDOWN = 1 << 7
121- """Hub shutdown was requested .
217+ """Hub has entered shutdown state .
122218
123219 .. availability:: Since Pybricks protocol v1.1.0.
124220 """
125221
222+ SHUTDOWN_REQUESTED = 1 << 8
223+ """Hub shutdown was requested.
224+
225+ .. availability:: Since Pybricks protocol v1.2.0.
226+ """
227+
228+
229+ class HubCapabilityFlag (IntFlag ):
230+ """
231+ Hub capability flags.
232+ """
233+
234+ HAS_REPL = 1 << 0
235+ """
236+ Indicates that the hub has an interactive REPL.
237+
238+ .. availability:: Since Pybricks protocol v1.2.0.
239+ """
240+
241+ USER_PROG_MULTI_FILE_MPY6 = 1 << 1
242+ """
243+ Hub supports user programs using a multi-file blob with MicroPython MPY (ABI V6) files.
244+
245+ .. availability:: Since Pybricks protocol v1.2.0.
246+ """
247+
248+
249+ def unpack_hub_capabilities (data : bytes ) -> Tuple [int , HubCapabilityFlag , int ]:
250+ """
251+ Unpacks the value read from the hub capabilities characteristic.
252+
253+ Args:
254+ data: The raw characteristic value.
255+
256+ Returns:
257+ A tuple of the maximum characteristic write size in bytes, the hub capability
258+ flags and the max user program size in bytes.
259+ """
260+ max_char_size , flags , max_user_prog_size = unpack ("<HII" , data )
261+ return max_char_size , HubCapabilityFlag (flags ), max_user_prog_size
262+
126263
127264# The Pybricks Protocol version also implies certain other services and
128265# and characteristics are present.
0 commit comments