From d1775dbdf9d0261647401c39fe5d76b4165f5b56 Mon Sep 17 00:00:00 2001 From: sailoog Date: Sat, 13 Apr 2024 19:47:29 +0200 Subject: [PATCH] new rescue management --- openplotterMaiana/maianaPostInstall.py | 9 ++ openplotterMaiana/maianaPreUninstall.py | 14 +- openplotterMaiana/openplotterMaiana.py | 25 ++- openplotterMaiana/openplotterMaianaRead.py | 169 +++++++++++---------- openplotterMaiana/service.py | 9 +- openplotterMaiana/startup.py | 44 +++--- 6 files changed, 140 insertions(+), 130 deletions(-) diff --git a/openplotterMaiana/maianaPostInstall.py b/openplotterMaiana/maianaPostInstall.py index 423412d..55e87d3 100755 --- a/openplotterMaiana/maianaPostInstall.py +++ b/openplotterMaiana/maianaPostInstall.py @@ -56,6 +56,15 @@ def main(): print(_('DONE')) except Exception as e: print(_('FAILED: ')+str(e)) + print(_('Creating services...')) + try: + fo = open('/etc/systemd/system/openplotter-maiana-read.service', "w") + fo.write( '[Service]\nEnvironment=OPrescue=0\nEnvironmentFile=/boot/firmware/config.txt\nExecStart=openplotter-maiana-read $OPrescue\nUser='+conf2.user+'\nRestart=always\nRestartSec=3\n\n[Install]\nWantedBy=local-fs.target') + fo.close() + subprocess.call(['systemctl', 'daemon-reload']) + print(_('DONE')) + except Exception as e: print(_('FAILED: ')+str(e)) + print(_('Setting version...')) try: conf2.set('APPS', 'maiana', version) diff --git a/openplotterMaiana/maianaPreUninstall.py b/openplotterMaiana/maianaPreUninstall.py index 32ed512..50d17a0 100755 --- a/openplotterMaiana/maianaPreUninstall.py +++ b/openplotterMaiana/maianaPreUninstall.py @@ -28,12 +28,6 @@ def main(): language.Language(currentdir, package, currentLanguage) platform2 = platform.Platform() - print(_('Stopping OpenPlotter MAIANA service...')) - try: - subprocess.call(['pkill','-f','openplotter-maiana-read']) - print(_('DONE')) - except Exception as e: print(_('FAILED: ')+str(e)) - print(_('Removing connection to Signal K server for MAIANA commands...')) try: data = {} @@ -57,6 +51,14 @@ def main(): print(_('DONE')) except Exception as e: print(_('FAILED: ')+str(e)) + print(_('Removing services...')) + try: + subprocess.call(['systemctl', 'disable', 'openplotter-maiana-read']) + subprocess.call(['systemctl', 'stop', 'openplotter-maiana-read']) + subprocess.call(['systemctl', 'daemon-reload']) + print(_('DONE')) + except Exception as e: print(_('FAILED: ')+str(e)) + print(_('Removing version...')) try: conf2.set('APPS', 'maiana', '') diff --git a/openplotterMaiana/openplotterMaiana.py b/openplotterMaiana/openplotterMaiana.py index 1ad69fc..c817cd8 100644 --- a/openplotterMaiana/openplotterMaiana.py +++ b/openplotterMaiana/openplotterMaiana.py @@ -122,8 +122,11 @@ class MyFrame(wx.Frame): webbrowser.open(url, new=2) def restartRead(self): - subprocess.call(['pkill','-f','openplotter-maiana-read']) - subprocess.Popen('openplotter-maiana-read') + subprocess.call([self.platform.admin, 'python3', self.currentdir+'/service.py', 'enable']) + time.sleep(1) + + def stopRead(self): + subprocess.call([self.platform.admin, 'python3', self.currentdir+'/service.py', 'disable']) time.sleep(1) def onRead(self): @@ -191,12 +194,10 @@ class MyFrame(wx.Frame): if deviceOld != self.device: if self.device: self.restartRead() - else: subprocess.call(['pkill','-f','openplotter-maiana-read']) + else: self.stopRead() else: - if self.device: - test = subprocess.check_output(['ps','aux']).decode(sys.stdin.encoding) - if not 'openplotter-maiana-read' in test: self.restartRead() - else: subprocess.call(['pkill','-f','openplotter-maiana-read']) + if self.device: self.restartRead() + else: self.stopRead() if self.device: self.sock.sendto(b'sys?\r\n',(self.UDP_IP,self.UDP_PORT)) @@ -213,7 +214,7 @@ class MyFrame(wx.Frame): ts = datetime.datetime.utcnow().timestamp() timestamp = data['hardwareRevision']['timestamp'] ts2 = time.mktime(datetime.datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S.%fZ").timetuple()) - if ts - ts2 > 3: + if ts - ts2 > 5: self.ShowStatusBarRED(_('Cannot connect with the device, try again by pressing "Refresh"')) return hardwareRevision = data['hardwareRevision']['value'] @@ -424,12 +425,10 @@ class MyFrame(wx.Frame): if deviceOld != self.device: if self.device: self.restartRead() - else: subprocess.call(['pkill','-f','openplotter-maiana-read']) + else: self.stopRead() else: - if self.device: - test = subprocess.check_output(['ps','aux']).decode(sys.stdin.encoding) - if not 'openplotter-maiana-read' in test: self.restartRead() - else: subprocess.call(['pkill','-f','openplotter-maiana-read']) + if self.device: self.restartRead() + else: self.stopRead() self.onRead() diff --git a/openplotterMaiana/openplotterMaianaRead.py b/openplotterMaiana/openplotterMaianaRead.py index edafb66..60c9524 100644 --- a/openplotterMaiana/openplotterMaianaRead.py +++ b/openplotterMaiana/openplotterMaianaRead.py @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with Openplotter. If not, see . -import os, socket, time, ssl, json, datetime +import os, socket, time, ssl, json, datetime, sys from openplotterSettings import conf from openplotterSettings import platform from openplotterSettings import language @@ -23,91 +23,92 @@ from websocket import create_connection from openplotterSignalkInstaller import connections def main(): - platform2 = platform.Platform() - conf2 = conf.Conf() - currentdir = os.path.dirname(os.path.abspath(__file__)) - currentLanguage = conf2.get('GENERAL', 'lang') - package = 'openplotter-maiana' - language.Language(currentdir, package, currentLanguage) - skConnections = connections.Connections('MAIANA') - token = skConnections.token - device = conf2.get('MAIANA', 'device') - if conf2.get('GENERAL', 'debug') == 'yes': debug = True - else: debug = False - if token and device: - ws = False - sock = False - while True: - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server_address = ('localhost', 10110) - sock.connect(server_address) - sock.setblocking(0) + if sys.argv[1] != '1': + platform2 = platform.Platform() + conf2 = conf.Conf() + currentdir = os.path.dirname(os.path.abspath(__file__)) + currentLanguage = conf2.get('GENERAL', 'lang') + package = 'openplotter-maiana' + language.Language(currentdir, package, currentLanguage) + skConnections = connections.Connections('MAIANA') + token = skConnections.token + device = conf2.get('MAIANA', 'device') + if conf2.get('GENERAL', 'debug') == 'yes': debug = True + else: debug = False + if token and device: + ws = False + sock = False + while True: + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_address = ('localhost', 10110) + sock.connect(server_address) + sock.setblocking(0) - uri = platform2.ws+'localhost:'+platform2.skPort+'/signalk/v1/stream?subscribe=none' - headers = {'Authorization': 'Bearer '+token} - ws = create_connection(uri, header=headers, sslopt={"cert_reqs": ssl.CERT_NONE}) + uri = platform2.ws+'localhost:'+platform2.skPort+'/signalk/v1/stream?subscribe=none' + headers = {'Authorization': 'Bearer '+token} + ws = create_connection(uri, header=headers, sslopt={"cert_reqs": ssl.CERT_NONE}) - tick = time.perf_counter() - while True: - time.sleep(0.01) - if (time.perf_counter() - tick) > 3: raise Exception('') - data = False - try: data = sock.recv(1024) - except: pass - if data: - tick = time.perf_counter() - data = data.decode("utf-8") - if '$PA' in data: - data = data.splitlines() - for data2 in data: - SKdata = {} - data3 = data2.split('*') - data3 = data3[0].split(',') - #$PAINF,A,0x20*5B - if data3[0] == '$PAINF': - try: - noiseValue = int(data3[2],16) - SKdata.update({"MAIANA.channel"+data3[1]+".noiseFloor":noiseValue}) - if conf2.get('MAIANA', 'noiseDetect') == '1': - if noiseValue > 64: - now = datetime.datetime.utcnow() - now = now.strftime("%Y-%m-%dT%H:%M:%S.%fZ") - SKdata.update({"notifications.MAIANA.channel"+data3[1]+".noiseFloor":{"message":_("There may be electromagnetic interference near the MAIANA AIS antenna"),"state":"alert","method": ["visual", "sound"],"timestamp":now}}) - else: - SKdata.update({"notifications.MAIANA.channel"+data3[1]+".noiseFloor":None}) - except: pass - #$PAITX,A,18*1C - elif data3[0] == '$PAITX': - SKdata.update({"MAIANA.channel"+data3[1]+".transmittedMessageType":data3[2]}) - #$PAISYS,11.3.0,4.0.0,,STM32L422,1,1*05 - elif data3[0] == '$PAISYS': - try: SKdata.update({"MAIANA.hardwareRevision":data3[1],"MAIANA.firmwareRevision":data3[2],"MAIANA.serialNumber":data3[3],"MAIANA.MCUtype":data3[4],"MAIANA.breakoutGeneration":data3[5],"MAIANA.bootloader":data3[6]}) - except: - try: SKdata.update({"MAIANA.hardwareRevision":data3[1],"MAIANA.firmwareRevision":data3[2],"MAIANA.serialNumber":data3[3],"MAIANA.MCUtype":data3[4],"MAIANA.breakoutGeneration":'',"MAIANA.bootloader":''}) - except: SKdata.update({"MAIANA.hardwareRevision":data3[1],"MAIANA.firmwareRevision":data3[2],"MAIANA.serialNumber":data3[3],"MAIANA.MCUtype":'',"MAIANA.breakoutGeneration":'',"MAIANA.bootloader":''}) - #$PAISTN,987654321,NAUT,,37,0,0,0,0*2A - elif data3[0] == '$PAISTN': - try: - SKdata.update({"MAIANA.station.MMSI":data3[1],"MAIANA.station.vesselName":data3[2],"MAIANA.station.callSign":data3[3],"MAIANA.station.vesselType":int(data3[4]),"MAIANA.station.LOA":int(data3[5]),"MAIANA.station.beam":int(data3[6]),"MAIANA.station.portOffset":int(data3[7]),"MAIANA.station.bowOffset":int(data3[8])}) - except: pass - #$PAITXCFG,1,0,1,1,0*0 - elif data3[0] == '$PAITXCFG': - try: - SKdata.update({"MAIANA.transmission.hardwarePresent":int(data3[1]),"MAIANA.transmission.hardwareSwitch":int(data3[2]),"MAIANA.transmission.softwareSwitch":int(data3[3]),"MAIANA.transmission.stationData":int(data3[4]),"MAIANA.transmission.status":int(data3[5])}) - except: pass - keys = [] - for i in SKdata: - keys.append({"path":i,"value":SKdata[i]}) - if keys: - SignalK = {"updates":[{"$source":"OpenPlotter.maiana","values":keys}]} - SignalK = json.dumps(SignalK) - ws.send(SignalK+'\r\n') - except Exception as e: - if debug: print(str(e)) - if ws: ws.close() - if sock: sock.close() - time.sleep(5) + tick = time.perf_counter() + while True: + time.sleep(0.01) + if (time.perf_counter() - tick) > 3: raise Exception('') + data = False + try: data = sock.recv(1024) + except: pass + if data: + tick = time.perf_counter() + data = data.decode("utf-8") + if '$PA' in data: + data = data.splitlines() + for data2 in data: + SKdata = {} + data3 = data2.split('*') + data3 = data3[0].split(',') + #$PAINF,A,0x20*5B + if data3[0] == '$PAINF': + try: + noiseValue = int(data3[2],16) + SKdata.update({"MAIANA.channel"+data3[1]+".noiseFloor":noiseValue}) + if conf2.get('MAIANA', 'noiseDetect') == '1': + if noiseValue > 64: + now = datetime.datetime.utcnow() + now = now.strftime("%Y-%m-%dT%H:%M:%S.%fZ") + SKdata.update({"notifications.MAIANA.channel"+data3[1]+".noiseFloor":{"message":_("There may be electromagnetic interference near the MAIANA AIS antenna"),"state":"alert","method": ["visual", "sound"],"timestamp":now}}) + else: + SKdata.update({"notifications.MAIANA.channel"+data3[1]+".noiseFloor":None}) + except: pass + #$PAITX,A,18*1C + elif data3[0] == '$PAITX': + SKdata.update({"MAIANA.channel"+data3[1]+".transmittedMessageType":data3[2]}) + #$PAISYS,11.3.0,4.0.0,,STM32L422,1,1*05 + elif data3[0] == '$PAISYS': + try: SKdata.update({"MAIANA.hardwareRevision":data3[1],"MAIANA.firmwareRevision":data3[2],"MAIANA.serialNumber":data3[3],"MAIANA.MCUtype":data3[4],"MAIANA.breakoutGeneration":data3[5],"MAIANA.bootloader":data3[6]}) + except: + try: SKdata.update({"MAIANA.hardwareRevision":data3[1],"MAIANA.firmwareRevision":data3[2],"MAIANA.serialNumber":data3[3],"MAIANA.MCUtype":data3[4],"MAIANA.breakoutGeneration":'',"MAIANA.bootloader":''}) + except: SKdata.update({"MAIANA.hardwareRevision":data3[1],"MAIANA.firmwareRevision":data3[2],"MAIANA.serialNumber":data3[3],"MAIANA.MCUtype":'',"MAIANA.breakoutGeneration":'',"MAIANA.bootloader":''}) + #$PAISTN,987654321,NAUT,,37,0,0,0,0*2A + elif data3[0] == '$PAISTN': + try: + SKdata.update({"MAIANA.station.MMSI":data3[1],"MAIANA.station.vesselName":data3[2],"MAIANA.station.callSign":data3[3],"MAIANA.station.vesselType":int(data3[4]),"MAIANA.station.LOA":int(data3[5]),"MAIANA.station.beam":int(data3[6]),"MAIANA.station.portOffset":int(data3[7]),"MAIANA.station.bowOffset":int(data3[8])}) + except: pass + #$PAITXCFG,1,0,1,1,0*0 + elif data3[0] == '$PAITXCFG': + try: + SKdata.update({"MAIANA.transmission.hardwarePresent":int(data3[1]),"MAIANA.transmission.hardwareSwitch":int(data3[2]),"MAIANA.transmission.softwareSwitch":int(data3[3]),"MAIANA.transmission.stationData":int(data3[4]),"MAIANA.transmission.status":int(data3[5])}) + except: pass + keys = [] + for i in SKdata: + keys.append({"path":i,"value":SKdata[i]}) + if keys: + SignalK = {"updates":[{"$source":"OpenPlotter.maiana","values":keys}]} + SignalK = json.dumps(SignalK) + ws.send(SignalK+'\r\n') + except Exception as e: + if debug: print(str(e)) + if ws: ws.close() + if sock: sock.close() + time.sleep(5) diff --git a/openplotterMaiana/service.py b/openplotterMaiana/service.py index fb7ca62..debbbb1 100644 --- a/openplotterMaiana/service.py +++ b/openplotterMaiana/service.py @@ -22,4 +22,11 @@ if sys.argv[1]=='sk': subprocess.call(['systemctl', 'stop', 'signalk.service']) subprocess.call(['systemctl', 'stop', 'signalk.socket']) subprocess.call(['systemctl', 'start', 'signalk.socket']) - subprocess.call(['systemctl', 'start', 'signalk.service']) \ No newline at end of file + subprocess.call(['systemctl', 'start', 'signalk.service']) + +if sys.argv[1]=='enable': + subprocess.call(['systemctl', 'restart', 'openplotter-maiana-read.service']) + subprocess.call(['systemctl', 'enable', 'openplotter-maiana-read.service']) +elif sys.argv[1]=='disable': + subprocess.call(['systemctl', 'stop', 'openplotter-maiana-read.service']) + subprocess.call(['systemctl', 'disable', 'openplotter-maiana-read.service']) \ No newline at end of file diff --git a/openplotterMaiana/startup.py b/openplotterMaiana/startup.py index 38418ff..d608463 100644 --- a/openplotterMaiana/startup.py +++ b/openplotterMaiana/startup.py @@ -20,23 +20,14 @@ from openplotterSettings import language from openplotterSettings import platform from openplotterSignalkInstaller import connections -class Start(): +class Start(): def __init__(self, conf, currentLanguage): - self.conf = conf - currentdir = os.path.dirname(os.path.abspath(__file__)) - language.Language(currentdir,'openplotter-maiana',currentLanguage) - - self.initialMessage = _('Starting MAIANA transponder...') - - def start(self): - green = '' - black = '' - red = '' - - subprocess.call(['pkill', '-f', 'openplotter-maiana-read']) - subprocess.Popen('openplotter-maiana-read') - time.sleep(1) + self.initialMessage = '' + def start(self): + green = '' + black = '' + red = '' return {'green': green,'black': black,'red': red} class Check(): @@ -157,24 +148,25 @@ class Check(): if not black: black = msg else: black+= ' | '+msg - # check service - test = subprocess.check_output(['ps','aux']).decode(sys.stdin.encoding) - if device and (result[0] == 'approved' or result[0] == 'validated'): - if 'openplotter-maiana-read' in test: - msg = _('running') + #service + if device and result[0] == 'validated': + try: + subprocess.check_output(['systemctl', 'is-active', 'openplotter-maiana-read.service']).decode(sys.stdin.encoding) + msg = _('service running') if not green: green = msg else: green+= ' | '+msg - else: - msg = _('not running') + except: + msg = _('service not running') if red: red += '\n '+msg else: red = msg else: - if 'openplotter-maiana-read' in test: - msg = _('running') + try: + subprocess.check_output(['systemctl', 'is-active', 'openplotter-maiana-read.service']).decode(sys.stdin.encoding) + msg = _('service running') if red: red += '\n '+msg else: red = msg - else: - msg = _('not running') + except: + msg = _('service not running') if not black: black = msg else: black+= ' | '+msg