From a1b6711cbd7325c6081230aa40bf46b973352a06 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Wed, 23 Feb 2022 18:18:31 +0100 Subject: [PATCH 01/17] Created GUI for bootloader Moved GUI from Flash boot speedup branch to develop branch. --- examples/bootloader/gui.py | 123 +++++++++++++++ examples/bootloader/guiFunctions.py | 228 ++++++++++++++++++++++++++++ 2 files changed, 351 insertions(+) create mode 100644 examples/bootloader/gui.py create mode 100644 examples/bootloader/guiFunctions.py diff --git a/examples/bootloader/gui.py b/examples/bootloader/gui.py new file mode 100644 index 000000000..9248a6443 --- /dev/null +++ b/examples/bootloader/gui.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 + +from guiFunctions import * + + +usbSpeeds = ["UNKNOWN", "LOW", "FULL", "HIGH", "SUPER", "SUPER_PLUS"] + +sg.theme('DarkGrey4') + +aboutDeviceLayout = [ + [sg.Text("About device", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")], + [sg.HSeparator()], + [ + sg.Text("Select device: ", size=(15, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.Combo([], "Search for devices", size=(30, 5), key="devices", enable_events=True), + sg.Button("Select"), sg.Button("Search") + ], + [sg.Text("Name of connected device:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black")], + [sg.Text("-name-", key="devName", size=(30, 1))], + [sg.Text("Version of newest bootloader:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black")], + [sg.Text("-version-", key="newBoot", size=(20, 1))], + [sg.Text("Current bootloader version:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black")], + [sg.Text("-version-", key="currBoot", size=(20, 1))], + [sg.HSeparator()], + [ + sg.Text("", size=(5, 2)), + sg.Button("Flash newest version", size=(20, 2), font=('Arial', 10, 'bold'), disabled=True, + button_color='#FFEA00'), + sg.Button("Factory reset", size=(20, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00')] +] + +deviceConfigLayout = [ + [sg.Text("Configuration settings", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")], + [sg.HSeparator()], + [ + sg.Text("IPv4 type:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.Radio('Static', "ipType", default=True, font=('Arial', 10, 'bold'), text_color="black", + key="staticBut", enable_events=True, disabled=True), + sg.Radio('Dynamic', "ipType", default=False, font=('Arial', 10, 'bold'), text_color="black", + key="dynamicBut", enable_events=True, disabled=True) + ], + [ + sg.Text("IPv4:", size=(12, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="staticIp", size=(16, 2), disabled=True), + sg.Text("Mask:", size=(5, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="staticMask", size=(16, 2), disabled=True), + sg.Text("Gateway:", size=(8, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="staticGateway", size=(16, 2), disabled=True) + ], + [ + sg.Text("DNS name:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="dns", size=(30, 2), disabled=True) + ], + [ + sg.Text("Alt DNS name:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="dnsAlt", size=(30, 2), disabled=True) + ], + [ + sg.Text("USB timeout:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="usbTimeout", size=(30, 2), disabled=True) + ], + [ + sg.Text("Network timeout:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="networkTimeout", size=(30, 2), disabled=True) + ], + [ + sg.Text("MAC address:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="mac", size=(30, 2), disabled=True) + ], + [ + sg.Text("USB max speed:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.Combo(usbSpeeds, "Select speed", key="usbSpeed", size=(30, 6), disabled=True) + ], + [sg.HSeparator()], + [ + sg.Text("", size=(20, 2)), + sg.Button("Flash configuration", size=(20, 2), font=('Arial', 10, 'bold'), disabled=True, + button_color='#FFEA00'), + sg.Button("Clear flash", size=(20, 2), font=('Arial', 10, 'bold'), disabled=True, + button_color='#FFEA00') + ] +] + +layout = [ + [sg.VSeparator(), + sg.Column(aboutDeviceLayout), + sg.VSeparator(), + sg.Column(deviceConfigLayout), + sg.VSeparator()] +] + +devices = dict() +devType = "" +window = sg.Window(title="Bootloader GUI", layout=layout) + +while True: + event, values = window.read() + if event == sg.WIN_CLOSED: + break + dev = values['devices'] + if event == "Select": + if dev != "Select device": + devType = getDeviceType(devices[values['devices']]) + getConfigs(window, devices[values['devices']], devType) + unlockConfig(window, devType) + else: + window.Element('progress').update("No device selected.") + if event == "Search": + getDevices(window, devices) + if event == "Flash newest version": + flashBootloader(window, devices[values['devices']]) + if event == "Flash configuration": + flashConfig(values, window, devices[values['devices']], devType, values['StaticBut']) + getConfigs(window, devices[values['devices']], devType) + lockConfig(window) + if devType != "Poe": + unlockConfig(window, devType) + else: + devices.clear() + window.Element('devices').update("Search for devices", values=[]) + if event == "Factory reset": + factoryReset(devices[values['devices']]) +window.close() diff --git a/examples/bootloader/guiFunctions.py b/examples/bootloader/guiFunctions.py new file mode 100644 index 000000000..046f02054 --- /dev/null +++ b/examples/bootloader/guiFunctions.py @@ -0,0 +1,228 @@ +from datetime import timedelta +import depthai as dai +import tempfile +import PySimpleGUI as sg + + +def check_ip(s: str): + spl = s.split(".") + if len(spl) != 4: + sg.Popup("Wrong IP format.\nValue should be similar to 255.255.255.255") + return False + for num in spl: + if 255 < int(num): + sg.Popup("Wrong IP format.\nValues can not be above 255!") + return False + return True + + +def check_mac(s): + if s.count(":") != 5: + sg.Popup("Wrong MAC format.\nValue should be similar to FF:FF:FF:FF:FF:FF") + return False + for i in s.split(":"): + for j in i: + if j > "F" or (j < "A" and not j.isdigit()) or len(i) != 2: + sg.Popup("Wrong MAC format.\nValue should be similar to FF:FF:FF:FF:FF:FF") + return False + return True + + +def usbSpeed(s): + if s == "UNKNOWN": + return dai.UsbSpeed.UNKNOWN + elif s == "LOW": + return dai.UsbSpeed.LOW + elif s == "FULL": + return dai.UsbSpeed.FULL + elif s == "HIGH": + return dai.UsbSpeed.HIGH + elif s == "SUPER": + return dai.UsbSpeed.SUPER + else: + return dai.UsbSpeed.SUPER_PLUS + + +def usbSpeedCorrection(s): + if s == 0: + return "UNKNOWN" + elif s == 1: + return "LOW" + elif s == 2: + return "FULL" + elif s == 3: + return "HIGH" + elif s == 4: + return "SUPER" + else: + return "SUPER_PLUS" + + +def macCorrectFormat(s): + ret = "" + for x in s: + ret += str(hex(x)).strip("0x").upper() + ":" + return ret[:-1] + + +def unlockConfig(window, devType): + if devType == "Poe": + window['staticIp'].update(disabled=False) + window['staticMask'].update(disabled=False) + window['staticGateway'].update(disabled=False) + window['dns'].update(disabled=False) + window['dnsAlt'].update(disabled=False) + window['networkTimeout'].update(disabled=False) + window['mac'].update(disabled=False) + window['staticBut'].update(disabled=False) + window['dynamicBut'].update(disabled=False) + else: + window['usbTimeout'].update(disabled=False) + window['usbSpeed'].update(disabled=False) + window['Flash newest version'].update(disabled=False) + window['Flash configuration'].update(disabled=False) + window['Factory reset'].update(disabled=False) + # window['Reset configuration'].update(disabled=False) + + +def lockConfig(window): + window['staticIp'].update(disabled=True) + window['staticMask'].update(disabled=True) + window['staticGateway'].update(disabled=True) + window['dns'].update(disabled=True) + window['dnsAlt'].update(disabled=True) + window['networkTimeout'].update(disabled=True) + window['mac'].update(disabled=True) + window['staticBut'].update(disabled=True) + window['dynamicBut'].update(disabled=True) + window['usbTimeout'].update(disabled=True) + window['usbSpeed'].update(disabled=True) + window['Flash newest version'].update(disabled=True) + window['Flash configuration'].update(disabled=True) + window['Factory reset'].update(disabled=True) + window['Reset configuration'].update(disabled=True) + + window.Element('staticIp').update("") + window.Element('staticMask').update("") + window.Element('staticGateway').update("") + window.Element('dns').update("") + window.Element('dnsAlt').update("") + window.Element('networkTimeout').update("") + window.Element('mac').update("") + window.Element('usbTimeout').update("") + window.Element('usbSpeed').update("") + window.Element('devName').update("-name-") + window.Element('newBoot').update("-version-") + window.Element('currBoot').update("-version-") + + +def getDevices(window, devices): + listedDevices = [] + devices.clear() + deviceInfos = dai.Device.getAllAvailableDevices() + if not deviceInfos: + window.Element('devices').update("No devices") + sg.Popup("No devices found.") + else: + for deviceInfo in deviceInfos: + listedDevices.append(deviceInfo.desc.name) + devices[deviceInfo.desc.name] = deviceInfo + sg.Popup("Found devices.") + window.Element('devices').update("Select device", values=listedDevices) + + +def getConfigs(window, device, devType): + bl = dai.DeviceBootloader(device) + conf = bl.readConfigData() + if devType == "Poe": + window.Element('staticIp').update(conf['network']['ipv4'] if conf['network']['ipv4'] != 0 else "0.0.0.0") + window.Element('staticMask').update(conf['network']['ipv4Mask'] if conf['network']['ipv4Mask'] != 0 + else "0.0.0.0") + window.Element('staticGateway').update(conf['network']['ipv4Gateway'] if conf['network']['ipv4Gateway'] != 0 + else "0.0.0.0") + window.Element('dns').update(conf['network']['ipv4Dns'] if conf['network']['ipv4Dns'] != 0 else "0.0.0.0") + window.Element('dnsAlt').update(conf['network']['ipv4DnsAlt'] if conf['network']['ipv4DnsAlt'] != 0 + else "0.0.0.0") + window.Element('networkTimeout').update(conf['network']['timeoutMs']) + window.Element('mac').update(macCorrectFormat(conf['network']['mac'])) + window.Element('usbTimeout').update("") + window.Element('usbSpeed').update("") + else: + window.Element('staticIp').update("") + window.Element('staticMask').update("") + window.Element('staticGateway').update("") + window.Element('dns').update("") + window.Element('dnsAlt').update("") + window.Element('networkTimeout').update("") + window.Element('mac').update("") + window.Element('usbTimeout').update(conf['usb']['timeoutMs']) + window.Element('usbSpeed').update(usbSpeedCorrection(conf['usb']['maxUsbSpeed'])) + window.Element('devName').update(device.desc.name) + window.Element('newBoot').update(dai.DeviceBootloader.getEmbeddedBootloaderVersion()) + window.Element('currBoot').update(bl.getVersion()) + + +def flashBootloader(window, device): + bl = dai.DeviceBootloader(device, True) + progress = lambda p: p * 100 + bl.flashBootloader(progress) + window.Element('currBoot').update(bl.getVersion()) + sg.Popup("Flashed newest bootloader version.") + + +def flashConfig(values, window, device, devType, ipType): + bl = dai.DeviceBootloader(device, True) + conf = dai.DeviceBootloader.Config() + if devType == "Poe": + if not(check_ip(values['staticIp']) and check_ip(values['staticMask']) + and check_ip(values['staticGateway'])): + return + if not check_mac(values['mac']): + return + if int(values['networkTimeout']) <= 0: + sg.Popup("Values can not be negative!") + return + if ipType: + conf.setStaticIPv4(values['staticIp'], values['staticIp'], values['staticIp']) + else: + conf.setDynamicIPv4(values['staticIp'], values['staticIp'], values['staticIp']) + conf.setDnsIPv4(values['dns'], "") + conf.setNetworkTimeout(timedelta(seconds=int(values['networkTimeout']) / 1000)) + conf.setMacAddress(values['mac']) + else: + if int(values['usbTimeout']) <= 0: + sg.Popup("Values can not be negative!") + return + conf.setUsbTimeout(timedelta(seconds=int(values['usbTimeout']) / 1000)) + conf.setUsbMaxSpeed(usbSpeed(values['usbSpeed'])) + success, error = bl.flashConfig(conf) + if not success: + sg.Popup(f"Flashing failed: {error}") + else: + sg.Popup("Flashing successful.") + + +def factoryReset(device): + blBinary = dai.DeviceBootloader.getEmbeddedBootloaderBinary(dai.DeviceBootloader.Type.NETWORK) + blBinary = blBinary + ([0xFF] * ((8 * 1024 * 1024 + 512) - len(blBinary))) + bl = dai.DeviceBootloader(device, True) + tmpBlFw = tempfile.NamedTemporaryFile(delete=False) + tmpBlFw.write(bytes(blBinary)) + progress = lambda p: p * 100 + success, msg = bl.flashBootloader(progress, tmpBlFw.name) + if success: + sg.Popup("Factory reset was successful.") + else: + sg.Popup(f"Factory reset failed. Error: {msg}") + tmpBlFw.close() + + +def getDeviceType(device): + bl = dai.DeviceBootloader(device) + conf = bl.readConfigData() + if conf is None: + success, error = bl.flashConfig(dai.DeviceBootloader.Config()) + if str(bl.getType()) == "Type.NETWORK": + return "Poe" + else: + return "NonPoe" From 9eb95cb9324008cc58b369186ded352679e86024 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Thu, 24 Feb 2022 12:22:56 +0100 Subject: [PATCH 02/17] Fixed needed changes - renamed file and moved to ```ustilities/device_manager.py``` (everything is now in 1 file) - GUI now has 2 pages (```About``` and ```Configuration settings```) - GUI also informs dai.__version__ and dai.__commmit__ - Added button ```Flash DAP``` that runs ```flashDepthaiApplicationPackage``` function - Changed device finding from ```dai.Device.getAllAvailableDevices()``` to ```dai.XLinkConnection.getAllConnectedDevices()``` --- examples/bootloader/gui.py | 123 ------------ .../device_manager.py | 180 +++++++++++++++++- 2 files changed, 178 insertions(+), 125 deletions(-) delete mode 100644 examples/bootloader/gui.py rename examples/bootloader/guiFunctions.py => utilities/device_manager.py (52%) diff --git a/examples/bootloader/gui.py b/examples/bootloader/gui.py deleted file mode 100644 index 9248a6443..000000000 --- a/examples/bootloader/gui.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env python3 - -from guiFunctions import * - - -usbSpeeds = ["UNKNOWN", "LOW", "FULL", "HIGH", "SUPER", "SUPER_PLUS"] - -sg.theme('DarkGrey4') - -aboutDeviceLayout = [ - [sg.Text("About device", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")], - [sg.HSeparator()], - [ - sg.Text("Select device: ", size=(15, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.Combo([], "Search for devices", size=(30, 5), key="devices", enable_events=True), - sg.Button("Select"), sg.Button("Search") - ], - [sg.Text("Name of connected device:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black")], - [sg.Text("-name-", key="devName", size=(30, 1))], - [sg.Text("Version of newest bootloader:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black")], - [sg.Text("-version-", key="newBoot", size=(20, 1))], - [sg.Text("Current bootloader version:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black")], - [sg.Text("-version-", key="currBoot", size=(20, 1))], - [sg.HSeparator()], - [ - sg.Text("", size=(5, 2)), - sg.Button("Flash newest version", size=(20, 2), font=('Arial', 10, 'bold'), disabled=True, - button_color='#FFEA00'), - sg.Button("Factory reset", size=(20, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00')] -] - -deviceConfigLayout = [ - [sg.Text("Configuration settings", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")], - [sg.HSeparator()], - [ - sg.Text("IPv4 type:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.Radio('Static', "ipType", default=True, font=('Arial', 10, 'bold'), text_color="black", - key="staticBut", enable_events=True, disabled=True), - sg.Radio('Dynamic', "ipType", default=False, font=('Arial', 10, 'bold'), text_color="black", - key="dynamicBut", enable_events=True, disabled=True) - ], - [ - sg.Text("IPv4:", size=(12, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.InputText(key="staticIp", size=(16, 2), disabled=True), - sg.Text("Mask:", size=(5, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.InputText(key="staticMask", size=(16, 2), disabled=True), - sg.Text("Gateway:", size=(8, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.InputText(key="staticGateway", size=(16, 2), disabled=True) - ], - [ - sg.Text("DNS name:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.InputText(key="dns", size=(30, 2), disabled=True) - ], - [ - sg.Text("Alt DNS name:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.InputText(key="dnsAlt", size=(30, 2), disabled=True) - ], - [ - sg.Text("USB timeout:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.InputText(key="usbTimeout", size=(30, 2), disabled=True) - ], - [ - sg.Text("Network timeout:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.InputText(key="networkTimeout", size=(30, 2), disabled=True) - ], - [ - sg.Text("MAC address:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.InputText(key="mac", size=(30, 2), disabled=True) - ], - [ - sg.Text("USB max speed:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.Combo(usbSpeeds, "Select speed", key="usbSpeed", size=(30, 6), disabled=True) - ], - [sg.HSeparator()], - [ - sg.Text("", size=(20, 2)), - sg.Button("Flash configuration", size=(20, 2), font=('Arial', 10, 'bold'), disabled=True, - button_color='#FFEA00'), - sg.Button("Clear flash", size=(20, 2), font=('Arial', 10, 'bold'), disabled=True, - button_color='#FFEA00') - ] -] - -layout = [ - [sg.VSeparator(), - sg.Column(aboutDeviceLayout), - sg.VSeparator(), - sg.Column(deviceConfigLayout), - sg.VSeparator()] -] - -devices = dict() -devType = "" -window = sg.Window(title="Bootloader GUI", layout=layout) - -while True: - event, values = window.read() - if event == sg.WIN_CLOSED: - break - dev = values['devices'] - if event == "Select": - if dev != "Select device": - devType = getDeviceType(devices[values['devices']]) - getConfigs(window, devices[values['devices']], devType) - unlockConfig(window, devType) - else: - window.Element('progress').update("No device selected.") - if event == "Search": - getDevices(window, devices) - if event == "Flash newest version": - flashBootloader(window, devices[values['devices']]) - if event == "Flash configuration": - flashConfig(values, window, devices[values['devices']], devType, values['StaticBut']) - getConfigs(window, devices[values['devices']], devType) - lockConfig(window) - if devType != "Poe": - unlockConfig(window, devType) - else: - devices.clear() - window.Element('devices').update("Search for devices", values=[]) - if event == "Factory reset": - factoryReset(devices[values['devices']]) -window.close() diff --git a/examples/bootloader/guiFunctions.py b/utilities/device_manager.py similarity index 52% rename from examples/bootloader/guiFunctions.py rename to utilities/device_manager.py index 046f02054..fca5725f0 100644 --- a/examples/bootloader/guiFunctions.py +++ b/utilities/device_manager.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + from datetime import timedelta import depthai as dai import tempfile @@ -83,6 +85,7 @@ def unlockConfig(window, devType): window['Flash configuration'].update(disabled=False) window['Factory reset'].update(disabled=False) # window['Reset configuration'].update(disabled=False) + window['Flash DAP'].update(disabled=False) def lockConfig(window): @@ -101,6 +104,7 @@ def lockConfig(window): window['Flash configuration'].update(disabled=True) window['Factory reset'].update(disabled=True) window['Reset configuration'].update(disabled=True) + window['Flash DAP'].update(disabled=True) window.Element('staticIp').update("") window.Element('staticMask').update("") @@ -114,17 +118,21 @@ def lockConfig(window): window.Element('devName').update("-name-") window.Element('newBoot').update("-version-") window.Element('currBoot').update("-version-") + window.Element('version').update("-version-") + window.Element('commit').update("-commit-") + window.Element('devState').update("-state-") def getDevices(window, devices): listedDevices = [] devices.clear() - deviceInfos = dai.Device.getAllAvailableDevices() + deviceInfos = dai.XLinkConnection.getAllConnectedDevices() if not deviceInfos: window.Element('devices').update("No devices") sg.Popup("No devices found.") else: for deviceInfo in deviceInfos: + # print(deviceInfo.state) listedDevices.append(deviceInfo.desc.name) devices[deviceInfo.desc.name] = deviceInfo sg.Popup("Found devices.") @@ -160,6 +168,9 @@ def getConfigs(window, device, devType): window.Element('devName').update(device.desc.name) window.Element('newBoot').update(dai.DeviceBootloader.getEmbeddedBootloaderVersion()) window.Element('currBoot').update(bl.getVersion()) + window.Element('version').update(dai.__version__) + window.Element('commit').update(dai.__commit__) + window.Element('devState').update(str(devices[device.desc.name].state).split(".")[1]) def flashBootloader(window, device): @@ -170,7 +181,7 @@ def flashBootloader(window, device): sg.Popup("Flashed newest bootloader version.") -def flashConfig(values, window, device, devType, ipType): +def flashConfig(values, device, devType, ipType): bl = dai.DeviceBootloader(device, True) conf = dai.DeviceBootloader.Config() if devType == "Poe": @@ -226,3 +237,168 @@ def getDeviceType(device): return "Poe" else: return "NonPoe" + + +def flashFromFile(file, device): + bl = dai.DeviceBootloader(device) + if str(file)[-3:] == "dap": + bl.flashDepthaiApplicationPackage(file) + else: + sg.Popup("Selected file is not .dap!") + + +usbSpeeds = ["UNKNOWN", "LOW", "FULL", "HIGH", "SUPER", "SUPER_PLUS"] + +sg.theme('DarkGrey4') + +aboutDeviceLayout = [ + [sg.Text("About device", size=(30, 1), font=('Arial', 30, 'bold'), text_color="black")], + [sg.HSeparator()], + [ + sg.Text("Select device: ", size=(15, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.Combo([], "Search for devices", size=(30, 5), key="devices", enable_events=True), + sg.Button("Select"), sg.Button("Search") + ], + [ + sg.Text("Name of connected device:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.VSeparator(), + sg.Text("Device state:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black") + ], + [sg.Text("-name-", key="devName", size=(30, 1)), sg.VSeparator(), sg.Text("-state-", key="devState", size=(30, 1))], + [ + sg.Text("Version of newest bootloader:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.VSeparator(), + sg.Text("Current bootloader version:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black") + ], + [ + sg.Text("-version-", key="newBoot", size=(30, 1)), + sg.VSeparator(), + sg.Text("-version-", key="currBoot", size=(30, 1)) + ], + [ + sg.Text("Current __version__:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.VSeparator(), + sg.Text("Current commit:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + ], + [ + sg.Text("-version-", key="version", size=(30, 1)), + sg.VSeparator(), + sg.Text("-version-", key="commit", size=(31, 1)) + ], + [sg.HSeparator()], + [ + sg.Text("", size=(5, 2)), + sg.Button("Flash newest version", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, + button_color='#FFEA00'), + sg.Button("Factory reset", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), + sg.Button("Config", size=(17, 2), font=('Arial', 10, 'bold'), disabled=False, button_color='#FFEA00') + ] +] + +deviceConfigLayout = [ + [sg.Text("Configuration settings", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")], + [sg.HSeparator()], + [ + sg.Text("IPv4 type:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.Radio('Static', "ipType", default=True, font=('Arial', 10, 'bold'), text_color="black", + key="staticBut", enable_events=True, disabled=True), + sg.Radio('Dynamic', "ipType", default=False, font=('Arial', 10, 'bold'), text_color="black", + key="dynamicBut", enable_events=True, disabled=True) + ], + [ + sg.Text("IPv4:", size=(12, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="staticIp", size=(16, 2), disabled=True), + sg.Text("Mask:", size=(5, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="staticMask", size=(16, 2), disabled=True), + sg.Text("Gateway:", size=(8, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="staticGateway", size=(16, 2), disabled=True) + ], + [ + sg.Text("DNS name:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="dns", size=(30, 2), disabled=True) + ], + [ + sg.Text("Alt DNS name:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="dnsAlt", size=(30, 2), disabled=True) + ], + [ + sg.Text("USB timeout:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="usbTimeout", size=(30, 2), disabled=True) + ], + [ + sg.Text("Network timeout:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="networkTimeout", size=(30, 2), disabled=True) + ], + [ + sg.Text("MAC address:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.InputText(key="mac", size=(30, 2), disabled=True) + ], + [ + sg.Text("USB max speed:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.Combo(usbSpeeds, "Select speed", key="usbSpeed", size=(30, 6), disabled=True) + ], + [sg.HSeparator()], + [ + sg.Text("", size=(1, 2)), + sg.Button("Flash configuration", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True, + button_color='#FFEA00'), + sg.Button("Clear flash", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True, + button_color='#FFEA00'), + sg.Button("Flash DAP", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True, + button_color='#FFEA00'), + sg.Button("Back", size=(15, 2), font=('Arial', 10, 'bold'), disabled=False, + button_color='#FFEA00') + ], +] + +layout = [ + [ + # sg.VSeparator(), + sg.Column(aboutDeviceLayout, key='-COL1-'), + # sg.VSeparator(), + sg.Column(deviceConfigLayout, visible=False, key='-COL2-'), + # sg.VSeparator() + ] +] + +devices = dict() +devType = "" +window = sg.Window(title="Bootloader GUI", layout=layout, size=(620, 350)) + +while True: + event, values = window.read() + if event == sg.WIN_CLOSED: + break + dev = values['devices'] + if event == "Select": + if dev != "Select device": + devType = getDeviceType(devices[values['devices']]) + getConfigs(window, devices[values['devices']], devType) + unlockConfig(window, devType) + else: + window.Element('progress').update("No device selected.") + if event == "Search": + getDevices(window, devices) + if event == "Flash newest version": + flashBootloader(window, devices[values['devices']]) + if event == "Flash configuration": + flashConfig(values, devices[values['devices']], devType, values['StaticBut']) + getConfigs(window, devices[values['devices']], devType) + lockConfig(window) + if devType != "Poe": + unlockConfig(window, devType) + else: + devices.clear() + window.Element('devices').update("Search for devices", values=[]) + if event == "Factory reset": + factoryReset(devices[values['devices']]) + if event == "Flash DAP": + file = sg.popup_get_file("Select .dap file") + flashFromFile(file, devices[values['devices']]) + if event == "Config": + window['-COL1-'].update(visible=False) + window['-COL2-'].update(visible=True) + if event == "Back": + window['-COL2-'].update(visible=False) + window['-COL1-'].update(visible=True) +window.close() From 93f52f848b4283507c719e0e288ab2c1b9ce74a9 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Thu, 24 Feb 2022 12:49:39 +0100 Subject: [PATCH 03/17] Added menu buttons Moved buttons for moving between pages to menu bar. --- utilities/device_manager.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index fca5725f0..314384a10 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -248,12 +248,18 @@ def flashFromFile(file, device): usbSpeeds = ["UNKNOWN", "LOW", "FULL", "HIGH", "SUPER", "SUPER_PLUS"] +menu = [["About"], ["Config"]] sg.theme('DarkGrey4') aboutDeviceLayout = [ [sg.Text("About device", size=(30, 1), font=('Arial', 30, 'bold'), text_color="black")], [sg.HSeparator()], + [ + sg.Button("About", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="aboutFake"), + sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="configReal") + ], + [sg.HSeparator()], [ sg.Text("Select device: ", size=(15, 1), font=('Arial', 10, 'bold'), text_color="black"), sg.Combo([], "Search for devices", size=(30, 5), key="devices", enable_events=True), @@ -287,17 +293,21 @@ def flashFromFile(file, device): ], [sg.HSeparator()], [ - sg.Text("", size=(5, 2)), + sg.Text("", size=(13, 2)), sg.Button("Flash newest version", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), sg.Button("Factory reset", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), - sg.Button("Config", size=(17, 2), font=('Arial', 10, 'bold'), disabled=False, button_color='#FFEA00') ] ] deviceConfigLayout = [ [sg.Text("Configuration settings", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")], [sg.HSeparator()], + [ + sg.Button("About", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="aboutReal"), + sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="configFake") + ], + [sg.HSeparator()], [ sg.Text("IPv4 type:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), sg.Radio('Static', "ipType", default=True, font=('Arial', 10, 'bold'), text_color="black", @@ -339,14 +349,12 @@ def flashFromFile(file, device): ], [sg.HSeparator()], [ - sg.Text("", size=(1, 2)), + sg.Text("", size=(10, 2)), sg.Button("Flash configuration", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), sg.Button("Clear flash", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), sg.Button("Flash DAP", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True, - button_color='#FFEA00'), - sg.Button("Back", size=(15, 2), font=('Arial', 10, 'bold'), disabled=False, button_color='#FFEA00') ], ] @@ -363,7 +371,7 @@ def flashFromFile(file, device): devices = dict() devType = "" -window = sg.Window(title="Bootloader GUI", layout=layout, size=(620, 350)) +window = sg.Window(title="Bootloader GUI", layout=layout, size=(620, 370)) while True: event, values = window.read() @@ -395,10 +403,10 @@ def flashFromFile(file, device): if event == "Flash DAP": file = sg.popup_get_file("Select .dap file") flashFromFile(file, devices[values['devices']]) - if event == "Config": + if event == "configReal": window['-COL1-'].update(visible=False) window['-COL2-'].update(visible=True) - if event == "Back": + if event == "aboutReal": window['-COL2-'].update(visible=False) window['-COL1-'].update(visible=True) window.close() From 9a71b495f2ee38ee89d5751d2900f37a2c004830 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Thu, 24 Feb 2022 13:02:28 +0100 Subject: [PATCH 04/17] Menu buttons animations Added pressed animation to menu buttons. --- utilities/device_manager.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index 314384a10..a1a7ac9c5 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -248,7 +248,6 @@ def flashFromFile(file, device): usbSpeeds = ["UNKNOWN", "LOW", "FULL", "HIGH", "SUPER", "SUPER_PLUS"] -menu = [["About"], ["Config"]] sg.theme('DarkGrey4') @@ -256,7 +255,7 @@ def flashFromFile(file, device): [sg.Text("About device", size=(30, 1), font=('Arial', 30, 'bold'), text_color="black")], [sg.HSeparator()], [ - sg.Button("About", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="aboutFake"), + sg.Button("About", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="aboutFake"), sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="configReal") ], [sg.HSeparator()], @@ -305,7 +304,7 @@ def flashFromFile(file, device): [sg.HSeparator()], [ sg.Button("About", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="aboutReal"), - sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="configFake") + sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="configFake") ], [sg.HSeparator()], [ From eaa91a104b724889c4aed7a4399c61d217c4e757 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Thu, 24 Feb 2022 14:11:58 +0100 Subject: [PATCH 05/17] Changed button About Changed button "About" to "Device select" to not confuse users --- utilities/device_manager.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index a1a7ac9c5..dec6372f9 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -255,7 +255,7 @@ def flashFromFile(file, device): [sg.Text("About device", size=(30, 1), font=('Arial', 30, 'bold'), text_color="black")], [sg.HSeparator()], [ - sg.Button("About", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="aboutFake"), + sg.Button("Device select", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="aboutFake"), sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="configReal") ], [sg.HSeparator()], @@ -303,7 +303,7 @@ def flashFromFile(file, device): [sg.Text("Configuration settings", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")], [sg.HSeparator()], [ - sg.Button("About", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="aboutReal"), + sg.Button("Device select", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="aboutReal"), sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="configFake") ], [sg.HSeparator()], @@ -360,11 +360,8 @@ def flashFromFile(file, device): layout = [ [ - # sg.VSeparator(), sg.Column(aboutDeviceLayout, key='-COL1-'), - # sg.VSeparator(), sg.Column(deviceConfigLayout, visible=False, key='-COL2-'), - # sg.VSeparator() ] ] From 7caca8925dbd50ec2f4b7cd16717792331eb5cdf Mon Sep 17 00:00:00 2001 From: Martin Peterlin Date: Tue, 1 Mar 2022 01:22:47 +0100 Subject: [PATCH 06/17] Some tweaks and support for devices lacking flash --- utilities/device_manager.py | 63 ++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index dec6372f9..7385e2b1e 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -135,39 +135,45 @@ def getDevices(window, devices): # print(deviceInfo.state) listedDevices.append(deviceInfo.desc.name) devices[deviceInfo.desc.name] = deviceInfo - sg.Popup("Found devices.") + # TODO - this action drags down user on correct path, no need for it + # sg.Popup("Found devices.") window.Element('devices').update("Select device", values=listedDevices) def getConfigs(window, device, devType): bl = dai.DeviceBootloader(device) + # TODO - might be better to readConfig instead of readConfigData conf = bl.readConfigData() - if devType == "Poe": - window.Element('staticIp').update(conf['network']['ipv4'] if conf['network']['ipv4'] != 0 else "0.0.0.0") - window.Element('staticMask').update(conf['network']['ipv4Mask'] if conf['network']['ipv4Mask'] != 0 + if conf is not None: + if devType == "Poe": + window.Element('staticIp').update(conf['network']['ipv4'] if conf['network']['ipv4'] != 0 else "0.0.0.0") + window.Element('staticMask').update(conf['network']['ipv4Mask'] if conf['network']['ipv4Mask'] != 0 + else "0.0.0.0") + window.Element('staticGateway').update(conf['network']['ipv4Gateway'] if conf['network']['ipv4Gateway'] != 0 + else "0.0.0.0") + window.Element('dns').update(conf['network']['ipv4Dns'] if conf['network']['ipv4Dns'] != 0 else "0.0.0.0") + window.Element('dnsAlt').update(conf['network']['ipv4DnsAlt'] if conf['network']['ipv4DnsAlt'] != 0 else "0.0.0.0") - window.Element('staticGateway').update(conf['network']['ipv4Gateway'] if conf['network']['ipv4Gateway'] != 0 - else "0.0.0.0") - window.Element('dns').update(conf['network']['ipv4Dns'] if conf['network']['ipv4Dns'] != 0 else "0.0.0.0") - window.Element('dnsAlt').update(conf['network']['ipv4DnsAlt'] if conf['network']['ipv4DnsAlt'] != 0 - else "0.0.0.0") - window.Element('networkTimeout').update(conf['network']['timeoutMs']) - window.Element('mac').update(macCorrectFormat(conf['network']['mac'])) - window.Element('usbTimeout').update("") - window.Element('usbSpeed').update("") - else: - window.Element('staticIp').update("") - window.Element('staticMask').update("") - window.Element('staticGateway').update("") - window.Element('dns').update("") - window.Element('dnsAlt').update("") - window.Element('networkTimeout').update("") - window.Element('mac').update("") - window.Element('usbTimeout').update(conf['usb']['timeoutMs']) - window.Element('usbSpeed').update(usbSpeedCorrection(conf['usb']['maxUsbSpeed'])) + window.Element('networkTimeout').update(conf['network']['timeoutMs']) + window.Element('mac').update(macCorrectFormat(conf['network']['mac'])) + window.Element('usbTimeout').update("") + window.Element('usbSpeed').update("") + else: + window.Element('staticIp').update("") + window.Element('staticMask').update("") + window.Element('staticGateway').update("") + window.Element('dns').update("") + window.Element('dnsAlt').update("") + window.Element('networkTimeout').update("") + window.Element('mac').update("") + window.Element('usbTimeout').update(conf['usb']['timeoutMs']) + window.Element('usbSpeed').update(usbSpeedCorrection(conf['usb']['maxUsbSpeed'])) window.Element('devName').update(device.desc.name) window.Element('newBoot').update(dai.DeviceBootloader.getEmbeddedBootloaderVersion()) - window.Element('currBoot').update(bl.getVersion()) + if bl.isEmbeddedVersion() is True: + window.Element('currBoot').update('None') + else: + window.Element('currBoot').update(bl.getVersion()) window.Element('version').update(dai.__version__) window.Element('commit').update(dai.__commit__) window.Element('devState').update(str(devices[device.desc.name].state).split(".")[1]) @@ -231,8 +237,9 @@ def factoryReset(device): def getDeviceType(device): bl = dai.DeviceBootloader(device) conf = bl.readConfigData() - if conf is None: - success, error = bl.flashConfig(dai.DeviceBootloader.Config()) + # TODO - Don't modify the device without explicit action + # if conf is None: + # success, error = bl.flashConfig(dai.DeviceBootloader.Config()) if str(bl.getType()) == "Type.NETWORK": return "Poe" else: @@ -293,7 +300,7 @@ def flashFromFile(file, device): [sg.HSeparator()], [ sg.Text("", size=(13, 2)), - sg.Button("Flash newest version", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, + sg.Button("Flash newest Bootloader", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), sg.Button("Factory reset", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), ] @@ -367,7 +374,7 @@ def flashFromFile(file, device): devices = dict() devType = "" -window = sg.Window(title="Bootloader GUI", layout=layout, size=(620, 370)) +window = sg.Window(title="Device Manager", layout=layout, size=(620, 370)) while True: event, values = window.read() From 3b80b81b4a808c239263fa5e9ee3043d349fc0cb Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Wed, 2 Mar 2022 16:51:00 +0100 Subject: [PATCH 07/17] Update device_manager.py Added new button "Flash from usb" --- utilities/device_manager.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index 7385e2b1e..a20aa55b1 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -81,11 +81,12 @@ def unlockConfig(window, devType): else: window['usbTimeout'].update(disabled=False) window['usbSpeed'].update(disabled=False) - window['Flash newest version'].update(disabled=False) + window['Flash newest Bootloader'].update(disabled=False) window['Flash configuration'].update(disabled=False) window['Factory reset'].update(disabled=False) # window['Reset configuration'].update(disabled=False) window['Flash DAP'].update(disabled=False) + window['Boot from USB'].update(disabled=False) def lockConfig(window): @@ -100,11 +101,12 @@ def lockConfig(window): window['dynamicBut'].update(disabled=True) window['usbTimeout'].update(disabled=True) window['usbSpeed'].update(disabled=True) - window['Flash newest version'].update(disabled=True) + window['Flash newest Bootloader'].update(disabled=True) window['Flash configuration'].update(disabled=True) window['Factory reset'].update(disabled=True) window['Reset configuration'].update(disabled=True) window['Flash DAP'].update(disabled=True) + window['Boot from USB'].update(disabled=True) window.Element('staticIp').update("") window.Element('staticMask').update("") @@ -254,10 +256,16 @@ def flashFromFile(file, device): sg.Popup("Selected file is not .dap!") +def flashFromUsb(device): + bl = dai.DeviceBootloader(device) + bl.bootUsbRomBootloader() + + usbSpeeds = ["UNKNOWN", "LOW", "FULL", "HIGH", "SUPER", "SUPER_PLUS"] sg.theme('DarkGrey4') +# layout for device tab aboutDeviceLayout = [ [sg.Text("About device", size=(30, 1), font=('Arial', 30, 'bold'), text_color="black")], [sg.HSeparator()], @@ -299,13 +307,15 @@ def flashFromFile(file, device): ], [sg.HSeparator()], [ - sg.Text("", size=(13, 2)), + sg.Text("", size=(7, 2)), sg.Button("Flash newest Bootloader", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), sg.Button("Factory reset", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), + sg.Button("Boot from USB", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00') ] ] +# layout for config tab deviceConfigLayout = [ [sg.Text("Configuration settings", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")], [sg.HSeparator()], @@ -365,6 +375,7 @@ def flashFromFile(file, device): ], ] +# layout of whole GUI with closed tabs set to false layout = [ [ sg.Column(aboutDeviceLayout, key='-COL1-'), @@ -390,7 +401,7 @@ def flashFromFile(file, device): window.Element('progress').update("No device selected.") if event == "Search": getDevices(window, devices) - if event == "Flash newest version": + if event == "Flash newest Bootloader": flashBootloader(window, devices[values['devices']]) if event == "Flash configuration": flashConfig(values, devices[values['devices']], devType, values['StaticBut']) @@ -412,4 +423,6 @@ def flashFromFile(file, device): if event == "aboutReal": window['-COL2-'].update(visible=False) window['-COL1-'].update(visible=True) + if event == "Boot from USB": + flashFromUsb(devices[values['devices']]) window.close() From 8eb2d9b726857a1f3196db4c8c32f74773e40299 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Thu, 3 Mar 2022 08:58:33 +0100 Subject: [PATCH 08/17] Update device_manager.py Changed program so that you connect to the device only once --- utilities/device_manager.py | 62 ++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index a20aa55b1..63a948968 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -84,9 +84,9 @@ def unlockConfig(window, devType): window['Flash newest Bootloader'].update(disabled=False) window['Flash configuration'].update(disabled=False) window['Factory reset'].update(disabled=False) - # window['Reset configuration'].update(disabled=False) + # window['Clear flash'].update(disabled=False) window['Flash DAP'].update(disabled=False) - window['Boot from USB'].update(disabled=False) + window['Boot into USB Recovery mode'].update(disabled=False) def lockConfig(window): @@ -104,9 +104,9 @@ def lockConfig(window): window['Flash newest Bootloader'].update(disabled=True) window['Flash configuration'].update(disabled=True) window['Factory reset'].update(disabled=True) - window['Reset configuration'].update(disabled=True) + window['Clear flash'].update(disabled=True) window['Flash DAP'].update(disabled=True) - window['Boot from USB'].update(disabled=True) + window['Boot into USB Recovery mode'].update(disabled=True) window.Element('staticIp').update("") window.Element('staticMask').update("") @@ -137,13 +137,11 @@ def getDevices(window, devices): # print(deviceInfo.state) listedDevices.append(deviceInfo.desc.name) devices[deviceInfo.desc.name] = deviceInfo - # TODO - this action drags down user on correct path, no need for it - # sg.Popup("Found devices.") window.Element('devices').update("Select device", values=listedDevices) -def getConfigs(window, device, devType): - bl = dai.DeviceBootloader(device) +def getConfigs(window, bl, devType, device): + # bl = dai.DeviceBootloader(device) # TODO - might be better to readConfig instead of readConfigData conf = bl.readConfigData() if conf is not None: @@ -181,16 +179,16 @@ def getConfigs(window, device, devType): window.Element('devState').update(str(devices[device.desc.name].state).split(".")[1]) -def flashBootloader(window, device): - bl = dai.DeviceBootloader(device, True) +def flashBootloader(window, bl): + # bl = dai.DeviceBootloader(device, True) progress = lambda p: p * 100 bl.flashBootloader(progress) window.Element('currBoot').update(bl.getVersion()) sg.Popup("Flashed newest bootloader version.") -def flashConfig(values, device, devType, ipType): - bl = dai.DeviceBootloader(device, True) +def flashConfig(values, bl, devType, ipType): + # bl = dai.DeviceBootloader(device, True) conf = dai.DeviceBootloader.Config() if devType == "Poe": if not(check_ip(values['staticIp']) and check_ip(values['staticMask']) @@ -205,7 +203,7 @@ def flashConfig(values, device, devType, ipType): conf.setStaticIPv4(values['staticIp'], values['staticIp'], values['staticIp']) else: conf.setDynamicIPv4(values['staticIp'], values['staticIp'], values['staticIp']) - conf.setDnsIPv4(values['dns'], "") + conf.setDnsIPv4(values['dns'], values['dnsAlt']) conf.setNetworkTimeout(timedelta(seconds=int(values['networkTimeout']) / 1000)) conf.setMacAddress(values['mac']) else: @@ -221,10 +219,10 @@ def flashConfig(values, device, devType, ipType): sg.Popup("Flashing successful.") -def factoryReset(device): +def factoryReset(bl): blBinary = dai.DeviceBootloader.getEmbeddedBootloaderBinary(dai.DeviceBootloader.Type.NETWORK) blBinary = blBinary + ([0xFF] * ((8 * 1024 * 1024 + 512) - len(blBinary))) - bl = dai.DeviceBootloader(device, True) + # bl = dai.DeviceBootloader(device, True) tmpBlFw = tempfile.NamedTemporaryFile(delete=False) tmpBlFw.write(bytes(blBinary)) progress = lambda p: p * 100 @@ -236,8 +234,8 @@ def factoryReset(device): tmpBlFw.close() -def getDeviceType(device): - bl = dai.DeviceBootloader(device) +def getDeviceType(bl): + # bl = dai.DeviceBootloader(device) conf = bl.readConfigData() # TODO - Don't modify the device without explicit action # if conf is None: @@ -248,16 +246,16 @@ def getDeviceType(device): return "NonPoe" -def flashFromFile(file, device): - bl = dai.DeviceBootloader(device) +def flashFromFile(file, bl): + # bl = dai.DeviceBootloader(device) if str(file)[-3:] == "dap": bl.flashDepthaiApplicationPackage(file) else: sg.Popup("Selected file is not .dap!") -def flashFromUsb(device): - bl = dai.DeviceBootloader(device) +def flashFromUsb(bl): + # bl = dai.DeviceBootloader(device) bl.bootUsbRomBootloader() @@ -311,7 +309,7 @@ def flashFromUsb(device): sg.Button("Flash newest Bootloader", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), sg.Button("Factory reset", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), - sg.Button("Boot from USB", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00') + sg.Button("Boot into USB Recovery mode", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00') ] ] @@ -385,6 +383,7 @@ def flashFromUsb(device): devices = dict() devType = "" +bl = None window = sg.Window(title="Device Manager", layout=layout, size=(620, 370)) while True: @@ -394,18 +393,19 @@ def flashFromUsb(device): dev = values['devices'] if event == "Select": if dev != "Select device": - devType = getDeviceType(devices[values['devices']]) - getConfigs(window, devices[values['devices']], devType) + bl = dai.DeviceBootloader(devices[values['devices']]) + devType = getDeviceType(bl) + getConfigs(window, bl, devType, devices[values['devices']]) unlockConfig(window, devType) else: window.Element('progress').update("No device selected.") if event == "Search": getDevices(window, devices) if event == "Flash newest Bootloader": - flashBootloader(window, devices[values['devices']]) + flashBootloader(window, bl) if event == "Flash configuration": - flashConfig(values, devices[values['devices']], devType, values['StaticBut']) - getConfigs(window, devices[values['devices']], devType) + flashConfig(values, bl, devType, values['staticBut']) + getConfigs(window, bl, devType, devices[values['devices']]) lockConfig(window) if devType != "Poe": unlockConfig(window, devType) @@ -413,16 +413,16 @@ def flashFromUsb(device): devices.clear() window.Element('devices').update("Search for devices", values=[]) if event == "Factory reset": - factoryReset(devices[values['devices']]) + factoryReset(bl) if event == "Flash DAP": file = sg.popup_get_file("Select .dap file") - flashFromFile(file, devices[values['devices']]) + flashFromFile(file, bl) if event == "configReal": window['-COL1-'].update(visible=False) window['-COL2-'].update(visible=True) if event == "aboutReal": window['-COL2-'].update(visible=False) window['-COL1-'].update(visible=True) - if event == "Boot from USB": - flashFromUsb(devices[values['devices']]) + if event == "Boot into USB Recovery mode": + flashFromUsb(bl) window.close() From b9deede9b44b5852eb72289e208024b9d40356bb Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Fri, 4 Mar 2022 09:38:37 +0100 Subject: [PATCH 09/17] Added requirements Added install_requirements.py and requirements.txt --- utilities/install_requirements.py | 20 ++++++++++++++++++++ utilities/requirements.txt | 1 + 2 files changed, 21 insertions(+) create mode 100644 utilities/install_requirements.py create mode 100644 utilities/requirements.txt diff --git a/utilities/install_requirements.py b/utilities/install_requirements.py new file mode 100644 index 000000000..ac402b47e --- /dev/null +++ b/utilities/install_requirements.py @@ -0,0 +1,20 @@ +import subprocess +import sys + + +in_venv = getattr(sys, "real_prefix", getattr(sys, "base_prefix", sys.prefix)) != sys.prefix +pip_call = [sys.executable, "-m", "pip"] +pip_install = pip_call + ["install"] + +if not in_venv: + pip_install.append("--user") + +subprocess.check_call([*pip_install, "pip", "-U"]) +subprocess.check_call([*pip_call, "uninstall", "depthai", "--yes"]) +subprocess.check_call([*pip_install, "-r", "requirements.txt"]) +try: + subprocess.check_call([*pip_install, "-r", "requirements-optional.txt"]) + if sys.platform == "linux": + print(f'$ sudo apt install python3-tk') +except subprocess.CalledProcessError as ex: + print(f"Optional dependencies were not installed (exit code {ex.returncode})") \ No newline at end of file diff --git a/utilities/requirements.txt b/utilities/requirements.txt new file mode 100644 index 000000000..ef2dc7bf6 --- /dev/null +++ b/utilities/requirements.txt @@ -0,0 +1 @@ +PySimpleGUI==4.57.0 \ No newline at end of file From 780fc442f29ee44eb9a3c4359cabea47336fa52f Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Fri, 11 Mar 2022 21:50:06 +0100 Subject: [PATCH 10/17] Fixed requested changes Fixed requested changes and also made GUI flashing to work so that you may flash only wanted configs and not all. --- utilities/device_manager.py | 55 +++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index 63a948968..1de5361f9 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -7,6 +7,8 @@ def check_ip(s: str): + if str == "": + return True spl = s.split(".") if len(spl) != 4: sg.Popup("Wrong IP format.\nValue should be similar to 255.255.255.255") @@ -19,6 +21,8 @@ def check_ip(s: str): def check_mac(s): + if s == "": + return True if s.count(":") != 5: sg.Popup("Wrong MAC format.\nValue should be similar to FF:FF:FF:FF:FF:FF") return False @@ -170,10 +174,11 @@ def getConfigs(window, bl, devType, device): window.Element('usbSpeed').update(usbSpeedCorrection(conf['usb']['maxUsbSpeed'])) window.Element('devName').update(device.desc.name) window.Element('newBoot').update(dai.DeviceBootloader.getEmbeddedBootloaderVersion()) - if bl.isEmbeddedVersion() is True: - window.Element('currBoot').update('None') - else: - window.Element('currBoot').update(bl.getVersion()) + # if bl.isEmbeddedVersion() is True: + # window.Element('currBoot').update('None') + # else: + # window.Element('currBoot').update(bl.getVersion()) + window.Element('currBoot').update(bl.getVersion()) window.Element('version').update(dai.__version__) window.Element('commit').update(dai.__commit__) window.Element('devState').update(str(devices[device.desc.name].state).split(".")[1]) @@ -200,18 +205,25 @@ def flashConfig(values, bl, devType, ipType): sg.Popup("Values can not be negative!") return if ipType: - conf.setStaticIPv4(values['staticIp'], values['staticIp'], values['staticIp']) + if values['staticIp'] != "" and values['staticMask'] != "" and values['staticGateway'] != "": + conf.setStaticIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) else: - conf.setDynamicIPv4(values['staticIp'], values['staticIp'], values['staticIp']) - conf.setDnsIPv4(values['dns'], values['dnsAlt']) - conf.setNetworkTimeout(timedelta(seconds=int(values['networkTimeout']) / 1000)) - conf.setMacAddress(values['mac']) + if values['staticIp'] != "" and values['staticMask'] != "" and values['staticGateway'] != "": + conf.setDynamicIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) + if values['dns'] != "" and values['dnsAlt'] != "": + conf.setDnsIPv4(values['dns'], values['dnsAlt']) + if values['networkTimeout'] != "": + conf.setNetworkTimeout(timedelta(seconds=int(values['networkTimeout']) / 1000)) + if values['mac'] != "": + conf.setMacAddress(values['mac']) else: if int(values['usbTimeout']) <= 0: sg.Popup("Values can not be negative!") return - conf.setUsbTimeout(timedelta(seconds=int(values['usbTimeout']) / 1000)) - conf.setUsbMaxSpeed(usbSpeed(values['usbSpeed'])) + if values['usbTimeout'] != "": + conf.setUsbTimeout(timedelta(seconds=int(values['usbTimeout']) / 1000)) + if values['usbSpeed'] != "": + conf.setUsbMaxSpeed(usbSpeed(values['usbSpeed'])) success, error = bl.flashConfig(conf) if not success: sg.Popup(f"Flashing failed: {error}") @@ -236,7 +248,7 @@ def factoryReset(bl): def getDeviceType(bl): # bl = dai.DeviceBootloader(device) - conf = bl.readConfigData() + # conf = bl.readConfigData() # TODO - Don't modify the device without explicit action # if conf is None: # success, error = bl.flashConfig(dai.DeviceBootloader.Config()) @@ -261,7 +273,7 @@ def flashFromUsb(bl): usbSpeeds = ["UNKNOWN", "LOW", "FULL", "HIGH", "SUPER", "SUPER_PLUS"] -sg.theme('DarkGrey4') +sg.theme('LightGrey2') # layout for device tab aboutDeviceLayout = [ @@ -294,7 +306,7 @@ def flashFromUsb(bl): sg.Text("-version-", key="currBoot", size=(30, 1)) ], [ - sg.Text("Current __version__:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.Text("Current Depthai version:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), sg.VSeparator(), sg.Text("Current commit:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), ], @@ -307,9 +319,10 @@ def flashFromUsb(bl): [ sg.Text("", size=(7, 2)), sg.Button("Flash newest Bootloader", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, - button_color='#FFEA00'), - sg.Button("Factory reset", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00'), - sg.Button("Boot into USB Recovery mode", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFEA00') + button_color='#FFA500'), + sg.Button("Factory reset", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, button_color='#FFA500'), + sg.Button("Boot into USB Recovery mode", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, + button_color='#FFA500') ] ] @@ -365,11 +378,11 @@ def flashFromUsb(bl): [ sg.Text("", size=(10, 2)), sg.Button("Flash configuration", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True, - button_color='#FFEA00'), + button_color='#FFA500'), sg.Button("Clear flash", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True, - button_color='#FFEA00'), + button_color='#FFA500'), sg.Button("Flash DAP", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True, - button_color='#FFEA00') + button_color='#FFA500') ], ] @@ -393,7 +406,7 @@ def flashFromUsb(bl): dev = values['devices'] if event == "Select": if dev != "Select device": - bl = dai.DeviceBootloader(devices[values['devices']]) + bl = dai.DeviceBootloader(devices[values['devices']], True) devType = getDeviceType(bl) getConfigs(window, bl, devType, devices[values['devices']]) unlockConfig(window, devType) From 350c4f2031e88ca7cdcc78df035e3cb7a8b582e0 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Sat, 12 Mar 2022 09:57:09 +0100 Subject: [PATCH 11/17] Removed select button Buttons select removed, GUI works with combo' events now( clicking in the combo box triggers same event as select did). --- utilities/device_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index 1de5361f9..1b076ee44 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -287,7 +287,7 @@ def flashFromUsb(bl): [ sg.Text("Select device: ", size=(15, 1), font=('Arial', 10, 'bold'), text_color="black"), sg.Combo([], "Search for devices", size=(30, 5), key="devices", enable_events=True), - sg.Button("Select"), sg.Button("Search") + sg.Button("Search") ], [ sg.Text("Name of connected device:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), @@ -404,7 +404,7 @@ def flashFromUsb(bl): if event == sg.WIN_CLOSED: break dev = values['devices'] - if event == "Select": + if event == "devices": if dev != "Select device": bl = dai.DeviceBootloader(devices[values['devices']], True) devType = getDeviceType(bl) From a3bb08ac09c42676e813a027dc38b64a9cc58cc0 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Sat, 12 Mar 2022 12:03:40 +0100 Subject: [PATCH 12/17] Changed widow size Changed window size and added device name to config tab. --- utilities/device_manager.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index 1b076ee44..091eb2a59 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -122,6 +122,7 @@ def lockConfig(window): window.Element('usbTimeout').update("") window.Element('usbSpeed').update("") window.Element('devName').update("-name-") + window.Element('devNameConf').update("") window.Element('newBoot').update("-version-") window.Element('currBoot').update("-version-") window.Element('version').update("-version-") @@ -173,6 +174,7 @@ def getConfigs(window, bl, devType, device): window.Element('usbTimeout').update(conf['usb']['timeoutMs']) window.Element('usbSpeed').update(usbSpeedCorrection(conf['usb']['maxUsbSpeed'])) window.Element('devName').update(device.desc.name) + window.Element('devNameConf').update(device.desc.name) window.Element('newBoot').update(dai.DeviceBootloader.getEmbeddedBootloaderVersion()) # if bl.isEmbeddedVersion() is True: # window.Element('currBoot').update('None') @@ -332,7 +334,11 @@ def flashFromUsb(bl): [sg.HSeparator()], [ sg.Button("Device select", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="aboutReal"), - sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="configFake") + sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="configFake"), + # TODO create library tab + # sg.Button("Library", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="configLib"), + sg.Text("", key="devNameConf", size=(30, 1)) + ], [sg.HSeparator()], [ @@ -397,7 +403,7 @@ def flashFromUsb(bl): devices = dict() devType = "" bl = None -window = sg.Window(title="Device Manager", layout=layout, size=(620, 370)) +window = sg.Window(title="Device Manager", layout=layout, size=(645, 370)) while True: event, values = window.read() From 1adcd96613cda97b7cd60d4f85ecb2bbf960041b Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Mon, 14 Mar 2022 17:20:18 +0100 Subject: [PATCH 13/17] Update device_manager.py Fixed values error --- utilities/device_manager.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index 091eb2a59..d06459b77 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -198,32 +198,32 @@ def flashConfig(values, bl, devType, ipType): # bl = dai.DeviceBootloader(device, True) conf = dai.DeviceBootloader.Config() if devType == "Poe": - if not(check_ip(values['staticIp']) and check_ip(values['staticMask']) - and check_ip(values['staticGateway'])): - return - if not check_mac(values['mac']): - return - if int(values['networkTimeout']) <= 0: - sg.Popup("Values can not be negative!") - return if ipType: if values['staticIp'] != "" and values['staticMask'] != "" and values['staticGateway'] != "": - conf.setStaticIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) + if check_ip(values['staticIp']) and check_ip(values['staticMask']) and check_ip( + values['staticGateway']): + conf.setStaticIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) else: if values['staticIp'] != "" and values['staticMask'] != "" and values['staticGateway'] != "": - conf.setDynamicIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) + if check_ip(values['staticIp']) and check_ip(values['staticMask']) and check_ip( + values['staticGateway']): + conf.setDynamicIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) if values['dns'] != "" and values['dnsAlt'] != "": conf.setDnsIPv4(values['dns'], values['dnsAlt']) if values['networkTimeout'] != "": - conf.setNetworkTimeout(timedelta(seconds=int(values['networkTimeout']) / 1000)) + if int(values['networkTimeout']) >= 0: + conf.setNetworkTimeout(timedelta(seconds=int(values['networkTimeout']) / 1000)) + else: + sg.Popup("Values can not be negative!") if values['mac'] != "": - conf.setMacAddress(values['mac']) + if check_mac(values['mac']): + conf.setMacAddress(values['mac']) else: - if int(values['usbTimeout']) <= 0: - sg.Popup("Values can not be negative!") - return if values['usbTimeout'] != "": - conf.setUsbTimeout(timedelta(seconds=int(values['usbTimeout']) / 1000)) + if int(values['usbTimeout']) >= 0: + conf.setUsbTimeout(timedelta(seconds=int(values['usbTimeout']) / 1000)) + else: + sg.Popup("Values can not be negative!") if values['usbSpeed'] != "": conf.setUsbMaxSpeed(usbSpeed(values['usbSpeed'])) success, error = bl.flashConfig(conf) From 0336a70f8b86010ba6ba58a342c0c075cc532be0 Mon Sep 17 00:00:00 2001 From: TheMarpe Date: Tue, 15 Mar 2022 18:46:05 +0100 Subject: [PATCH 14/17] Some fixes and review comments --- utilities/device_manager.py | 63 ++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index d06459b77..4c495c801 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -148,31 +148,39 @@ def getDevices(window, devices): def getConfigs(window, bl, devType, device): # bl = dai.DeviceBootloader(device) # TODO - might be better to readConfig instead of readConfigData - conf = bl.readConfigData() - if conf is not None: - if devType == "Poe": - window.Element('staticIp').update(conf['network']['ipv4'] if conf['network']['ipv4'] != 0 else "0.0.0.0") - window.Element('staticMask').update(conf['network']['ipv4Mask'] if conf['network']['ipv4Mask'] != 0 - else "0.0.0.0") - window.Element('staticGateway').update(conf['network']['ipv4Gateway'] if conf['network']['ipv4Gateway'] != 0 + + # TODO - apply to other functions as well, most of them may throw, catch such cases and present the user with an appropriate message + # Most of time the version difference is the culprit + try: + conf = bl.readConfigData() + if conf is not None: + if devType == "Poe": + window.Element('staticIp').update(conf['network']['ipv4'] if conf['network']['ipv4'] != 0 else "0.0.0.0") + window.Element('staticMask').update(conf['network']['ipv4Mask'] if conf['network']['ipv4Mask'] != 0 + else "0.0.0.0") + window.Element('staticGateway').update(conf['network']['ipv4Gateway'] if conf['network']['ipv4Gateway'] != 0 + else "0.0.0.0") + window.Element('dns').update(conf['network']['ipv4Dns'] if conf['network']['ipv4Dns'] != 0 else "0.0.0.0") + window.Element('dnsAlt').update(conf['network']['ipv4DnsAlt'] if conf['network']['ipv4DnsAlt'] != 0 else "0.0.0.0") - window.Element('dns').update(conf['network']['ipv4Dns'] if conf['network']['ipv4Dns'] != 0 else "0.0.0.0") - window.Element('dnsAlt').update(conf['network']['ipv4DnsAlt'] if conf['network']['ipv4DnsAlt'] != 0 - else "0.0.0.0") - window.Element('networkTimeout').update(conf['network']['timeoutMs']) - window.Element('mac').update(macCorrectFormat(conf['network']['mac'])) - window.Element('usbTimeout').update("") - window.Element('usbSpeed').update("") - else: - window.Element('staticIp').update("") - window.Element('staticMask').update("") - window.Element('staticGateway').update("") - window.Element('dns').update("") - window.Element('dnsAlt').update("") - window.Element('networkTimeout').update("") - window.Element('mac').update("") - window.Element('usbTimeout').update(conf['usb']['timeoutMs']) - window.Element('usbSpeed').update(usbSpeedCorrection(conf['usb']['maxUsbSpeed'])) + window.Element('networkTimeout').update(conf['network']['timeoutMs']) + window.Element('mac').update(macCorrectFormat(conf['network']['mac'])) + window.Element('usbTimeout').update("") + window.Element('usbSpeed').update("") + else: + window.Element('staticIp').update("") + window.Element('staticMask').update("") + window.Element('staticGateway').update("") + window.Element('dns').update("") + window.Element('dnsAlt').update("") + window.Element('networkTimeout').update("") + window.Element('mac').update("") + window.Element('usbTimeout').update(conf['usb']['timeoutMs']) + window.Element('usbSpeed').update(usbSpeedCorrection(conf['usb']['maxUsbSpeed'])) + except Exception as ex: + print(f'Exception: {ex}') + sg.Popup(f'{ex}') + window.Element('devName').update(device.desc.name) window.Element('devNameConf').update(device.desc.name) window.Element('newBoot').update(dai.DeviceBootloader.getEmbeddedBootloaderVersion()) @@ -187,6 +195,8 @@ def getConfigs(window, bl, devType, device): def flashBootloader(window, bl): + # FIXME - to flash bootloader, boot the same device again (from saved device info) but with allowFlashingBootloader = True + # FIXME 2 - Allow selection of bootloader type explicitly (eg network type when flashing a fresh PoE device which doesn't have an Ethernet bootloader on it yet) # bl = dai.DeviceBootloader(device, True) progress = lambda p: p * 100 bl.flashBootloader(progress) @@ -412,7 +422,10 @@ def flashFromUsb(bl): dev = values['devices'] if event == "devices": if dev != "Select device": - bl = dai.DeviceBootloader(devices[values['devices']], True) + # "allow flashing bootloader" boots latest bootloader first + # which makes the information of current bootloader, etc.. not correct (can be checked by "isEmbeddedVersion") + # So leave it to false, uncomment the isEmbeddedVersion below and only boot into latest bootlaoder upon the request to flash new bootloader + bl = dai.DeviceBootloader(devices[values['devices']], False) devType = getDeviceType(bl) getConfigs(window, bl, devType, devices[values['devices']]) unlockConfig(window, devType) From bab621636a50b5bbffb34911c341fdaf9bd881e0 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Tue, 22 Mar 2022 10:02:11 +0100 Subject: [PATCH 15/17] Addressed requested changes Fixed addressed changes. --- utilities/device_manager.py | 280 ++++++++++++++++++++++-------------- 1 file changed, 174 insertions(+), 106 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index 4c495c801..572d9cdbd 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -131,18 +131,22 @@ def lockConfig(window): def getDevices(window, devices): - listedDevices = [] - devices.clear() - deviceInfos = dai.XLinkConnection.getAllConnectedDevices() - if not deviceInfos: - window.Element('devices').update("No devices") - sg.Popup("No devices found.") - else: - for deviceInfo in deviceInfos: - # print(deviceInfo.state) - listedDevices.append(deviceInfo.desc.name) - devices[deviceInfo.desc.name] = deviceInfo - window.Element('devices').update("Select device", values=listedDevices) + try: + listedDevices = [] + devices.clear() + deviceInfos = dai.XLinkConnection.getAllConnectedDevices() + if not deviceInfos: + window.Element('devices').update("No devices") + sg.Popup("No devices found.") + else: + for deviceInfo in deviceInfos: + # print(deviceInfo.state) + listedDevices.append(deviceInfo.desc.name) + devices[deviceInfo.desc.name] = deviceInfo + window.Element('devices').update("Select device", values=listedDevices) + except Exception as ex: + print(f'Exception: {ex}') + sg.Popup(f'{ex}') def getConfigs(window, bl, devType, device): @@ -177,85 +181,100 @@ def getConfigs(window, bl, devType, device): window.Element('mac').update("") window.Element('usbTimeout').update(conf['usb']['timeoutMs']) window.Element('usbSpeed').update(usbSpeedCorrection(conf['usb']['maxUsbSpeed'])) + + window.Element('devName').update(device.desc.name) + window.Element('devNameConf').update(device.desc.name) + window.Element('newBoot').update(dai.DeviceBootloader.getEmbeddedBootloaderVersion()) + # if bl.isEmbeddedVersion() is True: + # window.Element('currBoot').update('None') + # else: + # window.Element('currBoot').update(bl.getVersion()) + window.Element('currBoot').update(bl.getVersion()) + window.Element('version').update(dai.__version__) + window.Element('commit').update(dai.__commit__) + window.Element('devState').update(str(devices[device.desc.name].state).split(".")[1]) except Exception as ex: print(f'Exception: {ex}') sg.Popup(f'{ex}') - window.Element('devName').update(device.desc.name) - window.Element('devNameConf').update(device.desc.name) - window.Element('newBoot').update(dai.DeviceBootloader.getEmbeddedBootloaderVersion()) - # if bl.isEmbeddedVersion() is True: - # window.Element('currBoot').update('None') - # else: - # window.Element('currBoot').update(bl.getVersion()) - window.Element('currBoot').update(bl.getVersion()) - window.Element('version').update(dai.__version__) - window.Element('commit').update(dai.__commit__) - window.Element('devState').update(str(devices[device.desc.name].state).split(".")[1]) - -def flashBootloader(window, bl): +def flashBootloader(window, device, values): # FIXME - to flash bootloader, boot the same device again (from saved device info) but with allowFlashingBootloader = True # FIXME 2 - Allow selection of bootloader type explicitly (eg network type when flashing a fresh PoE device which doesn't have an Ethernet bootloader on it yet) - # bl = dai.DeviceBootloader(device, True) - progress = lambda p: p * 100 - bl.flashBootloader(progress) - window.Element('currBoot').update(bl.getVersion()) - sg.Popup("Flashed newest bootloader version.") + try: + type = dai.DeviceBootloader.Type.USB + if values['bootType'] == "NETWORK": + type = dai.DeviceBootloader.Type.NETWORK + bl = dai.DeviceBootloader(device, True) + progress = lambda p: p * 100 + bl.flashBootloader(memory=dai.DeviceBootloader.Memory.FLASH, type=type, progressCallback=progress) + window.Element('currBoot').update(bl.getVersion()) + sg.Popup("Flashed newest bootloader version.") + except Exception as ex: + print(f'Exception: {ex}') + sg.Popup(f'{ex}') -def flashConfig(values, bl, devType, ipType): - # bl = dai.DeviceBootloader(device, True) - conf = dai.DeviceBootloader.Config() - if devType == "Poe": - if ipType: - if values['staticIp'] != "" and values['staticMask'] != "" and values['staticGateway'] != "": - if check_ip(values['staticIp']) and check_ip(values['staticMask']) and check_ip( - values['staticGateway']): - conf.setStaticIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) - else: - if values['staticIp'] != "" and values['staticMask'] != "" and values['staticGateway'] != "": - if check_ip(values['staticIp']) and check_ip(values['staticMask']) and check_ip( - values['staticGateway']): - conf.setDynamicIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) - if values['dns'] != "" and values['dnsAlt'] != "": - conf.setDnsIPv4(values['dns'], values['dnsAlt']) - if values['networkTimeout'] != "": - if int(values['networkTimeout']) >= 0: - conf.setNetworkTimeout(timedelta(seconds=int(values['networkTimeout']) / 1000)) - else: - sg.Popup("Values can not be negative!") - if values['mac'] != "": - if check_mac(values['mac']): - conf.setMacAddress(values['mac']) - else: - if values['usbTimeout'] != "": - if int(values['usbTimeout']) >= 0: - conf.setUsbTimeout(timedelta(seconds=int(values['usbTimeout']) / 1000)) +def flashConfig(values, device, devType, ipType): + try: + bl = dai.DeviceBootloader(device, True) + conf = dai.DeviceBootloader.Config() + if devType == "Poe": + if ipType: + if values['staticIp'] != "" and values['staticMask'] != "" and values['staticGateway'] != "": + if check_ip(values['staticIp']) and check_ip(values['staticMask']) and check_ip( + values['staticGateway']): + conf.setStaticIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) else: - sg.Popup("Values can not be negative!") - if values['usbSpeed'] != "": - conf.setUsbMaxSpeed(usbSpeed(values['usbSpeed'])) - success, error = bl.flashConfig(conf) - if not success: - sg.Popup(f"Flashing failed: {error}") - else: - sg.Popup("Flashing successful.") - - -def factoryReset(bl): - blBinary = dai.DeviceBootloader.getEmbeddedBootloaderBinary(dai.DeviceBootloader.Type.NETWORK) - blBinary = blBinary + ([0xFF] * ((8 * 1024 * 1024 + 512) - len(blBinary))) - # bl = dai.DeviceBootloader(device, True) - tmpBlFw = tempfile.NamedTemporaryFile(delete=False) - tmpBlFw.write(bytes(blBinary)) - progress = lambda p: p * 100 - success, msg = bl.flashBootloader(progress, tmpBlFw.name) - if success: - sg.Popup("Factory reset was successful.") - else: - sg.Popup(f"Factory reset failed. Error: {msg}") - tmpBlFw.close() + if values['staticIp'] != "" and values['staticMask'] != "" and values['staticGateway'] != "": + if check_ip(values['staticIp']) and check_ip(values['staticMask']) and check_ip( + values['staticGateway']): + conf.setDynamicIPv4(values['staticIp'], values['staticMask'], values['staticGateway']) + if values['dns'] != "" and values['dnsAlt'] != "": + conf.setDnsIPv4(values['dns'], values['dnsAlt']) + if values['networkTimeout'] != "": + if int(values['networkTimeout']) >= 0: + conf.setNetworkTimeout(timedelta(seconds=int(values['networkTimeout']) / 1000)) + else: + sg.Popup("Values can not be negative!") + if values['mac'] != "": + if check_mac(values['mac']): + conf.setMacAddress(values['mac']) + else: + if values['usbTimeout'] != "": + if int(values['usbTimeout']) >= 0: + conf.setUsbTimeout(timedelta(seconds=int(values['usbTimeout']) / 1000)) + else: + sg.Popup("Values can not be negative!") + if values['usbSpeed'] != "": + conf.setUsbMaxSpeed(usbSpeed(values['usbSpeed'])) + success, error = bl.flashConfig(conf) + if not success: + sg.Popup(f"Flashing failed: {error}") + else: + sg.Popup("Flashing successful.") + except Exception as ex: + print(f'Exception: {ex}') + sg.Popup(f'{ex}') + + +def factoryReset(device): + try: + blBinary = dai.DeviceBootloader.getEmbeddedBootloaderBinary(dai.DeviceBootloader.Type.NETWORK) + blBinary = blBinary + ([0xFF] * ((8 * 1024 * 1024 + 512) - len(blBinary))) + bl = dai.DeviceBootloader(device, True) + tmpBlFw = tempfile.NamedTemporaryFile(delete=False) + tmpBlFw.write(bytes(blBinary)) + progress = lambda p: p * 100 + success, msg = bl.flashBootloader(progress, tmpBlFw.name) + if success: + sg.Popup("Factory reset was successful.") + else: + sg.Popup(f"Factory reset failed. Error: {msg}") + tmpBlFw.close() + except Exception as ex: + print(f'Exception: {ex}') + sg.Popup(f'{ex}') def getDeviceType(bl): @@ -264,29 +283,62 @@ def getDeviceType(bl): # TODO - Don't modify the device without explicit action # if conf is None: # success, error = bl.flashConfig(dai.DeviceBootloader.Config()) - if str(bl.getType()) == "Type.NETWORK": - return "Poe" - else: - return "NonPoe" + try: + if str(bl.getType()) == "Type.NETWORK": + return "Poe" + else: + return "NonPoe" + except Exception as ex: + print(f'Exception: {ex}') + sg.Popup(f'{ex}') -def flashFromFile(file, bl): - # bl = dai.DeviceBootloader(device) - if str(file)[-3:] == "dap": - bl.flashDepthaiApplicationPackage(file) - else: - sg.Popup("Selected file is not .dap!") +def flashFromFile(file, device): + try: + bl = dai.DeviceBootloader(device, True) + if str(file)[-3:] == "dap": + bl.flashDepthaiApplicationPackage(file) + else: + sg.Popup("Selected file is not .dap!") + except Exception as ex: + print(f'Exception: {ex}') + sg.Popup(f'{ex}') -def flashFromUsb(bl): - # bl = dai.DeviceBootloader(device) - bl.bootUsbRomBootloader() +def flashFromUsb(device): + try: + bl = dai.DeviceBootloader(device, True) + bl.bootUsbRomBootloader() + except Exception as ex: + print(f'Exception: {ex}') + sg.Popup(f'{ex}') + + +def connectToDevice(device): + try: + bl = dai.DeviceBootloader(device, False) + return bl + except Exception as ex: + print(f'Exception: {ex}') + sg.Popup(f'{ex}') usbSpeeds = ["UNKNOWN", "LOW", "FULL", "HIGH", "SUPER", "SUPER_PLUS"] sg.theme('LightGrey2') +# first device search +allDevices = [] +devices = dict() +tmp = "Search for devices" +deviceInfos = dai.XLinkConnection.getAllConnectedDevices() + +if deviceInfos: + tmp = "Select device" + for deviceInfo in deviceInfos: + allDevices.append(deviceInfo.desc.name) + devices[deviceInfo.desc.name] = deviceInfo + # layout for device tab aboutDeviceLayout = [ [sg.Text("About device", size=(30, 1), font=('Arial', 30, 'bold'), text_color="black")], @@ -298,7 +350,7 @@ def flashFromUsb(bl): [sg.HSeparator()], [ sg.Text("Select device: ", size=(15, 1), font=('Arial', 10, 'bold'), text_color="black"), - sg.Combo([], "Search for devices", size=(30, 5), key="devices", enable_events=True), + sg.Combo(allDevices, tmp, size=(30, 5), key="devices", enable_events=True), sg.Button("Search") ], [ @@ -328,6 +380,12 @@ def flashFromUsb(bl): sg.Text("-version-", key="commit", size=(31, 1)) ], [sg.HSeparator()], + [ + sg.Text("Bootloader type:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), + sg.VSeparator(), + sg.Combo(["USB", "NETWORK"], "Select bootloader type", size=(30, 2), key="bootType"), + ], + [sg.HSeparator()], [ sg.Text("", size=(7, 2)), sg.Button("Flash newest Bootloader", size=(17, 2), font=('Arial', 10, 'bold'), disabled=True, @@ -410,10 +468,9 @@ def flashFromUsb(bl): ] ] -devices = dict() devType = "" bl = None -window = sg.Window(title="Device Manager", layout=layout, size=(645, 370)) +window = sg.Window(title="Device Manager", layout=layout, size=(645, 410)) while True: event, values = window.read() @@ -425,18 +482,26 @@ def flashFromUsb(bl): # "allow flashing bootloader" boots latest bootloader first # which makes the information of current bootloader, etc.. not correct (can be checked by "isEmbeddedVersion") # So leave it to false, uncomment the isEmbeddedVersion below and only boot into latest bootlaoder upon the request to flash new bootloader - bl = dai.DeviceBootloader(devices[values['devices']], False) - devType = getDeviceType(bl) - getConfigs(window, bl, devType, devices[values['devices']]) - unlockConfig(window, devType) + # bl = dai.DeviceBootloader(devices[values['devices']], False) + if str(devices[values['devices']].state).replace("XLinkDeviceState.X_LINK_", "") == "BOOTED": + # device is already booted somewhere else + sg.Popup("Device is already booted somewhere else!") + else: + bl = connectToDevice(devices[values['devices']]) + devType = getDeviceType(bl) + getConfigs(window, bl, devType, devices[values['devices']]) + unlockConfig(window, devType) else: window.Element('progress').update("No device selected.") if event == "Search": getDevices(window, devices) if event == "Flash newest Bootloader": - flashBootloader(window, bl) + bl.close() + flashBootloader(window, devices[values['devices']], values) if event == "Flash configuration": - flashConfig(values, bl, devType, values['staticBut']) + bl.close() + flashConfig(values, devices[values['devices']], devType, values['staticBut']) + bl = connectToDevice(devices[values['devices']]) getConfigs(window, bl, devType, devices[values['devices']]) lockConfig(window) if devType != "Poe": @@ -445,10 +510,12 @@ def flashFromUsb(bl): devices.clear() window.Element('devices').update("Search for devices", values=[]) if event == "Factory reset": - factoryReset(bl) + bl.close() + factoryReset(devices[values['devices']]) if event == "Flash DAP": file = sg.popup_get_file("Select .dap file") - flashFromFile(file, bl) + bl = None + flashFromFile(file, devices[values['devices']]) if event == "configReal": window['-COL1-'].update(visible=False) window['-COL2-'].update(visible=True) @@ -456,5 +523,6 @@ def flashFromUsb(bl): window['-COL2-'].update(visible=False) window['-COL1-'].update(visible=True) if event == "Boot into USB Recovery mode": - flashFromUsb(bl) + bl = None + flashFromUsb(devices[values['devices']]) window.close() From a61a609ca6901c8c05294c8739cf11cd235b5a09 Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Tue, 22 Mar 2022 16:57:17 +0100 Subject: [PATCH 16/17] Added default to bootloader type Added a default option which will auto select bootloader type based on device type --- utilities/device_manager.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index 572d9cdbd..836e10ceb 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -126,7 +126,7 @@ def lockConfig(window): window.Element('newBoot').update("-version-") window.Element('currBoot').update("-version-") window.Element('version').update("-version-") - window.Element('commit').update("-commit-") + window.Element('commit').update("-version-") window.Element('devState').update("-state-") @@ -185,11 +185,14 @@ def getConfigs(window, bl, devType, device): window.Element('devName').update(device.desc.name) window.Element('devNameConf').update(device.desc.name) window.Element('newBoot').update(dai.DeviceBootloader.getEmbeddedBootloaderVersion()) - # if bl.isEmbeddedVersion() is True: - # window.Element('currBoot').update('None') - # else: - # window.Element('currBoot').update(bl.getVersion()) - window.Element('currBoot').update(bl.getVersion()) + + # The "isEmbeddedVersion" tells you whether BL had to be booted, + # or we connected to an already flashed Bootloader. + if bl.isEmbeddedVersion() is True: + window.Element('currBoot').update('None') + else: + window.Element('currBoot').update(bl.getVersion()) + # window.Element('currBoot').update(bl.getVersion()) window.Element('version').update(dai.__version__) window.Element('commit').update(dai.__commit__) window.Element('devState').update(str(devices[device.desc.name].state).split(".")[1]) @@ -202,10 +205,16 @@ def flashBootloader(window, device, values): # FIXME - to flash bootloader, boot the same device again (from saved device info) but with allowFlashingBootloader = True # FIXME 2 - Allow selection of bootloader type explicitly (eg network type when flashing a fresh PoE device which doesn't have an Ethernet bootloader on it yet) try: - type = dai.DeviceBootloader.Type.USB + bl = dai.DeviceBootloader(device, True) if values['bootType'] == "NETWORK": type = dai.DeviceBootloader.Type.NETWORK - bl = dai.DeviceBootloader(device, True) + elif values['bootType'] == "USB": + type = dai.DeviceBootloader.Type.USB + else: + if str(bl.getType()) == "Type.NETWORK": + type = dai.DeviceBootloader.Type.NETWORK + else: + type = dai.DeviceBootloader.Type.USB progress = lambda p: p * 100 bl.flashBootloader(memory=dai.DeviceBootloader.Memory.FLASH, type=type, progressCallback=progress) window.Element('currBoot').update(bl.getVersion()) @@ -383,7 +392,7 @@ def connectToDevice(device): [ sg.Text("Bootloader type:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), sg.VSeparator(), - sg.Combo(["USB", "NETWORK"], "Select bootloader type", size=(30, 2), key="bootType"), + sg.Combo(["DEFAULT", "USB", "NETWORK"], "DEFAULT", size=(30, 2), key="bootType"), ], [sg.HSeparator()], [ @@ -495,6 +504,7 @@ def connectToDevice(device): window.Element('progress').update("No device selected.") if event == "Search": getDevices(window, devices) + lockConfig(window) if event == "Flash newest Bootloader": bl.close() flashBootloader(window, devices[values['devices']], values) From 0b95dcbed51ad527ff2e771dc7785de884e2b9ce Mon Sep 17 00:00:00 2001 From: zigakerzan Date: Tue, 22 Mar 2022 17:01:59 +0100 Subject: [PATCH 17/17] Addressed requested changes Addressed requested changes. --- utilities/device_manager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utilities/device_manager.py b/utilities/device_manager.py index 836e10ceb..8cbd5fcf4 100644 --- a/utilities/device_manager.py +++ b/utilities/device_manager.py @@ -128,6 +128,7 @@ def lockConfig(window): window.Element('version').update("-version-") window.Element('commit').update("-version-") window.Element('devState').update("-state-") + window.Element('bootType').update("DEFAULT") def getDevices(window, devices): @@ -392,7 +393,7 @@ def connectToDevice(device): [ sg.Text("Bootloader type:", size=(30, 1), font=('Arial', 10, 'bold'), text_color="black"), sg.VSeparator(), - sg.Combo(["DEFAULT", "USB", "NETWORK"], "DEFAULT", size=(30, 2), key="bootType"), + sg.Combo(["DEFAULT", "USB", "NETWORK"], "DEFAULT", size=(30, 3), key="bootType"), ], [sg.HSeparator()], [