Skip to content

Commit e737f81

Browse files
committed
flash: add option for setting hub name
This adds a new option to set the hub name when flashing firmware. This requires Pybricks firmware v3.1.0a1 or later.
1 parent 1cf89e7 commit e737f81

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
### Added
1010
- Support for Python 3.9.
1111
- Short `-n` option for `--name` option in `pybricksdev run`.
12+
- Option to set hub name when flashing firmware.
1213

1314
### Changed
1415
- Update to Bleak v0.12.0.

pybricksdev/cli/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,18 +192,23 @@ def add_parser(self, subparsers: argparse._SubParsersAction):
192192
"flash", help="flash firmware on a LEGO Powered Up device"
193193
)
194194
parser.tool = self
195+
195196
parser.add_argument(
196197
"firmware",
197198
metavar="<firmware-file>",
198199
type=argparse.FileType(mode="rb"),
199200
help="the firmware .zip file",
200201
).completer = FilesCompleter(allowednames=(".zip",))
201202

203+
parser.add_argument(
204+
"-n", "--name", metavar="<name>", type=str, help="a custom name for the hub"
205+
)
206+
202207
async def run(self, args: argparse.Namespace):
203208
from ..flash import create_firmware
204209

205210
print("Creating firmware")
206-
firmware, metadata = await create_firmware(args.firmware)
211+
firmware, metadata = await create_firmware(args.firmware, args.name)
207212

208213
if metadata["device-id"] == HubKind.TECHNIC_LARGE:
209214
from ..dfu import flash_dfu

pybricksdev/flash.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
import sys
1212
import zipfile
1313
from collections import namedtuple
14-
from typing import BinaryIO, Dict, Tuple, Union
14+
from typing import BinaryIO, Dict, Optional, Tuple, Union
1515

16+
import semver
1617
from tqdm.auto import tqdm
1718
from tqdm.contrib.logging import logging_redirect_tqdm
1819

@@ -26,17 +27,25 @@
2627

2728

2829
async def create_firmware(
29-
firmware_zip: Union[str, os.PathLike, BinaryIO]
30+
firmware_zip: Union[str, os.PathLike, BinaryIO], name: Optional[str] = None
3031
) -> Tuple[bytes, dict]:
3132
"""Creates a firmware blob from base firmware and main.mpy file.
3233
3334
Arguments:
3435
firmware_zip:
3536
Path to the firmware zip file or a file-like object.
37+
name:
38+
A custom name for the hub.
3639
3740
Returns:
3841
bytes: Composite binary blob with correct padding and checksum.
3942
dict: Meta data for this firmware file.
43+
44+
Raises:
45+
ValueError:
46+
A name is given but the firmware does not support it or the name
47+
exceeds the alloted space in the firmware.
48+
4049
"""
4150

4251
archive = zipfile.ZipFile(firmware_zip)
@@ -61,6 +70,23 @@ async def create_firmware(
6170
# pad with 0s to align to 4-byte boundary
6271
firmware.extend(0 for _ in range(-len(firmware) % 4))
6372

73+
if name:
74+
if semver.compare(metadata["metadata-version"], "1.1.0") < 0:
75+
raise ValueError(
76+
"this firmware image does not support setting the hub name"
77+
)
78+
79+
name = name.encode() + b"\0"
80+
81+
max_size = metadata["max-hub-name-size"]
82+
if len(name) > max_size:
83+
raise ValueError(
84+
f"name is too big - must be < {metadata['max-hub-name-size']} UTF-8 bytes"
85+
)
86+
87+
offset = metadata["hub-name-offset"]
88+
firmware[offset : offset + len(name)] = name
89+
6490
# append 32-bit little-endian checksum
6591
if metadata["checksum-type"] == "sum":
6692
firmware.extend(

0 commit comments

Comments
 (0)