Skip to content

Commit 712269e

Browse files
committed
Modified DeviceBootloader::Config to retain previous values and improved device_manager
1 parent a0cdd90 commit 712269e

File tree

3 files changed

+94
-19
lines changed

3 files changed

+94
-19
lines changed

depthai-core

src/DeviceBootloaderBindings.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ void DeviceBootloaderBindings::bind(pybind11::module& m, void* pCallstack){
110110
.def("getMacAddress", &DeviceBootloader::Config::getMacAddress)
111111
.def("setUsbMaxSpeed", &DeviceBootloader::Config::setUsbMaxSpeed)
112112
.def("getUsbMaxSpeed", &DeviceBootloader::Config::getUsbMaxSpeed)
113+
.def("toJson", &DeviceBootloader::Config::toJson)
114+
.def("fromJson", &DeviceBootloader::Config::fromJson)
113115
;
114116

115117
deviceBootloderApplicationInfo

utilities/device_manager.py

Lines changed: 91 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,13 @@ def factoryReset(device: dai.DeviceInfo, type: dai.DeviceBootloader.Type):
202202
def flashFromFile(file, bl: dai.DeviceBootloader):
203203
try:
204204
if str(file)[-3:] == "dap":
205-
bl.flashDepthaiApplicationPackage(file)
205+
pr = Progress('Flashing application...')
206+
progress = lambda p : pr.update(p)
207+
with open(file, mode = 'rb') as f:
208+
dap = list(f.read())
209+
success, msg = bl.flashDepthaiApplicationPackage(progress, dap)
210+
msg = "Flashing application was successful." if success else f"Flashing application failed. Error: {msg}"
211+
pr.finish(msg)
206212
else:
207213
sg.Popup("Selected file is not .dap!")
208214
except Exception as ex:
@@ -238,8 +244,9 @@ def deviceStateTxt(state: dai.XLinkDeviceState) -> str:
238244
[sg.Text("About device", size=(30, 1), font=('Arial', 30, 'bold'), text_color="black")],
239245
[sg.HSeparator()],
240246
[
241-
sg.Button("About device", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="aboutFake"),
242-
sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="configReal")
247+
sg.Button("About device", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="_unique_aboutBtn"),
248+
sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="_unique_configBtn"),
249+
sg.Button("Application", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="_unique_appBtn")
243250
],
244251
[sg.HSeparator()],
245252
[
@@ -290,8 +297,9 @@ def deviceStateTxt(state: dai.XLinkDeviceState) -> str:
290297
[sg.Text("Configuration settings", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")],
291298
[sg.HSeparator()],
292299
[
293-
sg.Button("About device", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="aboutReal"),
294-
sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="configFake"),
300+
sg.Button("About device", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="_unique_aboutBtn"),
301+
sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="_unique_configBtn"),
302+
sg.Button("Application", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="_unique_appBtn"),
295303
# TODO create library tab
296304
# sg.Button("Library", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="configLib"),
297305
sg.Text("", key="devNameConf", size=(30, 1))
@@ -340,23 +348,51 @@ def deviceStateTxt(state: dai.XLinkDeviceState) -> str:
340348
],
341349
[sg.HSeparator()],
342350
[
343-
sg.Text("", size=(1, 2)),
351+
sg.Text("", size=(8, 2)),
344352
sg.Button("Flash configuration", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True,
345353
button_color='#FFA500'),
346354
sg.Button("Clear configuration", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True,
347355
button_color='#FFA500'),
348-
sg.Button("Clear flash", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True,
356+
sg.Button("View configuration", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True,
349357
button_color='#FFA500'),
350-
sg.Button("Flash DAP", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True,
351-
button_color='#FFA500')
352358
],
353359
]
354360

361+
# layout for app tab
362+
appLayout = [
363+
[sg.Text("Application settings", size=(20, 1), font=('Arial', 30, 'bold'), text_color="black")],
364+
[sg.HSeparator()],
365+
[
366+
sg.Button("About device", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="_unique_aboutBtn"),
367+
sg.Button("Config", size=(15, 1), font=('Arial', 10, 'bold'), disabled=False, key="_unique_configBtn"),
368+
sg.Button("Application", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="_unique_appBtn"),
369+
# TODO create library tab
370+
# sg.Button("Library", size=(15, 1), font=('Arial', 10, 'bold'), disabled=True, key="configLib"),
371+
sg.Text("", key="devNameConf", size=(30, 1))
372+
373+
],
374+
# TODO - add bootloader_version information
375+
# [sg.HSeparator()],
376+
# [
377+
# sg.Text("", key="devNameConf", size=(30, 1))
378+
379+
# ],
380+
[sg.HSeparator()],
381+
[
382+
sg.Button("Flash application", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True,
383+
button_color='#FFA500'),
384+
sg.Button("Remove application", size=(15, 2), font=('Arial', 10, 'bold'), disabled=True,
385+
button_color='#FFA500'),
386+
],
387+
]
388+
389+
355390
# layout of whole GUI with closed tabs set to false
356391
layout = [
357392
[
358393
sg.Column(aboutDeviceLayout, key='-COL1-'),
359394
sg.Column(deviceConfigLayout, visible=False, key='-COL2-'),
395+
sg.Column(appLayout, visible=False, key='-COL3-'),
360396
]
361397
]
362398

@@ -488,16 +524,35 @@ def run(self) -> None:
488524
else:
489525
self.devices.clear()
490526
self.window.Element('devices').update("Search for devices", values=[])
491-
492-
elif event == "Flash DAP":
527+
elif event == "View configuration":
528+
try:
529+
confJson = self.bl.readConfigData()
530+
sg.popup_scrolled(confJson, title='Configuration')
531+
except Exception as ex:
532+
sg.popup(f'No existing config to view ({ex})')
533+
534+
elif event == "Flash application":
493535
file = sg.popup_get_file("Select .dap file", file_types=(('DepthAI Application Package', '*.dap'), ('All Files', '*.* *')))
494536
flashFromFile(file, self.bl)
495-
elif event == "configReal":
537+
elif event == "Remove application":
538+
try:
539+
self.bl.flashClear()
540+
sg.popup(f'Successfully removed application')
541+
except Exception as ex:
542+
sg.popup(f"Couldn't remove application ({ex})")
543+
544+
elif event.startswith("_unique_configBtn"):
496545
self.window['-COL1-'].update(visible=False)
497546
self.window['-COL2-'].update(visible=True)
498-
elif event == "aboutReal":
547+
self.window['-COL3-'].update(visible=False)
548+
elif event.startswith("_unique_aboutBtn"):
499549
self.window['-COL2-'].update(visible=False)
500550
self.window['-COL1-'].update(visible=True)
551+
self.window['-COL3-'].update(visible=False)
552+
elif event.startswith("_unique_appBtn"):
553+
self.window['-COL2-'].update(visible=False)
554+
self.window['-COL1-'].update(visible=False)
555+
self.window['-COL3-'].update(visible=True)
501556
elif event == "recoveryMode":
502557
if recoveryMode(self.bl):
503558
sg.Popup(f'Device successfully put into USB recovery mode.')
@@ -533,6 +588,11 @@ def getConfigs(self):
533588

534589
try:
535590
if self.isPoE():
591+
if conf.isStaticIPV4():
592+
self.window.Element('staticBut').update(True)
593+
else:
594+
self.window.Element('dynamicBut').update(True)
595+
536596
if conf.getIPv4() == '0.0.0.0':
537597
self.window.Element('ip').update('')
538598
else:
@@ -604,9 +664,12 @@ def unlockConfig(self):
604664
self.window['Flash newest Bootloader'].update(disabled=False)
605665
self.window['Flash configuration'].update(disabled=False)
606666
self.window['Clear configuration'].update(disabled=False)
667+
self.window['View configuration'].update(disabled=False)
607668
self.window['Factory reset'].update(disabled=False)
608-
# self.window['Clear flash'].update(disabled=False)
609-
self.window['Flash DAP'].update(disabled=False)
669+
670+
self.window['Flash application'].update(disabled=False)
671+
self.window['Remove application'].update(disabled=False)
672+
610673
self.window['recoveryMode'].update(disabled=False)
611674

612675
def resetGui(self):
@@ -624,9 +687,10 @@ def resetGui(self):
624687
self.window['Flash newest Bootloader'].update(disabled=True)
625688
self.window['Flash configuration'].update(disabled=True)
626689
self.window['Clear configuration'].update(disabled=True)
690+
self.window['View configuration'].update(disabled=True)
627691
self.window['Factory reset'].update(disabled=True)
628-
self.window['Clear flash'].update(disabled=True)
629-
self.window['Flash DAP'].update(disabled=True)
692+
self.window['Flash application'].update(disabled=True)
693+
self.window['Remove application'].update(disabled=True)
630694
self.window['recoveryMode'].update(disabled=True)
631695

632696
self.window.Element('devName').update("-name-")
@@ -665,8 +729,16 @@ def getDevices(self):
665729

666730
def flashConfig(self):
667731
values = self.values
732+
733+
# Read modify write instead of flashing over
734+
# clearConfig can be used to start from scratch
735+
conf = dai.DeviceBootloader.Config()
736+
try:
737+
conf = self.bl.readConfig()
738+
except:
739+
pass
740+
668741
try:
669-
conf = dai.DeviceBootloader.Config()
670742
if self.isPoE:
671743
if self.values['staticBut']:
672744
if check_ip(values['ip']) and check_ip(values['mask']) and check_ip(values['gateway']):
@@ -703,6 +775,7 @@ def flashConfig(self):
703775
except Exception as ex:
704776
PrintException()
705777
sg.Popup(f'{ex}')
778+
706779
def clearConfig(self):
707780
try:
708781
success, error = self.bl.flashConfigClear()

0 commit comments

Comments
 (0)