oak_luxonis
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| oak_luxonis [2026/06/05 09:12] – created 46.109.187.144 | oak_luxonis [2026/06/05 09:16] (current) – 46.109.187.144 | ||
|---|---|---|---|
| Line 5: | Line 5: | ||
| </ | </ | ||
| ===== Programmas instalācija Device Manager ===== | ===== Programmas instalācija Device Manager ===== | ||
| - | ==== SHORT SENSOR | + | ==== (oakenv) |
| - | < | + | < |
| + | python -m venv oakenv | ||
| .\oakenv\Scripts\activate | .\oakenv\Scripts\activate | ||
| pip install --upgrade pip | pip install --upgrade pip | ||
| + | pip install PySimpleGUI | ||
| pip install depthai | pip install depthai | ||
| + | python -m pip install --upgrade depthai | ||
| + | pip install pillow | ||
| + | </ | ||
| + | |||
| + | ==== device_manager.py ==== | ||
| + | < | ||
| + | # | ||
| + | |||
| + | USE_OPENCV = False | ||
| + | |||
| + | from datetime import timedelta | ||
| + | import depthai as dai | ||
| + | import tempfile | ||
| + | import PySimpleGUI as sg | ||
| + | import sys | ||
| + | from typing import Dict | ||
| + | import platform | ||
| + | import os | ||
| + | import numpy | ||
| + | |||
| + | if USE_OPENCV: | ||
| + | # import cv2 | ||
| + | pass | ||
| + | else: | ||
| + | import io | ||
| + | from PIL import Image | ||
| + | |||
| + | SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) | ||
| + | |||
| + | PLATFORM_ICON_PATH = None | ||
| + | if platform.system() == ' | ||
| + | PLATFORM_ICON_PATH = f' | ||
| + | else: | ||
| + | PLATFORM_ICON_PATH = f' | ||
| + | |||
| + | # Apply icon globally | ||
| + | sg.set_global_icon(PLATFORM_ICON_PATH) | ||
| + | |||
| + | CONF_TEXT_POE = [' | ||
| + | CONF_INPUT_POE = [' | ||
| + | CONF_TEXT_USB = [' | ||
| + | CONF_INPUT_USB = [' | ||
| + | USB_SPEEDS = [" | ||
| + | |||
| + | def PrintException(): | ||
| + | exc_type, exc_obj, tb = sys.exc_info() | ||
| + | f = tb.tb_frame | ||
| + | lineno = tb.tb_lineno | ||
| + | filename = f.f_code.co_filename | ||
| + | print(' | ||
| + | |||
| + | def Popup(msg, window): | ||
| + | main_window_location = window.CurrentLocation() | ||
| + | main_window_size = window.size | ||
| + | # Calculate the centered location for the new window | ||
| + | centered_location = (main_window_location[0] + (main_window_size[0] - 50) // 2, | ||
| + | | ||
| + | return sg.Popup(msg, | ||
| + | |||
| + | def check_ip(window, | ||
| + | if s == "": | ||
| + | return not req | ||
| + | spl = s.split(" | ||
| + | if len(spl) != 4: | ||
| + | Popup(" | ||
| + | return False | ||
| + | for num in spl: | ||
| + | if 255 < int(num): | ||
| + | Popup(" | ||
| + | return False | ||
| + | return True | ||
| + | |||
| + | def check_mac(window, | ||
| + | if s.count(":" | ||
| + | Popup(" | ||
| + | return False | ||
| + | for i in s.split(":" | ||
| + | for j in i: | ||
| + | if j > " | ||
| + | Popup(" | ||
| + | return False | ||
| + | return True | ||
| + | |||
| + | class Progress: | ||
| + | def __init__(self, | ||
| + | layout = [ | ||
| + | [sg.Text(txt, | ||
| + | [sg.ProgressBar(1.0, | ||
| + | ] | ||
| + | self.window = sg.Window(" | ||
| + | def update(self, | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | def finish(self, | ||
| + | self.window.close() | ||
| + | sg.Popup(msg) | ||
| + | |||
| + | class SelectBootloader: | ||
| + | def __init__(self, | ||
| + | self.ok = False | ||
| + | layout = [ | ||
| + | [sg.Text(text)], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.Combo(options, | ||
| + | ], | ||
| + | [sg.Text(" | ||
| + | [sg.Submit(), | ||
| + | ] | ||
| + | self.window = sg.Window(" | ||
| + | def wait(self): | ||
| + | event, values = self.window.Read() | ||
| + | self.window.close() | ||
| + | if values is not None: | ||
| + | type = getattr(dai.DeviceBootloader.Type, | ||
| + | return (str(event) == " | ||
| + | else: | ||
| + | return (False, None) | ||
| + | |||
| + | class AreYouSure: | ||
| + | def __init__(self, | ||
| + | self.ok = False | ||
| + | layout = [ | ||
| + | [sg.Text(text)], | ||
| + | [sg.Submit(), | ||
| + | ] | ||
| + | self.window = sg.Window(" | ||
| + | def wait(self): | ||
| + | event, values = self.window.Read() | ||
| + | self.window.close() | ||
| + | return str(event) == " | ||
| + | |||
| + | |||
| + | class SelectIP: | ||
| + | def __init__(self, | ||
| + | self.ok = False | ||
| + | layout = [ | ||
| + | [sg.Text(" | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.InputText(key=" | ||
| + | ], | ||
| + | [sg.Submit(), | ||
| + | ] | ||
| + | self.window = sg.Window(" | ||
| + | |||
| + | main_window_location = window.CurrentLocation() | ||
| + | main_window_size = window.size | ||
| + | new_window_size = self.window.size | ||
| + | # Calculate the centered location for the new window | ||
| + | centered_location = (main_window_location[0] + (main_window_size[0] - new_window_size[0]) // 2, | ||
| + | | ||
| + | self.window.move(*centered_location) | ||
| + | |||
| + | def wait(self): | ||
| + | event, values = self.window.Read() | ||
| + | self.window.close() | ||
| + | if str(event) == " | ||
| + | return False, "" | ||
| + | return True, values[" | ||
| + | |||
| + | class SearchDevice: | ||
| + | def __init__(self, | ||
| + | self.infos = [] | ||
| + | layout = [ | ||
| + | [sg.Text(" | ||
| + | [sg.Table(values=[], | ||
| + | # col_widths=[25, | ||
| + | # def_col_width=25, | ||
| + | # max_col_width=200, | ||
| + | # background_color=' | ||
| + | display_row_numbers=True, | ||
| + | justification=' | ||
| + | num_rows=8, | ||
| + | alternating_row_color=' | ||
| + | key=' | ||
| + | row_height=35, | ||
| + | # size=(500, 300) | ||
| + | expand_x = True, | ||
| + | enable_events = True, | ||
| + | enable_click_events = True, | ||
| + | ) | ||
| + | ], | ||
| + | [sg.Button(' | ||
| + | ] | ||
| + | self.window = sg.Window(" | ||
| + | |||
| + | main_window_location = window.CurrentLocation() | ||
| + | main_window_size = window.size | ||
| + | new_window_size = self.window.size | ||
| + | # Calculate the centered location for the new window | ||
| + | centered_location = (main_window_location[0] + (main_window_size[0] - new_window_size[0]) // 2, | ||
| + | | ||
| + | self.window.move(*centered_location) | ||
| + | |||
| + | self.search_devices() | ||
| + | |||
| + | def search_devices(self): | ||
| + | self.infos = dai.XLinkConnection.getAllConnectedDevices() | ||
| + | if not self.infos: | ||
| + | pass | ||
| + | # sg.Popup(" | ||
| + | else: | ||
| + | rows = [] | ||
| + | for info in self.infos: | ||
| + | if " | ||
| + | rows.append([info.getDeviceId(), | ||
| + | self.window[' | ||
| + | |||
| + | def wait(self) -> dai.DeviceInfo: | ||
| + | while True: | ||
| + | event, values = self.window.Read() | ||
| + | if event is None: | ||
| + | self.window.close() | ||
| + | return None | ||
| + | elif str(event) == ' | ||
| + | self.search_devices() | ||
| + | elif len(event) == 3 and event[0] == " | ||
| + | # User selected a device | ||
| + | deviceIndex = event[2][0] | ||
| + | if deviceIndex is not None: | ||
| + | deviceSelected = self.infos[deviceIndex] | ||
| + | self.window.close() | ||
| + | return deviceSelected | ||
| + | |||
| + | def flashBootloader(bl: | ||
| + | userBlWarningMessage = """ | ||
| + | Proceed with caution""" | ||
| + | factoryBlWarningMessage = """ | ||
| + | Factory bootloader will be updated instead. | ||
| + | Proceed with caution | ||
| + | """ | ||
| + | |||
| + | try: | ||
| + | if bl.isUserBootloaderSupported(): | ||
| + | if AreYouSure(text=userBlWarningMessage).wait(): | ||
| + | pr = Progress(' | ||
| + | progress = lambda p : pr.update(p) | ||
| + | bl.flashUserBootloader(progress) | ||
| + | pr.finish(" | ||
| + | else: | ||
| + | return False | ||
| + | elif AreYouSure(text=factoryBlWarningMessage).wait(): | ||
| + | bl.close() | ||
| + | pr = Progress(' | ||
| + | bl = dai.DeviceBootloader(device, | ||
| + | progress = lambda p : pr.update(p) | ||
| + | if type == dai.DeviceBootloader.Type.AUTO: | ||
| + | type = bl.getType() | ||
| + | bl.flashBootloader(memory=dai.DeviceBootloader.Memory.FLASH, | ||
| + | pr.finish(" | ||
| + | else: | ||
| + | return False | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | sg.Popup(f' | ||
| + | |||
| + | return True | ||
| + | |||
| + | |||
| + | # Danger | ||
| + | def flashFactoryBootloader(device: | ||
| + | try: | ||
| + | pr = Progress(' | ||
| + | bl = dai.DeviceBootloader(device, | ||
| + | progress = lambda p : pr.update(p) | ||
| + | if type == dai.DeviceBootloader.Type.AUTO: | ||
| + | type = bl.getType() | ||
| + | bl.flashBootloader(memory=dai.DeviceBootloader.Memory.FLASH, | ||
| + | pr.finish(" | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | sg.Popup(f' | ||
| + | |||
| + | def factoryReset(device: | ||
| + | try: | ||
| + | pr = Progress(' | ||
| + | |||
| + | bl = dai.DeviceBootloader(device, | ||
| + | progress = lambda p : pr.update(p) | ||
| + | if type == dai.DeviceBootloader.Type.AUTO: | ||
| + | type = bl.getType() | ||
| + | |||
| + | tmpBlFw = None | ||
| + | try: | ||
| + | blBinary = dai.DeviceBootloader.getEmbeddedBootloaderBinary(type) | ||
| + | # Clear 1 MiB for USB BL and 8 MiB for NETWORK BL | ||
| + | mib = 1 if type == dai.DeviceBootloader.Type.USB else 8 | ||
| + | blBinary = blBinary + ([0xFF] * ((mib * 1024 * 1024 + 512) - len(blBinary))) | ||
| + | tmpBlFw = tempfile.NamedTemporaryFile(delete=False) | ||
| + | tmpBlFw.write(bytes(blBinary)) | ||
| + | tmpBlFw.flush() | ||
| + | success, msg = bl.flashBootloader(progress, | ||
| + | except Exception as ex: | ||
| + | # In some depthai Python builds vector< | ||
| + | if " | ||
| + | success, msg = bl.flashBootloader( | ||
| + | memory=dai.DeviceBootloader.Memory.FLASH, | ||
| + | type=type, | ||
| + | progressCallback=progress | ||
| + | ) | ||
| + | else: | ||
| + | raise | ||
| + | finally: | ||
| + | if tmpBlFw is not None: | ||
| + | tmpBlFw.close() | ||
| + | |||
| + | msg = " | ||
| + | pr.finish(msg) | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | sg.Popup(f' | ||
| + | |||
| + | def flashFromFile(file, | ||
| + | try: | ||
| + | if str(file)[-3: | ||
| + | pr = Progress(' | ||
| + | progress = lambda p : pr.update(p) | ||
| + | with open(file, mode = ' | ||
| + | dap = list(f.read()) | ||
| + | success, msg = bl.flashDepthaiApplicationPackage(progress, | ||
| + | msg = " | ||
| + | pr.finish(msg) | ||
| + | else: | ||
| + | sg.Popup(" | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | sg.Popup(f' | ||
| + | |||
| + | def recoveryMode(bl: | ||
| + | try: | ||
| + | bl.bootUsbRomBootloader() | ||
| + | return True | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | sg.Popup(f' | ||
| + | return False | ||
| + | |||
| + | def connectToDevice(device: | ||
| + | try: | ||
| + | bl = dai.DeviceBootloader(device, | ||
| + | return bl | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | sg.Popup(f' | ||
| + | |||
| + | def deviceStateTxt(state: | ||
| + | return str(state).replace(" | ||
| + | |||
| + | # Start defying layout | ||
| + | |||
| + | sg.theme(' | ||
| + | |||
| + | # layout for device tab | ||
| + | aboutDeviceLayout = [ | ||
| + | [sg.Text(" | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | ], | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.Combo([], | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.VSeparator(), | ||
| + | sg.Text(" | ||
| + | ], | ||
| + | [sg.Text(" | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.VSeparator(), | ||
| + | sg.Text(" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.VSeparator(), | ||
| + | sg.Text(" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.VSeparator(), | ||
| + | sg.Text(" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.VSeparator(), | ||
| + | sg.Text(" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.VSeparator(), | ||
| + | sg.Text(" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.VSeparator(), | ||
| + | sg.Text(" | ||
| + | ] | ||
| + | ] | ||
| + | |||
| + | # layout for config tab | ||
| + | deviceConfigLayout = [ | ||
| + | [sg.Text(" | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | |||
| + | ], | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.Radio(' | ||
| + | | ||
| + | sg.Radio(' | ||
| + | | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.InputText(key=" | ||
| + | sg.Text(" | ||
| + | sg.InputText(key=" | ||
| + | sg.Text(" | ||
| + | sg.InputText(key=" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.InputText(key=" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.InputText(key=" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.InputText(key=" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.InputText(key=" | ||
| + | ], | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.InputText(key=" | ||
| + | ], | ||
| + | [ | ||
| + | sg.Text(" | ||
| + | sg.Combo(USB_SPEEDS, | ||
| + | ], | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Text("", | ||
| + | sg.Button(" | ||
| + | button_color='# | ||
| + | sg.Button(" | ||
| + | button_color='# | ||
| + | sg.Button(" | ||
| + | button_color='# | ||
| + | ], | ||
| + | ] | ||
| + | |||
| + | # layout for app tab | ||
| + | appLayout = [ | ||
| + | [sg.Text(" | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | ], | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Button(" | ||
| + | button_color='# | ||
| + | sg.Button(" | ||
| + | button_color='# | ||
| + | ], | ||
| + | ] | ||
| + | |||
| + | |||
| + | # layout for app tab | ||
| + | dangerLayout = [ | ||
| + | [sg.Text(" | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | ], | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Button(" | ||
| + | button_color='# | ||
| + | sg.Button(" | ||
| + | button_color='# | ||
| + | ], | ||
| + | [sg.HSeparator()], | ||
| + | [ | ||
| + | sg.Button(" | ||
| + | sg.Button(" | ||
| + | key=' | ||
| + | ] | ||
| + | ] | ||
| + | |||
| + | |||
| + | # layout of whole GUI with closed tabs set to false | ||
| + | layout = [ | ||
| + | [ | ||
| + | sg.Column(aboutDeviceLayout, | ||
| + | sg.Column(deviceConfigLayout, | ||
| + | sg.Column(appLayout, | ||
| + | sg.Column(dangerLayout, | ||
| + | ] | ||
| + | ] | ||
| + | |||
| + | |||
| + | class DeviceManager: | ||
| + | devices: Dict[str, dai.DeviceInfo] = dict() | ||
| + | values: Dict = None | ||
| + | |||
| + | def __init__(self) -> None: | ||
| + | self.window = sg.Window(title=" | ||
| + | icon=PLATFORM_ICON_PATH, | ||
| + | layout=layout, | ||
| + | size=(645, 380), | ||
| + | finalize=True # So we can do First search for devices | ||
| + | ) | ||
| + | |||
| + | self.bl: dai.DeviceBootloader = None | ||
| + | |||
| + | # First device search | ||
| + | self.getDevices() | ||
| + | |||
| + | def isPoE(self) -> bool: | ||
| + | try: | ||
| + | return self.bl.getType() == dai.DeviceBootloader.Type.NETWORK | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | Popup(f' | ||
| + | |||
| + | def isUsb(self) -> bool: | ||
| + | return not self.isPoE() | ||
| + | |||
| + | def run(self) -> None: | ||
| + | while True: | ||
| + | event, self.values = self.window.read() | ||
| + | if event == sg.WIN_CLOSED: | ||
| + | break | ||
| + | dev = self.values[' | ||
| + | |||
| + | if event == " | ||
| + | if dev != " | ||
| + | # "allow flashing bootloader" | ||
| + | # which makes the information of current bootloader, etc.. not correct (can be checked by " | ||
| + | # 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[' | ||
| + | device = self.device | ||
| + | if deviceStateTxt(device.state) == " | ||
| + | # device is already booted somewhere else | ||
| + | Popup(" | ||
| + | else: | ||
| + | self.resetGui() | ||
| + | self.bl = connectToDevice(device) | ||
| + | if self.bl is None: continue | ||
| + | self.getConfigs() | ||
| + | self.unlockConfig() | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | elif event == " | ||
| + | self.getDevices() # Re-search devices for dropdown | ||
| + | selDev = SearchDevice(window=self.window) | ||
| + | di = selDev.wait() | ||
| + | if di is not None: | ||
| + | self.resetGui() | ||
| + | self.addDeviceInfo(di) | ||
| + | self.window.Element(' | ||
| + | _, self.values = self.window.read(1) | ||
| + | self.bl = connectToDevice(di) | ||
| + | print(' | ||
| + | if self.bl is None: continue | ||
| + | self.getConfigs() | ||
| + | self.unlockConfig() | ||
| + | elif event == " | ||
| + | select = SelectIP(window=self.window) | ||
| + | ok, ip = select.wait() | ||
| + | if ok: | ||
| + | self.resetGui() | ||
| + | di = dai.DeviceInfo(ip) | ||
| + | di.state = dai.XLinkDeviceState.X_LINK_BOOTLOADER | ||
| + | di.protocol = dai.XLinkProtocol.X_LINK_TCP_IP | ||
| + | self.devices[ip] = di # Add to devices dict | ||
| + | self.window.Element(' | ||
| + | _, self.values = self.window.read(1) | ||
| + | self.bl = connectToDevice(di) | ||
| + | if self.bl is None: continue | ||
| + | self.getConfigs() | ||
| + | self.unlockConfig() | ||
| + | |||
| + | # Danger | ||
| + | elif event == " | ||
| + | # Use current type | ||
| + | if flashBootloader(self.bl, | ||
| + | # Device will reboot, close previous and reset GUI | ||
| + | self.closeDevice() | ||
| + | self.resetGui() | ||
| + | self.getDevices() | ||
| + | else: | ||
| + | print(" | ||
| + | elif event == " | ||
| + | sel = SelectBootloader([' | ||
| + | ok, type = sel.wait() | ||
| + | if ok: | ||
| + | # We will reconnect, as we need to set allowFlashingBootloader to True | ||
| + | self.closeDevice() | ||
| + | flashFactoryBootloader(self.device, | ||
| + | # Device will reboot, close previous and reset GUI | ||
| + | self.closeDevice() | ||
| + | self.resetGui() | ||
| + | self.getDevices() | ||
| + | else: | ||
| + | print(" | ||
| + | |||
| + | elif event == " | ||
| + | sel = SelectBootloader([' | ||
| + | ok, type = sel.wait() | ||
| + | if ok: | ||
| + | # We will reconnect, as we need to set allowFlashingBootloader to True | ||
| + | self.closeDevice() | ||
| + | factoryReset(self.device, | ||
| + | # Device will reboot, close previous and reset GUI | ||
| + | self.closeDevice() | ||
| + | self.resetGui() | ||
| + | self.getDevices() | ||
| + | else: | ||
| + | print(" | ||
| + | |||
| + | elif event == "Flash configuration": | ||
| + | if self.flashConfig() is not None: | ||
| + | self.getConfigs() | ||
| + | self.resetGui() | ||
| + | if self.isUsb(): | ||
| + | self.unlockConfig() | ||
| + | else: | ||
| + | self.devices.clear() | ||
| + | self.window.Element(' | ||
| + | elif event == "Clear configuration": | ||
| + | self.clearConfig() | ||
| + | self.getConfigs() | ||
| + | self.resetGui() | ||
| + | if self.isUsb(): | ||
| + | self.unlockConfig() | ||
| + | else: | ||
| + | self.devices.clear() | ||
| + | self.window.Element(' | ||
| + | elif event == "View configuration": | ||
| + | try: | ||
| + | confJson = self.bl.readConfigData() | ||
| + | sg.popup_scrolled(confJson, | ||
| + | except Exception as ex: | ||
| + | Popup(f' | ||
| + | |||
| + | elif event == "Flash application": | ||
| + | file = sg.popup_get_file(" | ||
| + | flashFromFile(file, | ||
| + | elif event == " | ||
| + | try: | ||
| + | self.bl.flashClear() | ||
| + | Popup(f' | ||
| + | except Exception as ex: | ||
| + | sg.popup(f" | ||
| + | |||
| + | elif event.startswith(" | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | elif event.startswith(" | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | elif event.startswith(" | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | elif event.startswith(" | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | |||
| + | |||
| + | elif event == " | ||
| + | if recoveryMode(self.bl): | ||
| + | Popup(f' | ||
| + | # Device will reboot, close previous and reset GUI | ||
| + | self.closeDevice() | ||
| + | self.resetGui() | ||
| + | self.getDevices() | ||
| + | elif event == " | ||
| + | # Clear out IPv4 settings to default to | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | |||
| + | |||
| + | self.window.close() | ||
| + | |||
| + | @property | ||
| + | def device(self) -> dai.DeviceInfo: | ||
| + | """ | ||
| + | Get selected device | ||
| + | """ | ||
| + | return self.devices[self.values[' | ||
| + | |||
| + | def addDeviceInfo(self, | ||
| + | if deviceInfo.getDeviceId() not in self.devices: | ||
| + | # Add the new deviceInfo | ||
| + | self.devices[deviceInfo.getDeviceId()] = deviceInfo | ||
| + | |||
| + | def getConfigs(self): | ||
| + | device = self.device | ||
| + | try: | ||
| + | conf = self.bl.readConfig() | ||
| + | except: | ||
| + | conf = dai.DeviceBootloader.Config() | ||
| + | |||
| + | try: | ||
| + | if self.isPoE(): | ||
| + | if conf.isStaticIPV4(): | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | |||
| + | if conf.getIPv4() == ' | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | |||
| + | if conf.getIPv4Mask() == ' | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | |||
| + | if conf.getIPv4Gateway() == ' | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | |||
| + | if conf.getDnsIPv4() == ' | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | if conf.getDnsAltIPv4() == ' | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | if conf.getMacAddress() == ' | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | for el in CONF_INPUT_USB: | ||
| + | self.window[el].update("" | ||
| + | else: | ||
| + | for el in CONF_INPUT_POE: | ||
| + | self.window[el].update("" | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | |||
| + | self.window.Element(' | ||
| + | # self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | |||
| + | # The " | ||
| + | # or we connected to an already flashed Bootloader. | ||
| + | if self.bl.isEmbeddedVersion(): | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | if deviceStateTxt(device.state) == " | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | if self.isPoE(): | ||
| + | self.window.Element(' | ||
| + | else: | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | sg.Popup(f' | ||
| + | |||
| + | def unlockConfig(self): | ||
| + | if self.bl is None: return | ||
| + | |||
| + | if self.isPoE(): | ||
| + | for el in CONF_INPUT_POE: | ||
| + | self.window[el].update(disabled=False) | ||
| + | for el in CONF_TEXT_POE: | ||
| + | self.window[el].update(text_color=" | ||
| + | else: | ||
| + | for el in CONF_INPUT_USB: | ||
| + | self.window[el].update(disabled=False) | ||
| + | for el in CONF_TEXT_USB: | ||
| + | self.window[el].update(text_color=" | ||
| + | |||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | |||
| + | self.window[' | ||
| + | self.window[' | ||
| + | |||
| + | self.window[' | ||
| + | |||
| + | def resetGui(self): | ||
| + | """ | ||
| + | Reset GUI to its original state | ||
| + | """ | ||
| + | for conf in [CONF_INPUT_POE, | ||
| + | for el in conf: | ||
| + | self.window[el].update(disabled=True) | ||
| + | self.window[el].update("" | ||
| + | for conf in [CONF_TEXT_POE, | ||
| + | for el in conf: | ||
| + | self.window[el].update(text_color=" | ||
| + | |||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | |||
| + | self.window[' | ||
| + | |||
| + | self.window.Element(' | ||
| + | # self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | self.window.Element(' | ||
| + | |||
| + | # Move back to ' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | self.window[' | ||
| + | |||
| + | def closeDevice(self): | ||
| + | if self.bl is not None: | ||
| + | self.bl.close() | ||
| + | self.bl = None | ||
| + | |||
| + | def getDevices(self): | ||
| + | self.closeDevice() | ||
| + | try: | ||
| + | listedDevices = [] | ||
| + | self.devices.clear() | ||
| + | deviceInfos = dai.XLinkConnection.getAllConnectedDevices() | ||
| + | if not deviceInfos: | ||
| + | self.window.Element(' | ||
| + | # sg.Popup(" | ||
| + | else: | ||
| + | for deviceInfo in deviceInfos: | ||
| + | deviceTxt = deviceInfo.getDeviceId() | ||
| + | print(deviceInfo.state.name) | ||
| + | if " | ||
| + | listedDevices.append(deviceTxt) | ||
| + | self.devices[deviceTxt] = deviceInfo | ||
| + | |||
| + | # Update the list regardless | ||
| + | self.window.Element(' | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | Popup(f' | ||
| + | |||
| + | def flashConfig(self): | ||
| + | values = self.values | ||
| + | |||
| + | # Read modify write instead of flashing over | ||
| + | # clearConfig can be used to start from scratch | ||
| + | conf = dai.DeviceBootloader.Config() | ||
| + | try: | ||
| + | conf = self.bl.readConfig() | ||
| + | except: | ||
| + | pass | ||
| + | |||
| + | try: | ||
| + | if self.isPoE: | ||
| + | if self.values[' | ||
| + | if check_ip(self.window, | ||
| + | conf.setStaticIPv4(values[' | ||
| + | else: | ||
| + | raise Exception(' | ||
| + | else: | ||
| + | if check_ip(self.window, | ||
| + | conf.setDynamicIPv4(values[' | ||
| + | |||
| + | conf.setDnsIPv4(values[' | ||
| + | if values[' | ||
| + | if int(values[' | ||
| + | conf.setNetworkTimeout(timedelta(seconds=int(values[' | ||
| + | else: | ||
| + | Popup(" | ||
| + | if values[' | ||
| + | if check_mac(self.window, | ||
| + | conf.setMacAddress(values[' | ||
| + | else: | ||
| + | conf.setMacAddress(' | ||
| + | else: | ||
| + | if values[' | ||
| + | if int(values[' | ||
| + | conf.setUsbTimeout(timedelta(seconds=int(values[' | ||
| + | else: | ||
| + | Popup(" | ||
| + | if values[' | ||
| + | conf.setUsbMaxSpeed(getattr(dai.UsbSpeed, | ||
| + | |||
| + | success, error = self.bl.flashConfig(conf) | ||
| + | if not success: | ||
| + | Popup(f" | ||
| + | return False | ||
| + | else: | ||
| + | Popup(" | ||
| + | return True | ||
| + | |||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | Popup(f' | ||
| + | |||
| + | return None | ||
| + | |||
| + | def clearConfig(self): | ||
| + | try: | ||
| + | success, error = self.bl.flashConfigClear() | ||
| + | if not success: | ||
| + | Popup(f" | ||
| + | else: | ||
| + | Popup(" | ||
| + | except Exception as ex: | ||
| + | PrintException() | ||
| + | Popup(f' | ||
| + | |||
| + | app = DeviceManager() | ||
| + | app.run() | ||
| </ | </ | ||
| - | ==== Device Manager ==== | ||
oak_luxonis.1780650737.txt.gz · Last modified: by 46.109.187.144 · Currently locked by: 216.73.217.69
