Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial setup of fprime-gds to work with OpenMCT #136

Open
wants to merge 7 commits into
base: devel
Choose a base branch
from
38 changes: 38 additions & 0 deletions src/fprime_gds/executables/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -782,3 +782,41 @@ def get_arguments(self) -> Dict[Tuple[str, ...], Dict[str, Any]]:

def handle_arguments(self, args, **kwargs):
return args

class OpenMCTTelemetryPollerParser(ParserBase):
thomas-bc marked this conversation as resolved.
Show resolved Hide resolved
""" Parser for OpenMCT Server arguments """

def get_arguments(self) -> Dict[Tuple[str, ...], Dict[str, Any]]:
""" Return arguments on whether to use OpenMCT, post to a specific URI, and publish telemetry at a specific frequency"""
thomas-bc marked this conversation as resolved.
Show resolved Hide resolved
return {
("--openmct",): {
"dest": "openmct",
"action": 'store_true',
"help": "Determines whethers OpenMCT will be used for Telemetry Visualization",
"required": False
},
("--openmct-uri",): {
"dest": "openmct_uri",
"type": str,
"default": "http://127.0.0.1:4052/fprime_telem",
"help": "URI of the OpenMCT Server. The URI at which the F-Prime telemetry will be broadcasted.",
"required": False
},
("--openmct-telem-rate",): {
"dest": "openmct_telem_rate",
"type": float,
"default": 1,
"help": "Rate(in Hz) at which we want to poll the F-Prime Telemetry Pipeline for new telemetry",
"required": False
},
("--openmct-dir",): {
"dest": "openmct_dir",
"type": str,
"default": "",
"help": "Directory where the OpenMCT Installation is located",
"required": False
}
}

def handle_arguments(self, args, **kwargs):
return args
69 changes: 67 additions & 2 deletions src/fprime_gds/executables/run_deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@
GdsParser,
ParserBase,
StandardPipelineParser,
OpenMCTTelemetryPollerParser
)
from fprime_gds.executables.utils import AppWrapperException, run_wrapped_application

import fprime_openmct
from fprime_openmct.config_server import register_npm_package, install_npm_package, start_npm_package
from fprime_openmct.src.fprime_openmct.TopAppDictXMLtoOpenMCTJSON import TopologyAppDictionaryJSONifier
thomas-bc marked this conversation as resolved.
Show resolved Hide resolved


BASE_MODULE_ARGUMENTS = [sys.executable, "-u", "-m"]


Expand All @@ -27,7 +33,7 @@ def parse_args():
:return: parsed argument namespace
"""
# Get custom handlers for all executables we are running
arg_handlers = [StandardPipelineParser, GdsParser, BinaryDeployment, CommParser]
arg_handlers = [StandardPipelineParser, GdsParser, BinaryDeployment, CommParser, OpenMCTTelemetryPollerParser]
# Parse the arguments, and refine through all handlers
args, parser = ParserBase.parse_args(arg_handlers, "Run F prime deployment and GDS")
return args
Expand Down Expand Up @@ -148,6 +154,54 @@ def launch_comm(parsed_args):
app_cmd = BASE_MODULE_ARGUMENTS + ["fprime_gds.executables.comm"] + arguments
return launch_process(app_cmd, name=f'comm[{parsed_args.adapter}] Application', launch_time=1)

def get_openmct_json(parsed_args):
""" Convert F-Prime Topology App Dictionary XML to Python Dictionary

Args:
parsed_args: parsed argument namespace
Return:
converted OpenMCT JSON Telemetry Definitions
Initial States JSON for OpenMCT
"""

openmct_dir = fprime_openmct.__file__.replace('__init__.py', 'src/fprime_openmct/javascript')
thomas-bc marked this conversation as resolved.
Show resolved Hide resolved

top_dict = TopologyAppDictionaryJSONifier(str(parsed_args.dictionary))
top_dict.writeOpenMCTJSON('FPrimeDeploymentTopologyAppDictionary', openmct_dir)
top_dict.writeInitialStatesJSON('initial_states', openmct_dir)

def launch_openmct(parsed_args):
""" Launch OpenMCT Node Server

Args:
parsed_args: parsed argument namespace
Return:
launched process
"""
openmct_dir = fprime_openmct.__file__.replace('__init__.py', 'src/fprime_openmct/javascript')


pkg = register_npm_package(openmct_dir + "/package.json")

# Check and install node server if needed
install_npm_package(pkg, openmct_dir)
thomas-bc marked this conversation as resolved.
Show resolved Hide resolved

app_cmd = start_npm_package(pkg, delay=5)

return app_cmd

def poll_telem(parsed_args):
""" Poll and Send Telemetry to OpenMCT

Args:
parsed_args: parsed argument namespace
Return:
launched process
"""

app_cmd = BASE_MODULE_ARGUMENTS + ["fprime_openmct.src.fprime_openmct.fprime_telem_poller"] + OpenMCTTelemetryPollerParser().reproduce_cli_args(parsed_args)

return launch_process(app_cmd, name='OpenMCT Poller', launch_time=1)

def main():
"""
Expand All @@ -174,11 +228,22 @@ def main():
# Launch the desired GUI package
launchers.append(launch_html)

# Check if OpenMCT is set to be used. If true, generate OpenMCT States and Launch the OpenMCT Server
if parsed_args.openmct:
# Try Generating the OpenMCT JSON and Initial States
get_openmct_json(parsed_args)

# Try Launching OpenMCT Server
launchers.append(launch_openmct)

#Try polling for telemetry
launchers.append(poll_telem)

# Launch launchers and wait for the last app to finish
try:
procs = [launcher(parsed_args) for launcher in launchers]
print("[INFO] F prime is now running. CTRL-C to shutdown all components.")
procs[-1].wait()
procs[-3].wait()
thomas-bc marked this conversation as resolved.
Show resolved Hide resolved
except KeyboardInterrupt:
print("[INFO] CTRL-C received. Exiting.")
except Exception as exc:
Expand Down