mpflash 1.25.0.post1__py3-none-any.whl → 1.25.0rc1__py3-none-any.whl
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.
- mpflash/add_firmware.py +43 -16
- mpflash/ask_input.py +4 -3
- mpflash/basicgit.py +1 -1
- mpflash/bootloader/manual.py +1 -1
- mpflash/cli_download.py +8 -5
- mpflash/cli_flash.py +17 -33
- mpflash/cli_group.py +3 -0
- mpflash/cli_list.py +2 -2
- mpflash/cli_main.py +4 -0
- mpflash/common.py +1 -36
- mpflash/config.py +21 -0
- mpflash/db/__init__.py +2 -0
- mpflash/db/core.py +56 -0
- mpflash/db/gather_boards.py +112 -0
- mpflash/db/loader.py +120 -0
- mpflash/db/meta.py +78 -0
- mpflash/db/micropython_boards.zip +0 -0
- mpflash/db/models.py +93 -0
- mpflash/db/tools.py +27 -0
- mpflash/download/__init__.py +46 -64
- mpflash/download/from_web.py +26 -36
- mpflash/download/fwinfo.py +41 -0
- mpflash/download/jid.py +53 -0
- mpflash/downloaded.py +79 -93
- mpflash/flash/__init__.py +7 -3
- mpflash/flash/esp.py +2 -1
- mpflash/flash/worklist.py +16 -28
- mpflash/list.py +3 -3
- mpflash/logger.py +2 -2
- mpflash/mpboard_id/__init__.py +3 -9
- mpflash/mpboard_id/alternate.py +56 -0
- mpflash/mpboard_id/board_id.py +11 -94
- mpflash/mpboard_id/known.py +44 -56
- mpflash/mpboard_id/resolve.py +19 -0
- mpflash/mpremoteboard/__init__.py +1 -1
- mpflash/mpremoteboard/mpy_fw_info.py +1 -0
- mpflash/mpremoteboard/runner.py +5 -2
- mpflash/vendor/pydfu.py +4 -5
- mpflash/versions.py +3 -0
- {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0rc1.dist-info}/METADATA +2 -2
- mpflash-1.25.0rc1.dist-info/RECORD +69 -0
- mpflash/db/boards.py +0 -63
- mpflash/db/downloads.py +0 -87
- mpflash/mpboard_id/add_boards.py +0 -260
- mpflash/mpboard_id/board.py +0 -40
- mpflash/mpboard_id/store.py +0 -47
- mpflash-1.25.0.post1.dist-info/RECORD +0 -62
- {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0rc1.dist-info}/LICENSE +0 -0
- {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0rc1.dist-info}/WHEEL +0 -0
- {mpflash-1.25.0.post1.dist-info → mpflash-1.25.0rc1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
from dataclasses import dataclass, field
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
|
5
|
+
@dataclass
|
6
|
+
class FWInfo:
|
7
|
+
"""
|
8
|
+
Downloaded Firmware information
|
9
|
+
is somewhat related to the BOARD class in the mpboard_id module
|
10
|
+
"""
|
11
|
+
|
12
|
+
port: str # MicroPython port
|
13
|
+
board: str # MicroPython board
|
14
|
+
filename: str = field(default="") # relative filename of the firmware image
|
15
|
+
url: str = field(default="") # url or path to original firmware image
|
16
|
+
variant: str = field(default="") # MicroPython variant
|
17
|
+
preview: bool = field(default=False) # True if the firmware is a preview version
|
18
|
+
version: str = field(default="") # MicroPython version (NO v prefix)
|
19
|
+
url: str = field(default="") # url to the firmware image download folder
|
20
|
+
build: str = field(default="0") # The build = number of commits since the last release
|
21
|
+
ext: str = field(default="") # the file extension of the firmware
|
22
|
+
family: str = field(default="micropython") # The family of the firmware
|
23
|
+
custom: bool = field(default=False) # True if the firmware is a custom build
|
24
|
+
description: str = field(default="") # Description used by this firmware (custom only)
|
25
|
+
mcu: str = field(default="")
|
26
|
+
|
27
|
+
def to_dict(self) -> dict:
|
28
|
+
"""Convert the object to a dictionary"""
|
29
|
+
return self.__dict__
|
30
|
+
|
31
|
+
@classmethod
|
32
|
+
def from_dict(cls, data: dict) -> "FWInfo":
|
33
|
+
"""Create a FWInfo object from a dictionary"""
|
34
|
+
valid_keys = {field.name for field in FWInfo.__dataclass_fields__.values()}
|
35
|
+
filtered_data = {k: v for k, v in data.items() if k in valid_keys}
|
36
|
+
# add missing keys
|
37
|
+
if "ext" not in data:
|
38
|
+
data["ext"] = Path(data["filename"]).suffix
|
39
|
+
if "family" not in data:
|
40
|
+
data["family"] = "micropython"
|
41
|
+
return FWInfo(**filtered_data)
|
mpflash/download/jid.py
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Just In-time Download of firmware if not already available
|
2
|
+
from loguru import logger as log
|
3
|
+
|
4
|
+
from mpflash.common import Params
|
5
|
+
from mpflash.download import download
|
6
|
+
from mpflash.downloaded import find_downloaded_firmware
|
7
|
+
from mpflash.errors import MPFlashError
|
8
|
+
from mpflash.flash.worklist import WorkList
|
9
|
+
from mpflash.mpboard_id.alternate import alternate_board_names
|
10
|
+
|
11
|
+
|
12
|
+
def ensure_firmware_downloaded(worklist: WorkList, version: str) -> None:
|
13
|
+
"""
|
14
|
+
Ensure all firmware in the worklist is downloaded for the given version.
|
15
|
+
|
16
|
+
Iterates over the worklist, downloads missing firmware, and updates the worklist
|
17
|
+
with the downloaded firmware.
|
18
|
+
|
19
|
+
Raises MPFlashError if download fails.
|
20
|
+
"""
|
21
|
+
# iterate over the worklist ann update missing firmware
|
22
|
+
newlist: WorkList = []
|
23
|
+
for mcu, firmware in worklist:
|
24
|
+
if firmware:
|
25
|
+
# firmware is already downloaded
|
26
|
+
newlist.append((mcu, firmware))
|
27
|
+
continue
|
28
|
+
# check if the firmware is already downloaded
|
29
|
+
board_firmwares = find_downloaded_firmware(
|
30
|
+
board_id=f"{mcu.board}-{mcu.variant}" if mcu.variant else mcu.board,
|
31
|
+
version=version,
|
32
|
+
port=mcu.port,
|
33
|
+
)
|
34
|
+
if not board_firmwares:
|
35
|
+
# download the firmware
|
36
|
+
log.info(f"Downloading {version} firmware for {mcu.board} on {mcu.serialport}.")
|
37
|
+
download(ports=[mcu.port], boards=alternate_board_names(mcu.board, mcu.port), versions=[version], force=True, clean=True)
|
38
|
+
new_firmware = find_downloaded_firmware(
|
39
|
+
board_id=f"{mcu.board}-{mcu.variant}" if mcu.variant else mcu.board,
|
40
|
+
version=version,
|
41
|
+
port=mcu.port,
|
42
|
+
)
|
43
|
+
if not new_firmware:
|
44
|
+
raise MPFlashError(f"Failed to download {version} firmware for {mcu.board} on {mcu.serialport}.")
|
45
|
+
newlist.append((mcu, new_firmware[0]))
|
46
|
+
else:
|
47
|
+
log.info(f"Found {version} firmware {board_firmwares[-1].firmware_file} for {mcu.board} on {mcu.serialport}.")
|
48
|
+
newlist.append((mcu, firmware))
|
49
|
+
|
50
|
+
worklist.clear()
|
51
|
+
worklist.extend(newlist)
|
52
|
+
|
53
|
+
pass
|
mpflash/downloaded.py
CHANGED
@@ -1,113 +1,99 @@
|
|
1
|
+
import os
|
1
2
|
from pathlib import Path
|
2
|
-
from typing import
|
3
|
+
from typing import List
|
3
4
|
|
4
|
-
import jsonlines
|
5
5
|
from loguru import logger as log
|
6
6
|
|
7
|
-
from mpflash.
|
8
|
-
from mpflash.db.
|
7
|
+
from mpflash.config import config
|
8
|
+
from mpflash.db.core import Session
|
9
|
+
from mpflash.db.models import Firmware
|
10
|
+
from mpflash.mpboard_id.alternate import alternate_board_names
|
9
11
|
from mpflash.versions import clean_version
|
10
12
|
|
11
|
-
from .config import config
|
12
|
-
|
13
13
|
# #########################################################################################################
|
14
14
|
|
15
15
|
|
16
|
-
def clean_downloaded_firmwares(
|
16
|
+
def clean_downloaded_firmwares() -> None:
|
17
|
+
"""
|
18
|
+
- Check if all firmware records in the database are still available on disk.
|
19
|
+
- If not, remove the record from the database.
|
20
|
+
- For all firmware files on disk that are not in the database:
|
21
|
+
- loag a warning message.
|
22
|
+
- Check if the file is a valid firmware file.
|
23
|
+
- If so, add it to the database.
|
24
|
+
|
17
25
|
"""
|
18
|
-
Remove duplicate entries from the firmware.jsonl file, keeping the latest one
|
19
|
-
uniqueness is based on the filename
|
20
26
|
"""
|
21
|
-
|
22
|
-
|
23
|
-
pass
|
27
|
+
Get all firmware files in the firmware directory and its subfolders.
|
28
|
+
"""
|
24
29
|
|
30
|
+
firmware_dir = Path(config.firmware_folder)
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
selector: Optional[Dict[str, str]] = None,
|
35
|
-
) -> List[FWInfo]:
|
36
|
-
if selector is None:
|
37
|
-
selector = {}
|
38
|
-
|
39
|
-
# Use the information in firmwares.jsonl to find the firmware file
|
40
|
-
log.debug(f"{trie}] Looking for firmware for {board_id} {version} ")
|
41
|
-
fw_list = downloaded()
|
42
|
-
if not fw_list:
|
43
|
-
log.error("No firmware files found. Please download the firmware first.")
|
44
|
-
return []
|
45
|
-
# filter by version
|
46
|
-
version = clean_version(version)
|
47
|
-
fw_list = filter_downloaded_fwlist(fw_list, board_id, version, port, variants, selector)
|
32
|
+
"""
|
33
|
+
Returns a set of firmware file paths (relative to firmware_dir) found on disk.
|
34
|
+
Uses a generator for performance and includes files in subfolders.
|
35
|
+
Skips files with certain extensions.
|
36
|
+
"""
|
37
|
+
firmware_files_on_disk = {
|
38
|
+
str(f.relative_to(firmware_dir)) for f in firmware_dir.rglob("*") if f.is_file() and f.suffix not in {".db", ".bak", ".jsonl"}
|
39
|
+
}
|
48
40
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# ESP board naming conventions have changed by adding a PORT prefix
|
53
|
-
if port.startswith("esp") and not board_id.startswith(port.upper()):
|
54
|
-
board_id = f"{port.upper()}_{board_id}"
|
55
|
-
# RP2 board naming conventions have changed by adding a _RPI prefix
|
56
|
-
if port == "rp2" and not board_id.startswith("RPI_"):
|
57
|
-
board_id = f"RPI_{board_id}"
|
58
|
-
elif trie == 2:
|
59
|
-
board_id = board_id.replace("_", "-")
|
41
|
+
with Session() as session:
|
42
|
+
db_firmwares = session.query(Firmware).all()
|
43
|
+
db_firmware_files = {fw.firmware_file for fw in db_firmwares}
|
60
44
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
selector=selector,
|
68
|
-
)
|
69
|
-
# hope we have a match now for the board
|
70
|
-
# sort by filename
|
71
|
-
fw_list.sort(key=lambda x: x.filename)
|
72
|
-
return fw_list
|
45
|
+
# Remove DB records for files not on disk
|
46
|
+
for fw in db_firmwares:
|
47
|
+
if fw.firmware_file not in firmware_files_on_disk:
|
48
|
+
log.warning(f"Firmware file missing on disk, removing DB record: {fw.firmware_file}")
|
49
|
+
session.delete(fw)
|
50
|
+
session.commit()
|
73
51
|
|
52
|
+
# Warn about files on disk not in DB
|
53
|
+
for fw_file in firmware_files_on_disk - db_firmware_files:
|
54
|
+
log.warning(f"Found file in firmware folder but not in DB: {fw_file}")
|
74
55
|
|
75
|
-
def filter_downloaded_fwlist(
|
76
|
-
fw_list: List[FWInfo],
|
77
|
-
board_id: str,
|
78
|
-
version: str, # v1.2.3
|
79
|
-
port: str,
|
80
|
-
# preview: bool,
|
81
|
-
variants: bool,
|
82
|
-
selector: dict,
|
83
|
-
) -> List[FWInfo]:
|
84
|
-
"""Filter the downloaded firmware list based on the provided parameters"""
|
85
|
-
if "preview" in version:
|
86
|
-
# never get a preview for an older version
|
87
|
-
fw_list = [fw for fw in fw_list if fw.preview]
|
88
|
-
else:
|
89
|
-
# older FWInfo version has no v1.2.3 prefix
|
90
|
-
either = [clean_version(version, drop_v=False), clean_version(version, drop_v=True)]
|
91
|
-
fw_list = [fw for fw in fw_list if fw.version in either]
|
92
|
-
log.trace(f"Filtering firmware for {version} : {len(fw_list)} found.")
|
93
|
-
# filter by port
|
94
|
-
if port:
|
95
|
-
fw_list = [fw for fw in fw_list if fw.port == port and Path(fw.firmware).suffix in PORT_FWTYPES[port]]
|
96
|
-
log.trace(f"Filtering firmware for {port} : {len(fw_list)} found.")
|
97
56
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
57
|
+
def find_downloaded_firmware(
|
58
|
+
board_id: str,
|
59
|
+
version: str = "",
|
60
|
+
port: str = "",
|
61
|
+
variants: bool = False,
|
62
|
+
) -> List[Firmware]:
|
63
|
+
version = clean_version(version)
|
64
|
+
log.debug(f"Looking for firmware for {board_id} {version} ")
|
65
|
+
# Special handling for preview versions
|
66
|
+
with Session() as session:
|
67
|
+
if version == "preview" or "preview" in version:
|
68
|
+
# Find all preview firmwares for this board/port, return the latest (highest build)
|
69
|
+
query = session.query(Firmware).filter(Firmware.board_id == board_id)
|
70
|
+
if port:
|
71
|
+
query = query.filter(Firmware.port == port)
|
72
|
+
query = query.filter(Firmware.firmware_file.contains("preview")).order_by(Firmware.build.desc())
|
73
|
+
fw_list = query.all()
|
74
|
+
if fw_list:
|
75
|
+
return [fw_list[0]] # Return the latest preview only
|
102
76
|
else:
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
77
|
+
fw_list = session.query(Firmware).filter(Firmware.board_id == board_id, Firmware.version == version).all()
|
78
|
+
if fw_list:
|
79
|
+
return fw_list
|
80
|
+
#
|
81
|
+
more_board_ids = alternate_board_names(board_id, port)
|
82
|
+
#
|
83
|
+
log.debug(f"2nd search with renamed board_id :{board_id}")
|
84
|
+
with Session() as session:
|
85
|
+
if version == "preview" or "preview" in version:
|
86
|
+
query = session.query(Firmware).filter(Firmware.board_id.in_(more_board_ids))
|
87
|
+
if port:
|
88
|
+
query = query.filter(Firmware.port == port)
|
89
|
+
query = query.filter(Firmware.firmware_file.contains("preview")).order_by(Firmware.build.desc())
|
90
|
+
fw_list = query.all()
|
91
|
+
if fw_list:
|
92
|
+
return [fw_list[0]]
|
93
|
+
else:
|
94
|
+
fw_list = session.query(Firmware).filter(Firmware.board_id.in_(more_board_ids), Firmware.version == version).all()
|
95
|
+
if fw_list:
|
96
|
+
return fw_list
|
97
|
+
log.warning(f"No firmware files found for board {board_id} version {version}")
|
98
|
+
return []
|
111
99
|
|
112
|
-
# #########################################################################################################
|
113
|
-
#
|
mpflash/flash/__init__.py
CHANGED
@@ -3,7 +3,8 @@ from pathlib import Path
|
|
3
3
|
from loguru import logger as log
|
4
4
|
|
5
5
|
from mpflash.bootloader.activate import enter_bootloader
|
6
|
-
from mpflash.common import PORT_FWTYPES,
|
6
|
+
from mpflash.common import PORT_FWTYPES, UF2_PORTS, BootloaderMethod
|
7
|
+
from mpflash.config import config
|
7
8
|
from mpflash.errors import MPFlashError
|
8
9
|
|
9
10
|
from .esp import flash_esp
|
@@ -15,7 +16,6 @@ from .worklist import WorkList
|
|
15
16
|
|
16
17
|
def flash_list(
|
17
18
|
todo: WorkList,
|
18
|
-
fw_folder: Path,
|
19
19
|
erase: bool,
|
20
20
|
bootloader: BootloaderMethod,
|
21
21
|
**kwargs
|
@@ -23,7 +23,11 @@ def flash_list(
|
|
23
23
|
"""Flash a list of boards with the specified firmware."""
|
24
24
|
flashed = []
|
25
25
|
for mcu, fw_info in todo:
|
26
|
-
|
26
|
+
if not fw_info:
|
27
|
+
log.error(f"Firmware not found for {mcu.board} on {mcu.serialport}, skipping")
|
28
|
+
continue
|
29
|
+
|
30
|
+
fw_file = config.firmware_folder / fw_info.firmware_file
|
27
31
|
if not fw_file.exists():
|
28
32
|
log.error(f"File {fw_file} does not exist, skipping {mcu.board} on {mcu.serialport}")
|
29
33
|
continue
|
mpflash/flash/esp.py
CHANGED
@@ -15,6 +15,7 @@ from mpflash.mpremoteboard import MPRemoteBoard
|
|
15
15
|
|
16
16
|
FlashMode = Literal["keep", "qio", "qout", "dio", "dout"]
|
17
17
|
|
18
|
+
|
18
19
|
def flash_esp(
|
19
20
|
mcu: MPRemoteBoard,
|
20
21
|
fw_file: Path,
|
@@ -30,7 +31,7 @@ def flash_esp(
|
|
30
31
|
log.info(f"Flashing {fw_file} on {mcu.board} on {mcu.serialport}")
|
31
32
|
if not mcu.cpu:
|
32
33
|
# Lookup CPU based on the board name
|
33
|
-
mcu.cpu = find_known_board(mcu.board).
|
34
|
+
mcu.cpu = find_known_board(mcu.board).mcu
|
34
35
|
|
35
36
|
cmds: List[List[str]] = []
|
36
37
|
|
mpflash/flash/worklist.py
CHANGED
@@ -5,7 +5,8 @@ from typing import Dict, List, Optional, Tuple
|
|
5
5
|
|
6
6
|
from loguru import logger as log
|
7
7
|
|
8
|
-
from mpflash.common import
|
8
|
+
from mpflash.common import filtered_comports
|
9
|
+
from mpflash.db.models import Firmware
|
9
10
|
from mpflash.downloaded import find_downloaded_firmware
|
10
11
|
from mpflash.errors import MPFlashError
|
11
12
|
from mpflash.list import show_mcus
|
@@ -13,45 +14,38 @@ from mpflash.mpboard_id import find_known_board
|
|
13
14
|
from mpflash.mpremoteboard import MPRemoteBoard
|
14
15
|
|
15
16
|
# #########################################################################################################
|
16
|
-
WorkList = List[Tuple[MPRemoteBoard,
|
17
|
+
WorkList = List[Tuple[MPRemoteBoard, Optional[Firmware]]]
|
17
18
|
# #########################################################################################################
|
18
19
|
|
19
20
|
|
20
21
|
def auto_update(
|
21
22
|
conn_boards: List[MPRemoteBoard],
|
22
23
|
target_version: str,
|
23
|
-
fw_folder: Path,
|
24
|
-
*,
|
25
|
-
selector: Optional[Dict[str, str]] = None,
|
26
24
|
) -> WorkList:
|
27
25
|
"""Builds a list of boards to update based on the connected boards and the firmwares available locally in the firmware folder.
|
28
26
|
|
29
27
|
Args:
|
30
28
|
conn_boards (List[MPRemoteBoard]): List of connected boards
|
31
29
|
target_version (str): Target firmware version
|
32
|
-
fw_folder (Path): Path to the firmware folder
|
33
30
|
selector (Optional[Dict[str, str]], optional): Selector for filtering firmware. Defaults to None.
|
34
31
|
|
35
32
|
Returns:
|
36
33
|
WorkList: List of boards and firmware information to update
|
37
34
|
"""
|
38
|
-
if selector is None:
|
39
|
-
selector = {}
|
40
35
|
wl: WorkList = []
|
41
36
|
for mcu in conn_boards:
|
42
37
|
if mcu.family not in ("micropython", "unknown"):
|
43
38
|
log.warning(f"Skipping flashing {mcu.family} {mcu.port} {mcu.board} on {mcu.serialport} as it is not a MicroPython firmware")
|
44
39
|
continue
|
45
40
|
board_firmwares = find_downloaded_firmware(
|
46
|
-
|
47
|
-
board_id=mcu.board if not mcu.variant else f"{mcu.board}-{mcu.variant}",
|
41
|
+
board_id=f"{mcu.board}-{mcu.variant}" if mcu.variant else mcu.board,
|
48
42
|
version=target_version,
|
49
43
|
port=mcu.port,
|
50
|
-
selector=selector,
|
51
44
|
)
|
52
45
|
|
53
46
|
if not board_firmwares:
|
54
|
-
log.
|
47
|
+
log.warning(f"No {target_version} firmware found for {mcu.board} on {mcu.serialport}.")
|
48
|
+
wl.append((mcu, None))
|
55
49
|
continue
|
56
50
|
|
57
51
|
if len(board_firmwares) > 1:
|
@@ -59,7 +53,7 @@ def auto_update(
|
|
59
53
|
|
60
54
|
# just use the last firmware
|
61
55
|
fw_info = board_firmwares[-1]
|
62
|
-
log.info(f"Found {target_version} firmware {fw_info.
|
56
|
+
log.info(f"Found {target_version} firmware {fw_info.firmware_file} for {mcu.board} on {mcu.serialport}.")
|
63
57
|
wl.append((mcu, fw_info))
|
64
58
|
return wl
|
65
59
|
|
@@ -69,7 +63,6 @@ def manual_worklist(
|
|
69
63
|
*,
|
70
64
|
board_id: str,
|
71
65
|
version: str,
|
72
|
-
fw_folder: Path,
|
73
66
|
) -> WorkList:
|
74
67
|
"""Create a worklist for a single board specified manually.
|
75
68
|
|
@@ -77,7 +70,6 @@ def manual_worklist(
|
|
77
70
|
serial (str): Serial port of the board
|
78
71
|
board (str): Board_ID
|
79
72
|
version (str): Firmware version
|
80
|
-
fw_folder (Path): Path to the firmware folder
|
81
73
|
|
82
74
|
Returns:
|
83
75
|
WorkList: List of boards and firmware information to update
|
@@ -89,13 +81,13 @@ def manual_worklist(
|
|
89
81
|
info = find_known_board(board_id)
|
90
82
|
mcu.port = info.port
|
91
83
|
# need the CPU type for the esptool
|
92
|
-
mcu.cpu = info.
|
84
|
+
mcu.cpu = info.mcu
|
93
85
|
except (LookupError, MPFlashError) as e:
|
94
86
|
log.error(f"Board {board_id} not found in board database")
|
95
87
|
log.exception(e)
|
96
88
|
return []
|
97
89
|
mcu.board = board_id
|
98
|
-
firmwares = find_downloaded_firmware(
|
90
|
+
firmwares = find_downloaded_firmware(board_id=board_id, version=version, port=mcu.port)
|
99
91
|
if not firmwares:
|
100
92
|
log.error(f"No firmware found for {mcu.port} {board_id} version {version}")
|
101
93
|
return []
|
@@ -107,32 +99,29 @@ def single_auto_worklist(
|
|
107
99
|
serial: str,
|
108
100
|
*,
|
109
101
|
version: str,
|
110
|
-
fw_folder: Path,
|
111
102
|
) -> WorkList:
|
112
103
|
"""Create a worklist for a single serial-port.
|
113
104
|
|
114
105
|
Args:
|
115
106
|
serial_port (str): Serial port of the board
|
116
107
|
version (str): Firmware version
|
117
|
-
fw_folder (Path): Path to the firmware folder
|
118
108
|
|
119
109
|
Returns:
|
120
110
|
WorkList: List of boards and firmware information to update
|
121
111
|
"""
|
122
112
|
log.trace(f"Auto updating {serial} to {version}")
|
123
113
|
conn_boards = [MPRemoteBoard(serial)]
|
124
|
-
todo = auto_update(conn_boards, version
|
125
|
-
show_mcus(conn_boards)
|
114
|
+
todo = auto_update(conn_boards, version) # type: ignore # List / list
|
115
|
+
show_mcus(conn_boards)
|
126
116
|
return todo
|
127
117
|
|
128
118
|
|
129
119
|
def full_auto_worklist(
|
130
120
|
all_boards: List[MPRemoteBoard],
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
fw_folder: Path,
|
121
|
+
*,
|
122
|
+
include: List[str],
|
123
|
+
ignore: List[str],
|
124
|
+
version: str,
|
136
125
|
) -> WorkList:
|
137
126
|
"""
|
138
127
|
Create a worklist for all connected micropython boards based on the information retrieved from the board.
|
@@ -140,14 +129,13 @@ def full_auto_worklist(
|
|
140
129
|
|
141
130
|
Args:
|
142
131
|
version (str): Firmware version
|
143
|
-
fw_folder (Path): Path to the firmware folder
|
144
132
|
|
145
133
|
Returns:
|
146
134
|
WorkList: List of boards and firmware information to update
|
147
135
|
"""
|
148
136
|
log.trace(f"Auto updating all boards to {version}")
|
149
137
|
if selected_boards := filter_boards(all_boards, include=include, ignore=ignore):
|
150
|
-
return auto_update(selected_boards, version
|
138
|
+
return auto_update(selected_boards, version)
|
151
139
|
else:
|
152
140
|
return []
|
153
141
|
|
mpflash/list.py
CHANGED
@@ -16,7 +16,7 @@ def show_mcus(
|
|
16
16
|
refresh: bool = True,
|
17
17
|
*,
|
18
18
|
title_style="magenta",
|
19
|
-
header_style="bold magenta",
|
19
|
+
header_style="bold magenta",
|
20
20
|
):
|
21
21
|
console.print(mcu_table(conn_mcus, title, refresh, title_style=title_style, header_style=header_style))
|
22
22
|
|
@@ -38,7 +38,7 @@ def mcu_table(
|
|
38
38
|
):
|
39
39
|
"""
|
40
40
|
builds a rich table with the connected boards information
|
41
|
-
The columns of the table are adjusted to the terminal width > 90
|
41
|
+
The columns of the table are adjusted to the terminal width > 90
|
42
42
|
the columns are :
|
43
43
|
Narrow Wide
|
44
44
|
- Serial Yes Yes
|
@@ -83,7 +83,7 @@ def mcu_table(
|
|
83
83
|
table.add_column("Port")
|
84
84
|
table.add_column("Board", overflow="fold")
|
85
85
|
if needs_variant:
|
86
|
-
table.add_column("Variant")
|
86
|
+
table.add_column("Variant")
|
87
87
|
if is_wide:
|
88
88
|
table.add_column("CPU")
|
89
89
|
table.add_column("Version", overflow="fold", min_width=5, max_width=16)
|
mpflash/logger.py
CHANGED
@@ -11,8 +11,8 @@ console = Console()
|
|
11
11
|
def _log_formatter(record: dict) -> str:
|
12
12
|
"""Log message formatter to combine loguru and rich formatting."""
|
13
13
|
color_map = {
|
14
|
-
"TRACE": "
|
15
|
-
"DEBUG": "
|
14
|
+
"TRACE": "cyan",
|
15
|
+
"DEBUG": "orange",
|
16
16
|
"INFO": "bold",
|
17
17
|
"SUCCESS": "bold green",
|
18
18
|
"WARNING": "yellow",
|
mpflash/mpboard_id/__init__.py
CHANGED
@@ -3,15 +3,9 @@ Access to the micropython port and board information that is stored in the board
|
|
3
3
|
that is included in the module.
|
4
4
|
|
5
5
|
"""
|
6
|
-
|
7
|
-
from functools import lru_cache
|
8
|
-
from typing import List, Optional, Tuple
|
9
|
-
import importlib
|
10
6
|
from mpflash.errors import MPFlashError
|
11
|
-
from .board import Board
|
12
|
-
|
13
7
|
from mpflash.versions import clean_version
|
14
|
-
from .store import read_known_boardinfo
|
15
|
-
from .known import get_known_ports, get_known_boards_for_port
|
16
|
-
from .known import known_stored_boards, find_known_board
|
17
8
|
|
9
|
+
from .known import (find_known_board, get_known_boards_for_port, known_ports,
|
10
|
+
known_stored_boards)
|
11
|
+
from .resolve import resolve_board_ids
|
@@ -0,0 +1,56 @@
|
|
1
|
+
from typing import Dict, List, Optional
|
2
|
+
|
3
|
+
from loguru import logger as log
|
4
|
+
|
5
|
+
|
6
|
+
def alternate_board_names(board_id, port="") -> List[str]:
|
7
|
+
more = [board_id]
|
8
|
+
|
9
|
+
log.debug("try for renamed board_id")
|
10
|
+
|
11
|
+
if board_id.startswith("PICO"):
|
12
|
+
more.append(board_id.replace("PICO", "RPI_PICO"))
|
13
|
+
elif board_id.startswith("RPI_"):
|
14
|
+
more.append(board_id.replace("RPI_", ""))
|
15
|
+
elif board_id.startswith("GENERIC"):
|
16
|
+
if port:
|
17
|
+
more.append(board_id.replace("GENERIC", f"{port.upper()}_GENERIC"))
|
18
|
+
else:
|
19
|
+
# just add both of them
|
20
|
+
more.append(board_id.replace("GENERIC", f"ESP32_GENERIC"))
|
21
|
+
more.append(board_id.replace("GENERIC", f"ESP8266_GENERIC"))
|
22
|
+
elif board_id.startswith("ESP32_"):
|
23
|
+
more.append(board_id.replace("ESP32_", ""))
|
24
|
+
elif board_id.startswith("ESP8266_"):
|
25
|
+
more.append(board_id.replace("ESP8266_", ""))
|
26
|
+
|
27
|
+
# VARIANT
|
28
|
+
variant_suffixes = ["SPIRAM", "THREAD"]
|
29
|
+
for board in more:
|
30
|
+
if any(suffix in board for suffix in variant_suffixes):
|
31
|
+
for suffix in variant_suffixes:
|
32
|
+
if board.endswith(f"_{suffix}"):
|
33
|
+
more.append(board.replace(f"_{suffix}", ""))
|
34
|
+
# more.append(board.replace(f"_{suffix}", f"-{suffix}"))
|
35
|
+
break # first one found
|
36
|
+
|
37
|
+
return more
|
38
|
+
|
39
|
+
|
40
|
+
def add_renamed_boards(boards: List[str]) -> List[str]:
|
41
|
+
"""
|
42
|
+
Adds the renamed boards to the list of boards.
|
43
|
+
|
44
|
+
Args:
|
45
|
+
boards : The list of boards to add the renamed boards to.
|
46
|
+
|
47
|
+
Returns:
|
48
|
+
List[str]: The list of boards with the renamed boards added.
|
49
|
+
"""
|
50
|
+
|
51
|
+
_boards = boards.copy()
|
52
|
+
for board in boards:
|
53
|
+
_boards.extend(alternate_board_names(board))
|
54
|
+
if board != board.upper():
|
55
|
+
_boards.extend(alternate_board_names(board.upper()))
|
56
|
+
return _boards
|