1111import sys
1212import zipfile
1313from collections import namedtuple
14- from typing import BinaryIO , Dict , Tuple , Union
14+ from typing import BinaryIO , Dict , Optional , Tuple , Union
1515
16+ import semver
1617from tqdm .auto import tqdm
1718from tqdm .contrib .logging import logging_redirect_tqdm
1819
2627
2728
2829async 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