Beispiel #1
0
    def __init__(self, number, FPE_Wrapper_version=None, debug=False, check_hk=True):
        from fpesocketconnection import FPESocketConnection
        from unit_tests import check_house_keeping_voltages
        import os
        import time

        # First sanity check: ping the observatory simulator
        if not self.ping():
            raise Exception("Cannot ping 192.168.100.1")
        self._debug = debug
        self.fpe_number = number
        self.connection = FPESocketConnection(5554 + number, self._debug)

        # Second sanity check: get the observatory simulator version
        try:
           version = self.version
           if self._debug:
              print version
        except Exception as e:
           raise type(e)("Could not read Observatory Simulator version... {0}\n".format(str(e)) + 
                         "Are you sure you firmware for the Observatory Simulator is properly installed?")
           

        self._dir = os.path.dirname(os.path.realpath(__file__))
        # Default memory configuration files
        self._program_file = os.path.join(self._dir, "..", "data", "files", "default_program.fpe")
        self.register_memory = os.path.join(self._dir, "MemFiles", "Reg.bin")

        # Set the House Keeping and Operating Parameters
        self.hsk_byte_array = house_keeping.identity_map
        self.ops = OperatingParameters(self)

        # Load the wrapper.  First check if loading the wrapper is *necessary* by checking reference values on housekeeping channels
        if FPE_Wrapper_version != None:
            try:
                check_house_keeping_voltages(self)
                if self._debug:
                    print "House keeping reports sane values for reference voltages, *NOT* loading wrapper"
            except:
                fpe_wrapper_bin = os.path.join(self._dir, "MemFiles",
                                               "FPE_Wrapper-{version}.bin".format(version=FPE_Wrapper_version))
                self.upload_fpe_wrapper_bin(fpe_wrapper_bin)

        self.upload_register_memory(self.register_memory)
        self.upload_housekeeping_memory(
            binary_files.write_hskmem(self.hsk_byte_array))
        self.ops.send()
        self.load_code()

        time.sleep(.01) # Need to wait for 1/100th of a sec for the box to catch up with us

        # Run sanity checks on the FPE to make sure basic functions are working (if specified)
        if check_hk:
            check_house_keeping_voltages(self)
Beispiel #2
0
    def __init__(self, number, FPE_Wrapper_version="6.1.1", debug=False, preload=False, hsk_byte_array=house_keeping.identity_map):
        from fpesocketconnection import FPESocketConnection
        from unit_tests import check_house_keeping_voltages
        import os
        import time
        if not self.ping():
            raise Exception("Cannot ping 192.168.100.1")
        self._debug = debug
        self.fpe_number = number
        self.connection = FPESocketConnection(5554 + number, self._debug)
        self._dir = os.path.dirname(os.path.realpath(__file__))

        # Default memory configuration files
        self.fpe_wrapper_bin = os.path.join(self._dir, "MemFiles",
                                            "FPE_Wrapper-{version}.bin".format(version=FPE_Wrapper_version))

        self._program_file = os.path.join(self._dir, "..", "data", "files", "default_program.fpe")

        # TODO: Sunset this
        self.register_memory = os.path.join(self._dir, "MemFiles", "Reg.bin")

        # Set the House Keeping and Operating Parameters
        self.hsk_byte_array = hsk_byte_array
        self.ops = OperatingParameters(self)

        self._safe_to_load_FPE = None

        if preload:
            self.upload_fpe_wrapper_bin(self.fpe_wrapper_bin)
        self.upload_register_memory(self.register_memory)
        self.upload_housekeeping_memory(
            binary_files.write_hskmem(self.hsk_byte_array))
        self.ops.send()
        self.load_code()

        # Run sanity checks on the FPE to make sure basic functions are working
        time.sleep(.01) # Need to wait for 1/100th of a sec for prince charming
        check_house_keeping_voltages(self)
Beispiel #3
0
class FPE(object):
    """An object for interacting with an FPE in an Observatory Simulator"""

    def __init__(self, number, FPE_Wrapper_version="6.1.1", debug=False, preload=False, hsk_byte_array=house_keeping.identity_map):
        from fpesocketconnection import FPESocketConnection
        from unit_tests import check_house_keeping_voltages
        import os
        import time
        if not self.ping():
            raise Exception("Cannot ping 192.168.100.1")
        self._debug = debug
        self.fpe_number = number
        self.connection = FPESocketConnection(5554 + number, self._debug)
        self._dir = os.path.dirname(os.path.realpath(__file__))

        # Default memory configuration files
        self.fpe_wrapper_bin = os.path.join(self._dir, "MemFiles",
                                            "FPE_Wrapper-{version}.bin".format(version=FPE_Wrapper_version))

        self._program_file = os.path.join(self._dir, "..", "data", "files", "default_program.fpe")

        # TODO: Sunset this
        self.register_memory = os.path.join(self._dir, "MemFiles", "Reg.bin")

        # Set the House Keeping and Operating Parameters
        self.hsk_byte_array = hsk_byte_array
        self.ops = OperatingParameters(self)

        self._safe_to_load_FPE = None

        if preload:
            self.upload_fpe_wrapper_bin(self.fpe_wrapper_bin)
        self.upload_register_memory(self.register_memory)
        self.upload_housekeeping_memory(
            binary_files.write_hskmem(self.hsk_byte_array))
        self.ops.send()
        self.load_code()

        # Run sanity checks on the FPE to make sure basic functions are working
        time.sleep(.01) # Need to wait for 1/100th of a sec for prince charming
        check_house_keeping_voltages(self)

    def tftp_put(self, file_name, destination):
        """Upload a file to the FPE"""
        from sh import tftp, ErrorReturnCode_1
        import re
        tftp_mode = "mode binary"
        tftp_port = "connect 192.168.100.1 {}".format(68 + self.fpe_number)
        tftp_file = "put {} {}".format(file_name, destination)
        tftp_command = tftp_mode + "\n" + tftp_port + "\n" + tftp_file

        if self._debug:
            print "Running:\ntftp <<EOF\n", \
                tftp_command, "\n", \
                "EOF"
        try:
            tftp(_in=tftp_command)
        except ErrorReturnCode_1 as e:
            # tftp *always* fails because it's awesome
            # so just check that it reports in stdout it sent the thing
            if self._debug:
                print e
            if not re.match(r'Sent [0-9]+ bytes in [0-9]+\.[0-9]+ seconds',
                            e.stdout):
                raise e

        # Wait for the fpe to report the load is complete
        self.connection.wait_for_pattern(r'.*Load complete\n\r')

    @staticmethod
    def ping():
        """Ping the Observation Simulator to make sure it is alive"""
        from sh import ping
        out = ping('-c', '1', '-t', '1', '192.168.100.1')
        return '1 packets transmitted, 1 packets received' in str(out)

    def cmd_camrst(self):
        """Reset the camera after running frames"""
        # Is it just me, or shouldn't this be "Reset" not "Rest"?
        return self.connection.send_command("camrst", reply_pattern='FPE Rest complete')

    def cmd_cam_status(self):
        """Get the camera status"""
        response = self.connection.send_command(
            "cam_status",
            reply_pattern="cam_status = 0x[0-9a-f]+")[13:]
        val = int(response, 16)
        return val

    def cmd_version(self):
        """Get the version of the Observatory Simulator DHU software"""
        import re
        return \
            re.sub(r'FPE[0-9]>', '',
                   self.connection.send_command(
                       "version",
                       reply_pattern="Observatory Simulator Version .*"))

    def cmd_start_frames(self):
        return self.connection.send_command(
            "cam_start_frames",
            reply_pattern="(Starting frames...|Frames already enabled)"
        )

    def cmd_stop_frames(self):
        return self.connection.send_command(
            "cam_stop_frames",
            reply_pattern="Frames Stopped..."
        )

    def cmd_cam_hsk(self):
        """Get the camera housekeeping data, outputs an array of the housekeeping data"""
        import re
        channels = 128
        # TODO: switch on whether frames have been started
        out = self.connection.send_command(
            "cam_hsk",
            reply_pattern="Hsk\[[0-9]+\] = 0x[0-9a-f]+",
            matches=channels
        )
        return [int(n, 16) for n in re.findall('0x[0-9a-f]+', out)]

    def load_code(self):
        """Loads the program code using tftp"""
        self.upload_sequencer_memory(
            binary_files.write_seqmem(self.sequences_byte_array))
        self.upload_program_memory(
            binary_files.write_prgmem(self.programs_byte_array))

    def capture_frames(self, n):
        """Capture frames"""
        import subprocess
        import os.path
        self.cmd_start_frames()
        proc = subprocess.Popen(
            [os.path.join(self._dir, "..", "fits_capture", "tess_obssim", "tess_obssim"), '-n', str(n)],
            shell=False)
        proc.communicate()
        self.cmd_stop_frames()

    @property
    def sequences_byte_array(self):
        """A byte array representing the sequences set by the program code"""
        from ..sequencer_dsl.sequence import compile_sequences
        return compile_sequences(self._ast)

    @property
    def programs_byte_array(self):
        """A byte array representing the programs set by the program code"""
        from ..sequencer_dsl.program import compile_programs
        return compile_programs(self._ast)

    @property
    def _ast(self):
        from ..sequencer_dsl.parse import parse_file
        return parse_file(self._program_file)

    @property
    def code(self):
        """The program code"""
        with open(self._program_file) as f:
            return "// File: {filename}\n\n{code}".format(
                file=self._program_file,
                code=f.read())

    @property
    def house_keeping(self):
        hsk = self.cmd_cam_hsk()
        # Create a dictionary of the analogue outputs
        analogue = house_keeping.hsk_to_analogue_dictionary(hsk)
        # Create array of digital outs
        digital = [k for i in range(0, 128, 32)
                   for j in hsk[17 + i:24 + i]
                   for k in house_keeping.unpack_pair(j)]
        return {"analogue": analogue,
                "digital": digital}

    @property
    def parameters(self):
        """The parameters set by the program code"""
        return self._ast["parameters"]

    @property
    def hold(self):
        """The hold instruction set by the program code"""
        return self._ast["hold"]

    @property
    def sequences(self):
        """The sequences set by the program code"""
        return self._ast["sequences"]

    @property
    def defaults(self):
        """The sequencer default values set by the program code"""
        return self._ast["defaults"]

    @property
    def version(self):
        """Version property for the Observatory Simulator DHU software"""
        return self.cmd_version()

    @property
    def cam_status(self):
        """Get the camera status for the Observatory Simulator for a particular FPE"""
        return self.cmd_cam_status()

    def upload_fpe_wrapper_bin(self, fpe_wrapper_bin):
        """Upload the FPE Wrapper binary file to the FPE"""
        return self.tftp_put(
            fpe_wrapper_bin,
            "bitmem")

    def upload_sequencer_memory(self, sequencer_memory):
        """Upload the Sequencer Memory to the FPE"""
        # self.camrst()
        return self.tftp_put(
            sequencer_memory,
            "seqmem")

    def upload_register_memory(self, register_memory):
        """Upload the Register Memory to the FPE"""
        return self.tftp_put(
            register_memory,
            "regmem")

    def upload_program_memory(self, program_memory):
        """Upload the Program Memory to the FPE"""
        return self.tftp_put(
            program_memory,
            "prgmem")

    def upload_operating_parameter_memory(self, operating_parameter_memory):
        """Upload the Operating Parameter Memory to the FPE"""
        return self.tftp_put(
            operating_parameter_memory,
            "clvmem")

    def upload_housekeeping_memory(self, hsk_memory):
        """Upload the Operating Parameter Memory to the FPE"""
        return self.tftp_put(
            hsk_memory,
            "hskmem")
Beispiel #4
0
 def ops(self):
     if self._ops is None:
         self._ops = OperatingParameters(self)
     return self._ops