black fixes

This commit is contained in:
Otto winter 2021-10-29 12:20:56 +02:00
parent 0e4322a51f
commit 5027bb389c
No known key found for this signature in database
GPG Key ID: 48ED2DDB96D7682C
5 changed files with 236 additions and 143 deletions

View File

@ -9,43 +9,62 @@ import esptool
import serial
from esphomeflasher import const
from esphomeflasher.common import ESP32ChipInfo, EsphomeflasherError, chip_run_stub, \
configure_write_flash_args, detect_chip, detect_flash_size, read_chip_info
from esphomeflasher.const import ESP32_DEFAULT_BOOTLOADER_FORMAT, ESP32_DEFAULT_OTA_DATA, \
ESP32_DEFAULT_PARTITIONS
from esphomeflasher.common import (
ESP32ChipInfo,
EsphomeflasherError,
chip_run_stub,
configure_write_flash_args,
detect_chip,
detect_flash_size,
read_chip_info,
)
from esphomeflasher.const import (
ESP32_DEFAULT_BOOTLOADER_FORMAT,
ESP32_DEFAULT_OTA_DATA,
ESP32_DEFAULT_PARTITIONS,
)
from esphomeflasher.helpers import list_serial_ports
def parse_args(argv):
parser = argparse.ArgumentParser(prog='esphomeflasher {}'.format(const.__version__))
parser.add_argument('-p', '--port',
help="Select the USB/COM port for uploading.")
parser = argparse.ArgumentParser(prog="esphomeflasher {}".format(const.__version__))
parser.add_argument("-p", "--port", help="Select the USB/COM port for uploading.")
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument('--esp8266', action='store_true')
group.add_argument('--esp32', action='store_true')
group.add_argument('--upload-baud-rate', type=int, default=460800,
help="Baud rate to upload with (not for logging)")
parser.add_argument('--bootloader',
help="(ESP32-only) The bootloader to flash.",
default=ESP32_DEFAULT_BOOTLOADER_FORMAT)
parser.add_argument('--partitions',
help="(ESP32-only) The partitions to flash.",
default=ESP32_DEFAULT_PARTITIONS)
parser.add_argument('--otadata',
help="(ESP32-only) The otadata file to flash.",
default=ESP32_DEFAULT_OTA_DATA)
parser.add_argument('--no-erase',
help="Do not erase flash before flashing",
action='store_true')
parser.add_argument('--show-logs', help="Only show logs", action='store_true')
parser.add_argument('binary', help="The binary image to flash.")
group.add_argument("--esp8266", action="store_true")
group.add_argument("--esp32", action="store_true")
group.add_argument(
"--upload-baud-rate",
type=int,
default=460800,
help="Baud rate to upload with (not for logging)",
)
parser.add_argument(
"--bootloader",
help="(ESP32-only) The bootloader to flash.",
default=ESP32_DEFAULT_BOOTLOADER_FORMAT,
)
parser.add_argument(
"--partitions",
help="(ESP32-only) The partitions to flash.",
default=ESP32_DEFAULT_PARTITIONS,
)
parser.add_argument(
"--otadata",
help="(ESP32-only) The otadata file to flash.",
default=ESP32_DEFAULT_OTA_DATA,
)
parser.add_argument(
"--no-erase", help="Do not erase flash before flashing", action="store_true"
)
parser.add_argument("--show-logs", help="Only show logs", action="store_true")
parser.add_argument("binary", help="The binary image to flash.")
return parser.parse_args(argv[1:])
def select_port(args):
if args.port is not None:
print(u"Using '{}' as serial port.".format(args.port))
print("Using '{}' as serial port.".format(args.port))
return args.port
ports = list_serial_ports()
if not ports:
@ -53,10 +72,10 @@ def select_port(args):
if len(ports) != 1:
print("Found more than one serial port:")
for port, desc in ports:
print(u" * {} ({})".format(port, desc))
print(" * {} ({})".format(port, desc))
print("Please choose one with the --port argument.")
raise EsphomeflasherError
print(u"Auto-detected serial port: {}".format(ports[0][0]))
print("Auto-detected serial port: {}".format(ports[0][0]))
return ports[0][0]
@ -69,14 +88,14 @@ def show_logs(serial_port):
except serial.SerialException:
print("Serial port closed!")
return
text = raw.decode(errors='ignore')
line = text.replace('\r', '').replace('\n', '')
time = datetime.now().time().strftime('[%H:%M:%S]')
text = raw.decode(errors="ignore")
line = text.replace("\r", "").replace("\n", "")
time = datetime.now().time().strftime("[%H:%M:%S]")
message = time + line
try:
print(message)
except UnicodeEncodeError:
print(message.encode('ascii', 'backslashreplace'))
print(message.encode("ascii", "backslashreplace"))
def run_esphomeflasher(argv):
@ -89,7 +108,7 @@ def run_esphomeflasher(argv):
return
try:
firmware = open(args.binary, 'rb')
firmware = open(args.binary, "rb")
except IOError as err:
raise EsphomeflasherError("Error opening binary: {}".format(err))
chip = detect_chip(port, args.esp8266, args.esp32)
@ -102,10 +121,17 @@ def run_esphomeflasher(argv):
if isinstance(info, ESP32ChipInfo):
print(" - Number of Cores: {}".format(info.num_cores))
print(" - Max CPU Frequency: {}".format(info.cpu_frequency))
print(" - Has Bluetooth: {}".format('YES' if info.has_bluetooth else 'NO'))
print(" - Has Embedded Flash: {}".format('YES' if info.has_embedded_flash else 'NO'))
print(" - Has Factory-Calibrated ADC: {}".format(
'YES' if info.has_factory_calibrated_adc else 'NO'))
print(" - Has Bluetooth: {}".format("YES" if info.has_bluetooth else "NO"))
print(
" - Has Embedded Flash: {}".format(
"YES" if info.has_embedded_flash else "NO"
)
)
print(
" - Has Factory-Calibrated ADC: {}".format(
"YES" if info.has_factory_calibrated_adc else "NO"
)
)
else:
print(" - Chip ID: {:08X}".format(info.chip_id))
@ -118,14 +144,20 @@ def run_esphomeflasher(argv):
try:
stub_chip.change_baud(args.upload_baud_rate)
except esptool.FatalError as err:
raise EsphomeflasherError("Error changing ESP upload baud rate: {}".format(err))
raise EsphomeflasherError(
"Error changing ESP upload baud rate: {}".format(err)
)
# Check if the higher baud rate works
try:
flash_size = detect_flash_size(stub_chip)
except EsphomeflasherError:
# Go back to old baud rate by recreating chip instance
print("Chip does not support baud rate {}, changing to 115200".format(args.upload_baud_rate))
print(
"Chip does not support baud rate {}, changing to 115200".format(
args.upload_baud_rate
)
)
stub_chip._port.close()
chip = detect_chip(port, args.esp8266, args.esp32)
stub_chip = chip_run_stub(chip)
@ -135,9 +167,9 @@ def run_esphomeflasher(argv):
print(" - Flash Size: {}".format(flash_size))
mock_args = configure_write_flash_args(info, firmware, flash_size,
args.bootloader, args.partitions,
args.otadata)
mock_args = configure_write_flash_args(
info, firmware, flash_size, args.bootloader, args.partitions, args.otadata
)
print(" - Flash Mode: {}".format(mock_args.flash_mode))
print(" - Flash Frequency: {}Hz".format(mock_args.flash_freq.upper()))

View File

@ -35,16 +35,24 @@ class ChipInfo(object):
def as_dict(self):
return {
'family': self.family,
'model': self.model,
'mac': self.mac,
'is_esp32': self.is_esp32,
"family": self.family,
"model": self.model,
"mac": self.mac,
"is_esp32": self.is_esp32,
}
class ESP32ChipInfo(ChipInfo):
def __init__(self, model, mac, num_cores, cpu_frequency, has_bluetooth, has_embedded_flash,
has_factory_calibrated_adc):
def __init__(
self,
model,
mac,
num_cores,
cpu_frequency,
has_bluetooth,
has_embedded_flash,
has_factory_calibrated_adc,
):
super(ESP32ChipInfo, self).__init__("ESP32", model, mac)
self.num_cores = num_cores
self.cpu_frequency = cpu_frequency
@ -54,13 +62,15 @@ class ESP32ChipInfo(ChipInfo):
def as_dict(self):
data = ChipInfo.as_dict(self)
data.update({
'num_cores': self.num_cores,
'cpu_frequency': self.cpu_frequency,
'has_bluetooth': self.has_bluetooth,
'has_embedded_flash': self.has_embedded_flash,
'has_factory_calibrated_adc': self.has_factory_calibrated_adc,
})
data.update(
{
"num_cores": self.num_cores,
"cpu_frequency": self.cpu_frequency,
"has_bluetooth": self.has_bluetooth,
"has_embedded_flash": self.has_embedded_flash,
"has_factory_calibrated_adc": self.has_factory_calibrated_adc,
}
)
return data
@ -71,9 +81,11 @@ class ESP8266ChipInfo(ChipInfo):
def as_dict(self):
data = ChipInfo.as_dict(self)
data.update({
'chip_id': self.chip_id,
})
data.update(
{
"chip_id": self.chip_id,
}
)
return data
@ -85,17 +97,24 @@ def read_chip_property(func, *args, **kwargs):
def read_chip_info(chip):
mac = ':'.join('{:02X}'.format(x) for x in read_chip_property(chip.read_mac))
mac = ":".join("{:02X}".format(x) for x in read_chip_property(chip.read_mac))
if isinstance(chip, esptool.ESP32ROM):
model = read_chip_property(chip.get_chip_description)
features = read_chip_property(chip.get_chip_features)
num_cores = 2 if 'Dual Core' in features else 1
frequency = next((x for x in ('160MHz', '240MHz') if x in features), '80MHz')
has_bluetooth = 'BT' in features
has_embedded_flash = 'Embedded Flash' in features
has_factory_calibrated_adc = 'VRef calibration in efuse' in features
return ESP32ChipInfo(model, mac, num_cores, frequency, has_bluetooth,
has_embedded_flash, has_factory_calibrated_adc)
num_cores = 2 if "Dual Core" in features else 1
frequency = next((x for x in ("160MHz", "240MHz") if x in features), "80MHz")
has_bluetooth = "BT" in features
has_embedded_flash = "Embedded Flash" in features
has_factory_calibrated_adc = "VRef calibration in efuse" in features
return ESP32ChipInfo(
model,
mac,
num_cores,
frequency,
has_bluetooth,
has_embedded_flash,
has_factory_calibrated_adc,
)
elif isinstance(chip, esptool.ESP8266ROM):
model = read_chip_property(chip.get_chip_description)
chip_id = read_chip_property(chip.chip_id)
@ -107,12 +126,14 @@ def chip_run_stub(chip):
try:
return chip.run_stub()
except esptool.FatalError as err:
raise EsphomeflasherError("Error putting ESP in stub flash mode: {}".format(err))
raise EsphomeflasherError(
"Error putting ESP in stub flash mode: {}".format(err)
)
def detect_flash_size(stub_chip):
flash_id = read_chip_property(stub_chip.flash_id)
return esptool.DETECTED_FLASH_SIZES.get(flash_id >> 16, '4MB')
return esptool.DETECTED_FLASH_SIZES.get(flash_id >> 16, "4MB")
def read_firmware_info(firmware):
@ -123,15 +144,16 @@ def read_firmware_info(firmware):
if magic != esptool.ESPLoader.ESP_IMAGE_MAGIC:
raise EsphomeflasherError(
"The firmware binary is invalid (magic byte={:02X}, should be {:02X})"
"".format(magic, esptool.ESPLoader.ESP_IMAGE_MAGIC))
"".format(magic, esptool.ESPLoader.ESP_IMAGE_MAGIC)
)
flash_freq_raw = flash_size_freq & 0x0F
flash_mode = {0: 'qio', 1: 'qout', 2: 'dio', 3: 'dout'}.get(flash_mode_raw)
flash_freq = {0: '40m', 1: '26m', 2: '20m', 0xF: '80m'}.get(flash_freq_raw)
flash_mode = {0: "qio", 1: "qout", 2: "dio", 3: "dout"}.get(flash_mode_raw)
flash_freq = {0: "40m", 1: "26m", 2: "20m", 0xF: "80m"}.get(flash_freq_raw)
return flash_mode, flash_freq
def open_downloadable_binary(path):
if hasattr(path, 'seek'):
if hasattr(path, "seek"):
path.seek(0)
return path
@ -143,10 +165,12 @@ def open_downloadable_binary(path):
response.raise_for_status()
except requests.exceptions.Timeout as err:
raise EsphomeflasherError(
"Timeout while retrieving firmware file '{}': {}".format(path, err))
"Timeout while retrieving firmware file '{}': {}".format(path, err)
)
except requests.exceptions.RequestException as err:
raise EsphomeflasherError(
"Error while retrieving firmware file '{}': {}".format(path, err))
"Error while retrieving firmware file '{}': {}".format(path, err)
)
binary = io.BytesIO()
binary.write(response.content)
@ -154,26 +178,29 @@ def open_downloadable_binary(path):
return binary
try:
return open(path, 'rb')
return open(path, "rb")
except IOError as err:
raise EsphomeflasherError("Error opening binary '{}': {}".format(path, err))
def format_bootloader_path(path, flash_mode, flash_freq):
return path.replace('$FLASH_MODE$', flash_mode).replace('$FLASH_FREQ$', flash_freq)
return path.replace("$FLASH_MODE$", flash_mode).replace("$FLASH_FREQ$", flash_freq)
def configure_write_flash_args(info, firmware_path, flash_size,
bootloader_path, partitions_path, otadata_path):
def configure_write_flash_args(
info, firmware_path, flash_size, bootloader_path, partitions_path, otadata_path
):
addr_filename = []
firmware = open_downloadable_binary(firmware_path)
flash_mode, flash_freq = read_firmware_info(firmware)
if isinstance(info, ESP32ChipInfo):
if flash_freq in ('26m', '20m'):
if flash_freq in ("26m", "20m"):
raise EsphomeflasherError(
"No bootloader available for flash frequency {}".format(flash_freq))
"No bootloader available for flash frequency {}".format(flash_freq)
)
bootloader = open_downloadable_binary(
format_bootloader_path(bootloader_path, flash_mode, flash_freq))
format_bootloader_path(bootloader_path, flash_mode, flash_freq)
)
partitions = open_downloadable_binary(partitions_path)
otadata = open_downloadable_binary(otadata_path)

View File

@ -2,10 +2,16 @@ import re
__version__ = "1.3.1"
ESP32_DEFAULT_OTA_DATA = 'https://raw.githubusercontent.com/espressif/arduino-esp32/1.0.0/tools/partitions/boot_app0.bin'
ESP32_DEFAULT_BOOTLOADER_FORMAT = 'https://raw.githubusercontent.com/espressif/arduino-esp32/' \
'1.0.4/tools/sdk/bin/bootloader_$FLASH_MODE$_$FLASH_FREQ$.bin'
ESP32_DEFAULT_PARTITIONS = 'https://raw.githubusercontent.com/esphome/esphomeflasher/main/partitions.bin'
ESP32_DEFAULT_OTA_DATA = "https://raw.githubusercontent.com/espressif/arduino-esp32/1.0.0/tools/partitions/boot_app0.bin"
ESP32_DEFAULT_BOOTLOADER_FORMAT = (
"https://raw.githubusercontent.com/espressif/arduino-esp32/"
"1.0.4/tools/sdk/bin/bootloader_$FLASH_MODE$_$FLASH_FREQ$.bin"
)
ESP32_DEFAULT_PARTITIONS = (
"https://raw.githubusercontent.com/esphome/esphomeflasher/main/partitions.bin"
)
# https://stackoverflow.com/a/3809435/8924614
HTTP_REGEX = re.compile(r'https?://(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)')
HTTP_REGEX = re.compile(
r"https?://(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)"
)

View File

@ -13,16 +13,16 @@ import wx.lib.mixins.inspection
from esphomeflasher.helpers import list_serial_ports
COLOR_RE = re.compile(r'(?:\033)(?:\[(.*?)[@-~]|\].*?(?:\007|\033\\))')
COLOR_RE = re.compile(r"(?:\033)(?:\[(.*?)[@-~]|\].*?(?:\007|\033\\))")
COLORS = {
'black': wx.BLACK,
'red': wx.RED,
'green': wx.GREEN,
'yellow': wx.YELLOW,
'blue': wx.BLUE,
'magenta': wx.Colour(255, 0, 255),
'cyan': wx.CYAN,
'white': wx.WHITE,
"black": wx.BLACK,
"red": wx.RED,
"green": wx.GREEN,
"yellow": wx.YELLOW,
"blue": wx.BLUE,
"magenta": wx.Colour(255, 0, 255),
"cyan": wx.CYAN,
"white": wx.WHITE,
}
FORE_COLORS = {**COLORS, None: wx.WHITE}
BACK_COLORS = {**COLORS, None: wx.BLACK}
@ -33,7 +33,7 @@ class RedirectText(TextIOBase):
def __init__(self, text_ctrl):
self._out = text_ctrl
self._i = 0
self._line = ''
self._line = ""
self._bold = False
self._italic = False
self._underline = False
@ -61,7 +61,7 @@ class RedirectText(TextIOBase):
self._add_content(self._line[pos:j])
pos = match.end()
for code in match.group(1).split(';'):
for code in match.group(1).split(";"):
code = int(code)
if code == 0:
self._bold = False
@ -87,39 +87,39 @@ class RedirectText(TextIOBase):
elif code == 24:
self._underline = False
elif code == 30:
self._foreground = 'black'
self._foreground = "black"
elif code == 31:
self._foreground = 'red'
self._foreground = "red"
elif code == 32:
self._foreground = 'green'
self._foreground = "green"
elif code == 33:
self._foreground = 'yellow'
self._foreground = "yellow"
elif code == 34:
self._foreground = 'blue'
self._foreground = "blue"
elif code == 35:
self._foreground = 'magenta'
self._foreground = "magenta"
elif code == 36:
self._foreground = 'cyan'
self._foreground = "cyan"
elif code == 37:
self._foreground = 'white'
self._foreground = "white"
elif code == 39:
self._foreground = None
elif code == 40:
self._background = 'black'
self._background = "black"
elif code == 41:
self._background = 'red'
self._background = "red"
elif code == 42:
self._background = 'green'
self._background = "green"
elif code == 43:
self._background = 'yellow'
self._background = "yellow"
elif code == 44:
self._background = 'blue'
self._background = "blue"
elif code == 45:
self._background = 'magenta'
self._background = "magenta"
elif code == 46:
self._background = 'cyan'
self._background = "cyan"
elif code == 47:
self._background = 'white'
self._background = "white"
elif code == 49:
self._background = None
@ -127,18 +127,18 @@ class RedirectText(TextIOBase):
def write(self, string):
for s in string:
if s == '\r':
if s == "\r":
current_value = self._out.GetValue()
last_newline = current_value.rfind("\n")
wx.CallAfter(self._out.Remove, last_newline + 1, len(current_value))
# self._line += '\n'
self._write_line()
self._line = ''
self._line = ""
continue
self._line += s
if s == '\n':
if s == "\n":
self._write_line()
self._line = ''
self._line = ""
continue
def writable(self):
@ -161,9 +161,9 @@ class FlashingThread(threading.Thread):
try:
from esphomeflasher.__main__ import run_esphomeflasher
argv = ['esphomeflasher', '--port', self._port, self._firmware]
argv = ["esphomeflasher", "--port", self._port, self._firmware]
if self._show_logs:
argv.append('--show-logs')
argv.append("--show-logs")
run_esphomeflasher(argv)
except Exception as e:
print("Unexpected error: {}".format(e))
@ -172,8 +172,14 @@ class FlashingThread(threading.Thread):
class MainFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, size=(725, 650),
style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
wx.Frame.__init__(
self,
parent,
-1,
title,
size=(725, 650),
style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE,
)
self._firmware = None
self._port = None
@ -197,7 +203,7 @@ class MainFrame(wx.Frame):
def on_logs_clicked(event):
self.console_ctrl.SetValue("")
worker = FlashingThread(self, 'dummy', self._port, show_logs=True)
worker = FlashingThread(self, "dummy", self._port, show_logs=True)
worker.start()
def on_select_port(event):
@ -216,8 +222,12 @@ class MainFrame(wx.Frame):
self.choice = wx.Choice(panel, choices=self._get_serial_ports())
self.choice.Bind(wx.EVT_CHOICE, on_select_port)
bmp = Reload.GetBitmap()
reload_button = wx.BitmapButton(panel, id=wx.ID_ANY, bitmap=bmp,
size=(bmp.GetWidth() + 7, bmp.GetHeight() + 7))
reload_button = wx.BitmapButton(
panel,
id=wx.ID_ANY,
bitmap=bmp,
size=(bmp.GetWidth() + 7, bmp.GetHeight() + 7),
)
reload_button.Bind(wx.EVT_BUTTON, on_reload)
reload_button.SetToolTip("Reload serial device list")
@ -235,9 +245,17 @@ class MainFrame(wx.Frame):
logs_button = wx.Button(panel, -1, "View Logs")
logs_button.Bind(wx.EVT_BUTTON, on_logs_clicked)
self.console_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL)
self.console_ctrl.SetFont(wx.Font((0, 13), wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL))
self.console_ctrl = wx.TextCtrl(
panel, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL
)
self.console_ctrl.SetFont(
wx.Font(
(0, 13),
wx.FONTFAMILY_TELETYPE,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL,
)
)
self.console_ctrl.SetBackgroundColour(wx.BLACK)
self.console_ctrl.SetForegroundColour(wx.WHITE)
self.console_ctrl.SetDefaultStyle(wx.TextAttr(wx.WHITE))
@ -247,18 +265,25 @@ class MainFrame(wx.Frame):
console_label = wx.StaticText(panel, label="Console")
fgs.AddMany([
# Port selection row
port_label, (serial_boxsizer, 1, wx.EXPAND),
# Firmware selection row (growable)
file_label, (file_picker, 1, wx.EXPAND),
# Flash ESP button
(wx.StaticText(panel, label="")), (button, 1, wx.EXPAND),
# View Logs button
(wx.StaticText(panel, label="")), (logs_button, 1, wx.EXPAND),
# Console View (growable)
(console_label, 1, wx.EXPAND), (self.console_ctrl, 1, wx.EXPAND),
])
fgs.AddMany(
[
# Port selection row
port_label,
(serial_boxsizer, 1, wx.EXPAND),
# Firmware selection row (growable)
file_label,
(file_picker, 1, wx.EXPAND),
# Flash ESP button
(wx.StaticText(panel, label="")),
(button, 1, wx.EXPAND),
# View Logs button
(wx.StaticText(panel, label="")),
(logs_button, 1, wx.EXPAND),
# Console View (growable)
(console_label, 1, wx.EXPAND),
(self.console_ctrl, 1, wx.EXPAND),
]
)
fgs.AddGrowableRow(4, 1)
fgs.AddGrowableCol(1, 1)
hbox.Add(fgs, proportion=2, flag=wx.ALL | wx.EXPAND, border=15)
@ -312,7 +337,8 @@ Exit = PyEmbeddedImage(
"3Rl+LVvOwG1syMBrYcbwfetmhmsOdgy/795iuMXEwnDh89c2oJ7jIL0AAQR2wQRgXvgKNAfo"
"qRIlJfk2NR42Rj5gEmb5+4/h35+/DJ+/fmd4DUyNN4B+v/DlWwcwcTWzA9PXQqBegACCGwAK"
"ERD+zsBgwszOXirEwe7OzvCP5y/QCx/+/v/26vfv/R///O0GOvkII1AdKxCDDAAIIEZKszNA"
"gAEA1sFjF+2KokIAAAAASUVORK5CYII=")
"gAEA1sFjF+2KokIAAAAASUVORK5CYII="
)
Reload = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGOfPtRkwAAACBj"
@ -332,7 +358,8 @@ Reload = PyEmbeddedImage(
"wS9NKRdXQr6kgeuBfwEbWdzTvan9igAAADV0RVh0Y29tbWVudABSZWZyZXNoIGZyb20gSWNv"
"biBHYWxsZXJ5IGh0dHA6Ly9pY29uZ2FsLmNvbS/RLzdIAAAAJXRFWHRkYXRlOmNyZWF0ZQAy"
"MDExLTA4LTIxVDE0OjAxOjU2LTA2OjAwdNJAnQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxMS0w"
"OC0yMVQxNDowMTo1Ni0wNjowMAWP+CEAAAAASUVORK5CYII=")
"OC0yMVQxNDowMTo1Ni0wNjowMAWP+CEAAAAASUVORK5CYII="
)
def main():

View File

@ -5,17 +5,18 @@ import sys
import serial
DEVNULL = open(os.devnull, 'w')
DEVNULL = open(os.devnull, "w")
def list_serial_ports():
# from https://github.com/pyserial/pyserial/blob/master/serial/tools/list_ports.py
from serial.tools.list_ports import comports
result = []
for port, desc, info in comports():
if not port or "VID:PID" not in info:
continue
split_desc = desc.split(' - ')
split_desc = desc.split(" - ")
if len(split_desc) == 2 and split_desc[0] == split_desc[1]:
desc = split_desc[0]
result.append((port, desc))