Skip to content
Snippets Groups Projects
Forked from an inaccessible project.
OBSW_CommandSenderReceiver.py 4.69 KiB
"""
Program: OBSW_UnitTest.py
Date: 01.11.2019
Description: All functions related to TmTc Sending and Receiving, used by UDP client

Manual:
Set up the UDP client as specified in the header comment and use the unit testing mode

A separate thread is used to listen for replies and send a new telecommand
if the first reply has not been received.
This is still experimental.

@author: R. Mueller
"""
from config import OBSW_Config as g
import time


# Generic TMTC SendReceive class which is implemented
# by specific implementations (e.g. SingleCommandSenderReceiver)
class CommandSenderReceiver:
    def __init__(self, comInterface, tmtcPrinter, tmTimeout, tcSendTimeoutFactor, doPrintToFile):
        self.tmTimeout = tmTimeout

        self.comInterface = comInterface
        self.tmtcPrinter = tmtcPrinter

        self.replyReceived = False
        self.tmReady = False
        self.pusPacketInfo = []
        self.pusPacket = []

        self.start_time = 0
        self.elapsed_time = 0
        self.timeoutCounter = 0
        self.tcSendTimeoutFactor = tcSendTimeoutFactor
        self.doPrintToFile = doPrintToFile
        self.queueEntryIsTelecommand = True

        # needed to store last actual tc packet form queue
        self.lastTc = []
        self.lastTcInfo = []
        # ignore periodic packets for timeout when checking a sequence
        self.isPacketToIgnore = False

    # checks for replies. if no reply is received, send telecommand again
    def checkForFirstReply(self):
        success = self.checkForOneTelemetrySequence()
        if success:
            self.replyReceived = True
        else:
            if len(self.pusPacket) == 0:
                print("Command Sender Receiver: No command has been sent yet")
            else:
                print("Command Sender Receiver: Sending command again")
                self.comInterface.sendTelecommand(self.pusPacket, self.pusPacketInfo)

    # Check for special queue entries.
    def checkQueueEntry(self, tcQueueEntry):
        (self.pusPacketInfo, self.pusPacket) = tcQueueEntry
        self.queueEntryIsTelecommand = False
        if self.pusPacketInfo == "wait":
            waitTime = self.pusPacket
            self.tmTimeout = self.tmTimeout + waitTime
            time.sleep(waitTime)
        elif self.pusPacketInfo == "print":
            printString = self.pusPacket
            self.tmtcPrinter.printString(printString)
        elif self.pusPacketInfo == "export":
            exportName = self.pusPacket
            if self.doPrintToFile:
                self.tmtcPrinter.printToFile(exportName, True)
        elif self.pusPacketInfo == "timeout":
            self.tmTimeout = self.pusPacket
        else:
            self.queueEntryIsTelecommand = True
            self.lastTc, self.lastTcInfo = (self.pusPacket, self.pusPacketInfo)

    def checkForTimeout(self):
        if self.timeoutCounter == 5:
            print("Command Sender Receiver: No response from command !")
            exit()
        if self.start_time != 0:
            self.elapsed_time = time.time() - self.start_time
        if self.elapsed_time > self.tmTimeout * self.tcSendTimeoutFactor:
            print("Command Sender Receiver: Timeout, sending TC again !")
            self.comInterface.sendTelecommand(self.lastTc, self.lastTcInfo)
            self.timeoutCounter = self.timeoutCounter + 1
            self.start_time = time.time()
        time.sleep(1)

    # check for sequence of replies for a telecommand (e.g. TM[1,1] , TM[1,7] ...) for tmTimeout value
    # returns True on success
    def checkForOneTelemetrySequence(self):
        tmReady = self.comInterface.dataAvailable(self.tmTimeout * self.tcSendTimeoutFactor)
        if tmReady is False:
            return False
        else:
            self.comInterface.receiveTelemetry()
            start_time = time.time()
            elapsed_time = 0
            while elapsed_time < self.tmTimeout:
                tmReady = self.comInterface.dataAvailable(1.0)
                if tmReady:
                    self.comInterface.receiveTelemetry()
                elapsed_time = time.time() - start_time
            # the timeout value can be set by special TC queue entries if packet handling takes longer,
            # but it is reset here to the global value
            if self.tmTimeout is not g.tmTimeout:
                self.tmTimeout = g.tmTimeout
            return True


def connectToBoard():
    # Maybe there is a cleaner way to start comm with udp server
    # so that it knows the ip address?
    test = bytearray([])
    g.sockSend.sendto(test, g.sendAddress)
    # send multiple times to get connection if there are problems