fprime-gds 3.4.4a1__py3-none-any.whl → 3.4.4a3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. fprime_gds/common/data_types/event_data.py +6 -1
  2. fprime_gds/common/data_types/exceptions.py +16 -11
  3. fprime_gds/common/loaders/ch_json_loader.py +107 -0
  4. fprime_gds/common/loaders/ch_xml_loader.py +5 -5
  5. fprime_gds/common/loaders/cmd_json_loader.py +85 -0
  6. fprime_gds/common/loaders/dict_loader.py +1 -1
  7. fprime_gds/common/loaders/event_json_loader.py +108 -0
  8. fprime_gds/common/loaders/event_xml_loader.py +10 -6
  9. fprime_gds/common/loaders/json_loader.py +222 -0
  10. fprime_gds/common/loaders/xml_loader.py +31 -9
  11. fprime_gds/common/pipeline/dictionaries.py +38 -3
  12. fprime_gds/common/tools/seqgen.py +4 -4
  13. fprime_gds/common/utils/string_util.py +57 -65
  14. fprime_gds/common/zmq_transport.py +4 -2
  15. fprime_gds/executables/cli.py +21 -39
  16. fprime_gds/executables/comm.py +3 -10
  17. fprime_gds/executables/data_product_writer.py +935 -0
  18. fprime_gds/executables/utils.py +23 -11
  19. fprime_gds/flask/sequence.py +1 -1
  20. fprime_gds/flask/static/addons/commanding/command-input.js +3 -2
  21. {fprime_gds-3.4.4a1.dist-info → fprime_gds-3.4.4a3.dist-info}/METADATA +14 -13
  22. {fprime_gds-3.4.4a1.dist-info → fprime_gds-3.4.4a3.dist-info}/RECORD +27 -22
  23. {fprime_gds-3.4.4a1.dist-info → fprime_gds-3.4.4a3.dist-info}/WHEEL +1 -1
  24. {fprime_gds-3.4.4a1.dist-info → fprime_gds-3.4.4a3.dist-info}/entry_points.txt +2 -3
  25. {fprime_gds-3.4.4a1.dist-info → fprime_gds-3.4.4a3.dist-info}/LICENSE.txt +0 -0
  26. {fprime_gds-3.4.4a1.dist-info → fprime_gds-3.4.4a3.dist-info}/NOTICE.txt +0 -0
  27. {fprime_gds-3.4.4a1.dist-info → fprime_gds-3.4.4a3.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,7 @@ helper functions
13
13
 
14
14
  @bug No known bugs
15
15
  """
16
+
16
17
  import os
17
18
 
18
19
  from fprime.common.models.serialize.array_type import ArrayType
@@ -34,6 +35,7 @@ from fprime.common.models.serialize.serializable_type import SerializableType
34
35
  from fprime.common.models.serialize.string_type import StringType
35
36
  from lxml import etree
36
37
 
38
+ from fprime_gds.common.utils.string_util import preprocess_c_style_format_str
37
39
  from fprime_gds.common.data_types import exceptions
38
40
  from fprime_gds.version import (
39
41
  MAXIMUM_SUPPORTED_FRAMEWORK_VERSION,
@@ -258,18 +260,21 @@ class XmlLoader(dict_loader.DictLoader):
258
260
  members = []
259
261
  for memb in memb_section:
260
262
  name = memb.get(self.SER_MEMB_NAME_TAG)
261
- fmt_str = memb.get(self.SER_MEMB_FMT_STR_TAG)
263
+ fmt_str = XmlLoader.preprocess_format_str(
264
+ memb.get(self.SER_MEMB_FMT_STR_TAG)
265
+ )
262
266
  desc = memb.get(self.SER_MEMB_DESC_TAG)
263
267
  memb_type_name = memb.get(self.SER_MEMB_TYPE_TAG)
264
268
  memb_size = memb.get(self.SER_MEMB_SIZE_TAG)
265
269
  type_obj = self.parse_type(memb_type_name, memb, xml_obj)
266
270
  # memb_size is not None for member array
267
- if(memb_size is not None):
271
+ if memb_size is not None:
268
272
  type_obj = ArrayType.construct_type(
269
273
  f"Array_{type_obj.__name__}_{memb_size}",
270
274
  type_obj,
271
275
  int(memb_size),
272
- fmt_str)
276
+ fmt_str,
277
+ )
273
278
 
274
279
  members.append((name, type_obj, fmt_str, desc))
275
280
 
@@ -319,10 +324,14 @@ class XmlLoader(dict_loader.DictLoader):
319
324
  # Make config
320
325
  arr_type = arr_memb.get(self.ARR_TYPE_TAG)
321
326
  type_obj = self.parse_type(arr_type, arr_memb, xml_obj)
322
- arr_format = arr_memb.get(self.ARR_FORMAT_TAG)
327
+ arr_format = XmlLoader.preprocess_format_str(
328
+ arr_memb.get(self.ARR_FORMAT_TAG)
329
+ )
323
330
  arr_size = arr_memb.get(self.ARR_SIZE_TAG)
324
331
 
325
- arr_obj = ArrayType.construct_type(type_name, type_obj, int(arr_size), arr_format)
332
+ arr_obj = ArrayType.construct_type(
333
+ type_name, type_obj, int(arr_size), arr_format
334
+ )
326
335
 
327
336
  self.array_types[type_name] = arr_obj
328
337
  return arr_obj
@@ -372,7 +381,9 @@ class XmlLoader(dict_loader.DictLoader):
372
381
  return BoolType
373
382
  if type_name == "string":
374
383
  if self.STR_LEN_TAG not in xml_item.attrib:
375
- print(f"Trying to parse string type, but found {self.STR_LEN_TAG} field")
384
+ print(
385
+ f"Trying to parse string type, but found {self.STR_LEN_TAG} field"
386
+ )
376
387
  return None
377
388
  max_length = int(xml_item.get(self.STR_LEN_TAG, 0))
378
389
  name = f"{context or ''}::{xml_item.get(self.ARG_NAME_TAG)}String"
@@ -394,6 +405,17 @@ class XmlLoader(dict_loader.DictLoader):
394
405
 
395
406
  # Abandon all hope
396
407
  msg = f"Could not find type {type_name}"
397
- raise exceptions.GseControllerParsingException(
398
- msg
399
- )
408
+ raise exceptions.GseControllerParsingException(msg)
409
+
410
+ @staticmethod
411
+ def preprocess_format_str(format_str):
412
+ """Converts C-style format strings to Python-style format strings
413
+ For example "%x" -> "{:x}" or "%.2f" -> "{:.2f}"
414
+
415
+ Args:
416
+ format_str (str): C-style format string
417
+
418
+ Returns:
419
+ str: Python-style format string
420
+ """
421
+ return preprocess_c_style_format_str(format_str)
@@ -6,7 +6,9 @@ class called "Dictionaries".
6
6
 
7
7
  @author mstarch
8
8
  """
9
+
9
10
  import os
11
+ from pathlib import Path
10
12
 
11
13
  import fprime_gds.common.loaders.ch_py_loader
12
14
  import fprime_gds.common.loaders.ch_xml_loader
@@ -19,6 +21,9 @@ import fprime_gds.common.loaders.cmd_xml_loader
19
21
  import fprime_gds.common.loaders.event_py_loader
20
22
  import fprime_gds.common.loaders.event_xml_loader
21
23
  import fprime_gds.common.loaders.pkt_xml_loader
24
+ import fprime_gds.common.loaders.ch_json_loader
25
+ import fprime_gds.common.loaders.cmd_json_loader
26
+ import fprime_gds.common.loaders.event_json_loader
22
27
 
23
28
 
24
29
  class Dictionaries:
@@ -80,8 +85,34 @@ class Dictionaries:
80
85
  self._channel_name_dict = channel_loader.get_name_dict(
81
86
  os.path.join(dictionary, "channels")
82
87
  )
88
+ elif Path(dictionary).is_file() and ".json" in Path(dictionary).suffixes:
89
+ # Events
90
+ json_event_loader = (
91
+ fprime_gds.common.loaders.event_json_loader.EventJsonLoader(dictionary)
92
+ )
93
+ self._event_name_dict = json_event_loader.get_name_dict(None)
94
+ self._event_id_dict = json_event_loader.get_id_dict(None)
95
+ self._versions = json_event_loader.get_versions()
96
+ # Commands
97
+ json_command_loader = (
98
+ fprime_gds.common.loaders.cmd_json_loader.CmdJsonLoader(dictionary)
99
+ )
100
+ self._command_name_dict = json_command_loader.get_name_dict(None)
101
+ self._command_id_dict = json_command_loader.get_id_dict(None)
102
+ assert (
103
+ self._versions == json_command_loader.get_versions()
104
+ ), "Version mismatch while loading"
105
+ # Channels
106
+ json_channel_loader = fprime_gds.common.loaders.ch_json_loader.ChJsonLoader(
107
+ dictionary
108
+ )
109
+ self._channel_name_dict = json_channel_loader.get_name_dict(None)
110
+ self._channel_id_dict = json_channel_loader.get_id_dict(None)
111
+ assert (
112
+ self._versions == json_channel_loader.get_versions()
113
+ ), "Version mismatch while loading"
83
114
  # XML dictionaries
84
- elif os.path.isfile(dictionary):
115
+ elif Path(dictionary).is_file():
85
116
  # Events
86
117
  event_loader = fprime_gds.common.loaders.event_xml_loader.EventXmlLoader()
87
118
  self._event_id_dict = event_loader.get_id_dict(dictionary)
@@ -91,12 +122,16 @@ class Dictionaries:
91
122
  command_loader = fprime_gds.common.loaders.cmd_xml_loader.CmdXmlLoader()
92
123
  self._command_id_dict = command_loader.get_id_dict(dictionary)
93
124
  self._command_name_dict = command_loader.get_name_dict(dictionary)
94
- assert self._versions == command_loader.get_versions(), "Version mismatch while loading"
125
+ assert (
126
+ self._versions == command_loader.get_versions()
127
+ ), "Version mismatch while loading"
95
128
  # Channels
96
129
  channel_loader = fprime_gds.common.loaders.ch_xml_loader.ChXmlLoader()
97
130
  self._channel_id_dict = channel_loader.get_id_dict(dictionary)
98
131
  self._channel_name_dict = channel_loader.get_name_dict(dictionary)
99
- assert self._versions == channel_loader.get_versions(), "Version mismatch while loading"
132
+ assert (
133
+ self._versions == channel_loader.get_versions()
134
+ ), "Version mismatch while loading"
100
135
  else:
101
136
  msg = f"[ERROR] Dictionary '{dictionary}' does not exist."
102
137
  raise Exception(msg)
@@ -22,7 +22,7 @@ from fprime.common.models.serialize.time_type import TimeBase, TimeType
22
22
  from fprime_gds.common.data_types import exceptions as gseExceptions
23
23
  from fprime_gds.common.data_types.cmd_data import CmdData, CommandArgumentsException
24
24
  from fprime_gds.common.encoders.seq_writer import SeqBinaryWriter
25
- from fprime_gds.common.loaders.cmd_xml_loader import CmdXmlLoader
25
+ from fprime_gds.common.loaders.cmd_json_loader import CmdJsonLoader
26
26
  from fprime_gds.common.parsers.seq_file_parser import SeqFileParser
27
27
 
28
28
  __author__ = "Tim Canham"
@@ -56,9 +56,9 @@ def generateSequence(inputFile, outputFile, dictionary, timebase, cont=False):
56
56
  raise SeqGenException(msg)
57
57
 
58
58
  # Check the user environment:
59
- cmd_xml_dict = CmdXmlLoader()
59
+ cmd_json_dict = CmdJsonLoader(dictionary)
60
60
  try:
61
- (cmd_id_dict, cmd_name_dict, versions) = cmd_xml_dict.construct_dicts(
61
+ (cmd_id_dict, cmd_name_dict, versions) = cmd_json_dict.construct_dicts(
62
62
  dictionary
63
63
  )
64
64
  except gseExceptions.GseControllerUndefinedFileException:
@@ -153,7 +153,7 @@ def main():
153
153
  action="store",
154
154
  type=str,
155
155
  required=True,
156
- help="Dictionary file name",
156
+ help="JSON Dictionary file name",
157
157
  )
158
158
  parser.add_argument(
159
159
  "-t",
@@ -9,12 +9,51 @@ Note: This function has an identical copy in fprime-gds
9
9
 
10
10
  import logging
11
11
  import re
12
+ from typing import Any, Union
12
13
 
13
14
  LOGGER = logging.getLogger("string_util_logger")
14
15
 
15
16
 
16
- def format_string_template(format_str, given_values):
17
- r"""
17
+ def format_string_template(template: str, value: Union[tuple, list, Any]) -> str:
18
+ """
19
+ Function to format a string template with values. This function is a simple wrapper around the
20
+ format function. It accepts a tuple, list, or single value and passes it to the format function
21
+
22
+ Args:
23
+ template (str): String template to be formatted
24
+ value (Union[tuple, list, Any]): Value(s) to be inserted into the template
25
+
26
+ Returns:
27
+ str: Formatted string
28
+ """
29
+ if not isinstance(value, (tuple, list)):
30
+ value = (value,)
31
+ try:
32
+ return template.format(*value)
33
+ except (IndexError, ValueError) as e:
34
+ LOGGER.error(
35
+ f"Error formatting string template: {template} with value: {str(value)}"
36
+ )
37
+ raise e
38
+
39
+
40
+ def preprocess_fpp_format_str(format_str: str) -> str:
41
+ """Preprocess a FPP-style format string and convert it to Python format string
42
+ FPP format strings are documented https://nasa.github.io/fpp/fpp-spec.html#Format-Strings
43
+ For example "{x}" -> "{:x}" or "{.2f}" -> "{:.2f}"
44
+
45
+ Args:
46
+ format_str (str): FPP-style format string
47
+
48
+ Returns:
49
+ str: Python-style format string
50
+ """
51
+ pattern = r"{(\d*\.?\d*[cdxoefgCDXOEFG])}"
52
+ return re.sub(pattern, r"{:\1}", format_str)
53
+
54
+
55
+ def preprocess_c_style_format_str(format_str: str) -> str:
56
+ """
18
57
  Function to convert C-string style to python format
19
58
  without using python interpolation
20
59
  Considered the following format for C-string:
@@ -31,20 +70,26 @@ def format_string_template(format_str, given_values):
31
70
  This function will keep the flags, width, and .precision of C-string
32
71
  template.
33
72
 
34
- It will keep f, d, x, o, and e flags and remove all other types.
35
- Other types will be duck-typed by python
36
- interpreter.
73
+ It will keep f, x, o, and e flags and remove all other types.
74
+ Other types will be duck-typed by python interpreter.
37
75
 
38
76
  lengths will also be removed since they are not meaningful to Python interpreter.
39
77
  `See: https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting`
40
-
41
78
  `Regex Source: https://www.regexlib.com/REDetails.aspx?regexp_id=3363`
79
+
80
+ For example "%x" -> "{:x}" or "%.2f" -> "{:.2f}"
81
+
82
+ Args:
83
+ format_str (str): C-style format string
84
+
85
+ Returns:
86
+ str: Python-style format string
42
87
  """
43
88
 
44
- def convert(match_obj, ignore_int):
89
+ def convert(match_obj: re.Match):
45
90
  if match_obj.group() is None:
46
91
  return match_obj
47
- flags, width, precision, length, conversion_type = match_obj.groups()
92
+ flags, width, precision, _, conversion_type = match_obj.groups()
48
93
  format_template = ""
49
94
  if flags:
50
95
  format_template += f"{flags}"
@@ -53,66 +98,13 @@ def format_string_template(format_str, given_values):
53
98
  if precision:
54
99
  format_template += f"{precision}"
55
100
 
56
- if conversion_type:
57
- if any(
58
- [
59
- str(conversion_type).lower() == "f",
60
- str(conversion_type).lower() == "x",
61
- str(conversion_type).lower() == "o",
62
- str(conversion_type).lower() == "e",
63
- ]
64
- ):
65
- format_template += f"{conversion_type}"
66
- elif all([not ignore_int, str(conversion_type).lower() == "d"]):
67
- format_template += f"{conversion_type}"
101
+ if conversion_type and str(conversion_type).lower() in {"f", "x", "o", "e"}:
102
+ format_template += f"{conversion_type}"
68
103
 
69
104
  return "{}" if format_template == "" else "{:" + format_template + "}"
70
105
 
71
- def convert_include_all(match_obj):
72
- return convert(match_obj, ignore_int=False)
73
-
74
- def convert_ignore_int(match_obj):
75
- return convert(match_obj, ignore_int=True)
76
-
77
- # Allowing single, list and tuple inputs
78
- if not isinstance(given_values, (list, tuple)):
79
- values = (given_values,)
80
- elif isinstance(given_values, list):
81
- values = tuple(given_values)
82
- else:
83
- values = given_values
84
-
85
- pattern = r"(?<!%)(?:%%)*%([\-\+0\ \#])?(\d+|\*)?(\.\*|\.\d+)?([hLIw]|l{1,2}|I32|I64)?([cCdiouxXeEfgGaAnpsSZ])"
106
+ pattern = r"(?<!%)(?:%%)*%([\-\+0\ \#])?(\d+|\*)?(\.\*|\.\d+)?([hLIw]|l{1,2}|I32|I64)?([cCdiouxXeEfgGaAnpsSZ])" # NOSONAR
86
107
 
87
108
  match = re.compile(pattern)
88
109
 
89
- # First try to include all types
90
- try:
91
- formatted_str = re.sub(match, convert_include_all, format_str)
92
- result = formatted_str.format(*values)
93
- result = result.replace("%%", "%")
94
- return result
95
- except Exception:
96
- msg = "Value and format string do not match. "
97
- msg += " Will ignore integer flags `d` in string template. "
98
- msg += f"values: {values}. "
99
- msg += f"format_str: {format_str}. "
100
- msg += f"given_values: {given_values}"
101
- LOGGER.warning(msg)
102
-
103
- # Second try by not including %d.
104
- # This will resolve failing ENUMs with %d
105
- # but will fail on other types.
106
- try:
107
- formatted_str = re.sub(match, convert_ignore_int, format_str)
108
- result = formatted_str.format(*values)
109
- result = result.replace("%%", "%")
110
- return result
111
- except ValueError as e:
112
- msg = "Value and format string do not match. "
113
- msg += f"values: {values}. "
114
- msg += f"format_str: {format_str}. "
115
- msg += f"given_values: {given_values}"
116
- msg += f"Err Msg: {str(e)}\n"
117
- LOGGER.error(msg)
118
- raise ValueError
110
+ return re.sub(match, convert, format_str).replace("%%", "%")
@@ -130,11 +130,13 @@ class ZmqWrapper(object):
130
130
 
131
131
  def disconnect_outgoing(self):
132
132
  """Disconnect the ZeroMQ sockets"""
133
- self.zmq_socket_outgoing.close()
133
+ if self.zmq_socket_outgoing is not None:
134
+ self.zmq_socket_outgoing.close()
134
135
 
135
136
  def disconnect_incoming(self):
136
137
  """Disconnect the ZeroMQ sockets"""
137
- self.zmq_socket_incoming.close()
138
+ if self.zmq_socket_incoming is not None:
139
+ self.zmq_socket_incoming.close()
138
140
 
139
141
  def terminate(self):
140
142
  """Terminate the ZeroMQ context"""
@@ -31,21 +31,8 @@ from fprime_gds.common.utils.config_manager import ConfigManager
31
31
  from fprime_gds.executables.utils import find_app, find_dict, get_artifacts_root
32
32
  from fprime_gds.plugin.definitions import PluginType
33
33
  from fprime_gds.plugin.system import Plugins
34
+ from fprime_gds.common.zmq_transport import ZmqClient
34
35
 
35
- # Optional import: ZeroMQ. Requires package: pyzmq
36
- try:
37
- import zmq
38
-
39
- from fprime_gds.common.zmq_transport import ZmqClient
40
- except ImportError:
41
- zmq = None
42
- ZmqClient = None
43
-
44
- # Optional import: Serial Adapter. Requires package: SerialAdapter
45
- try:
46
- from fprime_gds.common.communication.adapters.uart import SerialAdapter
47
- except ImportError:
48
- SerialAdapter = None
49
36
 
50
37
  GUIS = ["none", "html"]
51
38
 
@@ -197,7 +184,6 @@ class ParserBase(ABC):
197
184
  sys.exit(-1)
198
185
  except Exception as exc:
199
186
  print(f"[ERROR] {exc}", file=sys.stderr)
200
- raise
201
187
  sys.exit(-1)
202
188
  return args_ns, parser
203
189
 
@@ -578,40 +564,37 @@ class MiddleWareParser(ParserBase):
578
564
 
579
565
  def get_arguments(self) -> Dict[Tuple[str, ...], Dict[str, Any]]:
580
566
  """Return arguments necessary to run a and connect to the GDS middleware"""
581
- # May use ZMQ transportation layer if zmq package is available
582
- zmq_arguments = {}
583
- if zmq is not None and ZmqClient is not None:
584
- zmq_arguments = {
585
- ("--zmq",): {
586
- "dest": "zmq",
587
- "action": "store_true",
588
- "help": "Switch to using the ZMQ transportation layer",
589
- "default": False,
590
- },
591
- ("--zmq-transport",): {
592
- "dest": "zmq_transport",
593
- "nargs": 2,
594
- "help": "Pair of URls used with --zmq to setup ZeroMQ transportation [default: %(default)s]",
595
- "default": [
596
- "ipc:///tmp/fprime-server-in",
597
- "ipc:///tmp/fprime-server-out",
598
- ],
599
- "metavar": ("serverInUrl", "serverOutUrl"),
600
- },
601
- }
567
+ zmq_arguments = {
568
+ ("--no-zmq",): {
569
+ "dest": "zmq",
570
+ "action": "store_false",
571
+ "help": "Disable ZMQ transportation layer, falling back to TCP socket server.",
572
+ "default": True,
573
+ },
574
+ ("--zmq-transport",): {
575
+ "dest": "zmq_transport",
576
+ "nargs": 2,
577
+ "help": "Pair of URls used with --zmq to setup ZeroMQ transportation [default: %(default)s]",
578
+ "default": [
579
+ "ipc:///tmp/fprime-server-in",
580
+ "ipc:///tmp/fprime-server-out",
581
+ ],
582
+ "metavar": ("serverInUrl", "serverOutUrl"),
583
+ },
584
+ }
602
585
  tts_arguments = {
603
586
  ("--tts-port",): {
604
587
  "dest": "tts_port",
605
588
  "action": "store",
606
589
  "type": int,
607
- "help": "Set the threaded TCP socket server port [default: %(default)s]",
590
+ "help": "Set the threaded TCP socket server port when ZMQ is not used [default: %(default)s]",
608
591
  "default": 50050,
609
592
  },
610
593
  ("--tts-addr",): {
611
594
  "dest": "tts_addr",
612
595
  "action": "store",
613
596
  "type": str,
614
- "help": "Set the threaded TCP socket server address [default: %(default)s]",
597
+ "help": "Set the threaded TCP socket server address when ZMQ is not used [default: %(default)s]",
615
598
  "default": "0.0.0.0",
616
599
  },
617
600
  }
@@ -626,7 +609,6 @@ class MiddleWareParser(ParserBase):
626
609
  :return: args namespace
627
610
  """
628
611
  is_client = kwargs.get("client", False)
629
- args.zmq = getattr(args, "zmq", False)
630
612
  tts_connection_address = (
631
613
  args.tts_addr.replace("0.0.0.0", "127.0.0.1")
632
614
  if is_client
@@ -19,20 +19,16 @@ Note: assuming the module containing the ground adapter has been imported, then
19
19
  import logging
20
20
  import signal
21
21
  import sys
22
-
23
22
  from pathlib import Path
24
23
 
25
24
  # Required adapters built on standard tools
26
- try:
27
- from fprime_gds.common.zmq_transport import ZmqGround
28
- except ImportError:
29
- ZmqGround = None
30
25
  import fprime_gds.common.communication.adapters.base
31
26
  import fprime_gds.common.communication.adapters.ip
32
27
  import fprime_gds.common.communication.ground
33
28
  import fprime_gds.common.logger
34
29
  import fprime_gds.executables.cli
35
30
  from fprime_gds.common.communication.updown import Downlinker, Uplinker
31
+ from fprime_gds.common.zmq_transport import ZmqGround
36
32
 
37
33
  # Uses non-standard PIP package pyserial, so test the waters before getting a hard-import crash
38
34
  try:
@@ -68,11 +64,8 @@ def main():
68
64
  sys.exit(-1)
69
65
 
70
66
  # Create the handling components for either side of this script, adapter for hardware, and ground for the GDS side
71
- if args.zmq and ZmqGround is None:
72
- print("[ERROR] ZeroMQ is not available. Install pyzmq.", file=sys.stderr)
73
- sys.exit(-1)
74
- elif args.zmq:
75
- ground = fprime_gds.common.zmq_transport.ZmqGround(args.zmq_transport)
67
+ if args.zmq:
68
+ ground = ZmqGround(args.zmq_transport)
76
69
  else:
77
70
  ground = fprime_gds.common.communication.ground.TCPGround(
78
71
  args.tts_addr, args.tts_port