diff --git a/esptool-python-gui.py b/esptool-python-gui.py index bd06e6d..9243d86 100644 --- a/esptool-python-gui.py +++ b/esptool-python-gui.py @@ -1,7 +1,16 @@ from esptool import main as esptool_main -import PySimpleGUI as sg +import urllib.request +import json +import tempfile +import os +import serial +import sys +import glob +from tkinter import * -options = ['--chip', 'esp32', +github_api_url = 'https://api.github.com/repos/interactionresearchstudio/ESP32-SOCKETIO/releases' + +esptool_options = ['--chip', 'esp32', '--port', '/dev/cu.usbserial-01E5C374', '--baud', '921600', '--before', 'default_reset', @@ -9,32 +18,141 @@ 'write_flash', '-z', '--flash_mode', 'dio', '--flash_freq', '80m', '--flash_size', 'detect', -'0xe000', 'boot_app0.bin', -'0x1000', 'bootloader_qio_80m.bin', -'0x10000', '/var/folders/_c/51n3qnzd01sfpdd6mfq8j_jm0000gn/T/arduino_build_969576/sketch_aug05a.ino.bin', -'0x8000', '/var/folders/_c/51n3qnzd01sfpdd6mfq8j_jm0000gn/T/arduino_build_969576/sketch_aug05a.ino.partitions.bin'] +'0x10000', 'app.ino.bin' +] print("Imported esptool.") -layout = [ [sg.Text('Upload firmware')], - [sg.Text('Idle ', key='-OUTPUT-')], - [sg.Button('GO')] ] +def get_bin_url(api_url): + try: + with urllib.request.urlopen(api_url) as url: + data = json.loads(url.read().decode()) + print(data[0]) + return data[0]['assets'][0]['browser_download_url'] + except Exception as e: + print(e) + return None + +def serial_ports(): + """ Lists serial port names -window = sg.Window("SCADS ESP flasher", layout) + :raises EnvironmentError: + On unsupported or unknown platforms + :returns: + A list of the serial ports available on the system + """ + if sys.platform.startswith('win'): + print("win") + ports = ['COM%s' % (i + 1) for i in range(256)] + elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'): + # this excludes your current terminal "/dev/tty" + print("linux") + ports = glob.glob('/dev/tty[A-Za-z]*') + elif sys.platform.startswith('darwin'): + print("mac") + ports = glob.glob('/dev/tty.*') + else: + raise EnvironmentError('Unsupported platform') -while True: - event, values = window.read() - if values is not None: - print(values) - if event == 'GO': - print("Pressed ok.") + result = [] + for port in ports: try: - esptool_main(options) - window['-OUTPUT-'].update("Success!") - except: - window['-OUTPUT-'].update("ERROR :(") - elif event == sg.WIN_CLOSED: - - break -print("Bye.") -window.close() + s = serial.Serial(port) + s.close() + result.append(port) + except (OSError, serial.SerialException): + pass + return result + +def get_bin_file(bin_url): + try: + with urllib.request.urlopen(bin_url) as response: + data = response.read() + with tempfile.NamedTemporaryFile(delete=False) as fp: + fp.write(data) + fp.close() + return fp + except Exception as e: + return None + print(e) + +def upload_from_github(serial_port): + upload_button.config(state=DISABLED) + status_var.set("Downloading firmware...") + result_label.config(fg="blue") + window.update() + + # Get bin file URL from GitHub + bin_url = get_bin_url(github_api_url) + if bin_url == None: + status_var.set("Error finding firmware!") + result_label.config(fg="red") + upload_button.config(state=NORMAL) + return + + # Download bin file and save temporarily + fp = get_bin_file(bin_url) + if fp == None: + status_var.set("Error downloading firmware!") + result_label.config(fg="red") + upload_button.config(state=NORMAL) + return + + # Write to device with esptool + esptool_options[3] = serial_port + esptool_options[-1] = fp.name + try: + status_var.set("Writing firmware...") + window.update() + esptool_main(esptool_options) + os.unlink(fp.name) + status_var.set("Success!") + result_label.config(fg="green") + upload_button.config(state=NORMAL) + except Exception as e: + status_var.set("Error writing firmware!") + result_label.config(fg="red") + upload_button.config(state=NORMAL) + os.unlink(fp.name) + print(e) + + +def update_serial_list(): + print("Update serial list") + option.set('') + opt.children['menu'].delete(0, 'end') + new_list = serial_ports() + for item in new_list: + opt.children['menu'].add_command(label=item, command=lambda: option.set(item)) + option.set(new_list[0]) + + +window = Tk() +window.geometry('300x300') +window.title("IRS Firmware Uploader") + +instructions = Label(window, wraplength=200, justify="left", text="Please select the device from the dropdown menu. When you're ready to upload the firmware, click Upload Firmware!") +instructions.place(relx=0.5, y=50, anchor=CENTER) + +status_var = StringVar(window) +status_var.set("Idle") +result_label = Label(window, textvariable=status_var, width=30, fg="blue") +result_label.place(relx=0.5, rely=0.8, anchor=CENTER) + +option_list = serial_ports() +option = StringVar(window) +option.set(option_list[0]) +opt = OptionMenu(window, option, *option_list) +opt.config(width=30, font=('Helvetica', 12)) +opt.pack() +opt.place(relx=0.5, rely=0.4, anchor=CENTER) + +refresh_list_button = Button(window, text="Refresh device list", + command=update_serial_list) +refresh_list_button.place(relx=0.5, rely=0.5, anchor=CENTER) + +upload_button = Button(window, text="Upload Firmware", + command=lambda: upload_from_github(option.get())) +upload_button.place(relx=0.5, rely=0.9, anchor=CENTER) + +window.mainloop() diff --git a/requirements.txt b/requirements.txt index af22a94..e7b5771 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,12 @@ +altgraph==0.17 ecdsa==0.15 esptool==2.8 +macholib==1.14 pyaes==1.6.1 +PyInstaller==3.6 pyserial==3.4 PySide2==5.15.0 +PySimpleGUI==4.28.0 PySimpleGUIQt==0.35.0 shiboken2==5.15.0 six==1.15.0