diff --git a/latest/Apps/maiana-update/.gitignore b/latest/Apps/maiana-update/.gitignore new file mode 100644 index 0000000..ed8ebf5 --- /dev/null +++ b/latest/Apps/maiana-update/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/latest/Apps/maiana-update/.idea/.gitignore b/latest/Apps/maiana-update/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/latest/Apps/maiana-update/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/latest/Apps/maiana-update/.idea/inspectionProfiles/profiles_settings.xml b/latest/Apps/maiana-update/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/latest/Apps/maiana-update/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/latest/Apps/maiana-update/.idea/maiana-update.iml b/latest/Apps/maiana-update/.idea/maiana-update.iml new file mode 100644 index 0000000..74d515a --- /dev/null +++ b/latest/Apps/maiana-update/.idea/maiana-update.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/latest/Apps/maiana-update/.idea/misc.xml b/latest/Apps/maiana-update/.idea/misc.xml new file mode 100644 index 0000000..7a5e236 --- /dev/null +++ b/latest/Apps/maiana-update/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/latest/Apps/maiana-update/.idea/modules.xml b/latest/Apps/maiana-update/.idea/modules.xml new file mode 100644 index 0000000..f321b90 --- /dev/null +++ b/latest/Apps/maiana-update/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/latest/Apps/maiana-update/.idea/vcs.xml b/latest/Apps/maiana-update/.idea/vcs.xml new file mode 100644 index 0000000..c2365ab --- /dev/null +++ b/latest/Apps/maiana-update/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/latest/Apps/maiana-update/fwUpdateThread.py b/latest/Apps/maiana-update/fwUpdateThread.py new file mode 100644 index 0000000..b29a144 --- /dev/null +++ b/latest/Apps/maiana-update/fwUpdateThread.py @@ -0,0 +1,124 @@ +from threading import Thread +import wx +import os +import binascii +import sys +from enum import Enum + + +EVT_FWUPDATE_ID = wx.NewId() + +class EventType(Enum): + DFU_ENABLED = 1 + TRANSFER_STARTED = 2 + TRANSFER_PROGRESS = 3 + TRANSFER_COMPLETE = 4 + ERROR = 5 + +class FwUpdateEvent(wx.PyEvent): + def __init__(self, eventType, data): + wx.PyEvent.__init__(self) + self.SetEventType(EVT_FWUPDATE_ID) + self.eventType = eventType + self.data = data + + +class FWUpdateThread(Thread): + def __init__(self, window, port, filename): + Thread.__init__(self) + self.daemon = True + self.window = window + self.port = port + self.filesize = 0 + self.crc32 = 0 + + try: + self.file = open(filename, "rb") + except: + print("Unable to open file {0}".format(filename)) + sys.exit(2) + + self.filesize = os.stat(filename).st_size + # print filesize + self.data = self.file.read() + self.crc32 = (binascii.crc32(self.data) & 0xFFFFFFFF) + self.file.seek(0) + + def is_unit_running(self): + print("Checking if unit is running") + s = self.port.readline().strip().decode('utf-8') + if len(s) > 0: + # print s + tokens = s.split(',') + if len(tokens) > 3: + return True + return False + + def drain_port(self): + self.port.flushInput() + s = self.port.readline() + while len(s) > 0: + s = self.port.readline() + + def enable_dfu(self): + if self.is_unit_running(): + print("Unit is running, switching to DFU mode") + self.port.write(b'dfu\r\n') + self.drain_port() + + for x in range(5): + self.port.write(b'\r\n') + s = self.port.readline().strip() + if s.find(b"MAIANA bootloader") >= 0: + wx.PostEvent(self.window, FwUpdateEvent(EventType.DFU_ENABLED, None)) + return True + + wx.PostEvent(self.window, FwUpdateEvent(EventType.ERROR, b'Could not enter DFU mode')) + return False + + def begin_transfer(self): + self.drain_port() + command = "load {0} {1:x}\r\n".format(self.filesize, self.crc32).encode('utf-8') + self.port.write(command) + print(command) + + s = self.port.readline().strip() + if s == b"READY": + wx.PostEvent(self.window, FwUpdateEvent(EventType.TRANSFER_STARTED, None)) + return True + + wx.PostEvent(self.window, FwUpdateEvent(EventType.ERROR, 'Failed:{}'.format(s))) + return False + + def run(self): + if not self.enable_dfu(): + print("Could not get unit into DFU mode") + return + + print("Unit is in DFU mode") + + if not self.begin_transfer(): + print("Unable to begin transfer, restart the unit and retry") + return + + print("Starting transfer") + + bytes = self.file.read(2048) + resp = '' + bytesSent = 0 + while len(bytes) > 0: + self.port.write(bytes) + resp = self.port.readline().strip() + if resp.find(b"OK") < 0: + break + + bytesSent += len(bytes) + progress = bytesSent/self.filesize + wx.PostEvent(self.window, FwUpdateEvent(EventType.TRANSFER_PROGRESS, progress)) + bytes = self.file.read(2048) + + wx.PostEvent(self.window, FwUpdateEvent(EventType.TRANSFER_COMPLETE, None)) + + + + diff --git a/latest/Apps/maiana-update/maiana-update.fbp b/latest/Apps/maiana-update/maiana-update.fbp new file mode 100644 index 0000000..d9fa3f4 --- /dev/null +++ b/latest/Apps/maiana-update/maiana-update.fbp @@ -0,0 +1,2518 @@ + + + + + ; + Python + 1 + source_name + 0 + 0 + res + UTF-8 + connect + mainframe + 1000 + none + + + 0 + MAIANA Firmware Update + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + MainFrame + + 605,300 + wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX + ; ; forward_declare + MAIANA Transponder Manager ver 0.1 + + 0 + + + wxTAB_TRAVERSAL + 1 + + + bSizer1 + wxVERTICAL + none + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_notebook2 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + + + Status + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_StatusPnl + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + 2 + 0 + + gSizer1 + none + 5 + 0 + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Serial Port + 0 + + 0 + + + 0 + -1,-1 + 1 + m_staticText1 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND + 1 + + + bSizer4 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + 150,-1 + 1 + m_SerialPortChoice + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + onSerialPortSelection + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 0 + + 1 + + + 0 + 0 + wxID_ANY + Connect + + 0 + + 0 + + + 0 + + 1 + m_SerialBtn + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + onSerialBtnClick + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + CPU + 0 + + 0 + + + 0 + + 1 + m_staticText7 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,90,-1,70,0 + 0 + 0 + wxID_ANY + (unknown) + 0 + + 0 + + + 0 + + 1 + m_CPULbl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Hardware Revision + 0 + + 0 + + + 0 + + 1 + m_staticText3 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,90,-1,70,0 + 0 + 0 + wxID_ANY + (unknown) + 0 + + 0 + + + 0 + + 1 + m_HWRevLbl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Firmware Revision + 0 + + 0 + + + 0 + + 1 + m_staticText5 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,90,-1,70,0 + 0 + 0 + wxID_ANY + (unknown) + 0 + + 0 + + + 0 + + 1 + m_FWRevLbl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + + + + + Station Data + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_StationPnl + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + 4 + 0 + + gSizer2 + none + 0 + 0 + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + MMSI + 0 + + 0 + + + 0 + + 1 + m_staticText101 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_MMSIText + 1 + + + protected + 1 + + Resizable + 1 + 100,-1 + + ; ; forward_declare + 0 + + + wxFILTER_NUMERIC + wxTextValidator + + + + + + onStationEdit + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Call Sign + 0 + + 0 + + + 0 + + 1 + m_staticText11 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_CallsignText + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + onStationEdit + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Name + 0 + + 0 + + + 0 + + 1 + m_staticText12 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 20 + + 0 + 140,-1 + 1 + m_NameText + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + onStationEdit + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Vessel Type + 0 + + 0 + + + 0 + + 1 + m_staticText13 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Fishing" "Diving" "Sailing" "Pleasure" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_VesselTypeChoice + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + onStationEdit + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Length (m) + 0 + + 0 + + + 0 + + 1 + _ + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_LengthText + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NUMERIC + wxTextValidator + + 0 + + + + onStationEdit + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Beam (m) + 0 + + 0 + + + 0 + + 1 + m_staticText15 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_BeamText + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NUMERIC + wxTextValidator + + 0 + + + + onStationEdit + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Port Offset (m) + 0 + + 0 + + + 0 + + 1 + m_staticText17 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_PortOffsetText + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NUMERIC + wxTextValidator + + 0 + + + + onStationEdit + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Bow Offset (m) + 0 + + 0 + + + 0 + + 1 + m_staticText16 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_BowOffsetText + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + onStationEdit + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + m_staticText18 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + m_staticText19 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + + 1 + m_staticText20 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_BOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 0 + + 1 + + + 0 + 0 + wxID_ANY + Save + + 0 + + 0 + + + 0 + + 1 + m_StationSaveBtn + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + onStationSaveBtnClick + + + + + + + + FW Update + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_FWUpdatePnl + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + bSizer41 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 2 + 0 + -1,90 + gSizer4 + none + 1 + 0 + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Binary File: + 0 + + 0 + + + 0 + -1,-1 + 1 + m_staticText28 + 1 + + + protected + 1 + + Resizable + 1 + 80,-1 + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + Select a file + + 0 + + 1 + m_FWBinaryPicker + 1 + + + protected + 1 + + Resizable + 1 + -1,-1 + wxFLP_CHANGE_DIR|wxFLP_DEFAULT_STYLE|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + *.bin + + + + onFWBinarySelection + + + + + + 5 + wxEXPAND + 1 + + 2 + 0 + + gSizer5 + none + 1 + 0 + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_FWProgress + 1 + + + protected + 1 + + 100 + Resizable + 1 + 350,-1 + wxGA_HORIZONTAL + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + 5 + wxALL|wxALIGN_RIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 0 + + 1 + + + 0 + 0 + wxID_ANY + Update + + 0 + + 0 + + + 0 + + 1 + m_FWUpdateBtn + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + onFWUpdateBtnClick + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + + 0 + 520,-1 + 1 + m_FWUpdateStatusLbl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + + + + + + + + diff --git a/latest/Apps/maiana-update/maiana.py b/latest/Apps/maiana-update/maiana.py new file mode 100644 index 0000000..41212ef --- /dev/null +++ b/latest/Apps/maiana-update/maiana.py @@ -0,0 +1,9 @@ +import wx +from mainwindow import MainWindow + + +if __name__ == '__main__': + app = wx.App() + window = MainWindow() + window.Show(True) + app.MainLoop() diff --git a/latest/Apps/maiana-update/maianaclient.py b/latest/Apps/maiana-update/maianaclient.py new file mode 100644 index 0000000..208b3fe --- /dev/null +++ b/latest/Apps/maiana-update/maianaclient.py @@ -0,0 +1,132 @@ +import serial +import sys +import glob +import time +import re +from enum import Enum + + +class MaianaStatus(Enum): + UNKNOWN = 0 + RUNNING = 1 + DFU = 2 + +class MaianaClient: + VESSEL_TYPES = [30, 34, 36, 37] + + @staticmethod + def serial_ports(): + """ Lists serial port names + + :raises EnvironmentError: + On unsupported or unknown platforms + :returns: + A list of the serial ports available on the system + """ + if sys.platform.startswith('win'): + ports = ['COM%s' % (i + 1) for i in range(256)] + elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'): + # this excludes your current terminal "/dev/tty" + ports = glob.glob('/dev/tty[A-Za-z]*') + elif sys.platform.startswith('darwin'): + ports = glob.glob('/dev/tty\..*') + else: + raise EnvironmentError('Unsupported platform') + + result = [] + for port in ports: + # print port + try: + s = serial.Serial(port) + s.close() + result.append(port) + except (OSError, Exception): + pass + return result + + @staticmethod + def determineStatus(port): + port.flushInput() + port.flushOutput() + s = port.readline().strip() + port.write(b'\r\n') + for i in range(5): + s = port.readline().strip() + if s.find(b"bootloader") > -1: + return MaianaStatus.DFU + else: + tokens = s.decode('utf-8').split(',') + if (tokens[0][0] == '$' or tokens[0][0] == '!') and len(tokens) >= 2: + return MaianaStatus.RUNNING + + return MaianaStatus.UNKNOWN + + @staticmethod + def sendCmdWithResponse(port, cmd, resp): + port.flushInput() + port.flushOutput() + port.write(cmd + b'\r\n') + for i in range(25): + s = port.readline().strip() + #print(s) + if s == b'': + break + if resp in s: + return s + return None + + @staticmethod + def loadSys(port): + for i in range(2): + try: + sysline = MaianaClient.sendCmdWithResponse(port, b'sys?', b'$PAISYS') + if sysline is None: + return {} + + systokens = re.split(',|\\*', sysline.decode('utf-8')) + sysd = {'fw': systokens[2], 'hw': systokens[1], 'cpu': systokens[4]} + return sysd + except: + pass + + return {} + + @staticmethod + def loadStation(port): + for i in range(2): + try: + stationline = MaianaClient.sendCmdWithResponse(port, b'station?', b'$PAISTN') + if stationline is None: + return {} + + stationtokens = re.split(',|\\*', stationline.decode('utf-8')) + stad = {'mmsi': int(stationtokens[1]), 'name': stationtokens[2], 'callsign': stationtokens[3], + 'type': int(stationtokens[4]), 'len': int(stationtokens[5]), 'beam': int(stationtokens[6]), + 'portoffset': int(stationtokens[7]), 'bowoffset': int(stationtokens[8])} + + return stad + except: + pass + return {} + + @staticmethod + def setStationData(port, data): + line = 'station {},{},{},{},{},{},{},{}\r\n'.format( + data['mmsi'], + data['name'], + data['callsign'], + data['type'], + data['len'], + data['beam'], + data['portoffset'], + data['bowoffset'] + ) + + resp = MaianaClient.sendCmdWithResponse(port, line.encode('utf-8'), b'$PAISTN') + #print(resp) + if resp: + resp = MaianaClient.sendCmdWithResponse(port, b'reboot', b'$PAISTN') + #print(resp) + return not resp is None + + return False \ No newline at end of file diff --git a/latest/Apps/maiana-update/mainframe.py b/latest/Apps/maiana-update/mainframe.py new file mode 100644 index 0000000..37f2f7c --- /dev/null +++ b/latest/Apps/maiana-update/mainframe.py @@ -0,0 +1,291 @@ +# -*- coding: utf-8 -*- + +########################################################################### +## Python code generated with wxFormBuilder (version 3.10.1-39-g978478d5-dirty) +## http://www.wxformbuilder.org/ +## +## PLEASE DO *NOT* EDIT THIS FILE! +########################################################################### + +import wx +import wx.xrc + +########################################################################### +## Class MainFrame +########################################################################### + +class MainFrame ( wx.Frame ): + + def __init__( self, parent ): + wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"MAIANA Transponder Manager ver 0.1", pos = wx.DefaultPosition, size = wx.Size( 605,300 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.TAB_TRAVERSAL ) + + self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) + + bSizer1 = wx.BoxSizer( wx.VERTICAL ) + + self.m_notebook2 = wx.Notebook( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_StatusPnl = wx.Panel( self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) + gSizer1 = wx.GridSizer( 5, 2, 0, 0 ) + + self.m_staticText1 = wx.StaticText( self.m_StatusPnl, wx.ID_ANY, u"Serial Port", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText1.Wrap( -1 ) + + gSizer1.Add( self.m_staticText1, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + bSizer4 = wx.BoxSizer( wx.HORIZONTAL ) + + m_SerialPortChoiceChoices = [] + self.m_SerialPortChoice = wx.Choice( self.m_StatusPnl, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_SerialPortChoiceChoices, 0 ) + self.m_SerialPortChoice.SetSelection( 0 ) + self.m_SerialPortChoice.SetMinSize( wx.Size( 150,-1 ) ) + + bSizer4.Add( self.m_SerialPortChoice, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_SerialBtn = wx.Button( self.m_StatusPnl, wx.ID_ANY, u"Connect", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_SerialBtn.Enable( False ) + + bSizer4.Add( self.m_SerialBtn, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + + gSizer1.Add( bSizer4, 1, wx.EXPAND, 5 ) + + self.m_staticText7 = wx.StaticText( self.m_StatusPnl, wx.ID_ANY, u"CPU", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText7.Wrap( -1 ) + + gSizer1.Add( self.m_staticText7, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_CPULbl = wx.StaticText( self.m_StatusPnl, wx.ID_ANY, u"(unknown)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_CPULbl.Wrap( -1 ) + + self.m_CPULbl.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + + gSizer1.Add( self.m_CPULbl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_staticText3 = wx.StaticText( self.m_StatusPnl, wx.ID_ANY, u"Hardware Revision", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText3.Wrap( -1 ) + + gSizer1.Add( self.m_staticText3, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_HWRevLbl = wx.StaticText( self.m_StatusPnl, wx.ID_ANY, u"(unknown)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_HWRevLbl.Wrap( -1 ) + + self.m_HWRevLbl.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + + gSizer1.Add( self.m_HWRevLbl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_staticText5 = wx.StaticText( self.m_StatusPnl, wx.ID_ANY, u"Firmware Revision", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText5.Wrap( -1 ) + + gSizer1.Add( self.m_staticText5, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_FWRevLbl = wx.StaticText( self.m_StatusPnl, wx.ID_ANY, u"(unknown)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_FWRevLbl.Wrap( -1 ) + + self.m_FWRevLbl.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) + + gSizer1.Add( self.m_FWRevLbl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + + self.m_StatusPnl.SetSizer( gSizer1 ) + self.m_StatusPnl.Layout() + gSizer1.Fit( self.m_StatusPnl ) + self.m_notebook2.AddPage( self.m_StatusPnl, u"Status", True ) + self.m_StationPnl = wx.Panel( self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) + self.m_StationPnl.Enable( False ) + + gSizer2 = wx.GridSizer( 0, 4, 0, 0 ) + + self.m_staticText101 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, u"MMSI", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText101.Wrap( -1 ) + + gSizer2.Add( self.m_staticText101, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_MMSIText = wx.TextCtrl( self.m_StationPnl, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 100,-1 ), 0 ) + gSizer2.Add( self.m_MMSIText, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_staticText11 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, u"Call Sign", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText11.Wrap( -1 ) + + gSizer2.Add( self.m_staticText11, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_CallsignText = wx.TextCtrl( self.m_StationPnl, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + gSizer2.Add( self.m_CallsignText, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_staticText12 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, u"Name", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText12.Wrap( -1 ) + + gSizer2.Add( self.m_staticText12, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_NameText = wx.TextCtrl( self.m_StationPnl, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_NameText.SetMaxLength( 20 ) + self.m_NameText.SetMinSize( wx.Size( 140,-1 ) ) + + gSizer2.Add( self.m_NameText, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_staticText13 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, u"Vessel Type", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText13.Wrap( -1 ) + + gSizer2.Add( self.m_staticText13, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + m_VesselTypeChoiceChoices = [ u"Fishing", u"Diving", u"Sailing", u"Pleasure" ] + self.m_VesselTypeChoice = wx.Choice( self.m_StationPnl, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_VesselTypeChoiceChoices, 0 ) + self.m_VesselTypeChoice.SetSelection( 0 ) + gSizer2.Add( self.m_VesselTypeChoice, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self._ = wx.StaticText( self.m_StationPnl, wx.ID_ANY, u"Length (m)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self._.Wrap( -1 ) + + gSizer2.Add( self._, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_LengthText = wx.TextCtrl( self.m_StationPnl, wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 ) + gSizer2.Add( self.m_LengthText, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_staticText15 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, u"Beam (m)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText15.Wrap( -1 ) + + gSizer2.Add( self.m_staticText15, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_BeamText = wx.TextCtrl( self.m_StationPnl, wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 ) + gSizer2.Add( self.m_BeamText, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_staticText17 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, u"Port Offset (m)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText17.Wrap( -1 ) + + gSizer2.Add( self.m_staticText17, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_PortOffsetText = wx.TextCtrl( self.m_StationPnl, wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 ) + gSizer2.Add( self.m_PortOffsetText, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_staticText16 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, u"Bow Offset (m)", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText16.Wrap( -1 ) + + gSizer2.Add( self.m_staticText16, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_BowOffsetText = wx.TextCtrl( self.m_StationPnl, wx.ID_ANY, u"0", wx.DefaultPosition, wx.DefaultSize, 0 ) + gSizer2.Add( self.m_BowOffsetText, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_staticText18 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText18.Wrap( -1 ) + + gSizer2.Add( self.m_staticText18, 0, wx.ALL, 5 ) + + self.m_staticText19 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText19.Wrap( -1 ) + + gSizer2.Add( self.m_staticText19, 0, wx.ALL, 5 ) + + self.m_staticText20 = wx.StaticText( self.m_StationPnl, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_staticText20.Wrap( -1 ) + + gSizer2.Add( self.m_staticText20, 0, wx.ALL, 5 ) + + self.m_StationSaveBtn = wx.Button( self.m_StationPnl, wx.ID_ANY, u"Save", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_StationSaveBtn.Enable( False ) + + gSizer2.Add( self.m_StationSaveBtn, 0, wx.ALL|wx.ALIGN_BOTTOM, 5 ) + + + self.m_StationPnl.SetSizer( gSizer2 ) + self.m_StationPnl.Layout() + gSizer2.Fit( self.m_StationPnl ) + self.m_notebook2.AddPage( self.m_StationPnl, u"Station Data", False ) + self.m_FWUpdatePnl = wx.Panel( self.m_notebook2, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) + self.m_FWUpdatePnl.Enable( False ) + + bSizer41 = wx.BoxSizer( wx.VERTICAL ) + + gSizer4 = wx.GridSizer( 1, 2, 0, 0 ) + + gSizer4.SetMinSize( wx.Size( -1,90 ) ) + self.m_staticText28 = wx.StaticText( self.m_FWUpdatePnl, wx.ID_ANY, u"Binary File:", wx.DefaultPosition, wx.Size( 80,-1 ), 0 ) + self.m_staticText28.Wrap( -1 ) + + gSizer4.Add( self.m_staticText28, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) + + self.m_FWBinaryPicker = wx.FilePickerCtrl( self.m_FWUpdatePnl, wx.ID_ANY, wx.EmptyString, u"Select a file", u"*.bin", wx.DefaultPosition, wx.Size( -1,-1 ), wx.FLP_CHANGE_DIR|wx.FLP_DEFAULT_STYLE|wx.FLP_FILE_MUST_EXIST|wx.FLP_OPEN ) + gSizer4.Add( self.m_FWBinaryPicker, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 5 ) + + + bSizer41.Add( gSizer4, 1, wx.EXPAND, 5 ) + + gSizer5 = wx.GridSizer( 1, 2, 0, 0 ) + + self.m_FWProgress = wx.Gauge( self.m_FWUpdatePnl, wx.ID_ANY, 100, wx.DefaultPosition, wx.Size( 350,-1 ), wx.GA_HORIZONTAL ) + self.m_FWProgress.SetValue( 0 ) + gSizer5.Add( self.m_FWProgress, 0, wx.ALL, 5 ) + + self.m_FWUpdateBtn = wx.Button( self.m_FWUpdatePnl, wx.ID_ANY, u"Update", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_FWUpdateBtn.Enable( False ) + + gSizer5.Add( self.m_FWUpdateBtn, 0, wx.ALL|wx.ALIGN_RIGHT, 5 ) + + + bSizer41.Add( gSizer5, 1, wx.EXPAND, 5 ) + + self.m_FWUpdateStatusLbl = wx.StaticText( self.m_FWUpdatePnl, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) + self.m_FWUpdateStatusLbl.Wrap( -1 ) + + self.m_FWUpdateStatusLbl.SetMinSize( wx.Size( 520,-1 ) ) + + bSizer41.Add( self.m_FWUpdateStatusLbl, 0, wx.ALL, 5 ) + + + self.m_FWUpdatePnl.SetSizer( bSizer41 ) + self.m_FWUpdatePnl.Layout() + bSizer41.Fit( self.m_FWUpdatePnl ) + self.m_notebook2.AddPage( self.m_FWUpdatePnl, u"FW Update", False ) + + bSizer1.Add( self.m_notebook2, 1, wx.EXPAND |wx.ALL, 5 ) + + + self.SetSizer( bSizer1 ) + self.Layout() + + self.Centre( wx.BOTH ) + + # Connect Events + self.m_SerialPortChoice.Bind( wx.EVT_CHOICE, self.onSerialPortSelection ) + self.m_SerialBtn.Bind( wx.EVT_BUTTON, self.onSerialBtnClick ) + self.m_MMSIText.Bind( wx.EVT_TEXT, self.onStationEdit ) + self.m_CallsignText.Bind( wx.EVT_TEXT, self.onStationEdit ) + self.m_NameText.Bind( wx.EVT_TEXT, self.onStationEdit ) + self.m_VesselTypeChoice.Bind( wx.EVT_CHOICE, self.onStationEdit ) + self.m_LengthText.Bind( wx.EVT_TEXT, self.onStationEdit ) + self.m_BeamText.Bind( wx.EVT_TEXT, self.onStationEdit ) + self.m_PortOffsetText.Bind( wx.EVT_TEXT, self.onStationEdit ) + self.m_BowOffsetText.Bind( wx.EVT_TEXT, self.onStationEdit ) + self.m_StationSaveBtn.Bind( wx.EVT_BUTTON, self.onStationSaveBtnClick ) + self.m_FWBinaryPicker.Bind( wx.EVT_FILEPICKER_CHANGED, self.onFWBinarySelection ) + self.m_FWUpdateBtn.Bind( wx.EVT_BUTTON, self.onFWUpdateBtnClick ) + + def __del__( self ): + pass + + + # Virtual event handlers, override them in your derived class + def onSerialPortSelection( self, event ): + event.Skip() + + def onSerialBtnClick( self, event ): + event.Skip() + + def onStationEdit( self, event ): + event.Skip() + + + + + + + + + def onStationSaveBtnClick( self, event ): + event.Skip() + + def onFWBinarySelection( self, event ): + event.Skip() + + def onFWUpdateBtnClick( self, event ): + event.Skip() + + diff --git a/latest/Apps/maiana-update/mainwindow.py b/latest/Apps/maiana-update/mainwindow.py new file mode 100644 index 0000000..77a6d9d --- /dev/null +++ b/latest/Apps/maiana-update/mainwindow.py @@ -0,0 +1,146 @@ +from mainframe import MainFrame +from maianaclient import MaianaClient, MaianaStatus +import serial +import wx +from fwUpdateThread import * + +class MainWindow(MainFrame): + def __init__(self): + MainFrame.__init__(self, None) + self.m_SerialPortChoice.Set(MaianaClient.serial_ports()) + self.portname = None + self.port = None + self.data = None + + def onSerialPortSelection(self, event): + self.m_SerialBtn.Enable() + + def onSerialBtnClick(self, event): + if self.port is None: + try: + self.portname = self.m_SerialPortChoice.GetString(self.m_SerialPortChoice.GetSelection()) + self.port = serial.Serial(self.portname, 38400, timeout=1) + except: + wx.MessageBox(b'Unable to open port, it may be in use', 'Error', wx.OK | wx.ICON_ERROR) + return + + status = MaianaClient.determineStatus(self.port) + + if status == MaianaStatus.UNKNOWN: + pass + elif status == MaianaStatus.DFU: + wx.MessageBox(b'MAIANA is currently in firmware update mode. This is the only task you can perform.', + 'DFU warning', wx.OK) + self.enableUI() + self.m_SerialBtn.SetLabel(b'Disconnect') + self.m_StationSaveBtn.Disable() + else: + #Assuming status is RUNNING + self.m_SerialBtn.SetLabel(b'Disconnect') + self.enableUI() + if self.refreshSys(): + self.refreshStation() + self.m_StationSaveBtn.Disable() + else: + self.port.close() + self.port = None + self.m_SerialBtn.SetLabel(b'Connect') + self.disableUI() + + def onStationSaveBtnClick(self, event): + # Let's validate + if not self.validateStationInputs(): + return + + newdata = {'mmsi': int(self.m_MMSIText.Value), + 'name': self.m_NameText.Value, + 'callsign': self.m_CallsignText.Value, + 'len': int(self.m_LengthText.Value), + 'beam': int(self.m_BeamText.Value), + 'portoffset': int(self.m_PortOffsetText.Value), + 'bowoffset': int(self.m_BowOffsetText.Value), + 'type': MaianaClient.VESSEL_TYPES[self.m_VesselTypeChoice.Selection]} + #print(newdata) + + if MaianaClient.setStationData(self.port, newdata): + self.stationdata = newdata + self.m_StationSaveBtn.Disable() + + + def onFWBinarySelection(self, event): + self.m_FWUpdateBtn.Enable() + + def onFWUpdateBtnClick(self, event): + self.Connect(-1, -1, EVT_FWUPDATE_ID, self.onFwUpdateEvent) + thr = FWUpdateThread(self, self.port, self.m_FWBinaryPicker.Path) + thr.start() + self.m_FWUpdateBtn.Disable() + + def onFwUpdateEvent(self, evt): + print(evt.eventType, evt.data) + if evt.eventType == EventType.DFU_ENABLED: + self.m_FWUpdateStatusLbl.SetLabel("DFU enabled") + elif evt.eventType == EventType.TRANSFER_STARTED: + self.m_FWUpdateStatusLbl.SetLabel("Transferring") + elif evt.eventType == EventType.TRANSFER_PROGRESS: + self.m_FWProgress.SetValue(evt.data * 100) + elif evt.eventType == EventType.TRANSFER_COMPLETE: + self.m_FWProgress.SetValue(0) + self.m_FWUpdateStatusLbl.SetLabel("Transfer completed") + self.refreshSys() + self.refreshStation() + elif evt.eventType == EventType.ERROR: + self.m_FWUpdateStatusLbl.SetLabel(evt.data) + + def enableUI(self): + self.m_StationPnl.Enable() + self.m_FWUpdatePnl.Enable() + + def disableUI(self): + self.m_StationPnl.Disable() + self.m_FWUpdatePnl.Disable() + + def refreshSys(self): + self.sysdata = MaianaClient.loadSys(self.port) + return self.renderSys() + + def refreshStation(self): + self.stationdata = MaianaClient.loadStation(self.port) + return self.renderStation() + + def renderSys(self): + if not 'hw' in self.sysdata: + wx.MessageDialog(self, b'There was no response from MAIANA. Please check connections and try again.', + 'Timeout', wx.OK | wx.STAY_ON_TOP|wx.CENTRE).ShowModal() + return False + + self.m_HWRevLbl.SetLabel(self.sysdata['hw']) + self.m_FWRevLbl.SetLabel(self.sysdata['fw']) + self.m_CPULbl.SetLabel(self.sysdata['cpu']) + return True + + def renderStation(self): + if not 'mmsi' in self.stationdata: + wx.MessageDialog(self, b'There was no response from MAIANA. Please check connections and try again.', + 'Timeout', wx.OK | wx.STAY_ON_TOP|wx.CENTRE).ShowModal() + return False + + self.m_MMSIText.SetValue('{}'.format(self.stationdata['mmsi'])) + self.m_NameText.SetValue(self.stationdata['name']) + self.m_CallsignText.SetValue(self.stationdata['callsign']) + self.m_LengthText.SetValue('{}'.format(self.stationdata['len'])) + self.m_BeamText.SetValue('{}'.format(self.stationdata['beam'])) + self.m_PortOffsetText.SetValue('{}'.format(self.stationdata['portoffset'])) + self.m_BowOffsetText.SetValue('{}'.format(self.stationdata['bowoffset'])) + + t = self.stationdata['type'] + i = MaianaClient.VESSEL_TYPES.index(t) + self.m_VesselTypeChoice.SetSelection(i) + return True + + def validateStationInputs(self): + return True + + def onStationEdit( self, event ): + self.m_StationSaveBtn.Enable() + event.Skip()