fprime/Gse/bin/gse.py
2019-02-27 10:56:36 -08:00

288 lines
11 KiB
Python
Executable File

#!/usr/bin/env python
# encoding: utf-8
'''
This is the f prime ground support equipment client
program. It is designed to bring up a front end
GUI sending commands and receiving telemetry that
are defined utilizing the various XML files
used by the Autocoder to generate framework codes.
@author: Leonard J. Reder
@copyright: 2014 California Institute of Technology. All rights reserved.
@license: license
@contact: reder@jpl.nasa.gov
'''
import sys
import os
import Tkinter
import Pmw
import time
import glob
import random
from fprime.gse.utils import Logger
from fprime.gse.utils import PortFinder
from fprime.gse.utils import ConfigManager
import fprime.gse.controllers.exceptions
import traceback
from fprime.gse.views import main_panel_factory
from fprime.gse.views import main_panel
from optparse import OptionParser
__all__ = []
__version__ = 0.1
__date__ = '2015-04-03'
__updated__ = '2015-04-03'
LOGGER = None
def connect(opts):
"""
Routine to launch Threaded TCP Server
and connect to gse.py. The routine
creates default log files of stdout
and stderr.
"""
main_panel.TopPanel(None, None, opts).startTCP()
def execute(opts):
"""
Routine to launch a FSW binary that
must be specified on the command line.
The routine creates default log files
of stdout and stderr.
"""
#
# Setup log file name here...
#
if opts == None:
p = os.environ['HOME'] + os.sep + 'fprime_logs' + os.sep + "app"
else:
p = opts.log_file_path + os.sep + "app"
#
if not os.path.exists(p):
os.makedirs(p)
#
logfile = p + os.sep + time.strftime("%y%m%d%H%M%S", time.gmtime()) + '_GSE.log'
#
# Launch the FSW application saving both stdout and stdin to common log.
#
op_sys = os.uname()[0]
if 'BUILD_ROOT' in os.environ:
build_root_path = os.environ['BUILD_ROOT']
else:
print "EXCEPTIONS: BUILD_ROOT Environment Variable not found!"
raise exceptions.EnvironmentError
app_cmd = "\"%s -p %s | tee -a %s; exit\"" % (opts.exec_app, opts.port, logfile)
#app_cmd = "\"%s |& tee -a %s; exit\"" % (opts.exec_app, logfile)
#app_cmd = "\"%s\"" % (opts.exec_app)
if op_sys == 'Darwin':
app_script = '/usr/bin/osascript '
app_args = '-e \'tell application \"Terminal" to do script '
# Note the exit is so Mac Terminal.app window will exit when process killed...
cmd = app_script + app_args + app_cmd + " \'"
else:
app_script = "/usr/bin/gnome-terminal"
#app_args = "-e "
app_args = " -e"
cmd = app_script + app_args + app_cmd
os.system(cmd)
LOGGER.info("FSW Application Started: %s" % opts.exec_app)
def set_pmw_about_info():
config_manager = ConfigManager.ConfigManager.getInstance()
## Program Information
version_str = config_manager.get('about_info', 'version_number') + '\n' + config_manager.get('about_info', 'version_date')
version_str += '\n' + config_manager.get('about_info', 'last_modified') + '\n'
Pmw.aboutversion(version_str)
Pmw.aboutcopyright(config_manager.get('about_info', 'copyright'))
Pmw.aboutcontact(config_manager.get('about_info', 'contact'))
def main_window_start(opts):
"""
Everything GUI gets started from this routine.
"""
root = Tkinter.Tk()
#root.option_readfile('optionDB')
Pmw.initialise()
set_pmw_about_info()
mpf = main_panel_factory.MainPanelFactory(opts)
mpf.create(root)
if opts.no_about == False:
# Show about window
config_manager = ConfigManager.ConfigManager.getInstance()
a = Pmw.AboutDialog(root, applicationname=config_manager.get('about_info', 'app_name'))
a.show()
# This is a quick fix since something
# locks the main window event loop.
w = Tkinter.Toplevel()
w.destroy()
root.update()
return root
def main(argv=None):
'''
Command line options.
'''
global LOGGER
#
program_name = os.path.basename(sys.argv[0])
program_version = "v0.1"
program_build_date = "%s" % __updated__
program_version_string = '%%prog %s (%s)' % (program_version, program_build_date)
#program_usage = '''usage: spam two eggs''' # optional - will be autogenerated by optparse
program_longdesc = '''''' # optional - give further explanation about what the program does
program_license = "Copyright 2015 user_name (California Institute of Technology) \
ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged."
if argv is None:
argv = sys.argv[1:]
try:
# Get ConfigManager
config_manager = ConfigManager.ConfigManager.getInstance()
# Set default values
generated_path = config_manager.get("filepaths", "generated_path")
log_file_path = config_manager.get("filepaths", "log_file_path")
fsw_app = None
#
# setup option parser
parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
parser.add_option("-d", "--dictionary", dest="generated_path", action="store", type="string", \
help="Set base path to generated command/telemetry definition files [default: %default]", \
default=generated_path)
parser.add_option("-a", "--addr", dest="addr", action="store", type="string", help="set threaded tcp socket server address [default: %default]", \
default="127.0.0.1")
parser.add_option("-c", "--connect", action="store_true", dest="connect", help="Launches the Threaded TCP Socket Server on startup and connect to it [default: %default]", \
default=False)
parser.add_option("-p", "--port", dest="port", action="store", type="int", help="Set threaded tcp socket server port [default: %default]", \
#default=50007)
#default=PortFinder.old_getport(50000,[]))
)
parser.add_option("-s", "--stream_port", dest="stream_port", action="store", type="int", help="Set streaming socket server port [default: %default]", \
#default=50007)
#default=PortFinder.old_getport(50000,[]))
)
parser.add_option("-e", "--execute", dest="exec_app", action="store", type="string", help="Execute the specified fsw application after socket server and UI are up [default: %default]", \
default=fsw_app)
parser.add_option("-L", "--log-file-path", dest="log_file_path", action="store", type="string", help="Path to log files [default: %default]", \
default=log_file_path)
parser.add_option("-b", "--logbinary", dest="bin_logger_flag", action="store", type="int", help="Flag to log raw data from socket (1=ON, 0=OFF) [default: %default]", \
default=Logger.BIN_LOGGER_FLAG)
parser.add_option("-r", "--log-file-prefix", dest="log_file_prefix", action="store", type="string", help="Prefix in log file path for each run. [default: current date/time]", \
default=None)
parser.add_option("-l", "--log-time", dest="log_time", action="store", type="string", help="Time used for logging. (local, GMT)", \
default="local")
parser.add_option("-n", "--no-about", dest="no_about", action="store_true", help="Do not show about text screen on start", \
default=True)
parser.add_option("-t", "--title", dest="title", action="store",type="string", help="Set GUI title", default="Fprime")
parser.add_option("-x", "--packetspec", dest="packetspec", action="store",type="string", help="Path to packet specification file", default=None)
#parser.add_option("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %default]")
# process options
(opts, args) = parser.parse_args(argv)
#
# Launch the Threaded TCP Server here...
# check for gm time in options
if not (opts.log_time == "GMT" or opts.log_time == "local"):
raise Exception("-l,--log-time must be \"local\" or \"GMT\"")
if opts.log_time == "GMT" and opts.log_file_prefix == None:
opts.log_file_prefix = time.strftime("%Y-%m-%d_%H-%M-%S",time.gmtime())
elif opts.log_time == "local" and opts.log_file_prefix == None:
opts.log_file_prefix = time.strftime("%Y-%m-%d_%H-%M-%S",time.localtime())
# Make sure dictionary directory exists
print "Generated path %s"%opts.generated_path
if not os.path.exists(opts.generated_path):
sys.stderr.write("Error: dictionary directory %s does not exist."%opts.generated_path)
sys.exit(-1)
#
if opts.connect == True or opts.exec_app != None:
connect(opts)
opts.connect = True
# set the binary logger flag
Logger.setBinLoggerFlag(opts.bin_logger_flag)
# make the
#
# For every console output log to a default file and stdout.
#
logfile = 'StdOut.log'
p = opts.log_file_path + os.sep + opts.log_file_prefix + os.sep + "stdout"
if not os.path.exists(p):
os.makedirs(p)
f = p + os.sep + "stdout.log"
#
# display configuration before starting GUI here...
#
sep_line = 80*"="
logger = Logger.connectOutputLogger(f,'stdout')
logger.info("Created log: %s" % f)
logger.info("User: %s" % os.environ['USER'])
(sysname, nodename, release, version, machine) = os.uname()
logger.info("OS Name: %s" % sysname)
logger.info("Machine Network Host Name: %s" % nodename)
logger.info("Release: %s" % release)
logger.info("Version: %s" % version)
logger.info("Machine: %s" % machine)
#
logger.info(sep_line)
logger.info("Generated command/telemetry definition files: %s" % opts.generated_path)
logger.info("Threaded TCP Socket Server Address: %s" % opts.addr)
logger.info("Connection and starting Threaded TCP Socket Server: %s" % opts.connect)
logger.info("Threaded TCP Socket Server Port: %s" % opts.port)
logger.info("Execution of FSW Binary Application: %s" % opts.exec_app)
logger.info("Path to log files: %s" % opts.log_file_path)
logger.info(sep_line)
LOGGER = logger
#
# MAIN BODY #
root = main_window_start(opts)
root.geometry("900x800+10+10")
#
# Launch an FSW applicaiton but only after the gse.py is ready.
#
if opts.exec_app != None:
root.after(1000, execute, opts)
root.mainloop()
except fprime.gse.controllers.exceptions.GseControllerException, e:
sys.stderr.write("Exception: %s\n"%e.getMsg())
traceback.print_exc()
return 2
except Exception, e:
indent = len(program_name) * " "
sys.stderr.write(program_name + ": " + repr(e) + "\n")
sys.stderr.write(indent + " for help use --help\n")
traceback.print_exc()
return 2
if __name__ == "__main__":
sys.exit(main())