From 2a8911f9d10ba516d36ad68aae831c71fab0262b Mon Sep 17 00:00:00 2001 From: Leor Bleier Date: Fri, 26 Jun 2020 17:34:54 -0400 Subject: [PATCH] Enhancement #103 - updates to allow user to select header version Updates GUI and backend to allow user to select header version offsets, or custom byte offsets --- GroundSystem.py | 10 +++++----- Subsystems/cmdGui/CommandSystem.py | 12 +++++++++--- Subsystems/cmdGui/MiniCmdUtil.py | 23 +++++++++++++++++++---- Subsystems/cmdGui/Parameter.py | 11 ++++++++--- Subsystems/cmdGui/UdpCommands.py | 11 ++++++++--- Subsystems/tlmGUI/GenericTelemetry.py | 17 +++++++++++------ shareddata.py | 3 --- 7 files changed, 60 insertions(+), 27 deletions(-) diff --git a/GroundSystem.py b/GroundSystem.py index fe932ca..d77aa92 100644 --- a/GroundSystem.py +++ b/GroundSystem.py @@ -28,7 +28,6 @@ from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox -from shareddata import tlmOffset, cmdOffsetPri, cmdOffsetSec from RoutingService import RoutingService from Ui_MainWindow import Ui_MainWindow @@ -146,10 +145,10 @@ def setCmdOffsets(self): self.sbCmdOffsetSec.setValue(self.HDR_VER_1_OFFSET) def saveOffsets(self): - tlmOffset = self.sbTlmOffset.value() - cmdOffsetPri = self.sbCmdOffsetPri.value() - cmdOffsetSec = self.sbCmdOffsetSec.value() - print(tlmOffset, cmdOffsetPri, cmdOffsetSec) + offsets = bytes((self.sbTlmOffset.value(), self.sbCmdOffsetPri.value(), + self.sbCmdOffsetSec.value())) + with open("/tmp/OffsetData", "wb") as f: + f.write(offsets) # Update the combo box list in gui def updateIpList(self, ip, name): @@ -181,6 +180,7 @@ def initRoutingService(self): # Start the Routing Service MainWindow.initRoutingService() + MainWindow.saveOffsets() # Execute the app sys.exit(app.exec_()) diff --git a/Subsystems/cmdGui/CommandSystem.py b/Subsystems/cmdGui/CommandSystem.py index 3327240..ec842ad 100644 --- a/Subsystems/cmdGui/CommandSystem.py +++ b/Subsystems/cmdGui/CommandSystem.py @@ -45,6 +45,7 @@ def __init__(self): super().__init__() self.setupUi(self) self.move(800, 100) + self.mcu = None # # Processes 'Display Page' button @@ -97,9 +98,10 @@ def ProcessQuickButton(self, idx): subprocess.Popen(cmd_args) # if doesn't require parameters else: - mcu = MiniCmdUtil(address, quickPort[qIdx], quickEndian[qIdx], - pktId, quickCode[qIdx]) - sendSuccess = mcu.sendPacket() + self.mcu = MiniCmdUtil(address, quickPort[qIdx], + quickEndian[qIdx], pktId, + quickCode[qIdx]) + sendSuccess = self.mcu.sendPacket() print("Command sent successfully:", sendSuccess) # launch_string = ( # f'{ROOTDIR.parent}/cmdUtil/cmdUtil ' @@ -107,6 +109,10 @@ def ProcessQuickButton(self, idx): # f'--pktid={pktId} --endian={quickEndian[qIdx]} ' # f'--cmdcode={quickCode[qIdx]}') + def closeEvent(self, event): + self.mcu.mm.close() + super().closeEvent(event) + # # Main diff --git a/Subsystems/cmdGui/MiniCmdUtil.py b/Subsystems/cmdGui/MiniCmdUtil.py index 97e4c81..cae208f 100644 --- a/Subsystems/cmdGui/MiniCmdUtil.py +++ b/Subsystems/cmdGui/MiniCmdUtil.py @@ -21,6 +21,7 @@ ## This file is a Python implementation of a subset of functions in cmdUtil ## to support the GroundSystem GUI +import mmap import sys from pathlib import Path from collections import namedtuple @@ -29,7 +30,7 @@ sys.path.append(str(ROOTDIR.parent.parent)) ## The two preceding lines must be above ## the next import or the import will fail -from shareddata import cmdOffsetPri, cmdOffsetSec, sock +from shareddata import sock class MiniCmdUtil: @@ -69,15 +70,21 @@ def __init__(self, self.parameters = parameters self.payload = bytearray() self.packet = bytearray() + with open("/tmp/OffsetData", "r+b") as f: + self.mm = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) + + self.cmdOffsetPri = 0 + self.cmdOffsetSec = 0 def assemblePriHeader(self): + self._getOffsets() ccsdsPri = bytearray(6) ccsdsPri[:2] = self.pktID.to_bytes(2, byteorder='big') ccsdsPri[2:4] = (0xC000).to_bytes(2, byteorder='big') totalPacketLen = len(ccsdsPri) + len(self.cfsCmdSecHdr) self.assemblePayload() totalPacketLen += len(self.payload) - totalPacketLen += cmdOffsetPri + cmdOffsetSec + totalPacketLen += self.cmdOffsetPri + self.cmdOffsetSec ccsdsPri[4:] = (totalPacketLen - 7).to_bytes(2, byteorder="big") return ccsdsPri @@ -117,12 +124,13 @@ def assemblePayload(self): self.payload.extend(fixedLenStr) def assemblePacket(self): + self._getOffsets() pri = self.assemblePriHeader() self.packet.extend(pri) - priOffset = bytearray(cmdOffsetPri) + priOffset = bytearray(self.cmdOffsetPri) self.packet.extend(priOffset) self.cfsCmdSecHdr[0] = self.cmdCode - secOffset = bytearray(cmdOffsetSec) + secOffset = bytearray(self.cmdOffsetSec) for b in b''.join( (pri, priOffset, self.cfsCmdSecHdr, secOffset, self.payload)): self.checksum ^= b @@ -142,3 +150,10 @@ def sendPacket(self): print() bytesSent = sock.sendto(self.packet, (self.host, self.port)) return bytesSent > 0 + + def _getOffsets(self): + try: + self.cmdOffsetPri = self.mm[1] + self.cmdOffsetSec = self.mm[2] + except ValueError: + pass diff --git a/Subsystems/cmdGui/Parameter.py b/Subsystems/cmdGui/Parameter.py index 71114cd..cc531ea 100644 --- a/Subsystems/cmdGui/Parameter.py +++ b/Subsystems/cmdGui/Parameter.py @@ -46,6 +46,7 @@ def __init__(self): self.parser = HTMLDocsParser() self.setWindowTitle("Parameter Dialog") self.SendButton_1.clicked.connect(self.ProcessSendButton) + self.mcu = None # # Button method @@ -64,9 +65,9 @@ def ProcessSendButton(self): else: param_list.append(f'{dataType}={inpt}') # --byte=4 param_string = ' '.join(param_list) - mcu = MiniCmdUtil(pageAddress, pagePort, pageEndian, pagePktId, - cmdCode, param_string.strip()) - sendSuccess = mcu.sendPacket() + self.mcu = MiniCmdUtil(pageAddress, pagePort, pageEndian, pagePktId, + cmdCode, param_string.strip()) + sendSuccess = self.mcu.sendPacket() # launch_string = ( # f'{ROOTDIR.parent}/cmdUtil/cmdUtil --host={pageAddress} ' # f'--port={pagePort} --pktid={pagePktId} --endian={pageEndian} ' @@ -78,6 +79,10 @@ def ProcessSendButton(self): else: self.status_box.setText('Error occured') + def closeEvent(self, event): + self.mcu.mm.close() + super().closeEvent(event) + # # Main method diff --git a/Subsystems/cmdGui/UdpCommands.py b/Subsystems/cmdGui/UdpCommands.py index acd487c..dc1cceb 100644 --- a/Subsystems/cmdGui/UdpCommands.py +++ b/Subsystems/cmdGui/UdpCommands.py @@ -57,6 +57,7 @@ def __init__(self): super().__init__() self.setupUi(self) self.setWindowTitle(pageTitle) + self.mcu = None # for j in range(self.tblCommands.rowCount()): # btn = self.tblCommands.cellWidget(j, 1) @@ -96,15 +97,19 @@ def ProcessSendButtonGeneric(self, idx): subprocess.Popen(cmd_args) # If parameters not required, directly calls cmdUtil to send command else: - mcu = MiniCmdUtil(address, pagePort, pageEndian, pagePktId, - cmdCodes[idx]) - sendSuccess = mcu.sendPacket() + self.mcu = MiniCmdUtil(address, pagePort, pageEndian, + pagePktId, cmdCodes[idx]) + sendSuccess = self.mcu.sendPacket() print("Command sent successfully:", sendSuccess) # launch_string = ( # f'{ROOTDIR.parent}/cmdUtil/cmdUtil --host=\"{address}\" ' # f'--port={pagePort} --pktid={pagePktId} ' # f'--endian={pageEndian} --cmdcode={cmdCodes[idx]}') + def closeEvent(self, event): + self.mcu.mm.close() + super().closeEvent(event) + # # Display usage diff --git a/Subsystems/tlmGUI/GenericTelemetry.py b/Subsystems/tlmGUI/GenericTelemetry.py index 6cb08cd..ad764ac 100644 --- a/Subsystems/tlmGUI/GenericTelemetry.py +++ b/Subsystems/tlmGUI/GenericTelemetry.py @@ -19,9 +19,9 @@ # #!/usr/bin/env python3 # - import csv import getopt +import mmap import sys from pathlib import Path from struct import unpack @@ -38,9 +38,8 @@ ## Adds ../cFS/tools/cFS-GroundSystem to module search path ## for shared data import -sys.path.append(str(ROOTDIR.parent.parent)) -from shareddata import tlmOffset - +# sys.path.append(str(ROOTDIR.parent.parent)) +# import shareddata as shared class SubsystemTelemetry(QDialog, Ui_GenericTelemetryDialog): @@ -50,13 +49,18 @@ class SubsystemTelemetry(QDialog, Ui_GenericTelemetryDialog): def __init__(self): super().__init__() self.setupUi(self) + with open("/tmp/OffsetData", "r+b") as f: + self.mm = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) # # This method decodes a telemetry item from the packet and displays it # - @staticmethod - def displayTelemetryItem(datagram, tlmIndex, labelField, valueField): + def displayTelemetryItem(self, datagram, tlmIndex, labelField, valueField): if tlmItemIsValid[tlmIndex]: + try: + tlmOffset = self.mm[0] + except ValueError: + pass print(tlmOffset) TlmField1 = tlmItemFormat[tlmIndex] if TlmField1[0] == "<": @@ -109,6 +113,7 @@ def processPendingDatagrams(self, datagram): def closeEvent(self, event): self.thread.runs = False self.thread.wait(2000) + self.mm.close() super().closeEvent(event) diff --git a/shareddata.py b/shareddata.py index fb1a64a..1b4cbd8 100644 --- a/shareddata.py +++ b/shareddata.py @@ -24,7 +24,4 @@ import socket -tlmOffset = 0 -cmdOffsetPri = 0 -cmdOffsetSec = 0 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)