diff --git a/debian/changelog b/debian/changelog index c637b76..041fe3b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +openplotter-kplex (2.0.1-beta) bionic; urgency=medium + + * Beta release + * add process tab + * fix start kplex + + -- e-sailing Fri, 29 May 2020 18:59:22 +0100 + openplotter-kplex (2.0.0-dev) bionic; urgency=medium * Development release diff --git a/openplotterKplex/add_kplex.py b/openplotterKplex/add_kplex.py index a2448a2..06f2d4c 100644 --- a/openplotterKplex/add_kplex.py +++ b/openplotterKplex/add_kplex.py @@ -586,7 +586,7 @@ def ok_conn(self, event): if str(self.kplex_device_select.GetValue()) != 'none': port_address = str(self.kplex_device_select.GetValue()) else: - self.ShowMessage(_('You must select a Port.')) + self.ShowMessage(_('You must select a port.')) return bauds_port = str(self.kplex_baud_select.GetValue()) for index, sublist in enumerate(self.extkplex): @@ -600,16 +600,16 @@ def ok_conn(self, event): if self.kplex_address.GetValue(): port_address = self.kplex_address.GetValue() else: - self.ShowMessage(_('You must enter an Address.')) + self.ShowMessage(_('You must enter an address.')) return if self.kplex_netport.GetValue(): bauds_port = self.kplex_netport.GetValue() else: - self.ShowMessage(_('You must enter a Port.')) + self.ShowMessage(_('You must enter a port.')) return if bauds_port >= '10111' and bauds_port <= '10113' and type_conn == 'TCP': - self.ShowMessage(_('Cancelled. Port 10111-10113 are reserved.')) + self.ShowMessage(_('Cancelled. Ports 10111-10113 are reserved.')) return new_address_port = str(type_conn) + str(port_address) + str(bauds_port) diff --git a/openplotterKplex/data/process.png b/openplotterKplex/data/process.png new file mode 100644 index 0000000..54db51b Binary files /dev/null and b/openplotterKplex/data/process.png differ diff --git a/openplotterKplex/data/restart.png b/openplotterKplex/data/restart.png new file mode 100644 index 0000000..8a99433 Binary files /dev/null and b/openplotterKplex/data/restart.png differ diff --git a/openplotterKplex/data/start.png b/openplotterKplex/data/start.png new file mode 100644 index 0000000..eed3786 Binary files /dev/null and b/openplotterKplex/data/start.png differ diff --git a/openplotterKplex/data/stop.png b/openplotterKplex/data/stop.png new file mode 100644 index 0000000..822c044 Binary files /dev/null and b/openplotterKplex/data/stop.png differ diff --git a/openplotterKplex/kplexPostInstall.py b/openplotterKplex/kplexPostInstall.py index b8aa4e0..af70233 100644 --- a/openplotterKplex/kplexPostInstall.py +++ b/openplotterKplex/kplexPostInstall.py @@ -36,7 +36,7 @@ def main(): '[Service]\n'+ 'Type=forking\n'+ 'PIDFILE=/var/run/kplex.pid\n'+ - 'ExecStart=/usr/bin/kplex -p /var/run/kplex.pid -o mode=background\n'+ + 'ExecStart=/usr/bin/kplex -f ' + conf2.home + '/.kplex.conf -p /var/run/kplex.pid -o mode=background\n'+ 'KillMode=process\n'+ '[Install]\n'+ 'WantedBy=multi-user.target\n' diff --git a/openplotterKplex/openplotterKplex.py b/openplotterKplex/openplotterKplex.py index 3ac0b00..ee73d93 100644 --- a/openplotterKplex/openplotterKplex.py +++ b/openplotterKplex/openplotterKplex.py @@ -29,13 +29,12 @@ import version from add_kplex import addkplex -class CheckListCtrl2(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin): +class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin): def __init__(self, parent, height): wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER, size=(650, height)) CheckListCtrlMixin.__init__(self) ListCtrlAutoWidthMixin.__init__(self) - class KplexFrame(wx.Frame): def __init__(self): self.conf = conf.Conf() @@ -44,6 +43,7 @@ def __init__(self): self.currentdir = os.path.dirname(os.path.abspath(__file__)) self.currentLanguage = self.conf.get('GENERAL', 'lang') self.language = language.Language(self.currentdir,'openplotter-kplex',self.currentLanguage) + self.diagnostic = False self.selected = -1 @@ -70,8 +70,6 @@ def __init__(self): opSerial = self.toolbar1.AddTool(104, _('OP Serial'), wx.Bitmap(self.currentdir+"/data/usb.png")) self.Bind(wx.EVT_TOOL, self.OnOpSerial, opSerial) #self.toolbar1.AddSeparator() - restart = self.toolbar1.AddTool(105, _('restart'), wx.Bitmap(self.currentdir+"/data/kplex.png")) - self.Bind(wx.EVT_TOOL, self.OnRestart, restart) advanced = self.toolbar1.AddTool(106, _('manual settings'), wx.Bitmap(self.currentdir+"/data/kplex.png")) self.Bind(wx.EVT_TOOL, self.OnAdvanced, advanced) self.toolbar1.AddSeparator() @@ -81,22 +79,40 @@ def __init__(self): self.notebook = wx.Notebook(self) self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onTabChange) self.p_kplex = wx.Panel(self.notebook) + self.systemd = wx.Panel(self.notebook) self.output = wx.Panel(self.notebook) - self.notebook.AddPage(self.p_kplex, _('Devices')) + self.notebook.AddPage(self.p_kplex, _('Devices')) + self.notebook.AddPage(self.systemd, _('Processes')) self.notebook.AddPage(self.output, '') self.il = wx.ImageList(24, 24) img0 = self.il.Add(wx.Bitmap(self.currentdir+"/data/kplex.png", wx.BITMAP_TYPE_PNG)) - img1 = self.il.Add(wx.Bitmap(self.currentdir+"/data/output.png", wx.BITMAP_TYPE_PNG)) + img1 = self.il.Add(wx.Bitmap(self.currentdir+"/data/process.png", wx.BITMAP_TYPE_PNG)) + img2 = self.il.Add(wx.Bitmap(self.currentdir+"/data/output.png", wx.BITMAP_TYPE_PNG)) self.notebook.AssignImageList(self.il) self.notebook.SetPageImage(0, img0) self.notebook.SetPageImage(1, img1) + self.notebook.SetPageImage(2, img2) vbox = wx.BoxSizer(wx.VERTICAL) vbox.Add(self.toolbar1, 0, wx.EXPAND) vbox.Add(self.notebook, 1, wx.EXPAND) self.SetSizer(vbox) + + self.appsDict = [] + + app = { + 'name': 'Kplex', + 'included': True, + 'show': '', + 'service': ['openplotter-kplex'], + 'edit': False, + 'install': '', + 'uninstall': '', + } + self.appsDict.append(app) self.pageKplex() + self.pageSystemd() self.pageOutput() self.read_kplex_conf() @@ -125,6 +141,16 @@ def onTabChange(self, event): try: self.SetStatusText('') except: pass + + tab = self.notebook.GetSelection() + if tab == 0: + self.toolbar1.EnableTool(105,True) + self.toolbar1.EnableTool(106,True) + self.toolbar1.EnableTool(107,True) + else: + self.toolbar1.EnableTool(105,False) + self.toolbar1.EnableTool(106,False) + self.toolbar1.EnableTool(107,False) def OnToolHelp(self, event): url = "/usr/share/openplotter-doc/kplex/kplex_app.html" @@ -134,39 +160,6 @@ def OnToolSettings(self, event=0): subprocess.call(['pkill', '-f', 'openplotter-settings']) subprocess.Popen('openplotter-settings') - def OnRestart(self, event=0): - self.notebook.ChangeSelection(1) - self.logger.Clear() - err = False - #self.ShowStatusBarRED(_('Closing Kplex')) - print(_('Closing Kplex')) - self.notebook.Update() - command = self.platform.admin+' python3 ' + self.currentdir + '/service.py restart' - #subprocess.Popen([self.platform.admin, 'python3', self.currentdir+'/service.py', 'restart'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=True)) - popen = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=True) - time.sleep(5) - command = self.platform.admin+' python3 ' + self.currentdir + '/service.py status' - popen = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=True) - for line in popen.stdout: - if 'openplotter kplex' in line: - print(line[:-1]) - err = True - self.logger.ShowPosition(self.logger.GetLastPosition()) - if 'active (running)' in line: - print(_('Kplex running')) - - #subprocess.Popen([self.platform.admin, 'python3', self.currentdir+'/service.py', 'restart'],stdout=sys.stdout, stderr=sys.stderr, universal_newlines=True, shell=True) - #subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=True) - #popen = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=True) - - #self.ShowStatusBarGREEN(_('Kplex restarted')) - if err: - print(_("Error: Can't restart Kplex")) - else: - print(_('Kplex restarted')) - - self.read_kplex_conf() - def OnSkConnections(self,e): if self.platform.skPort: url = self.platform.http+'localhost:'+self.platform.skPort+'/admin/#/serverConfiguration/connections/-' @@ -191,8 +184,10 @@ def OnAdvanced(self, event): except: self.ShowMessage(_('Editor mousepad not found')) +################################################################################ + def pageKplex(self): - self.list_kplex = CheckListCtrl2(self.p_kplex, 152) + self.list_kplex = CheckListCtrl(self.p_kplex, 152) self.list_kplex.InsertColumn(0, _('Name'), width=130) self.list_kplex.InsertColumn(1, _('Type'), width=45) self.list_kplex.InsertColumn(2, _('io'), width=45) @@ -226,7 +221,8 @@ def pageKplex(self): self.onDeselected() def stop_kplex(self): - subprocess.Popen([self.platform.admin, 'python3', self.currentdir+'/service.py', 'stop']) + subprocess.Popen([self.platform.admin, 'pkill', '-f', 'diagnostic-NMEA.py']) + subprocess.Popen([self.platform.admin, 'pkill', '-f', 'debugkplex']) def OnEditButton(self, e): idx = self.selected @@ -416,6 +412,7 @@ def OnApply(self, event): file = open(self.home + '/.kplex.conf', 'w') file.write(data) file.close() + time.sleep(1) self.OnRestart() self.read_kplex_conf() @@ -435,6 +432,13 @@ def OnShowButton(self, event): if selected == -1: self.ShowStatusBarRED(_('Select an item.')) return + + command = 'systemctl show openplotter-kplex --no-page' + output = subprocess.check_output(command.split(),universal_newlines=True) + if 'SubState=running' in output: + self.ShowStatusBarRED(_('Please stop the process before you use Diagnostic.')) + return + num = len(self.kplex) for i in range(num): if self.list_kplex.IsSelected(i): @@ -457,6 +461,8 @@ def OnShowButton(self, event): file.close() self.stop_kplex() + self.diagnostic = True + time.sleep(0.2) subprocess.Popen(['kplex', '-f', self.home + '/.debugkplex.conf']) time.sleep(0.5) @@ -488,6 +494,132 @@ def ShowMessage(self, w_msg): def write(self, string): wx.CallAfter(self.logger.WriteText, string) +################################################################################ + + + def pageSystemd(self): + self.started = False + self.aStatusList = [_('inactive'),_('active')] + self.bStatusList = [_('dead'),_('running')] + + self.listSystemd = CheckListCtrl(self.systemd, 152) + self.listSystemd.InsertColumn(0, _('Autostart'), width=90) + self.listSystemd.InsertColumn(1, _('App'), width=90) + self.listSystemd.InsertColumn(2, _('Process'), width=140) + self.listSystemd.InsertColumn(3, _('Status'), width=120) + self.listSystemd.InsertColumn(4, ' ', width=100) + self.listSystemd.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onListSystemdSelected) + self.listSystemd.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.onListSystemdDeselected) + self.listSystemd.SetTextColour(wx.BLACK) + + self.listSystemd.OnCheckItem = self.OnCheckItem + + self.toolbar3 = wx.ToolBar(self.systemd, style=wx.TB_TEXT | wx.TB_VERTICAL) + start = self.toolbar3.AddTool(301, _('Start'), wx.Bitmap(self.currentdir+"/data/start.png")) + self.Bind(wx.EVT_TOOL, self.onStart, start) + stop = self.toolbar3.AddTool(302, _('Stop'), wx.Bitmap(self.currentdir+"/data/stop.png")) + self.Bind(wx.EVT_TOOL, self.onStop, stop) + restart = self.toolbar3.AddTool(303, _('Restart'), wx.Bitmap(self.currentdir+"/data/restart.png")) + self.Bind(wx.EVT_TOOL, self.onRestart, restart) + + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self.listSystemd, 1, wx.EXPAND, 0) + sizer.Add(self.toolbar3, 0) + + self.systemd.SetSizer(sizer) + + self.set_listSystemd() + self.started = True + + def onListSystemdSelected(self, e): + i = e.GetIndex() + valid = e and i >= 0 + if not valid: return + self.toolbar3.EnableTool(301,True) + self.toolbar3.EnableTool(302,True) + self.toolbar3.EnableTool(303,True) + + def onListSystemdDeselected(self, event=0): + self.toolbar3.EnableTool(301,False) + self.toolbar3.EnableTool(302,False) + self.toolbar3.EnableTool(303,False) + + def OnRefreshButton(self, event=0): + self.listSystemd.DeleteAllItems() + self.started = False + self.set_listSystemd() + self.started = True + + def set_listSystemd(self): + apps = list(reversed(self.appsDict)) + for i in apps: + if i['service']: + for ii in i['service']: + index = self.listSystemd.InsertItem(sys.maxsize, '') + self.listSystemd.SetItem(index, 1, i['name']) + self.listSystemd.SetItem(index, 2, ii) + command = 'systemctl show '+ii+' --no-page' + output = subprocess.check_output(command.split(),universal_newlines=True) + if 'UnitFileState=enabled' in output: self.listSystemd.CheckItem(index) + self.statusUpdate() + + def statusUpdate(self): + listCount = range(self.listSystemd.GetItemCount()) + for i in listCount: + service = self.listSystemd.GetItemText(i, 2) + command = 'systemctl show '+service+' --no-page' + output = subprocess.check_output(command.split(),universal_newlines=True) + if 'ActiveState=active' in output: self.listSystemd.SetItem(i, 3, _('active')) + else: self.listSystemd.SetItem(i, 3, _('inactive')) + if 'SubState=running' in output: + self.listSystemd.SetItem(i, 4, _('running')) + self.listSystemd.SetItemBackgroundColour(i,(0,255,0)) + else: + self.listSystemd.SetItem(i, 4, _('dead')) + self.listSystemd.SetItemBackgroundColour(i,(-1,-1,-1)) + + + def onStart(self,e): + index = self.listSystemd.GetFirstSelected() + if index == -1: return + self.ShowStatusBarYELLOW(_('Starting process...')) + subprocess.Popen([self.platform.admin, 'pkill', '-f', 'diagnostic-NMEA.py']) + subprocess.Popen([self.platform.admin, 'pkill', '-f', 'debugkplex']) + subprocess.call((self.platform.admin + ' systemctl start ' + self.listSystemd.GetItemText(index, 2)).split()) + time.sleep(1) + self.OnRefreshButton() + self.ShowStatusBarGREEN(_('Done')) + + def onStop(self,e): + index = self.listSystemd.GetFirstSelected() + if index == -1: return + self.ShowStatusBarYELLOW(_('Stopping process...')) + subprocess.call((self.platform.admin + ' systemctl stop ' + self.listSystemd.GetItemText(index, 2)).split()) + time.sleep(1) + self.OnRefreshButton() + self.ShowStatusBarGREEN(_('Done')) + + def onRestart(self,e): + index = self.listSystemd.GetFirstSelected() + if index == -1: return + self.ShowStatusBarYELLOW(_('Restarting process...')) + subprocess.Popen([self.platform.admin, 'pkill', '-f', 'diagnostic-NMEA.py']) + subprocess.Popen([self.platform.admin, 'pkill', '-f', 'debugkplex']) + subprocess.call((self.platform.admin + ' systemctl restart ' + self.listSystemd.GetItemText(index, 2)).split()) + time.sleep(1) + self.OnRefreshButton() + self.ShowStatusBarGREEN(_('Done')) + + def OnCheckItem(self, index, flag): + if not self.started: return + self.ShowStatusBarYELLOW(_('Enabling/Disabling process...')) + if flag: + subprocess.call((self.platform.admin + ' systemctl enable ' + self.listSystemd.GetItemText(index, 2)).split()) + else: + subprocess.call((self.platform.admin + ' systemctl disable ' + self.listSystemd.GetItemText(index, 2)).split()) + self.OnRefreshButton() + self.ShowStatusBarGREEN(_('Done')) + ################################################################################ def pageOutput(self): diff --git a/openplotterKplex/version.py b/openplotterKplex/version.py index a07b0e9..f2b9f05 100644 --- a/openplotterKplex/version.py +++ b/openplotterKplex/version.py @@ -1,3 +1,3 @@ -version = '2.0.0' -codeName = 'Open Arms' -state = 'dev' +version = '2.0.1' +codeName = 'Open Arms' +state = 'beta'