-
Notifications
You must be signed in to change notification settings - Fork 0
/
fw_update.py
152 lines (124 loc) · 5.07 KB
/
fw_update.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import re as regex
from pathlib import Path
import subprocess
from functools import cached_property
from typing import NamedTuple, Optional, List
FW_TOOL_VERSION_TO_REGEX = {
"2.55.1.0": r"[0-9]+\) \[USB\] Intel RealSense (.+?) s/n (\d+), update serial number: (\d+), firmware version: ([\d.]+)",
"default": r"[0-9]+\) Name: (.*?), serial number: (.*?), update serial number: ([0-9]+), firmware version: (.*?), USB type: (.*?)",
}
class FWDevice(NamedTuple):
serial_number: str
firmware_version: str
is_recovery: bool
class FirmwareUpdater: # noqa: D101
path = "rs-fw-update"
@cached_property
def devices(self) -> List[FWDevice]:
return self._get_devices()
@cached_property
def fw_updater_version(self) -> str:
"""Parses the firmware updater version from the output of the command `rs-fw-update --version`.
Needed because a genius at intel decided to change the output formats of the commands.
Returns:
str: Version of the fw updater tool.
"""
out = subprocess.check_output([FirmwareUpdater.path, "--version"])
line = out.decode("utf-8")
version = line.split("version: ")[1].split("\n")[0]
return version
def parse_device_line(self, line: str) -> Optional[FWDevice]:
"""Parses a line that can contain the device information, and creates a Device if the line is parsed.
Args:
line (str): line to parse
Returns:
Optional[Device]: Device if the line is parsed, None otherwise.
"""
if self.fw_updater_version in FW_TOOL_VERSION_TO_REGEX:
re = FW_TOOL_VERSION_TO_REGEX[self.fw_updater_version]
else:
re = FW_TOOL_VERSION_TO_REGEX["default"]
match = regex.match(re, line)
if "Recovery" in line:
match = regex.search(r"update serial number:\s*(\d+)", line)
update_firmware_serial_number = match.group(1)
return FWDevice(
serial_number=update_firmware_serial_number,
firmware_version="",
is_recovery=True,
)
if match is None:
return None
device_serial_number = match.group(2)
firmware_version = match.group(4)
return FWDevice(
serial_number=device_serial_number,
firmware_version=firmware_version,
is_recovery="Recovery" in line,
)
def _get_devices(self) -> List[FWDevice]: # noqa: D102
params = [FirmwareUpdater.path, "-l"]
res = subprocess.check_output(params)
devices = []
for line in res.splitlines():
print(line.decode("utf-8"))
parsed_device = self.parse_device_line(line.decode("utf-8"))
if parsed_device is None:
continue
else:
devices.append(parsed_device)
return devices
def update_device(
self, device: FWDevice, firmware_filepath: str
) -> bool: # noqa: D102
params = [
FirmwareUpdater.path,
"-f",
firmware_filepath,
"-s",
device.serial_number,
]
if device.is_recovery:
params.append("-r")
res = subprocess.check_output(params)
if "Firmware update done" not in res.decode("utf-8"):
print("Failed to update device, check the log:")
print(res.decode("utf-8"))
return False
print("Device updated successfully")
return True
def update_firmware(file_path: Path) -> None:
"""Updates the firmware of the connected cameras from the provided binary file.
Args:
file_path (Path): Path to the binary file containing the realsense update.
Raises:
FileNotFoundError: If the firmware binary file is not found.
"""
from rich.console import Console
console = Console()
firmware_updater = FirmwareUpdater()
if not file_path.exists() and file_path.is_file:
raise FileNotFoundError(file_path.resolve())
devices = firmware_updater.devices
if len(devices) == 0:
console.print("No devices found [red]:heavy_multiplication_x: [/red]")
return
console.print(f"Will update {devices} - DO NOT DISCONNECT THE CAMERAS!")
for device in devices:
if device.firmware_version in ("5.15.1", "05.15.01.00"):
console.print(
f"Device {device.serial_number} is already up to date {device.firmware_version} [green]:heavy_check_mark: [/green]"
)
continue
console.print(f"Updating {device.serial_number} ...")
res = firmware_updater.update_device(device, str(file_path.resolve()))
if res:
console.print(
f" ({device.serial_number}) updated successfully ! [green]:heavy_check_mark: [/green]"
)
else:
console.print(
f" ({device.serial_number}) failed to update [red]:heavy_multiplication_x: [/red]"
)
if __name__ == "__main__":
update_firmware(Path(__file__).parent / "assets" / "Signed_Image_UVC_5_15_1_0.bin")