From 31d39ba4897058de1b032396b365ae08af033ea5 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 19 Mar 2024 12:45:36 -0700 Subject: [PATCH 01/28] loading channels working - minus glutton of choice --- .../common/loaders/ch_json_loader.py | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 src/fprime_gds/common/loaders/ch_json_loader.py diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py new file mode 100644 index 00000000..a92aae01 --- /dev/null +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -0,0 +1,201 @@ +""" +ch_json_loader.py: + +Loads flight dictionary (JSON) and returns id and mnemonic based Python dictionaries + +@author thomas-bc + +""" + +from fprime_gds.common.templates.ch_template import ChTemplate +# from .json_loader import JsonLoader + +from fprime.common.models.serialize.array_type import ArrayType +from fprime.common.models.serialize.type_base import BaseType +from fprime.common.models.serialize.bool_type import BoolType +from fprime.common.models.serialize.enum_type import EnumType +from fprime.common.models.serialize.type_base import DictionaryType +from fprime.common.models.serialize.numerical_types import ( + F32Type, + F64Type, + I8Type, + I16Type, + I32Type, + I64Type, + U8Type, + U16Type, + U32Type, + U64Type, +) +from fprime.common.models.serialize.serializable_type import SerializableType +from fprime.common.models.serialize.string_type import StringType + +import json + + +class ChJsonLoader: + """Class to load python based telemetry channel dictionaries""" + + # Field names in the python module files (used to construct dictionaries) + ID_FIELD = "id" + NAME_FIELD = "name" + KIND_FIELD = "kind" + DESC_FIELD = "description" + TYPE_FIELD = "type" + FMT_STR_FIELD = "format" + LIMIT_FIELD = "limit" + LIMIT_LOW = "low" + LIMIT_HIGH = "high" + LIMIT_RED = "red" + LIMIT_ORANGE = "orange" + LIMIT_YELLOW = "yellow" + + def __init__(self, dict_path: str): + with open(dict_path, "r") as file: + self.json_dict = json.load(file) + + + def construct_dicts(self): + """ + Constructs and returns python dictionaries keyed on id and name + + Args: + path: Path to JSON dictionary file + Returns: + A tuple with two channel dictionaries (python type dict): + (id_dict, name_dict). The keys should be the channels' id and + name fields respectively and the values should be ChTemplate + objects. + """ + id_dict = {} + name_dict = {} + + for ch_dict in self.json_dict["telemetryChannels"]: + # Create a channel template object + ch_temp = self.construct_template_from_dict(ch_dict) + + id_dict[ch_dict[self.ID_FIELD]] = ch_temp + name_dict[ch_dict[self.NAME_FIELD]] = ch_temp + + return dict(sorted(id_dict.items())), dict(sorted(name_dict.items())) + + + def construct_template_from_dict(self, channel_dict: dict): + component_name = channel_dict[self.NAME_FIELD].split(".")[0] + channel_name = channel_dict[self.NAME_FIELD].split(".")[-1] + channel_type = channel_dict.get("type") + if channel_type is None: + print("Hello!") + type_obj = self.parse_type(channel_type) + + limit_field = channel_dict.get(self.LIMIT_FIELD) + limit_low = limit_field.get(self.LIMIT_LOW) if limit_field else None + limit_high = limit_field.get(self.LIMIT_HIGH) if limit_field else None + + limit_low_yellow = limit_low.get(self.LIMIT_YELLOW) if limit_low else None + limit_low_red = limit_low.get(self.LIMIT_RED) if limit_low else None + limit_low_orange = limit_low.get(self.LIMIT_ORANGE) if limit_low else None + + limit_high_yellow = limit_high.get(self.LIMIT_YELLOW) if limit_high else None + limit_high_red = limit_high.get(self.LIMIT_RED) if limit_high else None + limit_high_orange = limit_high.get(self.LIMIT_ORANGE) if limit_high else None + + tmp = ChTemplate( + channel_dict[self.ID_FIELD], + channel_name, + component_name, + type_obj, + ch_fmt_str=channel_dict.get(self.FMT_STR_FIELD), + ch_desc=channel_dict.get(self.DESC_FIELD), + low_red=limit_low_red, + low_orange=limit_low_orange, + low_yellow=limit_low_yellow, + high_yellow=limit_high_yellow, + high_orange=limit_high_orange, + high_red=limit_high_red, + ) + return tmp + + + def parse_type(self, type_dict: dict) -> BaseType: + + type_name: str = type_dict.get(ChJsonLoader.NAME_FIELD, None) + + if type_name is None: + raise ValueError( + f"Channel entry in dictionary has no `name` field" + ) + + if type_name == "I8": + return I8Type + if type_name == "I16": + return I16Type + if type_name == "I32": + return I32Type + if type_name == "I64": + return I64Type + if type_name == "U8": + return U8Type + if type_name == "U16": + return U16Type + if type_name == "U32": + return U32Type + if type_name == "U64": + return U64Type + if type_name == "F32": + return F32Type + if type_name == "F64": + return F64Type + if type_name == "bool": + return BoolType + + if type_name == "string": + return StringType.construct_type( + type_dict.get(ChJsonLoader.NAME_FIELD), type_dict.get("size") + ) + + # Process for enum/array/serializable types + qualified_type = None + for type_def in self.json_dict.get("typeDefinitions", []): + if type_name == type_def.get("qualifiedName"): + qualified_type = type_def + break + + if qualified_type is None: + # TODO: There's an issue here with PacketTypes not being in dictionary??? + return DictionaryType.construct_type(SerializableType, type_name) + # raise ValueError( + # f"Channel entry in dictionary has no corresponding type definition." + # ) + + if qualified_type.get("kind") == "array": + return ArrayType.construct_type( + type_name, + self.parse_type(qualified_type.get("elementType")), + qualified_type.get("size"), + qualified_type.get("format", "%s"), + ) + + if qualified_type.get("kind") == "enum": + return EnumType.construct_type( + type_name, + qualified_type.get("identifiers"), + qualified_type.get("representationType").get("name"), + # self.parse_type(qualified_type.get("representationType")), + ) + + if qualified_type.get("kind") == "struct": + struct_member_list = [ + ( + name, + self.parse_type(member_dict.get("type")), + member_dict.get("type", {}).get("format", "%s"), + member_dict.get("type", {}).get("description", ""), + ) + for name, member_dict in qualified_type.get("members", {}).items() + ] + return SerializableType.construct_type( + type_name, + struct_member_list, + ) + From 2054755a8fa57e0b14ab8fa2e5e3685ec3dd3512 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 19 Mar 2024 13:47:28 -0700 Subject: [PATCH 02/28] Handle struct member arrays (inline) --- .../common/loaders/ch_json_loader.py | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index a92aae01..2464895f 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -181,21 +181,29 @@ def parse_type(self, type_dict: dict) -> BaseType: type_name, qualified_type.get("identifiers"), qualified_type.get("representationType").get("name"), - # self.parse_type(qualified_type.get("representationType")), ) if qualified_type.get("kind") == "struct": - struct_member_list = [ - ( - name, - self.parse_type(member_dict.get("type")), - member_dict.get("type", {}).get("format", "%s"), - member_dict.get("type", {}).get("description", ""), - ) - for name, member_dict in qualified_type.get("members", {}).items() - ] + struct_members = [] + for name, member_dict in qualified_type.get("members").items(): + member_type_dict = member_dict.get("type") + member_type_obj = self.parse_type(member_type_dict) + + # For member arrays (declared inline, so we create a type on the fly) + if member_dict.get("size") is not None: + member_type_obj = ArrayType.construct_type( + f"Array_{member_type_obj.__name__}_{member_dict.get('size')}", + member_type_obj, + member_dict.get("size"), + member_dict.get("type").get("format", "%s"), + ) + + fmt_str = member_type_dict.get("format", "%s") + description = member_type_dict.get("description", "") + struct_members.append((name, member_type_obj, fmt_str, description)) + return SerializableType.construct_type( type_name, - struct_member_list, + struct_members, ) From ff45a01fb2bf38993c9ee1358e9a7ab26e7d5ab5 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Thu, 21 Mar 2024 11:47:26 -0700 Subject: [PATCH 03/28] Add JsonLoader base type --- .../common/loaders/ch_json_loader.py | 217 ++++++++---------- src/fprime_gds/common/loaders/json_loader.py | 187 +++++++++++++++ 2 files changed, 286 insertions(+), 118 deletions(-) create mode 100644 src/fprime_gds/common/loaders/json_loader.py diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index 2464895f..bf2e9a09 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -8,32 +8,13 @@ """ from fprime_gds.common.templates.ch_template import ChTemplate -# from .json_loader import JsonLoader - -from fprime.common.models.serialize.array_type import ArrayType -from fprime.common.models.serialize.type_base import BaseType -from fprime.common.models.serialize.bool_type import BoolType -from fprime.common.models.serialize.enum_type import EnumType -from fprime.common.models.serialize.type_base import DictionaryType -from fprime.common.models.serialize.numerical_types import ( - F32Type, - F64Type, - I8Type, - I16Type, - I32Type, - I64Type, - U8Type, - U16Type, - U32Type, - U64Type, -) -from fprime.common.models.serialize.serializable_type import SerializableType -from fprime.common.models.serialize.string_type import StringType +from fprime_gds.common.loaders.json_loader import JsonLoader + import json -class ChJsonLoader: +class ChJsonLoader(JsonLoader): """Class to load python based telemetry channel dictionaries""" # Field names in the python module files (used to construct dictionaries) @@ -51,11 +32,10 @@ class ChJsonLoader: LIMIT_YELLOW = "yellow" def __init__(self, dict_path: str): - with open(dict_path, "r") as file: - self.json_dict = json.load(file) + super().__init__(dict_path) - def construct_dicts(self): + def construct_dicts(self, dict_path: str): """ Constructs and returns python dictionaries keyed on id and name @@ -70,22 +50,23 @@ def construct_dicts(self): id_dict = {} name_dict = {} - for ch_dict in self.json_dict["telemetryChannels"]: + with open(dict_path, "r") as file: + json_dict = json.load(file) + + for ch_dict in json_dict["telemetryChannels"]: # Create a channel template object ch_temp = self.construct_template_from_dict(ch_dict) id_dict[ch_dict[self.ID_FIELD]] = ch_temp name_dict[ch_dict[self.NAME_FIELD]] = ch_temp - return dict(sorted(id_dict.items())), dict(sorted(name_dict.items())) + return dict(sorted(id_dict.items())), dict(sorted(name_dict.items())), ("unknown", "unknown") def construct_template_from_dict(self, channel_dict: dict): component_name = channel_dict[self.NAME_FIELD].split(".")[0] channel_name = channel_dict[self.NAME_FIELD].split(".")[-1] channel_type = channel_dict.get("type") - if channel_type is None: - print("Hello!") type_obj = self.parse_type(channel_type) limit_field = channel_dict.get(self.LIMIT_FIELD) @@ -117,93 +98,93 @@ def construct_template_from_dict(self, channel_dict: dict): return tmp - def parse_type(self, type_dict: dict) -> BaseType: - - type_name: str = type_dict.get(ChJsonLoader.NAME_FIELD, None) - - if type_name is None: - raise ValueError( - f"Channel entry in dictionary has no `name` field" - ) - - if type_name == "I8": - return I8Type - if type_name == "I16": - return I16Type - if type_name == "I32": - return I32Type - if type_name == "I64": - return I64Type - if type_name == "U8": - return U8Type - if type_name == "U16": - return U16Type - if type_name == "U32": - return U32Type - if type_name == "U64": - return U64Type - if type_name == "F32": - return F32Type - if type_name == "F64": - return F64Type - if type_name == "bool": - return BoolType - - if type_name == "string": - return StringType.construct_type( - type_dict.get(ChJsonLoader.NAME_FIELD), type_dict.get("size") - ) - - # Process for enum/array/serializable types - qualified_type = None - for type_def in self.json_dict.get("typeDefinitions", []): - if type_name == type_def.get("qualifiedName"): - qualified_type = type_def - break - - if qualified_type is None: - # TODO: There's an issue here with PacketTypes not being in dictionary??? - return DictionaryType.construct_type(SerializableType, type_name) - # raise ValueError( - # f"Channel entry in dictionary has no corresponding type definition." - # ) - - if qualified_type.get("kind") == "array": - return ArrayType.construct_type( - type_name, - self.parse_type(qualified_type.get("elementType")), - qualified_type.get("size"), - qualified_type.get("format", "%s"), - ) - - if qualified_type.get("kind") == "enum": - return EnumType.construct_type( - type_name, - qualified_type.get("identifiers"), - qualified_type.get("representationType").get("name"), - ) - - if qualified_type.get("kind") == "struct": - struct_members = [] - for name, member_dict in qualified_type.get("members").items(): - member_type_dict = member_dict.get("type") - member_type_obj = self.parse_type(member_type_dict) - - # For member arrays (declared inline, so we create a type on the fly) - if member_dict.get("size") is not None: - member_type_obj = ArrayType.construct_type( - f"Array_{member_type_obj.__name__}_{member_dict.get('size')}", - member_type_obj, - member_dict.get("size"), - member_dict.get("type").get("format", "%s"), - ) - - fmt_str = member_type_dict.get("format", "%s") - description = member_type_dict.get("description", "") - struct_members.append((name, member_type_obj, fmt_str, description)) - - return SerializableType.construct_type( - type_name, - struct_members, - ) + # def parse_type(self, type_dict: dict) -> BaseType: + + # type_name: str = type_dict.get(ChJsonLoader.NAME_FIELD, None) + + # if type_name is None: + # raise ValueError( + # f"Channel entry in dictionary has no `name` field" + # ) + + # if type_name == "I8": + # return I8Type + # if type_name == "I16": + # return I16Type + # if type_name == "I32": + # return I32Type + # if type_name == "I64": + # return I64Type + # if type_name == "U8": + # return U8Type + # if type_name == "U16": + # return U16Type + # if type_name == "U32": + # return U32Type + # if type_name == "U64": + # return U64Type + # if type_name == "F32": + # return F32Type + # if type_name == "F64": + # return F64Type + # if type_name == "bool": + # return BoolType + + # if type_name == "string": + # return StringType.construct_type( + # type_dict.get(ChJsonLoader.NAME_FIELD), type_dict.get("size") + # ) + + # # Process for enum/array/serializable types + # qualified_type = None + # for type_def in self.json_dict.get("typeDefinitions", []): + # if type_name == type_def.get("qualifiedName"): + # qualified_type = type_def + # break + + # if qualified_type is None: + # # TODO: There's an issue here with PacketTypes not being in dictionary??? + # return DictionaryType.construct_type(SerializableType, type_name) + # # raise ValueError( + # # f"Channel entry in dictionary has no corresponding type definition." + # # ) + + # if qualified_type.get("kind") == "array": + # return ArrayType.construct_type( + # type_name, + # self.parse_type(qualified_type.get("elementType")), + # qualified_type.get("size"), + # qualified_type.get("format", "%s"), + # ) + + # if qualified_type.get("kind") == "enum": + # return EnumType.construct_type( + # type_name, + # qualified_type.get("identifiers"), + # qualified_type.get("representationType").get("name"), + # ) + + # if qualified_type.get("kind") == "struct": + # struct_members = [] + # for name, member_dict in qualified_type.get("members").items(): + # member_type_dict = member_dict.get("type") + # member_type_obj = self.parse_type(member_type_dict) + + # # For member arrays (declared inline, so we create a type on the fly) + # if member_dict.get("size") is not None: + # member_type_obj = ArrayType.construct_type( + # f"Array_{member_type_obj.__name__}_{member_dict.get('size')}", + # member_type_obj, + # member_dict.get("size"), + # member_dict.get("type").get("format", "%s"), + # ) + + # fmt_str = member_type_dict.get("format", "%s") + # description = member_type_dict.get("description", "") + # struct_members.append((name, member_type_obj, fmt_str, description)) + + # return SerializableType.construct_type( + # type_name, + # struct_members, + # ) diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py new file mode 100644 index 00000000..546cbb67 --- /dev/null +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -0,0 +1,187 @@ +""" +json_loader.py: + +Base class for all loaders that load dictionaries from json dictionaries + +@author thomas-bc +""" +from fprime.common.models.serialize.array_type import ArrayType +from fprime.common.models.serialize.bool_type import BoolType +from fprime.common.models.serialize.enum_type import EnumType +from fprime.common.models.serialize.numerical_types import ( + F32Type, + F64Type, + I8Type, + I16Type, + I32Type, + I64Type, + U8Type, + U16Type, + U32Type, + U64Type, +) +from fprime.common.models.serialize.serializable_type import SerializableType +from fprime.common.models.serialize.string_type import StringType +from fprime.common.models.serialize.type_base import DictionaryType, BaseType +from fprime_gds.version import ( + MAXIMUM_SUPPORTED_FRAMEWORK_VERSION, + MINIMUM_SUPPORTED_FRAMEWORK_VERSION, +) + +# Custom Python Modules +from . import dict_loader +import json + +FORMAT_STR_MAP = { + "U8": "%u", + "I8": "%d", + "U16": "%u", + "I16": "%d", + "U32": "%u", + "I32": "%d", + "U64": "%lu", + "I64": "%ld", + "F32": "%g", + "F64": "%g", + "bool": "%s", + "string": "%s", + "ENUM": "%d", +} + +class JsonLoader(dict_loader.DictLoader): + """Class to help load JSON dictionaries""" + + def __init__(self, json_dict: dict): + """ + Constructor + + Returns: + An initialized loader object + """ + super().__init__() + + # These dicts hold already parsed enum objects so things don't need + # to be parsed multiple times + self.enums = {} + self.serializable_types = {} + self.array_types = {} + with open(json_dict, "r") as f: + self.json_dict = json.load(f) + + + def parse_type(self, type_dict: dict) -> BaseType: + + type_name: str = type_dict.get("name", None) + + if type_name is None: + raise ValueError( + "Channel entry in dictionary has no `name` field" + ) + + + match type_name: + case "I8": + return I8Type + case "I16": + return I16Type + case "I32": + return I32Type + case "I64": + return I64Type + case "U8": + return U8Type + case "U16": + return U16Type + case "U32": + return U32Type + case "U64": + return U64Type + case "F32": + return F32Type + case "F64": + return F64Type + case "bool": + return BoolType + case "string": + return StringType.construct_type( + type_dict.get("name"), type_dict.get("size") + ) + + # Process for enum/array/serializable types + qualified_type = None + for type_def in self.json_dict.get("typeDefinitions", []): + if type_name == type_def.get("qualifiedName"): + qualified_type = type_def + break + + if qualified_type is None: + # TODO: There's an issue here with PacketTypes not being in dictionary??? + return DictionaryType.construct_type(SerializableType, type_name) + # raise ValueError( + # f"Channel entry in dictionary has no corresponding type definition." + # ) + + if qualified_type.get("kind") == "array": + return ArrayType.construct_type( + type_name, + self.parse_type(qualified_type.get("elementType")), + qualified_type.get("size"), + self.get_format_string(qualified_type.get("elementType")), + ) + + if qualified_type.get("kind") == "enum": + return EnumType.construct_type( + type_name, + qualified_type.get("identifiers"), + qualified_type.get("representationType").get("name"), + ) + + if qualified_type.get("kind") == "struct": + struct_members = [] + for name, member_dict in qualified_type.get("members").items(): + member_type_dict = member_dict.get("type") + member_type_obj = self.parse_type(member_type_dict) + + # For member arrays (declared inline, so we create a type on the fly) + if member_dict.get("size") is not None: + member_type_obj = ArrayType.construct_type( + f"Array_{member_type_obj.__name__}_{member_dict.get('size')}", + member_type_obj, + member_dict.get("size"), + self.get_format_string(member_dict.get("type")), + ) + + fmt_str = self.get_format_string_obj(member_type_obj) + description = member_type_dict.get("description", "") + struct_members.append((name, member_type_obj, fmt_str, description)) + + return SerializableType.construct_type( + type_name, + struct_members, + ) + + def get_format_string(self, type_dict: dict) -> str | None: + + #probably useless + if type_dict.get("format") is not None: + return type_dict.get("format") + + type_name = type_dict.get("name") + if type_name in FORMAT_STR_MAP: + return FORMAT_STR_MAP[type_name] + + return "%s" + + def get_format_string_obj(self, type_obj: BaseType) -> str | None: + + # needs a lot of rework + if hasattr(type_obj, "FORMAT"): + return type_obj.FORMAT + + if hasattr(type_obj, "REP_TYPE"): + type_name = type_obj.REP_TYPE + if type_name in FORMAT_STR_MAP: + return FORMAT_STR_MAP[type_name] + + # Why? idk + return "%s" \ No newline at end of file From 1c758fd20da76d30c8f98332c5d657e0e2a8e4f9 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Thu, 21 Mar 2024 14:48:31 -0700 Subject: [PATCH 04/28] working MVP for all cmd/channels/events --- .../common/loaders/ch_json_loader.py | 11 +-- .../common/loaders/cmd_json_loader.py | 60 +++++++++++ .../common/loaders/event_json_loader.py | 99 +++++++++++++++++++ src/fprime_gds/common/loaders/json_loader.py | 16 ++- .../common/pipeline/dictionaries.py | 34 ++++++- 5 files changed, 209 insertions(+), 11 deletions(-) create mode 100644 src/fprime_gds/common/loaders/cmd_json_loader.py create mode 100644 src/fprime_gds/common/loaders/event_json_loader.py diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index bf2e9a09..d3f1cc3b 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -1,19 +1,15 @@ """ ch_json_loader.py: -Loads flight dictionary (JSON) and returns id and mnemonic based Python dictionaries +Loads flight dictionary (JSON) and returns id and mnemonic based Python dictionaries of channels @author thomas-bc - """ from fprime_gds.common.templates.ch_template import ChTemplate from fprime_gds.common.loaders.json_loader import JsonLoader -import json - - class ChJsonLoader(JsonLoader): """Class to load python based telemetry channel dictionaries""" @@ -50,10 +46,7 @@ def construct_dicts(self, dict_path: str): id_dict = {} name_dict = {} - with open(dict_path, "r") as file: - json_dict = json.load(file) - - for ch_dict in json_dict["telemetryChannels"]: + for ch_dict in self.json_dict["telemetryChannels"]: # Create a channel template object ch_temp = self.construct_template_from_dict(ch_dict) diff --git a/src/fprime_gds/common/loaders/cmd_json_loader.py b/src/fprime_gds/common/loaders/cmd_json_loader.py new file mode 100644 index 00000000..dc933d9c --- /dev/null +++ b/src/fprime_gds/common/loaders/cmd_json_loader.py @@ -0,0 +1,60 @@ +""" +cmd_json_loader.py: + +Loads flight dictionary (JSON) and returns id and mnemonic based Python dictionaries of commands + +@author thomas-bc +""" + +from fprime_gds.common.templates.cmd_template import CmdTemplate +from fprime_gds.common.loaders.json_loader import JsonLoader + + +class CmdJsonLoader(JsonLoader): + """Class to load xml based command dictionaries""" + + MNEMONIC_TAG = "name" + OPCODE_TAG = "opcode" + DESC_TAG = "description" + PARAMETERS_TAG = "formalParams" + + def __init__(self, dict_path: str): + super().__init__(dict_path) + + + def construct_dicts(self, path): + """ + Constructs and returns python dictionaries keyed on id and name + + Args: + path: Path to JSON dictionary file + Returns: + A tuple with two command dictionaries (python type dict): + (id_dict, name_dict). The keys are the events' id and name fields + respectively and the values are CmdTemplate objects + """ + + id_dict = {} + name_dict = {} + + for cmd_dict in self.json_dict["commands"]: + cmd_name = cmd_dict.get("name") + + cmd_comp = cmd_name.split(".")[0] + cmd_mnemonic = cmd_name.split(".")[1] + + cmd_opcode = cmd_dict.get("opcode") + + cmd_desc = cmd_dict.get("description") + + # Parse Arguments + cmd_args = [] + for arg in cmd_dict.get("formalParams", []): + cmd_args.append((arg.get("name"), arg.get("description"), self.parse_type(arg.get("type")))) + + cmd_temp = CmdTemplate(cmd_opcode, cmd_mnemonic, cmd_comp, cmd_args, cmd_desc) + + id_dict[cmd_opcode] = cmd_temp + name_dict[cmd_temp.get_full_name()] = cmd_temp + + return id_dict, name_dict, ("unknown", "unknown") diff --git a/src/fprime_gds/common/loaders/event_json_loader.py b/src/fprime_gds/common/loaders/event_json_loader.py new file mode 100644 index 00000000..ab0ba4e7 --- /dev/null +++ b/src/fprime_gds/common/loaders/event_json_loader.py @@ -0,0 +1,99 @@ +""" +event_json_loader.py: + +Loads flight dictionary (JSON) and returns id and mnemonic based Python dictionaries of events + +@author thomas-bc +""" + +from fprime_gds.common.data_types import exceptions +from fprime_gds.common.templates.event_template import EventTemplate +from fprime_gds.common.utils.event_severity import EventSeverity + +# Custom Python Modules +from fprime_gds.common.loaders.json_loader import JsonLoader + + +class EventJsonLoader(JsonLoader): + """Class to load xml based event dictionaries""" + + EVENT_SECT = "events" + + COMP_TAG = "component" + NAME_TAG = "name" + ID_TAG = "id" + SEVERITY_TAG = "severity" + FMT_STR_TAG = "format" + DESC_TAG = "description" + + def construct_dicts(self, path): + """ + Constructs and returns python dictionaries keyed on id and name + + This function should not be called directly, instead, use + get_id_dict(path) and get_name_dict(path) + + Args: + path: Path to the xml dictionary file containing event information + + Returns: + A tuple with two event dictionaries (python type dict): + (id_idct, name_dict). The keys are the events' id and name fields + respectively and the values are ChTemplate objects + """ + versions = self.get_versions() + + # Check if xml dict has events section + if self.json_dict.get("events") is None: + msg = "JSON dict did not have a events section" + raise exceptions.GseControllerParsingException( + msg + ) + + id_dict = {} + name_dict = {} + + # Needed cause names LOW/HIGH are really LO/HI + severity_map = { + "COMMAND": "COMMAND", + "ACTIVITY_LOW": "ACTIVITY_LO", + "ACTIVITY_HIGH": "ACTIVITY_HI", + "WARNING_LOW": "WARNING_LO", + "WARNING_HIGH": "WARNING_HI", + "DIAGNOSTIC": "DIAGNOSTIC", + "FATAL": "FATAL", + + } + + for event_dict in self.json_dict.get("events"): + event_mnemonic = event_dict.get("name") + event_comp = event_mnemonic.split(".")[0] + event_name = event_mnemonic.split(".")[1] + + event_id = event_dict[self.ID_TAG] + event_severity = EventSeverity[severity_map[event_dict[self.SEVERITY_TAG]]] + + event_fmt_str = event_dict.get(self.FMT_STR_TAG, "") + + event_desc = event_dict.get(self.DESC_TAG) + + # Parse arguments + event_args = [] + for arg in event_dict.get("formalParams", []): + event_args.append((arg.get("name"), arg.get("description"), self.parse_type(arg.get("type")))) + + + event_temp = EventTemplate( + event_id, + event_name, + event_comp, + event_args, + event_severity, + event_fmt_str, + event_desc, + ) + + id_dict[event_id] = event_temp + name_dict[event_temp.get_full_name()] = event_temp + + return id_dict, name_dict, versions diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index 546cbb67..67b831b1 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -68,6 +68,18 @@ def __init__(self, json_dict: dict): with open(json_dict, "r") as f: self.json_dict = json.load(f) + def get_versions(self) -> tuple[str, str]: + """ + Get the framework and project versions of the dictionary + + Returns: + A tuple of the framework and project versions + """ + return ( + self.json_dict.get("framework_version", "unknown"), + self.json_dict.get("project_version", "unknown"), + ) + def parse_type(self, type_dict: dict) -> BaseType: @@ -103,8 +115,9 @@ def parse_type(self, type_dict: dict) -> BaseType: case "bool": return BoolType case "string": + # Does this break the logic of checking for original arguments? return StringType.construct_type( - type_dict.get("name"), type_dict.get("size") + f'String_{type_dict.get("size")}', type_dict.get("size") ) # Process for enum/array/serializable types @@ -170,6 +183,7 @@ def get_format_string(self, type_dict: dict) -> str | None: if type_name in FORMAT_STR_MAP: return FORMAT_STR_MAP[type_name] + # idk either return "%s" def get_format_string_obj(self, type_obj: BaseType) -> str | None: diff --git a/src/fprime_gds/common/pipeline/dictionaries.py b/src/fprime_gds/common/pipeline/dictionaries.py index 548445ef..d2e3b0fe 100644 --- a/src/fprime_gds/common/pipeline/dictionaries.py +++ b/src/fprime_gds/common/pipeline/dictionaries.py @@ -19,6 +19,9 @@ class called "Dictionaries". import fprime_gds.common.loaders.event_py_loader import fprime_gds.common.loaders.event_xml_loader import fprime_gds.common.loaders.pkt_xml_loader +import fprime_gds.common.loaders.ch_json_loader +import fprime_gds.common.loaders.cmd_json_loader +import fprime_gds.common.loaders.event_json_loader class Dictionaries: @@ -80,23 +83,52 @@ def load_dictionaries(self, dictionary, packet_spec): self._channel_name_dict = channel_loader.get_name_dict( os.path.join(dictionary, "channels") ) + # TODO: rework with Pathlib + elif os.path.isfile(dictionary) and ".json" in str(dictionary): + # Events + json_event_loader = fprime_gds.common.loaders.event_json_loader.EventJsonLoader(dictionary) + self._event_name_dict = json_event_loader.get_name_dict(None) + self._event_id_dict = json_event_loader.get_id_dict(None) + self._versions = json_event_loader.get_versions() + # Commands + json_command_loader = fprime_gds.common.loaders.cmd_json_loader.CmdJsonLoader(dictionary) + self._command_name_dict = json_command_loader.get_name_dict(None) + self._command_id_dict = json_command_loader.get_id_dict(None) + assert self._versions == json_command_loader.get_versions(), "Version mismatch while loading" + # Channels + json_channel_loader = fprime_gds.common.loaders.ch_json_loader.ChJsonLoader(dictionary) + self._channel_name_dict = json_channel_loader.get_name_dict(None) + self._channel_id_dict = json_channel_loader.get_id_dict(None) + assert self._versions == json_channel_loader.get_versions(), "Version mismatch while loading" # XML dictionaries elif os.path.isfile(dictionary): # Events event_loader = fprime_gds.common.loaders.event_xml_loader.EventXmlLoader() self._event_id_dict = event_loader.get_id_dict(dictionary) - self._event_name_dict = event_loader.get_name_dict(dictionary) + self._event_name_dict = event_loader.get_name_dict(dictionary) self._versions = event_loader.get_versions() + # if os.path.isfile(ref_json_dict) and True: + # json_event_loader = fprime_gds.common.loaders.event_json_loader.EventJsonLoader(ref_json_dict) + # self._event_name_dict = json_event_loader.get_name_dict(None) + # self._event_id_dict = json_event_loader.get_id_dict(None) # Commands command_loader = fprime_gds.common.loaders.cmd_xml_loader.CmdXmlLoader() self._command_id_dict = command_loader.get_id_dict(dictionary) self._command_name_dict = command_loader.get_name_dict(dictionary) assert self._versions == command_loader.get_versions(), "Version mismatch while loading" + # if os.path.isfile(ref_json_dict) and True: + # json_command_loader = fprime_gds.common.loaders.cmd_json_loader.CmdJsonLoader(ref_json_dict) + # self._command_name_dict = json_command_loader.get_name_dict(None) + # self._command_id_dict = json_command_loader.get_id_dict(None) # Channels channel_loader = fprime_gds.common.loaders.ch_xml_loader.ChXmlLoader() self._channel_id_dict = channel_loader.get_id_dict(dictionary) self._channel_name_dict = channel_loader.get_name_dict(dictionary) assert self._versions == channel_loader.get_versions(), "Version mismatch while loading" + # if os.path.isfile(ref_json_dict) and True: + # json_channel_loader = fprime_gds.common.loaders.ch_json_loader.ChJsonLoader(ref_json_dict) + # self._channel_name_dict = json_channel_loader.get_name_dict(None) + # self._channel_id_dict = json_channel_loader.get_id_dict(None) else: msg = f"[ERROR] Dictionary '{dictionary}' does not exist." raise Exception(msg) From 63fa9095c6c9b7e851ef8fed99a331a3f5a10383 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Mon, 25 Mar 2024 09:49:58 -0700 Subject: [PATCH 05/28] Remove commented out code --- .../common/loaders/ch_json_loader.py | 97 +------------------ 1 file changed, 2 insertions(+), 95 deletions(-) diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index d3f1cc3b..45e06dad 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -58,7 +58,7 @@ def construct_dicts(self, dict_path: str): def construct_template_from_dict(self, channel_dict: dict): component_name = channel_dict[self.NAME_FIELD].split(".")[0] - channel_name = channel_dict[self.NAME_FIELD].split(".")[-1] + channel_name = channel_dict[self.NAME_FIELD].split(".")[1] channel_type = channel_dict.get("type") type_obj = self.parse_type(channel_type) @@ -74,7 +74,7 @@ def construct_template_from_dict(self, channel_dict: dict): limit_high_red = limit_high.get(self.LIMIT_RED) if limit_high else None limit_high_orange = limit_high.get(self.LIMIT_ORANGE) if limit_high else None - tmp = ChTemplate( + return ChTemplate( channel_dict[self.ID_FIELD], channel_name, component_name, @@ -88,96 +88,3 @@ def construct_template_from_dict(self, channel_dict: dict): high_orange=limit_high_orange, high_red=limit_high_red, ) - return tmp - - - # def parse_type(self, type_dict: dict) -> BaseType: - - # type_name: str = type_dict.get(ChJsonLoader.NAME_FIELD, None) - - # if type_name is None: - # raise ValueError( - # f"Channel entry in dictionary has no `name` field" - # ) - - # if type_name == "I8": - # return I8Type - # if type_name == "I16": - # return I16Type - # if type_name == "I32": - # return I32Type - # if type_name == "I64": - # return I64Type - # if type_name == "U8": - # return U8Type - # if type_name == "U16": - # return U16Type - # if type_name == "U32": - # return U32Type - # if type_name == "U64": - # return U64Type - # if type_name == "F32": - # return F32Type - # if type_name == "F64": - # return F64Type - # if type_name == "bool": - # return BoolType - - # if type_name == "string": - # return StringType.construct_type( - # type_dict.get(ChJsonLoader.NAME_FIELD), type_dict.get("size") - # ) - - # # Process for enum/array/serializable types - # qualified_type = None - # for type_def in self.json_dict.get("typeDefinitions", []): - # if type_name == type_def.get("qualifiedName"): - # qualified_type = type_def - # break - - # if qualified_type is None: - # # TODO: There's an issue here with PacketTypes not being in dictionary??? - # return DictionaryType.construct_type(SerializableType, type_name) - # # raise ValueError( - # # f"Channel entry in dictionary has no corresponding type definition." - # # ) - - # if qualified_type.get("kind") == "array": - # return ArrayType.construct_type( - # type_name, - # self.parse_type(qualified_type.get("elementType")), - # qualified_type.get("size"), - # qualified_type.get("format", "%s"), - # ) - - # if qualified_type.get("kind") == "enum": - # return EnumType.construct_type( - # type_name, - # qualified_type.get("identifiers"), - # qualified_type.get("representationType").get("name"), - # ) - - # if qualified_type.get("kind") == "struct": - # struct_members = [] - # for name, member_dict in qualified_type.get("members").items(): - # member_type_dict = member_dict.get("type") - # member_type_obj = self.parse_type(member_type_dict) - - # # For member arrays (declared inline, so we create a type on the fly) - # if member_dict.get("size") is not None: - # member_type_obj = ArrayType.construct_type( - # f"Array_{member_type_obj.__name__}_{member_dict.get('size')}", - # member_type_obj, - # member_dict.get("size"), - # member_dict.get("type").get("format", "%s"), - # ) - - # fmt_str = member_type_dict.get("format", "%s") - # description = member_type_dict.get("description", "") - # struct_members.append((name, member_type_obj, fmt_str, description)) - - # return SerializableType.construct_type( - # type_name, - # struct_members, - # ) - From 47719a9e7482c3738638db5bca7927cd3b4cfbcd Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Mon, 15 Apr 2024 19:04:12 -0700 Subject: [PATCH 06/28] Update for latest JSON format --- .../common/loaders/ch_json_loader.py | 2 +- .../common/loaders/cmd_json_loader.py | 6 +++--- .../common/loaders/event_json_loader.py | 18 +++--------------- src/fprime_gds/common/loaders/json_loader.py | 18 +++++++++++------- src/fprime_gds/common/pipeline/dictionaries.py | 18 +++--------------- 5 files changed, 21 insertions(+), 41 deletions(-) diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index 45e06dad..999b4a08 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -17,7 +17,7 @@ class ChJsonLoader(JsonLoader): ID_FIELD = "id" NAME_FIELD = "name" KIND_FIELD = "kind" - DESC_FIELD = "description" + DESC_FIELD = "annotation" TYPE_FIELD = "type" FMT_STR_FIELD = "format" LIMIT_FIELD = "limit" diff --git a/src/fprime_gds/common/loaders/cmd_json_loader.py b/src/fprime_gds/common/loaders/cmd_json_loader.py index dc933d9c..e5e0e5e0 100644 --- a/src/fprime_gds/common/loaders/cmd_json_loader.py +++ b/src/fprime_gds/common/loaders/cmd_json_loader.py @@ -15,7 +15,7 @@ class CmdJsonLoader(JsonLoader): MNEMONIC_TAG = "name" OPCODE_TAG = "opcode" - DESC_TAG = "description" + DESC_TAG = "annotation" PARAMETERS_TAG = "formalParams" def __init__(self, dict_path: str): @@ -45,12 +45,12 @@ def construct_dicts(self, path): cmd_opcode = cmd_dict.get("opcode") - cmd_desc = cmd_dict.get("description") + cmd_desc = cmd_dict.get("annotation") # Parse Arguments cmd_args = [] for arg in cmd_dict.get("formalParams", []): - cmd_args.append((arg.get("name"), arg.get("description"), self.parse_type(arg.get("type")))) + cmd_args.append((arg.get("name"), arg.get("annotation"), self.parse_type(arg.get("type")))) cmd_temp = CmdTemplate(cmd_opcode, cmd_mnemonic, cmd_comp, cmd_args, cmd_desc) diff --git a/src/fprime_gds/common/loaders/event_json_loader.py b/src/fprime_gds/common/loaders/event_json_loader.py index ab0ba4e7..66116eee 100644 --- a/src/fprime_gds/common/loaders/event_json_loader.py +++ b/src/fprime_gds/common/loaders/event_json_loader.py @@ -24,7 +24,7 @@ class EventJsonLoader(JsonLoader): ID_TAG = "id" SEVERITY_TAG = "severity" FMT_STR_TAG = "format" - DESC_TAG = "description" + DESC_TAG = "annotation" def construct_dicts(self, path): """ @@ -53,25 +53,13 @@ def construct_dicts(self, path): id_dict = {} name_dict = {} - # Needed cause names LOW/HIGH are really LO/HI - severity_map = { - "COMMAND": "COMMAND", - "ACTIVITY_LOW": "ACTIVITY_LO", - "ACTIVITY_HIGH": "ACTIVITY_HI", - "WARNING_LOW": "WARNING_LO", - "WARNING_HIGH": "WARNING_HI", - "DIAGNOSTIC": "DIAGNOSTIC", - "FATAL": "FATAL", - - } - for event_dict in self.json_dict.get("events"): event_mnemonic = event_dict.get("name") event_comp = event_mnemonic.split(".")[0] event_name = event_mnemonic.split(".")[1] event_id = event_dict[self.ID_TAG] - event_severity = EventSeverity[severity_map[event_dict[self.SEVERITY_TAG]]] + event_severity = EventSeverity[event_dict[self.SEVERITY_TAG]] event_fmt_str = event_dict.get(self.FMT_STR_TAG, "") @@ -80,7 +68,7 @@ def construct_dicts(self, path): # Parse arguments event_args = [] for arg in event_dict.get("formalParams", []): - event_args.append((arg.get("name"), arg.get("description"), self.parse_type(arg.get("type")))) + event_args.append((arg.get("name"), arg.get("annotation"), self.parse_type(arg.get("type")))) event_temp = EventTemplate( diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index 67b831b1..e83dab58 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -23,6 +23,9 @@ from fprime.common.models.serialize.serializable_type import SerializableType from fprime.common.models.serialize.string_type import StringType from fprime.common.models.serialize.type_base import DictionaryType, BaseType + +from fprime_gds.common.data_types import exceptions + from fprime_gds.version import ( MAXIMUM_SUPPORTED_FRAMEWORK_VERSION, MINIMUM_SUPPORTED_FRAMEWORK_VERSION, @@ -128,11 +131,9 @@ def parse_type(self, type_dict: dict) -> BaseType: break if qualified_type is None: - # TODO: There's an issue here with PacketTypes not being in dictionary??? - return DictionaryType.construct_type(SerializableType, type_name) - # raise ValueError( - # f"Channel entry in dictionary has no corresponding type definition." - # ) + raise ValueError( + f"Channel entry in dictionary has no corresponding type definition." + ) if qualified_type.get("kind") == "array": return ArrayType.construct_type( @@ -143,9 +144,12 @@ def parse_type(self, type_dict: dict) -> BaseType: ) if qualified_type.get("kind") == "enum": + enum_dict = {} + for member in qualified_type.get("enumeratedConstants"): + enum_dict[member.get("name")] = member.get("value") return EnumType.construct_type( type_name, - qualified_type.get("identifiers"), + enum_dict, qualified_type.get("representationType").get("name"), ) @@ -165,7 +169,7 @@ def parse_type(self, type_dict: dict) -> BaseType: ) fmt_str = self.get_format_string_obj(member_type_obj) - description = member_type_dict.get("description", "") + description = member_type_dict.get("annotation", "") struct_members.append((name, member_type_obj, fmt_str, description)) return SerializableType.construct_type( diff --git a/src/fprime_gds/common/pipeline/dictionaries.py b/src/fprime_gds/common/pipeline/dictionaries.py index d2e3b0fe..590272ee 100644 --- a/src/fprime_gds/common/pipeline/dictionaries.py +++ b/src/fprime_gds/common/pipeline/dictionaries.py @@ -7,6 +7,7 @@ class called "Dictionaries". @author mstarch """ import os +from pathlib import Path import fprime_gds.common.loaders.ch_py_loader import fprime_gds.common.loaders.ch_xml_loader @@ -83,8 +84,7 @@ def load_dictionaries(self, dictionary, packet_spec): self._channel_name_dict = channel_loader.get_name_dict( os.path.join(dictionary, "channels") ) - # TODO: rework with Pathlib - elif os.path.isfile(dictionary) and ".json" in str(dictionary): + elif Path(dictionary).is_file() and ".json" in Path(dictionary).suffixes: # Events json_event_loader = fprime_gds.common.loaders.event_json_loader.EventJsonLoader(dictionary) self._event_name_dict = json_event_loader.get_name_dict(None) @@ -101,34 +101,22 @@ def load_dictionaries(self, dictionary, packet_spec): self._channel_id_dict = json_channel_loader.get_id_dict(None) assert self._versions == json_channel_loader.get_versions(), "Version mismatch while loading" # XML dictionaries - elif os.path.isfile(dictionary): + elif Path(dictionary).is_file(): # Events event_loader = fprime_gds.common.loaders.event_xml_loader.EventXmlLoader() self._event_id_dict = event_loader.get_id_dict(dictionary) self._event_name_dict = event_loader.get_name_dict(dictionary) self._versions = event_loader.get_versions() - # if os.path.isfile(ref_json_dict) and True: - # json_event_loader = fprime_gds.common.loaders.event_json_loader.EventJsonLoader(ref_json_dict) - # self._event_name_dict = json_event_loader.get_name_dict(None) - # self._event_id_dict = json_event_loader.get_id_dict(None) # Commands command_loader = fprime_gds.common.loaders.cmd_xml_loader.CmdXmlLoader() self._command_id_dict = command_loader.get_id_dict(dictionary) self._command_name_dict = command_loader.get_name_dict(dictionary) assert self._versions == command_loader.get_versions(), "Version mismatch while loading" - # if os.path.isfile(ref_json_dict) and True: - # json_command_loader = fprime_gds.common.loaders.cmd_json_loader.CmdJsonLoader(ref_json_dict) - # self._command_name_dict = json_command_loader.get_name_dict(None) - # self._command_id_dict = json_command_loader.get_id_dict(None) # Channels channel_loader = fprime_gds.common.loaders.ch_xml_loader.ChXmlLoader() self._channel_id_dict = channel_loader.get_id_dict(dictionary) self._channel_name_dict = channel_loader.get_name_dict(dictionary) assert self._versions == channel_loader.get_versions(), "Version mismatch while loading" - # if os.path.isfile(ref_json_dict) and True: - # json_channel_loader = fprime_gds.common.loaders.ch_json_loader.ChJsonLoader(ref_json_dict) - # self._channel_name_dict = json_channel_loader.get_name_dict(None) - # self._channel_id_dict = json_channel_loader.get_id_dict(None) else: msg = f"[ERROR] Dictionary '{dictionary}' does not exist." raise Exception(msg) From b5a98a1fbb75a1454b8fc554fba0e8e79a0808df Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Mon, 22 Apr 2024 18:57:20 -0700 Subject: [PATCH 07/28] Formatting --- .../common/data_types/event_data.py | 7 +++- .../common/loaders/ch_json_loader.py | 8 +++-- .../common/loaders/cmd_json_loader.py | 33 +++++++++++-------- src/fprime_gds/common/loaders/dict_loader.py | 2 +- .../common/loaders/event_json_loader.py | 13 +++++--- src/fprime_gds/common/loaders/json_loader.py | 30 ++++++++--------- .../common/pipeline/dictionaries.py | 31 ++++++++++++----- src/fprime_gds/common/utils/string_util.py | 14 ++++++++ 8 files changed, 92 insertions(+), 46 deletions(-) diff --git a/src/fprime_gds/common/data_types/event_data.py b/src/fprime_gds/common/data_types/event_data.py index be7c2e1a..1f35aaf7 100644 --- a/src/fprime_gds/common/data_types/event_data.py +++ b/src/fprime_gds/common/data_types/event_data.py @@ -44,7 +44,12 @@ def __init__(self, event_args, event_time, event_temp): self.display_text = event_temp.description elif event_temp.format_str == "": args_template = self.template.get_args() - self.display_text = str([{args_template[index][0]:arg.val} for index, arg in enumerate(event_args)]) + self.display_text = str( + [ + {args_template[index][0]: arg.val} + for index, arg in enumerate(event_args) + ] + ) else: self.display_text = format_string_template( event_temp.format_str, tuple([arg.val for arg in event_args]) diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index 999b4a08..7d8b7517 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -30,7 +30,6 @@ class ChJsonLoader(JsonLoader): def __init__(self, dict_path: str): super().__init__(dict_path) - def construct_dicts(self, dict_path: str): """ Constructs and returns python dictionaries keyed on id and name @@ -53,8 +52,11 @@ def construct_dicts(self, dict_path: str): id_dict[ch_dict[self.ID_FIELD]] = ch_temp name_dict[ch_dict[self.NAME_FIELD]] = ch_temp - return dict(sorted(id_dict.items())), dict(sorted(name_dict.items())), ("unknown", "unknown") - + return ( + dict(sorted(id_dict.items())), + dict(sorted(name_dict.items())), + ("unknown", "unknown"), + ) def construct_template_from_dict(self, channel_dict: dict): component_name = channel_dict[self.NAME_FIELD].split(".")[0] diff --git a/src/fprime_gds/common/loaders/cmd_json_loader.py b/src/fprime_gds/common/loaders/cmd_json_loader.py index e5e0e5e0..c2c620ab 100644 --- a/src/fprime_gds/common/loaders/cmd_json_loader.py +++ b/src/fprime_gds/common/loaders/cmd_json_loader.py @@ -21,17 +21,16 @@ class CmdJsonLoader(JsonLoader): def __init__(self, dict_path: str): super().__init__(dict_path) - def construct_dicts(self, path): """ - Constructs and returns python dictionaries keyed on id and name - - Args: - path: Path to JSON dictionary file - Returns: - A tuple with two command dictionaries (python type dict): - (id_dict, name_dict). The keys are the events' id and name fields - respectively and the values are CmdTemplate objects + Constructs and returns python dictionaries keyed on id and name + + Args: + path: Path to JSON dictionary file + Returns: + A tuple with two command dictionaries (python type dict): + (id_dict, name_dict). The keys are the events' id and name fields + respectively and the values are CmdTemplate objects """ id_dict = {} @@ -39,7 +38,7 @@ def construct_dicts(self, path): for cmd_dict in self.json_dict["commands"]: cmd_name = cmd_dict.get("name") - + cmd_comp = cmd_name.split(".")[0] cmd_mnemonic = cmd_name.split(".")[1] @@ -50,9 +49,17 @@ def construct_dicts(self, path): # Parse Arguments cmd_args = [] for arg in cmd_dict.get("formalParams", []): - cmd_args.append((arg.get("name"), arg.get("annotation"), self.parse_type(arg.get("type")))) - - cmd_temp = CmdTemplate(cmd_opcode, cmd_mnemonic, cmd_comp, cmd_args, cmd_desc) + cmd_args.append( + ( + arg.get("name"), + arg.get("annotation"), + self.parse_type(arg.get("type")), + ) + ) + + cmd_temp = CmdTemplate( + cmd_opcode, cmd_mnemonic, cmd_comp, cmd_args, cmd_desc + ) id_dict[cmd_opcode] = cmd_temp name_dict[cmd_temp.get_full_name()] = cmd_temp diff --git a/src/fprime_gds/common/loaders/dict_loader.py b/src/fprime_gds/common/loaders/dict_loader.py index e645da9e..cdd7052b 100644 --- a/src/fprime_gds/common/loaders/dict_loader.py +++ b/src/fprime_gds/common/loaders/dict_loader.py @@ -93,7 +93,7 @@ def get_name_dict(self, path): return name_dict def get_versions(self): - """ Get version tuple """ + """Get version tuple""" return self.versions def construct_dicts(self, path): diff --git a/src/fprime_gds/common/loaders/event_json_loader.py b/src/fprime_gds/common/loaders/event_json_loader.py index 66116eee..973505e0 100644 --- a/src/fprime_gds/common/loaders/event_json_loader.py +++ b/src/fprime_gds/common/loaders/event_json_loader.py @@ -46,9 +46,7 @@ def construct_dicts(self, path): # Check if xml dict has events section if self.json_dict.get("events") is None: msg = "JSON dict did not have a events section" - raise exceptions.GseControllerParsingException( - msg - ) + raise exceptions.GseControllerParsingException(msg) id_dict = {} name_dict = {} @@ -68,8 +66,13 @@ def construct_dicts(self, path): # Parse arguments event_args = [] for arg in event_dict.get("formalParams", []): - event_args.append((arg.get("name"), arg.get("annotation"), self.parse_type(arg.get("type")))) - + event_args.append( + ( + arg.get("name"), + arg.get("annotation"), + self.parse_type(arg.get("type")), + ) + ) event_temp = EventTemplate( event_id, diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index e83dab58..2dc28cce 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -5,6 +5,7 @@ @author thomas-bc """ + from fprime.common.models.serialize.array_type import ArrayType from fprime.common.models.serialize.bool_type import BoolType from fprime.common.models.serialize.enum_type import EnumType @@ -51,6 +52,7 @@ "ENUM": "%d", } + class JsonLoader(dict_loader.DictLoader): """Class to help load JSON dictionaries""" @@ -83,16 +85,12 @@ def get_versions(self) -> tuple[str, str]: self.json_dict.get("project_version", "unknown"), ) - def parse_type(self, type_dict: dict) -> BaseType: type_name: str = type_dict.get("name", None) if type_name is None: - raise ValueError( - "Channel entry in dictionary has no `name` field" - ) - + raise ValueError("Channel entry in dictionary has no `name` field") match type_name: case "I8": @@ -178,21 +176,23 @@ def parse_type(self, type_dict: dict) -> BaseType: ) def get_format_string(self, type_dict: dict) -> str | None: - - #probably useless + + # TODO: this function is probably useless now if type_dict.get("format") is not None: return type_dict.get("format") - type_name = type_dict.get("name") - if type_name in FORMAT_STR_MAP: - return FORMAT_STR_MAP[type_name] + # type_name = type_dict.get("name") + # if type_name in FORMAT_STR_MAP: + # return FORMAT_STR_MAP[type_name] + + # return "{}" + # raise exceptions.GseControllerParsingException( + # f"Could not find `format` attribute for type {type_name}" + # ) - # idk either - return "%s" - def get_format_string_obj(self, type_obj: BaseType) -> str | None: - # needs a lot of rework + # TODO: look into this more, unclear what really needs to happen if hasattr(type_obj, "FORMAT"): return type_obj.FORMAT @@ -202,4 +202,4 @@ def get_format_string_obj(self, type_obj: BaseType) -> str | None: return FORMAT_STR_MAP[type_name] # Why? idk - return "%s" \ No newline at end of file + # return "{}" diff --git a/src/fprime_gds/common/pipeline/dictionaries.py b/src/fprime_gds/common/pipeline/dictionaries.py index 590272ee..77dbb385 100644 --- a/src/fprime_gds/common/pipeline/dictionaries.py +++ b/src/fprime_gds/common/pipeline/dictionaries.py @@ -6,6 +6,7 @@ class called "Dictionaries". @author mstarch """ + import os from pathlib import Path @@ -86,37 +87,51 @@ def load_dictionaries(self, dictionary, packet_spec): ) elif Path(dictionary).is_file() and ".json" in Path(dictionary).suffixes: # Events - json_event_loader = fprime_gds.common.loaders.event_json_loader.EventJsonLoader(dictionary) + json_event_loader = ( + fprime_gds.common.loaders.event_json_loader.EventJsonLoader(dictionary) + ) self._event_name_dict = json_event_loader.get_name_dict(None) self._event_id_dict = json_event_loader.get_id_dict(None) self._versions = json_event_loader.get_versions() # Commands - json_command_loader = fprime_gds.common.loaders.cmd_json_loader.CmdJsonLoader(dictionary) + json_command_loader = ( + fprime_gds.common.loaders.cmd_json_loader.CmdJsonLoader(dictionary) + ) self._command_name_dict = json_command_loader.get_name_dict(None) self._command_id_dict = json_command_loader.get_id_dict(None) - assert self._versions == json_command_loader.get_versions(), "Version mismatch while loading" + assert ( + self._versions == json_command_loader.get_versions() + ), "Version mismatch while loading" # Channels - json_channel_loader = fprime_gds.common.loaders.ch_json_loader.ChJsonLoader(dictionary) + json_channel_loader = fprime_gds.common.loaders.ch_json_loader.ChJsonLoader( + dictionary + ) self._channel_name_dict = json_channel_loader.get_name_dict(None) self._channel_id_dict = json_channel_loader.get_id_dict(None) - assert self._versions == json_channel_loader.get_versions(), "Version mismatch while loading" + assert ( + self._versions == json_channel_loader.get_versions() + ), "Version mismatch while loading" # XML dictionaries elif Path(dictionary).is_file(): # Events event_loader = fprime_gds.common.loaders.event_xml_loader.EventXmlLoader() self._event_id_dict = event_loader.get_id_dict(dictionary) - self._event_name_dict = event_loader.get_name_dict(dictionary) + self._event_name_dict = event_loader.get_name_dict(dictionary) self._versions = event_loader.get_versions() # Commands command_loader = fprime_gds.common.loaders.cmd_xml_loader.CmdXmlLoader() self._command_id_dict = command_loader.get_id_dict(dictionary) self._command_name_dict = command_loader.get_name_dict(dictionary) - assert self._versions == command_loader.get_versions(), "Version mismatch while loading" + assert ( + self._versions == command_loader.get_versions() + ), "Version mismatch while loading" # Channels channel_loader = fprime_gds.common.loaders.ch_xml_loader.ChXmlLoader() self._channel_id_dict = channel_loader.get_id_dict(dictionary) self._channel_name_dict = channel_loader.get_name_dict(dictionary) - assert self._versions == channel_loader.get_versions(), "Version mismatch while loading" + assert ( + self._versions == channel_loader.get_versions() + ), "Version mismatch while loading" else: msg = f"[ERROR] Dictionary '{dictionary}' does not exist." raise Exception(msg) diff --git a/src/fprime_gds/common/utils/string_util.py b/src/fprime_gds/common/utils/string_util.py index 044030cd..b9d78b1a 100644 --- a/src/fprime_gds/common/utils/string_util.py +++ b/src/fprime_gds/common/utils/string_util.py @@ -14,6 +14,20 @@ def format_string_template(format_str, given_values): + # Regular expression pattern to match format strings like "{.3f}" + pattern = r"{(\.?\d*[cdxoefg])}" + + # Replace the format string with the correct Python representation + try: + corrected_format_string = re.sub(pattern, r"{:\1}", format_str) + return corrected_format_string.format(*given_values) + except ValueError: + # TODO: This doesn't work correctly - needs rework + # Goal is to format either FPP-style of C-style strings + format_c_style_string_template(format_str, given_values) + + +def format_c_style_string_template(format_str, given_values): r""" Function to convert C-string style to python format without using python interpolation From e595fe3e86454eb30667c692f93e1f0f46f1241c Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Wed, 24 Apr 2024 09:01:37 -0700 Subject: [PATCH 08/28] Fix Python<3.10 compatibility (remove match statement) --- src/fprime_gds/common/loaders/json_loader.py | 127 +++++++------------ 1 file changed, 48 insertions(+), 79 deletions(-) diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index 2dc28cce..c7ebf0c0 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -25,31 +25,40 @@ from fprime.common.models.serialize.string_type import StringType from fprime.common.models.serialize.type_base import DictionaryType, BaseType -from fprime_gds.common.data_types import exceptions - -from fprime_gds.version import ( - MAXIMUM_SUPPORTED_FRAMEWORK_VERSION, - MINIMUM_SUPPORTED_FRAMEWORK_VERSION, -) # Custom Python Modules from . import dict_loader + import json -FORMAT_STR_MAP = { - "U8": "%u", - "I8": "%d", - "U16": "%u", - "I16": "%d", - "U32": "%u", - "I32": "%d", - "U64": "%lu", - "I64": "%ld", - "F32": "%g", - "F64": "%g", - "bool": "%s", - "string": "%s", - "ENUM": "%d", +# FORMAT_STR_MAP = { +# "U8": "%u", +# "I8": "%d", +# "U16": "%u", +# "I16": "%d", +# "U32": "%u", +# "I32": "%d", +# "U64": "%lu", +# "I64": "%ld", +# "F32": "%g", +# "F64": "%g", +# "bool": "%s", +# "string": "%s", +# "ENUM": "%d", +# } + +PRIMITIVE_TYPE_MAP = { + "I8": I8Type, + "I16": I16Type, + "I32": I32Type, + "I64": I64Type, + "U8": U8Type, + "U16": U16Type, + "U32": U32Type, + "U64": U64Type, + "F32": F32Type, + "F64": F64Type, + "bool": BoolType, } @@ -92,36 +101,17 @@ def parse_type(self, type_dict: dict) -> BaseType: if type_name is None: raise ValueError("Channel entry in dictionary has no `name` field") - match type_name: - case "I8": - return I8Type - case "I16": - return I16Type - case "I32": - return I32Type - case "I64": - return I64Type - case "U8": - return U8Type - case "U16": - return U16Type - case "U32": - return U32Type - case "U64": - return U64Type - case "F32": - return F32Type - case "F64": - return F64Type - case "bool": - return BoolType - case "string": - # Does this break the logic of checking for original arguments? - return StringType.construct_type( - f'String_{type_dict.get("size")}', type_dict.get("size") - ) + if type_name in PRIMITIVE_TYPE_MAP: + return PRIMITIVE_TYPE_MAP[type_name] + + if type_name == "string": + # REVIEW NOTE: Does name matter? I believe not + return StringType.construct_type( + f'String_{type_dict.get("size")}', type_dict.get("size") + ) # Process for enum/array/serializable types + # TODO: Rework logic here to cache typeDefinitions in member variable, either at read-time or init-time? qualified_type = None for type_def in self.json_dict.get("typeDefinitions", []): if type_name == type_def.get("qualifiedName"): @@ -138,7 +128,7 @@ def parse_type(self, type_dict: dict) -> BaseType: type_name, self.parse_type(qualified_type.get("elementType")), qualified_type.get("size"), - self.get_format_string(qualified_type.get("elementType")), + qualified_type.get("elementType").get("format", "{}"), ) if qualified_type.get("kind") == "enum": @@ -163,10 +153,14 @@ def parse_type(self, type_dict: dict) -> BaseType: f"Array_{member_type_obj.__name__}_{member_dict.get('size')}", member_type_obj, member_dict.get("size"), - self.get_format_string(member_dict.get("type")), + member_dict.get("type").get("format", "{}"), ) - fmt_str = self.get_format_string_obj(member_type_obj) + fmt_str = ( + member_type_obj.FORMAT + if hasattr(member_type_obj, "FORMAT") + else "{}" + ) description = member_type_dict.get("annotation", "") struct_members.append((name, member_type_obj, fmt_str, description)) @@ -175,31 +169,6 @@ def parse_type(self, type_dict: dict) -> BaseType: struct_members, ) - def get_format_string(self, type_dict: dict) -> str | None: - - # TODO: this function is probably useless now - if type_dict.get("format") is not None: - return type_dict.get("format") - - # type_name = type_dict.get("name") - # if type_name in FORMAT_STR_MAP: - # return FORMAT_STR_MAP[type_name] - - # return "{}" - # raise exceptions.GseControllerParsingException( - # f"Could not find `format` attribute for type {type_name}" - # ) - - def get_format_string_obj(self, type_obj: BaseType) -> str | None: - - # TODO: look into this more, unclear what really needs to happen - if hasattr(type_obj, "FORMAT"): - return type_obj.FORMAT - - if hasattr(type_obj, "REP_TYPE"): - type_name = type_obj.REP_TYPE - if type_name in FORMAT_STR_MAP: - return FORMAT_STR_MAP[type_name] - - # Why? idk - # return "{}" + raise ValueError( + f"Channel entry in dictionary has unknown type {str(type_dict)}" + ) From 07d6f62b2cdf87ff6221873b5b1d8e82ec6e3869 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Fri, 26 Apr 2024 15:35:49 -0700 Subject: [PATCH 09/28] Translate format strings at load-time --- .../common/loaders/ch_json_loader.py | 5 +- .../common/loaders/ch_xml_loader.py | 10 +- .../common/loaders/event_json_loader.py | 4 +- .../common/loaders/event_xml_loader.py | 16 ++- src/fprime_gds/common/loaders/json_loader.py | 34 ++--- src/fprime_gds/common/loaders/xml_loader.py | 40 ++++-- src/fprime_gds/common/utils/string_util.py | 128 ++++++++---------- .../common/utils/test_string_util.py | 115 +++++++++++++--- 8 files changed, 222 insertions(+), 130 deletions(-) diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index 7d8b7517..0c4cfe83 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -63,6 +63,9 @@ def construct_template_from_dict(self, channel_dict: dict): channel_name = channel_dict[self.NAME_FIELD].split(".")[1] channel_type = channel_dict.get("type") type_obj = self.parse_type(channel_type) + format_str = JsonLoader.preprocess_format_str( + channel_dict.get(self.FMT_STR_FIELD) + ) limit_field = channel_dict.get(self.LIMIT_FIELD) limit_low = limit_field.get(self.LIMIT_LOW) if limit_field else None @@ -81,7 +84,7 @@ def construct_template_from_dict(self, channel_dict: dict): channel_name, component_name, type_obj, - ch_fmt_str=channel_dict.get(self.FMT_STR_FIELD), + ch_fmt_str=format_str, ch_desc=channel_dict.get(self.DESC_FIELD), low_red=limit_low_red, low_orange=limit_low_orange, diff --git a/src/fprime_gds/common/loaders/ch_xml_loader.py b/src/fprime_gds/common/loaders/ch_xml_loader.py index 26a75a96..63b3dea6 100644 --- a/src/fprime_gds/common/loaders/ch_xml_loader.py +++ b/src/fprime_gds/common/loaders/ch_xml_loader.py @@ -49,15 +49,15 @@ def construct_dicts(self, path): respectively and the values are ChTemplate objects """ xml_tree = self.get_xml_tree(path) - versions = xml_tree.attrib.get("framework_version", "unknown"), xml_tree.attrib.get("project_version", "unknown") + versions = xml_tree.attrib.get( + "framework_version", "unknown" + ), xml_tree.attrib.get("project_version", "unknown") # Check if xml dict has channels section ch_section = self.get_xml_section(self.CH_SECT, xml_tree) if ch_section is None: msg = f"Xml dict did not have a {self.CH_SECT} section" - raise exceptions.GseControllerParsingException( - msg - ) + raise exceptions.GseControllerParsingException(msg) id_dict = {} name_dict = {} @@ -84,7 +84,7 @@ def construct_dicts(self, path): ch_desc = ch_dict[self.DESC_TAG] if self.FMT_STR_TAG in ch_dict: - ch_fmt_str = ch_dict[self.FMT_STR_TAG] + ch_fmt_str = XmlLoader.preprocess_format_str(ch_dict[self.FMT_STR_TAG]) # TODO we need to convert these into numbers, is this the best # way to do it? diff --git a/src/fprime_gds/common/loaders/event_json_loader.py b/src/fprime_gds/common/loaders/event_json_loader.py index 973505e0..08f793b8 100644 --- a/src/fprime_gds/common/loaders/event_json_loader.py +++ b/src/fprime_gds/common/loaders/event_json_loader.py @@ -59,7 +59,9 @@ def construct_dicts(self, path): event_id = event_dict[self.ID_TAG] event_severity = EventSeverity[event_dict[self.SEVERITY_TAG]] - event_fmt_str = event_dict.get(self.FMT_STR_TAG, "") + event_fmt_str = JsonLoader.preprocess_format_str( + event_dict.get(self.FMT_STR_TAG, "") + ) event_desc = event_dict.get(self.DESC_TAG) diff --git a/src/fprime_gds/common/loaders/event_xml_loader.py b/src/fprime_gds/common/loaders/event_xml_loader.py index 22b690fb..17e41b09 100644 --- a/src/fprime_gds/common/loaders/event_xml_loader.py +++ b/src/fprime_gds/common/loaders/event_xml_loader.py @@ -43,15 +43,15 @@ def construct_dicts(self, path): respectively and the values are ChTemplate objects """ xml_tree = self.get_xml_tree(path) - versions = xml_tree.attrib.get("framework_version", "unknown"), xml_tree.attrib.get("project_version", "unknown") + versions = xml_tree.attrib.get( + "framework_version", "unknown" + ), xml_tree.attrib.get("project_version", "unknown") # Check if xml dict has events section event_section = self.get_xml_section(self.EVENT_SECT, xml_tree) if event_section is None: msg = f"Xml dict did not have a {self.EVENT_SECT} section" - raise exceptions.GseControllerParsingException( - msg - ) + raise exceptions.GseControllerParsingException(msg) id_dict = {} name_dict = {} @@ -63,14 +63,18 @@ def construct_dicts(self, path): event_name = event_dict[self.NAME_TAG] event_id = int(event_dict[self.ID_TAG], base=16) event_severity = EventSeverity[event_dict[self.SEVERITY_TAG]] - event_fmt_str = event_dict[self.FMT_STR_TAG] + event_fmt_str = XmlLoader.preprocess_format_str( + event_dict[self.FMT_STR_TAG] + ) event_desc = None if self.DESC_TAG in event_dict: event_desc = event_dict[self.DESC_TAG] # Parse arguments - args = self.get_args_list(event, xml_tree, f"{ event_comp }::{ event_name }") + args = self.get_args_list( + event, xml_tree, f"{ event_comp }::{ event_name }" + ) event_temp = EventTemplate( event_id, diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index c7ebf0c0..90359f13 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -23,29 +23,16 @@ ) from fprime.common.models.serialize.serializable_type import SerializableType from fprime.common.models.serialize.string_type import StringType -from fprime.common.models.serialize.type_base import DictionaryType, BaseType +from fprime.common.models.serialize.type_base import BaseType +from typing import Optional # Custom Python Modules from . import dict_loader import json +from fprime_gds.common.utils.string_util import preprocess_fpp_format_str -# FORMAT_STR_MAP = { -# "U8": "%u", -# "I8": "%d", -# "U16": "%u", -# "I16": "%d", -# "U32": "%u", -# "I32": "%d", -# "U64": "%lu", -# "I64": "%ld", -# "F32": "%g", -# "F64": "%g", -# "bool": "%s", -# "string": "%s", -# "ENUM": "%d", -# } PRIMITIVE_TYPE_MAP = { "I8": I8Type, @@ -172,3 +159,18 @@ def parse_type(self, type_dict: dict) -> BaseType: raise ValueError( f"Channel entry in dictionary has unknown type {str(type_dict)}" ) + + @staticmethod + def preprocess_format_str(format_str: Optional[str]) -> str: + """Preprocess format strings before using them in Python format function + Internally, this converts FPP-style format strings to Python-style format strings + + Args: + format_str (str): FPP-style format string + + Returns: + str: Python-style format string + """ + if format_str is None: + return None + return preprocess_fpp_format_str(format_str) diff --git a/src/fprime_gds/common/loaders/xml_loader.py b/src/fprime_gds/common/loaders/xml_loader.py index 0fdc5259..8bff5365 100644 --- a/src/fprime_gds/common/loaders/xml_loader.py +++ b/src/fprime_gds/common/loaders/xml_loader.py @@ -13,6 +13,7 @@ @bug No known bugs """ + import os from fprime.common.models.serialize.array_type import ArrayType @@ -34,6 +35,7 @@ from fprime.common.models.serialize.string_type import StringType from lxml import etree +from fprime_gds.common.utils.string_util import preprocess_c_style_format_str from fprime_gds.common.data_types import exceptions from fprime_gds.version import ( MAXIMUM_SUPPORTED_FRAMEWORK_VERSION, @@ -258,18 +260,21 @@ def get_serializable_type(self, type_name, xml_obj): members = [] for memb in memb_section: name = memb.get(self.SER_MEMB_NAME_TAG) - fmt_str = memb.get(self.SER_MEMB_FMT_STR_TAG) + fmt_str = XmlLoader.preprocess_format_str( + memb.get(self.SER_MEMB_FMT_STR_TAG) + ) desc = memb.get(self.SER_MEMB_DESC_TAG) memb_type_name = memb.get(self.SER_MEMB_TYPE_TAG) memb_size = memb.get(self.SER_MEMB_SIZE_TAG) type_obj = self.parse_type(memb_type_name, memb, xml_obj) # memb_size is not None for member array - if(memb_size is not None): + if memb_size is not None: type_obj = ArrayType.construct_type( f"Array_{type_obj.__name__}_{memb_size}", type_obj, int(memb_size), - fmt_str) + fmt_str, + ) members.append((name, type_obj, fmt_str, desc)) @@ -319,10 +324,14 @@ def get_array_type(self, type_name, xml_obj): # Make config arr_type = arr_memb.get(self.ARR_TYPE_TAG) type_obj = self.parse_type(arr_type, arr_memb, xml_obj) - arr_format = arr_memb.get(self.ARR_FORMAT_TAG) + arr_format = XmlLoader.preprocess_format_str( + arr_memb.get(self.ARR_FORMAT_TAG) + ) arr_size = arr_memb.get(self.ARR_SIZE_TAG) - arr_obj = ArrayType.construct_type(type_name, type_obj, int(arr_size), arr_format) + arr_obj = ArrayType.construct_type( + type_name, type_obj, int(arr_size), arr_format + ) self.array_types[type_name] = arr_obj return arr_obj @@ -372,7 +381,9 @@ def parse_type(self, type_name, xml_item, xml_tree, context=None): return BoolType if type_name == "string": if self.STR_LEN_TAG not in xml_item.attrib: - print(f"Trying to parse string type, but found {self.STR_LEN_TAG} field") + print( + f"Trying to parse string type, but found {self.STR_LEN_TAG} field" + ) return None max_length = int(xml_item.get(self.STR_LEN_TAG, 0)) name = f"{context or ''}::{xml_item.get(self.ARG_NAME_TAG)}String" @@ -394,6 +405,17 @@ def parse_type(self, type_name, xml_item, xml_tree, context=None): # Abandon all hope msg = f"Could not find type {type_name}" - raise exceptions.GseControllerParsingException( - msg - ) + raise exceptions.GseControllerParsingException(msg) + + @staticmethod + def preprocess_format_str(format_str): + """Converts C-style format strings to Python-style format strings + For example "%x" -> "{:x}" or "%.2f" -> "{:.2f}" + + Args: + format_str (str): C-style format string + + Returns: + str: Python-style format string + """ + return preprocess_c_style_format_str(format_str) diff --git a/src/fprime_gds/common/utils/string_util.py b/src/fprime_gds/common/utils/string_util.py index b9d78b1a..343159df 100644 --- a/src/fprime_gds/common/utils/string_util.py +++ b/src/fprime_gds/common/utils/string_util.py @@ -7,28 +7,53 @@ Note: This function has an identical copy in fprime-gds """ +from typing import Any, Union import logging import re LOGGER = logging.getLogger("string_util_logger") -def format_string_template(format_str, given_values): - # Regular expression pattern to match format strings like "{.3f}" - pattern = r"{(\.?\d*[cdxoefg])}" +def format_string_template(template: str, value: Union[tuple, list, Any]) -> str: + """ + Function to format a string template with values. This function is a simple wrapper around the + format function. It accepts a tuple, list, or single value and passes it to the format function + + Args: + template (str): String template to be formatted + value (Union[tuple, list, Any]): Value(s) to be inserted into the template - # Replace the format string with the correct Python representation + Returns: + str: Formatted string + """ + if not isinstance(value, (tuple, list)): + value = (value,) try: - corrected_format_string = re.sub(pattern, r"{:\1}", format_str) - return corrected_format_string.format(*given_values) - except ValueError: - # TODO: This doesn't work correctly - needs rework - # Goal is to format either FPP-style of C-style strings - format_c_style_string_template(format_str, given_values) + return template.format(*value) + except (IndexError, ValueError) as e: + LOGGER.error( + f"Error formatting string template: {template} with value: {str(value)}" + ) + raise e + + +def preprocess_fpp_format_str(format_str: str) -> str: + """Preprocess a FPP-style format string and convert it to Python format string + FPP format strings are documented https://nasa.github.io/fpp/fpp-spec.html#Format-Strings + For example "{x}" -> "{:x}" or "{.2f}" -> "{:.2f}" + Args: + format_str (str): FPP-style format string -def format_c_style_string_template(format_str, given_values): - r""" + Returns: + str: Python-style format string + """ + pattern = r"{(\d*\.?\d*[cdxoefgCDXOEFG])}" + return re.sub(pattern, r"{:\1}", format_str) + + +def preprocess_c_style_format_str(format_str: str) -> str: + """ Function to convert C-string style to python format without using python interpolation Considered the following format for C-string: @@ -45,20 +70,26 @@ def format_c_style_string_template(format_str, given_values): This function will keep the flags, width, and .precision of C-string template. - It will keep f, d, x, o, and e flags and remove all other types. - Other types will be duck-typed by python - interpreter. + It will keep f, x, o, and e flags and remove all other types. + Other types will be duck-typed by python interpreter. lengths will also be removed since they are not meaningful to Python interpreter. `See: https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting` - `Regex Source: https://www.regexlib.com/REDetails.aspx?regexp_id=3363` + + For example "%x" -> "{:x}" or "%.2f" -> "{:.2f}" + + Args: + format_str (str): C-style format string + + Returns: + str: Python-style format string """ - def convert(match_obj, ignore_int): + def convert(match_obj: re.Match): if match_obj.group() is None: return match_obj - flags, width, precision, length, conversion_type = match_obj.groups() + flags, width, precision, _, conversion_type = match_obj.groups() format_template = "" if flags: format_template += f"{flags}" @@ -67,66 +98,13 @@ def convert(match_obj, ignore_int): if precision: format_template += f"{precision}" - if conversion_type: - if any( - [ - str(conversion_type).lower() == "f", - str(conversion_type).lower() == "x", - str(conversion_type).lower() == "o", - str(conversion_type).lower() == "e", - ] - ): - format_template += f"{conversion_type}" - elif all([not ignore_int, str(conversion_type).lower() == "d"]): - format_template += f"{conversion_type}" + if conversion_type and str(conversion_type).lower() in {"f", "x", "o", "e"}: + format_template += f"{conversion_type}" return "{}" if format_template == "" else "{:" + format_template + "}" - def convert_include_all(match_obj): - return convert(match_obj, ignore_int=False) - - def convert_ignore_int(match_obj): - return convert(match_obj, ignore_int=True) - - # Allowing single, list and tuple inputs - if not isinstance(given_values, (list, tuple)): - values = (given_values,) - elif isinstance(given_values, list): - values = tuple(given_values) - else: - values = given_values - - pattern = r"(? Date: Fri, 26 Apr 2024 15:40:08 -0700 Subject: [PATCH 10/28] Remove tuple type hint that break Python3.8 --- src/fprime_gds/common/loaders/json_loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index 90359f13..6202087f 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -69,7 +69,7 @@ def __init__(self, json_dict: dict): with open(json_dict, "r") as f: self.json_dict = json.load(f) - def get_versions(self) -> tuple[str, str]: + def get_versions(self): """ Get the framework and project versions of the dictionary From bb7ab3d7a9ea57c5ed862d2becf5f77a2a29e019 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Fri, 26 Apr 2024 15:42:10 -0700 Subject: [PATCH 11/28] Fix CodeQL warnings in test code --- test/fprime_gds/common/utils/test_string_util.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/fprime_gds/common/utils/test_string_util.py b/test/fprime_gds/common/utils/test_string_util.py index 4fdbff04..c700444b 100644 --- a/test/fprime_gds/common/utils/test_string_util.py +++ b/test/fprime_gds/common/utils/test_string_util.py @@ -41,9 +41,7 @@ def test_format_bad_case(self): template = "Opcode 0x%04X dispatched to port %04d and value %0.02f" values = ("181", "8", "0.123") with self.assertRaises(ValueError): - self.assertEqual( - format_string_template(preprocess_c_style_format_str(template), values) - ) + format_string_template(preprocess_c_style_format_str(template), values) def test_format_decimal_with_width_flag(self): template = "Decimals: %d %ld" @@ -159,9 +157,7 @@ def test_fpp_format_bad_case(self): template = "Opcode 0x{04X} dispatched to port {04d} and value {0.02f}" values = ("181", "8", "0.123") with self.assertRaises(ValueError): - self.assertEqual( - format_string_template(preprocess_fpp_format_str(template), values) - ) + format_string_template(preprocess_fpp_format_str(template), values) def test_fpp_format_decimal_with_width_flag(self): template = "Decimals: {} {}" From 9f64f1ef900e00dbfecd05df1468925668935ea4 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Fri, 26 Apr 2024 15:46:26 -0700 Subject: [PATCH 12/28] spelling --- .github/actions/spelling/expect.txt | 3 +++ src/fprime_gds/common/loaders/json_loader.py | 6 ++++-- test/fprime_gds/common/utils/test_string_util.py | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 8f576beb..7ff0d21c 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -69,6 +69,7 @@ CCB CCFF cdn Cdioux +cdxoefg CFDG CFDP CFPD @@ -229,6 +230,7 @@ focusring FONTNAME FONTPATH FONTSIZE +fpp fprime fptable frac @@ -420,6 +422,7 @@ nitpicky noapp noqa normpath +NOSONAR nosort Noto novalidate diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index 6202087f..e54e8840 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -86,7 +86,9 @@ def parse_type(self, type_dict: dict) -> BaseType: type_name: str = type_dict.get("name", None) if type_name is None: - raise ValueError("Channel entry in dictionary has no `name` field") + raise ValueError( + f"Channel entry in dictionary has no `name` field: {str(type_dict)}" + ) if type_name in PRIMITIVE_TYPE_MAP: return PRIMITIVE_TYPE_MAP[type_name] @@ -107,7 +109,7 @@ def parse_type(self, type_dict: dict) -> BaseType: if qualified_type is None: raise ValueError( - f"Channel entry in dictionary has no corresponding type definition." + f"Channel entry {type_name} in dictionary has no corresponding type definition." ) if qualified_type.get("kind") == "array": diff --git a/test/fprime_gds/common/utils/test_string_util.py b/test/fprime_gds/common/utils/test_string_util.py index c700444b..6f401a83 100644 --- a/test/fprime_gds/common/utils/test_string_util.py +++ b/test/fprime_gds/common/utils/test_string_util.py @@ -189,7 +189,7 @@ def test_fpp_format_with_escape_sequence(self): def test_fpp_format_regular_string(self): template = "{}" - values = ["A string"] # list instead of tupes + values = ["A string"] # list instead of tuples expected = "A string" actual = format_string_template(preprocess_fpp_format_str(template), values) self.assertEqual(expected, actual) From 486ff6ee53c10c22d98305db5d1d20a20e133a91 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Fri, 26 Apr 2024 15:47:24 -0700 Subject: [PATCH 13/28] Fix changed test case for more surface area --- test/fprime_gds/common/utils/test_string_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fprime_gds/common/utils/test_string_util.py b/test/fprime_gds/common/utils/test_string_util.py index 6f401a83..4e66c772 100644 --- a/test/fprime_gds/common/utils/test_string_util.py +++ b/test/fprime_gds/common/utils/test_string_util.py @@ -142,7 +142,7 @@ def test_fpp_format_with_no_issue(self): def test_fpp_format_value_with_string_input_as_other_types(self): template = "Opcode 0x{04x} dispatched to port {} and value {.2f}" values = (181, "8", 1.234) - expected = "Opcode 0x00B5 dispatched to port 8 and value 1.23" + expected = "Opcode 0x00b5 dispatched to port 8 and value 1.23" actual = format_string_template(preprocess_fpp_format_str(template), values) self.assertEqual(expected, actual) From 87e1e464f4e101e6eba0f174f181cee80143c16d Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Fri, 26 Apr 2024 15:55:08 -0700 Subject: [PATCH 14/28] Formatting --- src/fprime_gds/common/loaders/json_loader.py | 44 +++++++------------- src/fprime_gds/common/utils/string_util.py | 2 +- 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index e54e8840..53f83bfc 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -6,45 +6,32 @@ @author thomas-bc """ +import json +from typing import Optional + from fprime.common.models.serialize.array_type import ArrayType from fprime.common.models.serialize.bool_type import BoolType from fprime.common.models.serialize.enum_type import EnumType -from fprime.common.models.serialize.numerical_types import ( - F32Type, - F64Type, - I8Type, - I16Type, - I32Type, - I64Type, - U8Type, - U16Type, - U32Type, - U64Type, -) +import fprime.common.models.serialize.numerical_types as numerical_types from fprime.common.models.serialize.serializable_type import SerializableType from fprime.common.models.serialize.string_type import StringType from fprime.common.models.serialize.type_base import BaseType -from typing import Optional - -# Custom Python Modules -from . import dict_loader - -import json from fprime_gds.common.utils.string_util import preprocess_fpp_format_str +from fprime_gds.common.loaders import dict_loader PRIMITIVE_TYPE_MAP = { - "I8": I8Type, - "I16": I16Type, - "I32": I32Type, - "I64": I64Type, - "U8": U8Type, - "U16": U16Type, - "U32": U32Type, - "U64": U64Type, - "F32": F32Type, - "F64": F64Type, + "I8": numerical_types.I8Type, + "I16": numerical_types.I16Type, + "I32": numerical_types.I32Type, + "I64": numerical_types.I64Type, + "U8": numerical_types.U8Type, + "U16": numerical_types.U16Type, + "U32": numerical_types.U32Type, + "U64": numerical_types.U64Type, + "F32": numerical_types.F32Type, + "F64": numerical_types.F64Type, "bool": BoolType, } @@ -82,7 +69,6 @@ def get_versions(self): ) def parse_type(self, type_dict: dict) -> BaseType: - type_name: str = type_dict.get("name", None) if type_name is None: diff --git a/src/fprime_gds/common/utils/string_util.py b/src/fprime_gds/common/utils/string_util.py index 343159df..cc309681 100644 --- a/src/fprime_gds/common/utils/string_util.py +++ b/src/fprime_gds/common/utils/string_util.py @@ -7,9 +7,9 @@ Note: This function has an identical copy in fprime-gds """ -from typing import Any, Union import logging import re +from typing import Any, Union LOGGER = logging.getLogger("string_util_logger") From db6aa693a0a27c00fb4713cce4a8c270062b49a1 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 12:41:34 -0700 Subject: [PATCH 15/28] Fix get_versions() --- src/fprime_gds/common/loaders/json_loader.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index 53f83bfc..94e472d8 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -63,9 +63,12 @@ def get_versions(self): Returns: A tuple of the framework and project versions """ + if "metadata" not in self.json_dict: + # REVIEW NOTE: Should we raise an error instead? + return ("unknown", "unknown") return ( - self.json_dict.get("framework_version", "unknown"), - self.json_dict.get("project_version", "unknown"), + self.json_dict.get("metadata").get("frameworkVersion", "unknown"), + self.json_dict.get("metadata").get("projectVersion", "unknown"), ) def parse_type(self, type_dict: dict) -> BaseType: From 75b0a0a6f6bcc69481fcd838d39f39e3dff4f4a3 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 12:42:04 -0700 Subject: [PATCH 16/28] reorganize code --- .../common/loaders/ch_json_loader.py | 14 ++-- .../common/loaders/cmd_json_loader.py | 49 ++++++----- .../common/loaders/event_json_loader.py | 82 +++++++++---------- 3 files changed, 76 insertions(+), 69 deletions(-) diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index 0c4cfe83..c6509b12 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -49,19 +49,19 @@ def construct_dicts(self, dict_path: str): # Create a channel template object ch_temp = self.construct_template_from_dict(ch_dict) - id_dict[ch_dict[self.ID_FIELD]] = ch_temp - name_dict[ch_dict[self.NAME_FIELD]] = ch_temp + id_dict[ch_temp.get_id()] = ch_temp + name_dict[ch_temp.get_full_name()] = ch_temp return ( - dict(sorted(id_dict.items())), - dict(sorted(name_dict.items())), - ("unknown", "unknown"), + id_dict, + name_dict, + self.get_versions(), ) - def construct_template_from_dict(self, channel_dict: dict): + def construct_template_from_dict(self, channel_dict: dict) -> ChTemplate: component_name = channel_dict[self.NAME_FIELD].split(".")[0] channel_name = channel_dict[self.NAME_FIELD].split(".")[1] - channel_type = channel_dict.get("type") + channel_type = channel_dict["type"] type_obj = self.parse_type(channel_type) format_str = JsonLoader.preprocess_format_str( channel_dict.get(self.FMT_STR_FIELD) diff --git a/src/fprime_gds/common/loaders/cmd_json_loader.py b/src/fprime_gds/common/loaders/cmd_json_loader.py index c2c620ab..1abcb832 100644 --- a/src/fprime_gds/common/loaders/cmd_json_loader.py +++ b/src/fprime_gds/common/loaders/cmd_json_loader.py @@ -37,31 +37,38 @@ def construct_dicts(self, path): name_dict = {} for cmd_dict in self.json_dict["commands"]: - cmd_name = cmd_dict.get("name") + cmd_temp = self.construct_template_from_dict(cmd_dict) - cmd_comp = cmd_name.split(".")[0] - cmd_mnemonic = cmd_name.split(".")[1] + id_dict[cmd_temp.get_id()] = cmd_temp + name_dict[cmd_temp.get_full_name()] = cmd_temp - cmd_opcode = cmd_dict.get("opcode") + return ( + id_dict, + name_dict, + self.get_versions(), + ) - cmd_desc = cmd_dict.get("annotation") + def construct_template_from_dict(self, cmd_dict: dict) -> CmdTemplate: + cmd_name = cmd_dict.get("name") - # Parse Arguments - cmd_args = [] - for arg in cmd_dict.get("formalParams", []): - cmd_args.append( - ( - arg.get("name"), - arg.get("annotation"), - self.parse_type(arg.get("type")), - ) - ) + cmd_comp = cmd_name.split(".")[0] + cmd_mnemonic = cmd_name.split(".")[1] - cmd_temp = CmdTemplate( - cmd_opcode, cmd_mnemonic, cmd_comp, cmd_args, cmd_desc - ) + cmd_opcode = cmd_dict.get("opcode") - id_dict[cmd_opcode] = cmd_temp - name_dict[cmd_temp.get_full_name()] = cmd_temp + cmd_desc = cmd_dict.get("annotation") + + # Parse Arguments + cmd_args = [] + for arg in cmd_dict.get("formalParams", []): + cmd_args.append( + ( + arg.get("name"), + arg.get("annotation"), + self.parse_type(arg.get("type")), + ) + ) - return id_dict, name_dict, ("unknown", "unknown") + return CmdTemplate( + cmd_opcode, cmd_mnemonic, cmd_comp, cmd_args, cmd_desc + ) diff --git a/src/fprime_gds/common/loaders/event_json_loader.py b/src/fprime_gds/common/loaders/event_json_loader.py index 08f793b8..a0b766d8 100644 --- a/src/fprime_gds/common/loaders/event_json_loader.py +++ b/src/fprime_gds/common/loaders/event_json_loader.py @@ -38,55 +38,55 @@ def construct_dicts(self, path): Returns: A tuple with two event dictionaries (python type dict): - (id_idct, name_dict). The keys are the events' id and name fields + (id_dict, name_dict). The keys are the events' id and name fields respectively and the values are ChTemplate objects """ - versions = self.get_versions() - - # Check if xml dict has events section - if self.json_dict.get("events") is None: - msg = "JSON dict did not have a events section" - raise exceptions.GseControllerParsingException(msg) - id_dict = {} name_dict = {} for event_dict in self.json_dict.get("events"): - event_mnemonic = event_dict.get("name") - event_comp = event_mnemonic.split(".")[0] - event_name = event_mnemonic.split(".")[1] + event_temp = self.construct_template_from_dict(event_dict) - event_id = event_dict[self.ID_TAG] - event_severity = EventSeverity[event_dict[self.SEVERITY_TAG]] - - event_fmt_str = JsonLoader.preprocess_format_str( - event_dict.get(self.FMT_STR_TAG, "") - ) + id_dict[event_temp.get_id()] = event_temp + name_dict[event_temp.get_full_name()] = event_temp - event_desc = event_dict.get(self.DESC_TAG) - - # Parse arguments - event_args = [] - for arg in event_dict.get("formalParams", []): - event_args.append( - ( - arg.get("name"), - arg.get("annotation"), - self.parse_type(arg.get("type")), - ) + return ( + id_dict, + name_dict, + self.get_versions(), + ) + + def construct_template_from_dict(self, event_dict: dict): + event_mnemonic = event_dict.get("name") + event_comp = event_mnemonic.split(".")[0] + event_name = event_mnemonic.split(".")[1] + + event_id = event_dict[self.ID_TAG] + event_severity = EventSeverity[event_dict[self.SEVERITY_TAG]] + + event_fmt_str = JsonLoader.preprocess_format_str( + event_dict.get(self.FMT_STR_TAG, "") + ) + + event_desc = event_dict.get(self.DESC_TAG) + + # Parse arguments + event_args = [] + for arg in event_dict.get("formalParams", []): + event_args.append( + ( + arg.get("name"), + arg.get("annotation"), + self.parse_type(arg.get("type")), ) - - event_temp = EventTemplate( - event_id, - event_name, - event_comp, - event_args, - event_severity, - event_fmt_str, - event_desc, ) - id_dict[event_id] = event_temp - name_dict[event_temp.get_full_name()] = event_temp - - return id_dict, name_dict, versions + return EventTemplate( + event_id, + event_name, + event_comp, + event_args, + event_severity, + event_fmt_str, + event_desc, + ) From f6abfda1697e7c0f7b0aae2bc5ebb35d007b8400 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 12:42:53 -0700 Subject: [PATCH 17/28] Improve behavior of default command selection --- src/fprime_gds/flask/static/addons/commanding/command-input.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fprime_gds/flask/static/addons/commanding/command-input.js b/src/fprime_gds/flask/static/addons/commanding/command-input.js index cee65d51..f34264c5 100644 --- a/src/fprime_gds/flask/static/addons/commanding/command-input.js +++ b/src/fprime_gds/flask/static/addons/commanding/command-input.js @@ -83,7 +83,8 @@ Vue.component("command-input", { this.$root.$refs.command_input = this; }, data: function() { - let selected = command_assignment_helper(null, [], "CMD_NO_OP"); + // Select CMD_NO_OP by default if it exists, otherwise select the first command + let selected = command_assignment_helper("cmdDisp.CMD_NO_OP", [], "CMD_NO_OP"); selected = (selected != null)? selected : Object.values(_datastore.commands)[0]; return { "commands": _datastore.commands, From f53342ee1b0fe582c52081a541d9655951832a90 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 13:00:08 -0700 Subject: [PATCH 18/28] Prioritize selection of JSON dictionary over XML --- src/fprime_gds/executables/utils.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/fprime_gds/executables/utils.py b/src/fprime_gds/executables/utils.py index e81bfa6e..9fc7d124 100644 --- a/src/fprime_gds/executables/utils.py +++ b/src/fprime_gds/executables/utils.py @@ -3,6 +3,7 @@ Utility functions to enable the executables package to function seamlessly. """ + import atexit import signal import subprocess @@ -147,7 +148,7 @@ def get_artifacts_root() -> Path: except FprimeLocationUnknownException: print( "[ERROR] Not in fprime project and no deployment path provided, unable to find dictionary and/or app", - file=sys.stderr + file=sys.stderr, ) sys.exit(-1) except FprimeSettingsException as e: @@ -177,7 +178,7 @@ def find_app(root: Path) -> Path: if len(files) > 1: print( f"[ERROR] Multiple app candidates in binary location {bin_dir}. Specify app manually with --app.", - file=sys.stderr + file=sys.stderr, ) sys.exit(-1) @@ -191,21 +192,31 @@ def find_dict(root: Path) -> Path: print(f"[ERROR] dictionary location {dict_dir} does not exist", file=sys.stderr) sys.exit(-1) - files = [ + xml_dicts = [ child for child in dict_dir.iterdir() if child.is_file() and child.name.endswith("Dictionary.xml") ] + json_dicts = [ + child + for child in dict_dir.iterdir() + if child.is_file() and child.name.endswith("Dictionary.json") + ] + # Select json dictionary if available, otherwise use xml dictionary + dicts = json_dicts or xml_dicts - if not files: - print(f"[ERROR] No xml dictionary found in dictionary location {dict_dir}", file=sys.stderr) + if not dicts: + print( + f"[ERROR] No dictionary found in dictionary location {dict_dir}", + file=sys.stderr, + ) sys.exit(-1) - if len(files) > 1: + if len(dicts) > 1: print( - f"[ERROR] Multiple xml dictionaries found in dictionary location {dict_dir}. Specify dictionary manually with --dictionary.", - file=sys.stderr + f"[ERROR] Multiple dictionaries of same type found in dictionary location {dict_dir}. Specify dictionary manually with --dictionary.", + file=sys.stderr, ) sys.exit(-1) - return files[0] + return dicts[0] From c323648d8c240b419c016de00a4d6ddf316080e8 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 16:39:49 -0700 Subject: [PATCH 19/28] Cache parsed_types in JsonLoader class --- src/fprime_gds/common/loaders/json_loader.py | 153 ++++++++++++------- 1 file changed, 102 insertions(+), 51 deletions(-) diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index 94e472d8..79ea8396 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -39,7 +39,10 @@ class JsonLoader(dict_loader.DictLoader): """Class to help load JSON dictionaries""" - def __init__(self, json_dict: dict): + # Cache parsed type objects at the class level so they can be reused across subclasses + parsed_types: dict = {} + + def __init__(self, json_file: str): """ Constructor @@ -47,13 +50,7 @@ def __init__(self, json_dict: dict): An initialized loader object """ super().__init__() - - # These dicts hold already parsed enum objects so things don't need - # to be parsed multiple times - self.enums = {} - self.serializable_types = {} - self.array_types = {} - with open(json_dict, "r") as f: + with open(json_file, "r") as f: self.json_dict = json.load(f) def get_versions(self): @@ -83,13 +80,16 @@ def parse_type(self, type_dict: dict) -> BaseType: return PRIMITIVE_TYPE_MAP[type_name] if type_name == "string": - # REVIEW NOTE: Does name matter? I believe not + # REVIEW NOTE: All strings of same size will share the same type. I believe this is good? return StringType.construct_type( f'String_{type_dict.get("size")}', type_dict.get("size") ) - # Process for enum/array/serializable types - # TODO: Rework logic here to cache typeDefinitions in member variable, either at read-time or init-time? + # Check if type has already been parsed + if type_name in self.parsed_types: + return self.parsed_types[type_name] + + # Parse new enum/array/serializable types qualified_type = None for type_def in self.json_dict.get("typeDefinitions", []): if type_name == type_def.get("qualifiedName"): @@ -102,55 +102,106 @@ def parse_type(self, type_dict: dict) -> BaseType: ) if qualified_type.get("kind") == "array": - return ArrayType.construct_type( - type_name, - self.parse_type(qualified_type.get("elementType")), - qualified_type.get("size"), - qualified_type.get("elementType").get("format", "{}"), - ) + return self.construct_array_type(type_name, qualified_type) if qualified_type.get("kind") == "enum": - enum_dict = {} - for member in qualified_type.get("enumeratedConstants"): - enum_dict[member.get("name")] = member.get("value") - return EnumType.construct_type( - type_name, - enum_dict, - qualified_type.get("representationType").get("name"), - ) + return self.construct_enum_type(type_name, qualified_type) if qualified_type.get("kind") == "struct": - struct_members = [] - for name, member_dict in qualified_type.get("members").items(): - member_type_dict = member_dict.get("type") - member_type_obj = self.parse_type(member_type_dict) - - # For member arrays (declared inline, so we create a type on the fly) - if member_dict.get("size") is not None: - member_type_obj = ArrayType.construct_type( - f"Array_{member_type_obj.__name__}_{member_dict.get('size')}", - member_type_obj, - member_dict.get("size"), - member_dict.get("type").get("format", "{}"), - ) - - fmt_str = ( - member_type_obj.FORMAT - if hasattr(member_type_obj, "FORMAT") - else "{}" - ) - description = member_type_dict.get("annotation", "") - struct_members.append((name, member_type_obj, fmt_str, description)) - - return SerializableType.construct_type( - type_name, - struct_members, - ) + return self.construct_serializable_type(type_name, qualified_type) raise ValueError( f"Channel entry in dictionary has unknown type {str(type_dict)}" ) + def construct_enum_type(self, type_name: str, qualified_type: dict) -> EnumType: + """ + Constructs an EnumType object of the given type name and qualified type dictionary. + Caches the constructed EnumType object in the parsed_types dictionary. + + Args: + type_name (str): The name of the enum type. + qualified_type (dict): A dictionary containing the qualified type information. + + Returns: + EnumType: The constructed EnumType object. + + """ + enum_dict = {} + for member in qualified_type.get("enumeratedConstants"): + enum_dict[member.get("name")] = member.get("value") + enum_type = EnumType.construct_type( + type_name, + enum_dict, + qualified_type.get("representationType").get("name"), + ) + self.parsed_types[type_name] = enum_type + return enum_type + + def construct_array_type(self, type_name: str, qualified_type: dict) -> ArrayType: + """ + Constructs an ArrayType object based on the given type name and qualified type dictionary. + Caches the constructed ArrayType object in the parsed_types dictionary. + + Args: + type_name (str): The name of the array type. + qualified_type (dict): The qualified type dictionary containing information about the array type. + + Returns: + ArrayType: The constructed ArrayType object. + + """ + array_type = ArrayType.construct_type( + type_name, + self.parse_type(qualified_type.get("elementType")), + qualified_type.get("size"), + qualified_type.get("elementType").get("format", "{}"), + ) + self.parsed_types[type_name] = array_type + return array_type + + def construct_serializable_type( + self, type_name: str, qualified_type: dict + ) -> SerializableType: + """ + Constructs a SerializableType based on the given type name and qualified type dictionary. + Caches the constructed SerializableType object in the parsed_types dictionary. + + Args: + type_name (str): The name of the serializable type. + qualified_type (dict): The qualified type dictionary containing information about the type. + + Returns: + SerializableType: The constructed serializable type. + + """ + struct_members = [] + for name, member_dict in qualified_type.get("members").items(): + member_type_dict = member_dict.get("type") + member_type_obj = self.parse_type(member_type_dict) + + # For member arrays (declared inline, so we create a type on the fly) + if member_dict.get("size") is not None: + member_type_obj = ArrayType.construct_type( + f"Array_{member_type_obj.__name__}_{member_dict.get('size')}", + member_type_obj, + member_dict.get("size"), + member_dict.get("type").get("format", "{}"), + ) + # TODO: does this need to be preprocessed or something? + fmt_str = ( + member_type_obj.FORMAT if hasattr(member_type_obj, "FORMAT") else "{}" + ) + description = member_type_dict.get("annotation", "") + struct_members.append((name, member_type_obj, fmt_str, description)) + + ser_type = SerializableType.construct_type( + type_name, + struct_members, + ) + self.parsed_types[type_name] = ser_type + return ser_type + @staticmethod def preprocess_format_str(format_str: Optional[str]) -> str: """Preprocess format strings before using them in Python format function From c6e79bd25f1fe18cd41fc7dfc7c1d521c402d3f2 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 16:44:06 -0700 Subject: [PATCH 20/28] Add test cases --- .../resources/RefTopologyDictionary.json | 9659 +++++++++++++++++ .../common/loaders/test_json_loader.py | 152 + 2 files changed, 9811 insertions(+) create mode 100644 test/fprime_gds/common/loaders/resources/RefTopologyDictionary.json create mode 100644 test/fprime_gds/common/loaders/test_json_loader.py diff --git a/test/fprime_gds/common/loaders/resources/RefTopologyDictionary.json b/test/fprime_gds/common/loaders/resources/RefTopologyDictionary.json new file mode 100644 index 00000000..a51b36f4 --- /dev/null +++ b/test/fprime_gds/common/loaders/resources/RefTopologyDictionary.json @@ -0,0 +1,9659 @@ +{ + "metadata" : { + "deploymentName" : "Ref", + "projectVersion" : "TestVersion", + "frameworkVersion" : "TestVersion", + "libraryVersions" : [ + ], + "dictionarySpecVersion" : "1.0.0" + }, + "typeDefinitions" : [ + { + "kind" : "struct", + "qualifiedName" : "Ref.PacketStat", + "members" : { + "BuffRecv" : { + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "index" : 0, + "annotation" : "Number of buffers received" + }, + "BuffErr" : { + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "index" : 1, + "annotation" : "Number of buffers received with errors" + }, + "PacketStatus" : { + "type" : { + "name" : "Ref.PacketRecvStatus", + "kind" : "qualifiedIdentifier" + }, + "index" : 2, + "annotation" : "Packet Status" + } + }, + "default" : { + "BuffRecv" : 0, + "BuffErr" : 0, + "PacketStatus" : "Ref.PacketRecvStatus.PACKET_STATE_NO_PACKETS" + }, + "annotation" : "Some Packet Statistics" + }, + { + "kind" : "array", + "qualifiedName" : "Ref.SignalPairSet", + "size" : 4, + "elementType" : { + "name" : "Ref.SignalPair", + "kind" : "qualifiedIdentifier" + }, + "default" : [ + { + "time" : 0.0, + "value" : 0.0 + }, + { + "time" : 0.0, + "value" : 0.0 + }, + { + "time" : 0.0, + "value" : 0.0 + }, + { + "time" : 0.0, + "value" : 0.0 + } + ] + }, + { + "kind" : "enum", + "qualifiedName" : "Fw.Wait", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "WAIT", + "value" : 0 + }, + { + "name" : "NO_WAIT", + "value" : 1 + } + ], + "default" : "Fw.Wait.WAIT", + "annotation" : "Wait or don't wait for something" + }, + { + "kind" : "enum", + "qualifiedName" : "Svc.CmdSequencer.FileReadStage", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "READ_HEADER", + "value" : 0 + }, + { + "name" : "READ_HEADER_SIZE", + "value" : 1 + }, + { + "name" : "DESER_SIZE", + "value" : 2 + }, + { + "name" : "DESER_NUM_RECORDS", + "value" : 3 + }, + { + "name" : "DESER_TIME_BASE", + "value" : 4 + }, + { + "name" : "DESER_TIME_CONTEXT", + "value" : 5 + }, + { + "name" : "READ_SEQ_CRC", + "value" : 6 + }, + { + "name" : "READ_SEQ_DATA", + "value" : 7 + }, + { + "name" : "READ_SEQ_DATA_SIZE", + "value" : 8 + } + ], + "default" : "Svc.CmdSequencer.FileReadStage.READ_HEADER", + "annotation" : "The stage of the file read operation" + }, + { + "kind" : "enum", + "qualifiedName" : "Fw.ParamValid", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "UNINIT", + "value" : 0 + }, + { + "name" : "VALID", + "value" : 1 + }, + { + "name" : "INVALID", + "value" : 2 + }, + { + "name" : "DEFAULT", + "value" : 3 + } + ], + "default" : "Fw.ParamValid.UNINIT", + "annotation" : "Enum representing parameter validity" + }, + { + "kind" : "enum", + "qualifiedName" : "Svc.ActiveLogger.Enabled", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "ENABLED", + "value" : 0, + "annotation" : "Enabled state" + }, + { + "name" : "DISABLED", + "value" : 1, + "annotation" : "Disabled state" + } + ], + "default" : "Svc.ActiveLogger.Enabled.ENABLED", + "annotation" : "Enabled and disabled state" + }, + { + "kind" : "enum", + "qualifiedName" : "Ref.Choice", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "ONE", + "value" : 0 + }, + { + "name" : "TWO", + "value" : 1 + }, + { + "name" : "RED", + "value" : 2 + }, + { + "name" : "BLUE", + "value" : 3 + } + ], + "default" : "Ref.Choice.ONE", + "annotation" : "Enumeration type for use later" + }, + { + "kind" : "struct", + "qualifiedName" : "Ref.SignalPair", + "members" : { + "time" : { + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "index" : 0, + "format" : "{f}" + }, + "value" : { + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "index" : 1, + "format" : "{f}" + } + }, + "default" : { + "time" : 0.0, + "value" : 0.0 + } + }, + { + "kind" : "enum", + "qualifiedName" : "Svc.PrmDb.PrmReadError", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "OPEN", + "value" : 0 + }, + { + "name" : "DELIMITER", + "value" : 1 + }, + { + "name" : "DELIMITER_SIZE", + "value" : 2 + }, + { + "name" : "DELIMITER_VALUE", + "value" : 3 + }, + { + "name" : "RECORD_SIZE", + "value" : 4 + }, + { + "name" : "RECORD_SIZE_SIZE", + "value" : 5 + }, + { + "name" : "RECORD_SIZE_VALUE", + "value" : 6 + }, + { + "name" : "PARAMETER_ID", + "value" : 7 + }, + { + "name" : "PARAMETER_ID_SIZE", + "value" : 8 + }, + { + "name" : "PARAMETER_VALUE", + "value" : 9 + }, + { + "name" : "PARAMETER_VALUE_SIZE", + "value" : 10 + } + ], + "default" : "Svc.PrmDb.PrmReadError.OPEN", + "annotation" : "Parameter read error" + }, + { + "kind" : "array", + "qualifiedName" : "Ref.ManyChoices", + "size" : 2, + "elementType" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "default" : [ + "Ref.Choice.ONE", + "Ref.Choice.ONE" + ], + "annotation" : "Enumeration array" + }, + { + "kind" : "enum", + "qualifiedName" : "Svc.CmdSequencer.SeqMode", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "STEP", + "value" : 0 + }, + { + "name" : "AUTO", + "value" : 1 + } + ], + "default" : "Svc.CmdSequencer.SeqMode.STEP", + "annotation" : "The sequencer mode" + }, + { + "kind" : "enum", + "qualifiedName" : "Fw.DeserialStatus", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "OK", + "value" : 0 + }, + { + "name" : "BUFFER_EMPTY", + "value" : 3, + "annotation" : "Deserialization buffer was empty when trying to read data" + }, + { + "name" : "FORMAT_ERROR", + "value" : 4, + "annotation" : "Deserialization data had incorrect values (unexpected data types)" + }, + { + "name" : "SIZE_MISMATCH", + "value" : 5, + "annotation" : "Data was left in in the buffer, but not enough to deserialize" + }, + { + "name" : "TYPE_MISMATCH", + "value" : 6, + "annotation" : "Deserialized type ID didn't match" + } + ], + "default" : "Fw.DeserialStatus.OK", + "annotation" : "Deserialization status" + }, + { + "kind" : "enum", + "qualifiedName" : "Ref.PacketRecvStatus", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "PACKET_STATE_NO_PACKETS", + "value" : 0 + }, + { + "name" : "PACKET_STATE_OK", + "value" : 1 + }, + { + "name" : "PACKET_STATE_ERRORS", + "value" : 3, + "annotation" : "Receiver has seen errors" + } + ], + "default" : "Ref.PacketRecvStatus.PACKET_STATE_NO_PACKETS", + "annotation" : "Packet receive status" + }, + { + "kind" : "struct", + "qualifiedName" : "Ref.ChoicePair", + "members" : { + "firstChoice" : { + "type" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "index" : 0, + "annotation" : "The first choice to make" + }, + "secondChoice" : { + "type" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "index" : 1, + "annotation" : "The second choice to make" + } + }, + "default" : { + "firstChoice" : "Ref.Choice.ONE", + "secondChoice" : "Ref.Choice.ONE" + }, + "annotation" : "Structure of enums" + }, + { + "kind" : "enum", + "qualifiedName" : "Svc.PrmDb.PrmWriteError", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "OPEN", + "value" : 0 + }, + { + "name" : "DELIMITER", + "value" : 1 + }, + { + "name" : "DELIMITER_SIZE", + "value" : 2 + }, + { + "name" : "RECORD_SIZE", + "value" : 3 + }, + { + "name" : "RECORD_SIZE_SIZE", + "value" : 4 + }, + { + "name" : "PARAMETER_ID", + "value" : 5 + }, + { + "name" : "PARAMETER_ID_SIZE", + "value" : 6 + }, + { + "name" : "PARAMETER_VALUE", + "value" : 7 + }, + { + "name" : "PARAMETER_VALUE_SIZE", + "value" : 8 + } + ], + "default" : "Svc.PrmDb.PrmWriteError.OPEN", + "annotation" : "Parameter write error" + }, + { + "kind" : "array", + "qualifiedName" : "Ref.TooManyChoices", + "size" : 2, + "elementType" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "default" : [ + [ + "Ref.Choice.ONE", + "Ref.Choice.ONE" + ], + [ + "Ref.Choice.ONE", + "Ref.Choice.ONE" + ] + ], + "annotation" : "Array of array" + }, + { + "kind" : "struct", + "qualifiedName" : "Ref.SignalInfo", + "members" : { + "type" : { + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "index" : 0 + }, + "history" : { + "type" : { + "name" : "Ref.SignalSet", + "kind" : "qualifiedIdentifier" + }, + "index" : 1 + }, + "pairHistory" : { + "type" : { + "name" : "Ref.SignalPairSet", + "kind" : "qualifiedIdentifier" + }, + "index" : 2 + } + }, + "default" : { + "type" : "Ref.SignalType.TRIANGLE", + "history" : [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "pairHistory" : [ + { + "time" : 0.0, + "value" : 0.0 + }, + { + "time" : 0.0, + "value" : 0.0 + }, + { + "time" : 0.0, + "value" : 0.0 + }, + { + "time" : 0.0, + "value" : 0.0 + } + ] + } + }, + { + "kind" : "struct", + "qualifiedName" : "Ref.ScalarStruct", + "members" : { + "u32" : { + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "index" : 0 + }, + "f64" : { + "type" : { + "name" : "F64", + "kind" : "float", + "size" : 64 + }, + "index" : 1 + }, + "f32" : { + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "index" : 2 + }, + "i8" : { + "type" : { + "name" : "I8", + "kind" : "integer", + "size" : 8, + "signed" : true + }, + "index" : 3 + }, + "i16" : { + "type" : { + "name" : "I16", + "kind" : "integer", + "size" : 16, + "signed" : true + }, + "index" : 4 + }, + "u8" : { + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "index" : 5 + }, + "u64" : { + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "index" : 6 + }, + "i64" : { + "type" : { + "name" : "I64", + "kind" : "integer", + "size" : 64, + "signed" : true + }, + "index" : 7 + }, + "i32" : { + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "index" : 8 + }, + "u16" : { + "type" : { + "name" : "U16", + "kind" : "integer", + "size" : 16, + "signed" : false + }, + "index" : 9 + } + }, + "default" : { + "u32" : 0, + "f64" : 0.0, + "f32" : 0.0, + "i8" : 0, + "i16" : 0, + "u8" : 0, + "u64" : 0, + "i64" : 0, + "i32" : 0, + "u16" : 0 + }, + "annotation" : "All scalar inputs" + }, + { + "kind" : "enum", + "qualifiedName" : "Fw.Enabled", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "DISABLED", + "value" : 0, + "annotation" : "Disabled state" + }, + { + "name" : "ENABLED", + "value" : 1, + "annotation" : "Enabled state" + } + ], + "default" : "Fw.Enabled.DISABLED", + "annotation" : "Enabled and disabled states" + }, + { + "kind" : "enum", + "qualifiedName" : "Fw.CmdResponse", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "OK", + "value" : 0, + "annotation" : "Command successfully executed" + }, + { + "name" : "INVALID_OPCODE", + "value" : 1, + "annotation" : "Invalid opcode dispatched" + }, + { + "name" : "VALIDATION_ERROR", + "value" : 2, + "annotation" : "Command failed validation" + }, + { + "name" : "FORMAT_ERROR", + "value" : 3, + "annotation" : "Command failed to deserialize" + }, + { + "name" : "EXECUTION_ERROR", + "value" : 4, + "annotation" : "Command had execution error" + }, + { + "name" : "BUSY", + "value" : 5, + "annotation" : "Component busy" + } + ], + "default" : "Fw.CmdResponse.OK", + "annotation" : "Enum representing a command response" + }, + { + "kind" : "enum", + "qualifiedName" : "Svc.CmdSequencer.BlockState", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "BLOCK", + "value" : 0 + }, + { + "name" : "NO_BLOCK", + "value" : 1 + } + ], + "default" : "Svc.CmdSequencer.BlockState.BLOCK", + "annotation" : "Sequencer blocking state" + }, + { + "kind" : "enum", + "qualifiedName" : "Fw.DpState", + "representationType" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "enumeratedConstants" : [ + { + "name" : "UNTRANSMITTED", + "value" : 0, + "annotation" : "The untransmitted state" + }, + { + "name" : "PARTIAL", + "value" : 1, + "annotation" : "The partially transmitted state\nA data product is in this state from the start of transmission\nuntil transmission is complete." + }, + { + "name" : "TRANSMITTED", + "value" : 2, + "annotation" : "The transmitted state" + } + ], + "default" : "Fw.DpState.UNTRANSMITTED" + }, + { + "kind" : "enum", + "qualifiedName" : "Ref.SignalType", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "TRIANGLE", + "value" : 0 + }, + { + "name" : "SQUARE", + "value" : 1 + }, + { + "name" : "SINE", + "value" : 2 + }, + { + "name" : "NOISE", + "value" : 3 + } + ], + "default" : "Ref.SignalType.TRIANGLE" + }, + { + "kind" : "struct", + "qualifiedName" : "Ref.ChoiceSlurry", + "members" : { + "tooManyChoices" : { + "type" : { + "name" : "Ref.TooManyChoices", + "kind" : "qualifiedIdentifier" + }, + "index" : 0, + "annotation" : "A large set of disorganized choices" + }, + "separateChoice" : { + "type" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "index" : 1, + "annotation" : "A singular choice" + }, + "choicePair" : { + "type" : { + "name" : "Ref.ChoicePair", + "kind" : "qualifiedIdentifier" + }, + "index" : 2, + "annotation" : "A pair of choices" + }, + "choiceAsMemberArray" : { + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "index" : 3, + "size" : 2, + "annotation" : "An array of choices defined as member array" + } + }, + "default" : { + "tooManyChoices" : [ + [ + "Ref.Choice.ONE", + "Ref.Choice.ONE" + ], + [ + "Ref.Choice.ONE", + "Ref.Choice.ONE" + ] + ], + "separateChoice" : "Ref.Choice.ONE", + "choicePair" : { + "firstChoice" : "Ref.Choice.ONE", + "secondChoice" : "Ref.Choice.ONE" + }, + "choiceAsMemberArray" : 0 + }, + "annotation" : "Structure of enums (with an multi-dimensional array and structure)" + }, + { + "kind" : "enum", + "qualifiedName" : "Svc.DpHdrField", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "DESCRIPTOR", + "value" : 0 + }, + { + "name" : "ID", + "value" : 1 + }, + { + "name" : "PRIORITY", + "value" : 2 + }, + { + "name" : "CRC", + "value" : 3 + } + ], + "default" : "Svc.DpHdrField.DESCRIPTOR", + "annotation" : "Header validation error" + }, + { + "kind" : "array", + "qualifiedName" : "Ref.FloatSet", + "size" : 3, + "elementType" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "default" : [ + 0.0, + 0.0, + 0.0 + ], + "annotation" : "Set of floating points to emit" + }, + { + "kind" : "enum", + "qualifiedName" : "Ref.SendBuff.ActiveState", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "SEND_IDLE", + "value" : 0 + }, + { + "name" : "SEND_ACTIVE", + "value" : 1 + } + ], + "default" : "Ref.SendBuff.ActiveState.SEND_IDLE", + "annotation" : "Active state" + }, + { + "kind" : "enum", + "qualifiedName" : "Svc.ActiveLogger.FilterSeverity", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "WARNING_HI", + "value" : 0, + "annotation" : "Filter WARNING_HI events" + }, + { + "name" : "WARNING_LO", + "value" : 1, + "annotation" : "Filter WARNING_LO events" + }, + { + "name" : "COMMAND", + "value" : 2, + "annotation" : "Filter COMMAND events" + }, + { + "name" : "ACTIVITY_HI", + "value" : 3, + "annotation" : "Filter ACTIVITY_HI events" + }, + { + "name" : "ACTIVITY_LO", + "value" : 4, + "annotation" : "Filter ACTIVITY_LO events" + }, + { + "name" : "DIAGNOSTIC", + "value" : 5, + "annotation" : "Filter DIAGNOSTIC events" + } + ], + "default" : "Svc.ActiveLogger.FilterSeverity.WARNING_HI", + "annotation" : "Severity level for event filtering\nSimilar to Fw::LogSeverity, but no FATAL event" + }, + { + "kind" : "enum", + "qualifiedName" : "Svc.SystemResourceEnabled", + "representationType" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "enumeratedConstants" : [ + { + "name" : "DISABLED", + "value" : 0 + }, + { + "name" : "ENABLED", + "value" : 1 + } + ], + "default" : "Svc.SystemResourceEnabled.DISABLED" + }, + { + "kind" : "array", + "qualifiedName" : "Ref.SignalSet", + "size" : 4, + "elementType" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "default" : [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "format" : "{f}" + }, + { + "kind" : "struct", + "qualifiedName" : "Svc.DpRecord", + "members" : { + "priority" : { + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "index" : 0 + }, + "size" : { + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "index" : 1 + }, + "state" : { + "type" : { + "name" : "Fw.DpState", + "kind" : "qualifiedIdentifier" + }, + "index" : 2 + }, + "tSec" : { + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "index" : 3 + }, + "id" : { + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "index" : 4 + }, + "tSub" : { + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "index" : 5 + } + }, + "default" : { + "priority" : 0, + "size" : 0, + "state" : "Fw.DpState.UNTRANSMITTED", + "tSec" : 0, + "id" : 0, + "tSub" : 0 + }, + "annotation" : "Data structure representing a data product." + } + ], + "commands" : [ + { + "name" : "pingRcvr.PR_StopPings", + "commandKind" : "async", + "opcode" : 2560, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Command to disable ping response" + }, + { + "name" : "fileManager.CreateDirectory", + "commandKind" : "async", + "opcode" : 2048, + "formalParams" : [ + { + "name" : "dirName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The directory to create" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Create a directory" + }, + { + "name" : "health.HLTH_ENABLE", + "commandKind" : "async", + "opcode" : 8192, + "formalParams" : [ + { + "name" : "enable", + "type" : { + "name" : "Fw.Enabled", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "whether or not health checks are enabled" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "A command to enable or disable health checks" + }, + { + "name" : "cmdSeq.CS_CANCEL", + "commandKind" : "async", + "opcode" : 1538, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Cancel a command sequence" + }, + { + "name" : "SG3.SignalGen_Toggle", + "commandKind" : "async", + "opcode" : 8961, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Toggle Signal Generator On/Off." + }, + { + "name" : "SG3.SignalGen_Settings", + "commandKind" : "async", + "opcode" : 8960, + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SigType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "sendBuffComp.SB_GEN_ASSERT", + "commandKind" : "async", + "opcode" : 9731, + "formalParams" : [ + { + "name" : "arg1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "First ASSERT Argument" + }, + { + "name" : "arg2", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Second ASSERT Argument" + }, + { + "name" : "arg3", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Third ASSERT Argument" + }, + { + "name" : "arg4", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Fourth ASSERT Argument" + }, + { + "name" : "arg5", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Fifth ASSERT Argument" + }, + { + "name" : "arg6", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Sixth ASSERT Argument" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Generate an ASSERT" + }, + { + "name" : "SG1.SignalGen_Skip", + "commandKind" : "async", + "opcode" : 8450, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Skip next sample" + }, + { + "name" : "fileDownlink.Cancel", + "commandKind" : "async", + "opcode" : 1793, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Cancel the downlink in progress, if any" + }, + { + "name" : "recvBuffComp.PARAMETER2_PARAM_SET", + "commandKind" : "set", + "opcode" : 18178, + "formalParams" : [ + { + "name" : "val", + "type" : { + "name" : "I16", + "kind" : "integer", + "size" : 16, + "signed" : true + }, + "ref" : false + } + ], + "annotation" : "A test parameter" + }, + { + "name" : "SG3.SignalGen_Dp", + "commandKind" : "async", + "opcode" : 8963, + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "SG4.SignalGen_Skip", + "commandKind" : "async", + "opcode" : 9218, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Skip next sample" + }, + { + "name" : "typeDemo.DUMP_TYPED_PARAMETERS", + "commandKind" : "sync", + "opcode" : 4371, + "formalParams" : [ + ], + "annotation" : "Dump the typed parameters" + }, + { + "name" : "SG2.SignalGen_Toggle", + "commandKind" : "async", + "opcode" : 8705, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Toggle Signal Generator On/Off." + }, + { + "name" : "eventLogger.DUMP_FILTER_STATE", + "commandKind" : "async", + "opcode" : 2819, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Dump the filter states via events" + }, + { + "name" : "fileDownlink.SendFile", + "commandKind" : "async", + "opcode" : 1792, + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The name of the on-board file to send" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The name of the destination file on the ground" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Read a named file off the disk. Divide it into packets and send the packets for transmission to the ground." + }, + { + "name" : "SG4.SignalGen_Settings", + "commandKind" : "async", + "opcode" : 9216, + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SigType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "dpMgr.CLEAR_EVENT_THROTTLE", + "commandKind" : "async", + "opcode" : 3840, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Clear event throttling" + }, + { + "name" : "typeDemo.CHOICE_PRM_PARAM_SET", + "commandKind" : "set", + "opcode" : 4353, + "formalParams" : [ + { + "name" : "val", + "type" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "annotation" : "Single enumeration parameter" + }, + { + "name" : "typeDemo.GLUTTON_OF_CHOICE_WITH_FRIENDS", + "commandKind" : "sync", + "opcode" : 4368, + "formalParams" : [ + { + "name" : "repeat", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "Number of times to repeat the choices" + }, + { + "name" : "choices", + "type" : { + "name" : "Ref.ChoiceSlurry", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "A phenomenal amount of choice" + }, + { + "name" : "repeat_max", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "Limit to the number of repetitions" + } + ], + "annotation" : "Multiple choices command via Complex Structure with a preceding and following argument" + }, + { + "name" : "SG5.SignalGen_Dp", + "commandKind" : "async", + "opcode" : 9475, + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "typeDemo.CHOICES_PRM_PARAM_SAVE", + "commandKind" : "save", + "opcode" : 4358, + "formalParams" : [ + ], + "annotation" : "Multiple enumeration parameter via Array" + }, + { + "name" : "fileManager.MoveFile", + "commandKind" : "async", + "opcode" : 2049, + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The source file name" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The destination file name" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Move a file" + }, + { + "name" : "systemResources.VERSION", + "commandKind" : "guarded", + "opcode" : 19201, + "formalParams" : [ + ], + "annotation" : "Report version as EVR" + }, + { + "name" : "cmdDisp.CMD_CLEAR_TRACKING", + "commandKind" : "async", + "opcode" : 1283, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Clear command tracking info to recover from components not returning status" + }, + { + "name" : "typeDemo.CHOICE_PAIR_WITH_FRIENDS", + "commandKind" : "sync", + "opcode" : 4364, + "formalParams" : [ + { + "name" : "repeat", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "Number of times to repeat the choices" + }, + { + "name" : "choices", + "type" : { + "name" : "Ref.ChoicePair", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "A pair of choices" + }, + { + "name" : "repeat_max", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "Limit to the number of repetitions" + } + ], + "annotation" : "Multiple choices command via Structure with a preceding and following argument" + }, + { + "name" : "sendBuffComp.PARAMETER3_PARAM_SET", + "commandKind" : "set", + "opcode" : 9738, + "formalParams" : [ + { + "name" : "val", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false + } + ], + "annotation" : "A test parameter" + }, + { + "name" : "SG5.SignalGen_Settings", + "commandKind" : "async", + "opcode" : 9472, + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SigType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "recvBuffComp.PARAMETER1_PARAM_SAVE", + "commandKind" : "save", + "opcode" : 18177, + "formalParams" : [ + ], + "annotation" : "A test parameter" + }, + { + "name" : "typeDemo.GLUTTON_OF_CHOICE_PRM_PARAM_SAVE", + "commandKind" : "save", + "opcode" : 4370, + "formalParams" : [ + ], + "annotation" : "Multiple enumeration parameter via Complex Structure" + }, + { + "name" : "SG4.SignalGen_Toggle", + "commandKind" : "async", + "opcode" : 9217, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Toggle Signal Generator On/Off." + }, + { + "name" : "cmdDisp.CMD_NO_OP_STRING", + "commandKind" : "async", + "opcode" : 1281, + "formalParams" : [ + { + "name" : "arg1", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The String command argument" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "No-op string command" + }, + { + "name" : "cmdSeq.CS_AUTO", + "commandKind" : "async", + "opcode" : 1541, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Set the run mode to AUTO." + }, + { + "name" : "sendBuffComp.SB_GEN_FATAL", + "commandKind" : "async", + "opcode" : 9730, + "formalParams" : [ + { + "name" : "arg1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "First FATAL Argument" + }, + { + "name" : "arg2", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Second FATAL Argument" + }, + { + "name" : "arg3", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Third FATAL Argument" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Generate a FATAL EVR" + }, + { + "name" : "fileDownlink.SendPartial", + "commandKind" : "async", + "opcode" : 1794, + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The name of the on-board file to send" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The name of the destination file on the ground" + }, + { + "name" : "startOffset", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Starting offset of the source file" + }, + { + "name" : "length", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Number of bytes to send from starting offset. Length of 0 implies until the end of the file" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Read a named file off the disk from a starting position. Divide it into packets and send the packets for transmission to the ground." + }, + { + "name" : "SG1.SignalGen_Dp", + "commandKind" : "async", + "opcode" : 8451, + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "cmdSeq.CS_STEP", + "commandKind" : "async", + "opcode" : 1540, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Perform one step in a command sequence. Valid only if CmdSequencer is in MANUAL run mode." + }, + { + "name" : "SG2.SignalGen_Settings", + "commandKind" : "async", + "opcode" : 8704, + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SigType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "fileManager.AppendFile", + "commandKind" : "async", + "opcode" : 2053, + "formalParams" : [ + { + "name" : "source", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file to take content from" + }, + { + "name" : "target", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file to append to" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Append 1 file's contents to the end of another." + }, + { + "name" : "cmdSeq.CS_START", + "commandKind" : "async", + "opcode" : 1539, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Start running a command sequence" + }, + { + "name" : "fileManager.ShellCommand", + "commandKind" : "async", + "opcode" : 2052, + "formalParams" : [ + { + "name" : "command", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The shell command string" + }, + { + "name" : "logFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the log file" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Perform a Linux shell command and write the output to a log file." + }, + { + "name" : "typeDemo.EXTRA_CHOICES_PRM_PARAM_SET", + "commandKind" : "set", + "opcode" : 4361, + "formalParams" : [ + { + "name" : "val", + "type" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "annotation" : "Too many enumeration parameter via Array" + }, + { + "name" : "sendBuffComp.PARAMETER3_PARAM_SAVE", + "commandKind" : "save", + "opcode" : 9739, + "formalParams" : [ + ], + "annotation" : "A test parameter" + }, + { + "name" : "recvBuffComp.PARAMETER1_PARAM_SET", + "commandKind" : "set", + "opcode" : 18176, + "formalParams" : [ + { + "name" : "val", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "annotation" : "A test parameter" + }, + { + "name" : "typeDemo.CHOICE", + "commandKind" : "sync", + "opcode" : 4352, + "formalParams" : [ + { + "name" : "choice", + "type" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "A single choice" + } + ], + "annotation" : "Single choice command" + }, + { + "name" : "dpCat.CLEAR_CATALOG", + "commandKind" : "async", + "opcode" : 3587, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "clear existing catalog" + }, + { + "name" : "typeDemo.CHOICE_PRM_PARAM_SAVE", + "commandKind" : "save", + "opcode" : 4354, + "formalParams" : [ + ], + "annotation" : "Single enumeration parameter" + }, + { + "name" : "typeDemo.EXTRA_CHOICES", + "commandKind" : "sync", + "opcode" : 4359, + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.TooManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "Way to many choices to make" + } + ], + "annotation" : "Too many choice command via Array" + }, + { + "name" : "typeDemo.CHOICE_PAIR_PRM_PARAM_SET", + "commandKind" : "set", + "opcode" : 4365, + "formalParams" : [ + { + "name" : "val", + "type" : { + "name" : "Ref.ChoicePair", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "annotation" : "Multiple enumeration parameter via Structure" + }, + { + "name" : "dpWriter.CLEAR_EVENT_THROTTLE", + "commandKind" : "async", + "opcode" : 4096, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Clear event throttling" + }, + { + "name" : "sendBuffComp.SB_INJECT_PKT_ERROR", + "commandKind" : "async", + "opcode" : 9729, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Send a bad packet" + }, + { + "name" : "cmdSeq.CS_MANUAL", + "commandKind" : "async", + "opcode" : 1542, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Set the run mode to MANUAL." + }, + { + "name" : "dpCat.STOP_XMIT_CATALOG", + "commandKind" : "async", + "opcode" : 3586, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Stop transmitting catalog" + }, + { + "name" : "cmdDisp.CMD_TEST_CMD_1", + "commandKind" : "async", + "opcode" : 1282, + "formalParams" : [ + { + "name" : "arg1", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The I32 command argument" + }, + { + "name" : "arg2", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false, + "annotation" : "The F32 command argument" + }, + { + "name" : "arg3", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "The U8 command argument" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "No-op command" + }, + { + "name" : "typeDemo.GLUTTON_OF_CHOICE_PRM_PARAM_SET", + "commandKind" : "set", + "opcode" : 4369, + "formalParams" : [ + { + "name" : "val", + "type" : { + "name" : "Ref.ChoiceSlurry", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "annotation" : "Multiple enumeration parameter via Complex Structure" + }, + { + "name" : "fileManager.RemoveFile", + "commandKind" : "async", + "opcode" : 2051, + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The file to remove" + }, + { + "name" : "ignoreErrors", + "type" : { + "name" : "bool", + "kind" : "bool", + "size" : 8 + }, + "ref" : false, + "annotation" : "Ignore nonexistent files" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Remove a file" + }, + { + "name" : "sendBuffComp.PARAMETER4_PARAM_SAVE", + "commandKind" : "save", + "opcode" : 9741, + "formalParams" : [ + ], + "annotation" : "A test parameter" + }, + { + "name" : "typeDemo.SEND_SCALARS", + "commandKind" : "sync", + "opcode" : 4373, + "formalParams" : [ + { + "name" : "scalar_input", + "type" : { + "name" : "Ref.ScalarStruct", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "annotation" : "Send scalars" + }, + { + "name" : "typeDemo.EXTRA_CHOICES_PRM_PARAM_SAVE", + "commandKind" : "save", + "opcode" : 4362, + "formalParams" : [ + ], + "annotation" : "Too many enumeration parameter via Array" + }, + { + "name" : "sendBuffComp.PARAMETER4_PARAM_SET", + "commandKind" : "set", + "opcode" : 9740, + "formalParams" : [ + { + "name" : "val", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + } + ], + "annotation" : "A test parameter" + }, + { + "name" : "fileManager.FileSize", + "commandKind" : "async", + "opcode" : 2054, + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The file to get the size of" + } + ], + "queueFullBehavior" : "assert" + }, + { + "name" : "eventLogger.SET_EVENT_FILTER", + "commandKind" : "sync", + "opcode" : 2816, + "formalParams" : [ + { + "name" : "filterLevel", + "type" : { + "name" : "Svc.ActiveLogger.FilterSeverity", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "Filter level" + }, + { + "name" : "filterEnabled", + "type" : { + "name" : "Svc.ActiveLogger.Enabled", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "Filter state" + } + ], + "annotation" : "Set filter for reporting events. Events are not stored in component." + }, + { + "name" : "typeDemo.CHOICES", + "commandKind" : "sync", + "opcode" : 4355, + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "A set of choices" + } + ], + "annotation" : "Multiple choice command via Array" + }, + { + "name" : "health.HLTH_CHNG_PING", + "commandKind" : "async", + "opcode" : 8194, + "formalParams" : [ + { + "name" : "entry", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The entry to modify" + }, + { + "name" : "warningValue", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Ping warning threshold" + }, + { + "name" : "fatalValue", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Ping fatal threshold" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Change ping value" + }, + { + "name" : "typeDemo.EXTRA_CHOICES_WITH_FRIENDS", + "commandKind" : "sync", + "opcode" : 4360, + "formalParams" : [ + { + "name" : "repeat", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "Number of times to repeat the choices" + }, + { + "name" : "choices", + "type" : { + "name" : "Ref.TooManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "Way to many choices to make" + }, + { + "name" : "repeat_max", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "Limit to the number of repetitions" + } + ], + "annotation" : "Too many choices command via Array with a preceding and following argument" + }, + { + "name" : "SG2.SignalGen_Dp", + "commandKind" : "async", + "opcode" : 8707, + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "typeDemo.CHOICE_PAIR_PRM_PARAM_SAVE", + "commandKind" : "save", + "opcode" : 4366, + "formalParams" : [ + ], + "annotation" : "Multiple enumeration parameter via Structure" + }, + { + "name" : "SG5.SignalGen_Toggle", + "commandKind" : "async", + "opcode" : 9473, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Toggle Signal Generator On/Off." + }, + { + "name" : "cmdSeq.CS_JOIN_WAIT", + "commandKind" : "async", + "opcode" : 1543, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Wait for sequences that are running to finish. Allow user to run multiple seq files in SEQ_NO_BLOCK mode then wait for them to finish before allowing more seq run request." + }, + { + "name" : "SG1.SignalGen_Settings", + "commandKind" : "async", + "opcode" : 8448, + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SigType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "cmdSeq.CS_RUN", + "commandKind" : "async", + "opcode" : 1536, + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 240 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + }, + { + "name" : "block", + "type" : { + "name" : "Svc.CmdSequencer.BlockState", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "Return command status when complete or not" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Run a command sequence file" + }, + { + "name" : "SG1.SignalGen_Toggle", + "commandKind" : "async", + "opcode" : 8449, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Toggle Signal Generator On/Off." + }, + { + "name" : "dpCat.BUILD_CATALOG", + "commandKind" : "async", + "opcode" : 3584, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Build catalog from data product directory" + }, + { + "name" : "eventLogger.SET_ID_FILTER", + "commandKind" : "async", + "opcode" : 2818, + "formalParams" : [ + { + "name" : "ID", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "idFilterEnabled", + "type" : { + "name" : "Svc.ActiveLogger.Enabled", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "ID filter state" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Filter a particular ID" + }, + { + "name" : "SG4.SignalGen_Dp", + "commandKind" : "async", + "opcode" : 9219, + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Signal Generator Settings" + }, + { + "name" : "recvBuffComp.PARAMETER2_PARAM_SAVE", + "commandKind" : "save", + "opcode" : 18179, + "formalParams" : [ + ], + "annotation" : "A test parameter" + }, + { + "name" : "SG3.SignalGen_Skip", + "commandKind" : "async", + "opcode" : 8962, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Skip next sample" + }, + { + "name" : "dpCat.START_XMIT_CATALOG", + "commandKind" : "async", + "opcode" : 3585, + "formalParams" : [ + { + "name" : "wait", + "type" : { + "name" : "Fw.Wait", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "have START_XMIT command wait for catalog to complete transmitting" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Start transmitting catalog" + }, + { + "name" : "typeDemo.DUMP_FLOATS", + "commandKind" : "sync", + "opcode" : 4372, + "formalParams" : [ + ], + "annotation" : "Dump the float values" + }, + { + "name" : "cmdDisp.CMD_NO_OP", + "commandKind" : "async", + "opcode" : 1280, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "No-op command" + }, + { + "name" : "fileManager.RemoveDirectory", + "commandKind" : "async", + "opcode" : 2050, + "formalParams" : [ + { + "name" : "dirName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The directory to remove" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Remove a directory, which must be empty" + }, + { + "name" : "typeDemo.CHOICES_PRM_PARAM_SET", + "commandKind" : "set", + "opcode" : 4357, + "formalParams" : [ + { + "name" : "val", + "type" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "annotation" : "Multiple enumeration parameter via Array" + }, + { + "name" : "sendBuffComp.SB_START_PKTS", + "commandKind" : "async", + "opcode" : 9728, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Command to start sending packets" + }, + { + "name" : "typeDemo.GLUTTON_OF_CHOICE", + "commandKind" : "sync", + "opcode" : 4367, + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.ChoiceSlurry", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "A phenomenal amount of choice" + } + ], + "annotation" : "Multiple choice command via Complex Structure" + }, + { + "name" : "typeDemo.CHOICES_WITH_FRIENDS", + "commandKind" : "sync", + "opcode" : 4356, + "formalParams" : [ + { + "name" : "repeat", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "Number of times to repeat the choices" + }, + { + "name" : "choices", + "type" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "A set of choices" + }, + { + "name" : "repeat_max", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "Limit to the number of repetitions" + } + ], + "annotation" : "Multiple choice command via Array with a preceding and following argument" + }, + { + "name" : "health.HLTH_PING_ENABLE", + "commandKind" : "async", + "opcode" : 8193, + "formalParams" : [ + { + "name" : "entry", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The entry to enable/disable" + }, + { + "name" : "enable", + "type" : { + "name" : "Fw.Enabled", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "whether or not a port is pinged" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Ignore a particular ping entry" + }, + { + "name" : "prmDb.PRM_SAVE_FILE", + "commandKind" : "async", + "opcode" : 3328, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Command to save parameter image to file. Uses file name passed to constructor" + }, + { + "name" : "systemResources.ENABLE", + "commandKind" : "guarded", + "opcode" : 19200, + "formalParams" : [ + { + "name" : "enable", + "type" : { + "name" : "Svc.SystemResourceEnabled", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "whether or not system resource telemetry is enabled" + } + ], + "annotation" : "A command to enable or disable system resource telemetry" + }, + { + "name" : "SG2.SignalGen_Skip", + "commandKind" : "async", + "opcode" : 8706, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Skip next sample" + }, + { + "name" : "cmdSeq.CS_VALIDATE", + "commandKind" : "async", + "opcode" : 1537, + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 240 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + } + ], + "queueFullBehavior" : "assert", + "annotation" : "Validate a command sequence file" + }, + { + "name" : "SG5.SignalGen_Skip", + "commandKind" : "async", + "opcode" : 9474, + "formalParams" : [ + ], + "queueFullBehavior" : "assert", + "annotation" : "Skip next sample" + }, + { + "name" : "typeDemo.CHOICE_PAIR", + "commandKind" : "sync", + "opcode" : 4363, + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.ChoicePair", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "A pair of choices" + } + ], + "annotation" : "Multiple choice command via Structure" + } + ], + "parameters" : [ + { + "name" : "typeDemo.CHOICES_PRM", + "type" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "id" : 4353, + "annotation" : "Multiple enumeration parameter via Array" + }, + { + "name" : "recvBuffComp.parameter2", + "type" : { + "name" : "I16", + "kind" : "integer", + "size" : 16, + "signed" : true + }, + "id" : 18177, + "default" : 11, + "annotation" : "A test parameter" + }, + { + "name" : "recvBuffComp.parameter1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 18176, + "default" : 10, + "annotation" : "A test parameter" + }, + { + "name" : "typeDemo.CHOICE_PRM", + "type" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "id" : 4352, + "annotation" : "Single enumeration parameter" + }, + { + "name" : "typeDemo.EXTRA_CHOICES_PRM", + "type" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "id" : 4354, + "annotation" : "Too many enumeration parameter via Array" + }, + { + "name" : "sendBuffComp.parameter4", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 9729, + "default" : 13.14, + "annotation" : "A test parameter" + }, + { + "name" : "typeDemo.CHOICE_PAIR_PRM", + "type" : { + "name" : "Ref.ChoicePair", + "kind" : "qualifiedIdentifier" + }, + "id" : 4355, + "annotation" : "Multiple enumeration parameter via Structure" + }, + { + "name" : "typeDemo.GLUTTON_OF_CHOICE_PRM", + "type" : { + "name" : "Ref.ChoiceSlurry", + "kind" : "qualifiedIdentifier" + }, + "id" : 4356, + "annotation" : "Multiple enumeration parameter via Complex Structure" + }, + { + "name" : "sendBuffComp.parameter3", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "id" : 9728, + "default" : 12, + "annotation" : "A test parameter" + } + ], + "events" : [ + { + "name" : "SG3.SignalGen_SettingsChanged", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SignalType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 8960, + "format" : "Set Frequency(Hz) {}, Amplitude {f}, Phase {f}, Signal Type {}", + "annotation" : "Signal Generator Settings Changed" + }, + { + "name" : "rateGroup3Comp.RateGroupStarted", + "severity" : "DIAGNOSTIC", + "formalParams" : [ + ], + "id" : 1024, + "format" : "Rate group started.", + "annotation" : "Informational event that rate group has started" + }, + { + "name" : "cmdSeq.CS_JoinWaiting", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "filename", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The sequence file" + }, + { + "name" : "recordNumber", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The record number" + }, + { + "name" : "opCode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The opcode" + } + ], + "id" : 1559, + "format" : "Start waiting for sequence file {}: Command {} (opcode {}) to complete", + "annotation" : "Wait for the current running sequence file complete" + }, + { + "name" : "sendBuffComp.SendBuffFatal", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "arg1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "First FATAL argument" + }, + { + "name" : "arg2", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Second FATAL argument" + }, + { + "name" : "arg3", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Second FATAL argument" + } + ], + "id" : 9731, + "format" : "Test Fatal: {} {} {}", + "annotation" : "A test FATAL" + }, + { + "name" : "cmdSeq.CS_TimeBaseMismatch", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + }, + { + "name" : "time_base", + "type" : { + "name" : "U16", + "kind" : "integer", + "size" : 16, + "signed" : false + }, + "ref" : false, + "annotation" : "The current time" + }, + { + "name" : "seq_time_base", + "type" : { + "name" : "U16", + "kind" : "integer", + "size" : 16, + "signed" : false + }, + "ref" : false, + "annotation" : "The sequence time base" + } + ], + "id" : 1549, + "format" : "Sequence file {}: Current time base doesn't match sequence time: base: {} seq: {}", + "annotation" : "The running time base doesn't match the time base in the sequence files" + }, + { + "name" : "cmdSeq.CS_NoSequenceActive", + "severity" : "WARNING_LO", + "formalParams" : [ + ], + "id" : 1554, + "format" : "No sequence active.", + "annotation" : "A sequence related command came with no active sequence" + }, + { + "name" : "fileUplink.FileReceived", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The name of the file" + } + ], + "id" : 2306, + "format" : "Received file {}", + "annotation" : "The File Uplink component successfully received a file" + }, + { + "name" : "dpWriter.FileOpenError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "status", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The status code returned from the open operation" + }, + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The file" + } + ], + "id" : 4101, + "format" : "Error {} opening file {}", + "annotation" : "An error occurred when opening a file", + "throttle" : 10 + }, + { + "name" : "fatalAdapter.AF_ASSERT_2", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The source file of the assert" + }, + { + "name" : "line", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Line number of the assert" + }, + { + "name" : "arg1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "First assert argument" + }, + { + "name" : "arg2", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Second assert argument" + } + ], + "id" : 16898, + "format" : "Assert in file {}, line {}: {} {}", + "annotation" : "An assert happened" + }, + { + "name" : "fileUplink.PacketOutOfBounds", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "packetIndex", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The sequence index of the packet" + }, + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The name of the file" + } + ], + "id" : 2309, + "format" : "Packet {} out of bounds for file {}", + "annotation" : "During receipt of a file, the File Uplink component encountered a packet with offset and size out of bounds for the current file", + "throttle" : 5 + }, + { + "name" : "SG1.SignalGen_DpComplete", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 8450, + "format" : "Writing {} DP records {} bytes total" + }, + { + "name" : "cmdDisp.OpCodeReregistered", + "severity" : "DIAGNOSTIC", + "formalParams" : [ + { + "name" : "Opcode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The opcode reregistered" + }, + { + "name" : "port", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The reregistration port" + } + ], + "id" : 1290, + "format" : "Opcode 0x{x} is already registered to port {}", + "annotation" : "Op code reregistered event" + }, + { + "name" : "fileManager.CreateDirectoryStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "dirName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the directory" + } + ], + "id" : 2062, + "format" : "Creating directory {}...", + "annotation" : "The File System component began creating a new directory" + }, + { + "name" : "cmdSeq.CS_CommandComplete", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + }, + { + "name" : "recordNumber", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The record number of the command" + }, + { + "name" : "opCode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The command opcode" + } + ], + "id" : 1544, + "format" : "Sequence file {}: Command {} (opcode {}) complete", + "annotation" : "The Command Sequencer issued a command and received a success status in return." + }, + { + "name" : "fileDownlink.FileReadError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The name of the file" + }, + { + "name" : "status", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The file status of read" + } + ], + "id" : 1793, + "format" : "Could not read file {} with status {}", + "annotation" : "An error occurred reading a file" + }, + { + "name" : "recvBuffComp.BuffRecvParameterUpdated", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID argument" + } + ], + "id" : 18178, + "format" : "BuffRecv Parameter {} was updated", + "annotation" : "Report parameter update" + }, + { + "name" : "SG3.SignalGen_DpRecordFull", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 8963, + "format" : "DP container full with {} records and {} bytes. Closing DP." + }, + { + "name" : "prmDb.PrmFileWriteError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "stage", + "type" : { + "name" : "Svc.PrmDb.PrmWriteError", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The write stage" + }, + { + "name" : "record", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The record that had the failure" + }, + { + "name" : "error", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The error code" + } + ], + "id" : 3332, + "format" : "Parameter write failed in stage {} with record {} and error {}", + "annotation" : "Failed to write parameter file" + }, + { + "name" : "dpWriter.BufferTooSmallForPacket", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "bufferSize", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The incoming buffer size" + }, + { + "name" : "minSize", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The minimum required size" + } + ], + "id" : 4097, + "format" : "Received buffer has size {}; minimum required size is {}", + "annotation" : "Received buffer is too small to hold a data product packet", + "throttle" : 10 + }, + { + "name" : "SG4.SignalGen_DpComplete", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 9218, + "format" : "Writing {} DP records {} bytes total" + }, + { + "name" : "prmDb.PrmFileLoadComplete", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The number of records loaded" + } + ], + "id" : 3335, + "format" : "Parameter file load completed. Read {} records.", + "annotation" : "Load of parameter file completed" + }, + { + "name" : "SG5.SignalGen_DpsNotConnected", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 9476, + "format" : "DP Ports not connected!" + }, + { + "name" : "SG2.SignalGen_DpStarted", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 8705, + "format" : "Writing {} DP records" + }, + { + "name" : "fileManager.FileSizeError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file" + }, + { + "name" : "status", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The error status" + } + ], + "id" : 2067, + "format" : "Failed to get the size of file {}, returned status {}", + "annotation" : "Failed to get file size" + }, + { + "name" : "eventLogger.ID_FILTER_REMOVED", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "ID", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID removed" + } + ], + "id" : 2819, + "format" : "ID filter ID {} removed.", + "annotation" : "Removed an ID from the filter" + }, + { + "name" : "dpCat.SendingProduct", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The file" + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "file size" + }, + { + "name" : "prio", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "DP priority" + } + ], + "id" : 3597, + "format" : "Sending product {} of size {} priority {}", + "annotation" : "Sending product" + }, + { + "name" : "cmdDisp.NoOpReceived", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + ], + "id" : 1287, + "format" : "Received a NO-OP command", + "annotation" : "The command dispatcher has successfully received a NO-OP command" + }, + { + "name" : "fileDownlink.FileOpenError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The name of the file" + } + ], + "id" : 1792, + "format" : "Could not open file {}", + "annotation" : "An error occurred opening a file" + }, + { + "name" : "SG4.SignalGen_SettingsChanged", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SignalType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 9216, + "format" : "Set Frequency(Hz) {}, Amplitude {f}, Phase {f}, Signal Type {}", + "annotation" : "Signal Generator Settings Changed" + }, + { + "name" : "dpCat.DpDuplicate", + "severity" : "DIAGNOSTIC", + "formalParams" : [ + { + "name" : "dp", + "type" : { + "name" : "Svc.DpRecord", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The DP" + } + ], + "id" : 3612, + "format" : "DP {} already in catalog", + "annotation" : "Error inserting entry into list", + "throttle" : 10 + }, + { + "name" : "cmdSeq.CS_SequenceComplete", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + } + ], + "id" : 1545, + "format" : "Sequence file {} complete", + "annotation" : "A command sequence successfully completed." + }, + { + "name" : "fileDownlink.SendStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "fileSize", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The source file size" + }, + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The source filename" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The destination filename" + } + ], + "id" : 1800, + "format" : "Downlink of {} bytes started from {} to {}", + "annotation" : "The File Downlink component started a file download." + }, + { + "name" : "dpMgr.BufferAllocationFailed", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The container ID" + } + ], + "id" : 3840, + "format" : "Buffer allocation failed for container id {}", + "annotation" : "Buffer allocation failed", + "throttle" : 10 + }, + { + "name" : "typeDemo.ChoicesEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4353, + "format" : "Choices: {}", + "annotation" : "Multiple choice event via Array" + }, + { + "name" : "SG5.SignalGen_DpRecordFull", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 9475, + "format" : "DP container full with {} records and {} bytes. Closing DP." + }, + { + "name" : "typeDemo.ChoicesPrmEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + }, + { + "name" : "validity", + "type" : { + "name" : "Fw.ParamValid", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4358, + "format" : "CHOICES_PRM: {} with validity: {}", + "annotation" : "Multiple choice parameter event via Array" + }, + { + "name" : "fileManager.DirectoryRemoveError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "dirName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the directory" + }, + { + "name" : "status", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The error status" + } + ], + "id" : 2049, + "format" : "Could not remove directory {}, returned status {}", + "annotation" : "An error occurred while attempting to remove a directory" + }, + { + "name" : "systemResources.PROJECT_VERSION", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "version", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "version string" + } + ], + "id" : 19201, + "format" : "Project Version: [{}]", + "annotation" : "Version of the git repository." + }, + { + "name" : "fatalAdapter.AF_ASSERT_1", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The source file of the assert" + }, + { + "name" : "line", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Line number of the assert" + }, + { + "name" : "arg1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "First assert argument" + } + ], + "id" : 16897, + "format" : "Assert in file {}, line {}: {}", + "annotation" : "An assert happened" + }, + { + "name" : "health.HLTH_CHECK_PING", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "enabled", + "type" : { + "name" : "Fw.Enabled", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "If health pinging is enabled for a particular entry" + }, + { + "name" : "entry", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The entry passing the warning level" + } + ], + "id" : 8196, + "format" : "Health checking set to {} for {}", + "annotation" : "Report a particular entry on or off" + }, + { + "name" : "cmdDisp.OpCodeError", + "severity" : "COMMAND", + "formalParams" : [ + { + "name" : "Opcode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The opcode with the error" + }, + { + "name" : "error", + "type" : { + "name" : "Fw.CmdResponse", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The error value" + } + ], + "id" : 1283, + "format" : "Opcode 0x{x} completed with error {}", + "annotation" : "Op code completed with error event" + }, + { + "name" : "fileManager.MoveFileSucceeded", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the source file" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the destination file" + } + ], + "id" : 2058, + "format" : "Moved file {} to file {} successfully", + "annotation" : "The File System component moved a file to a new location without error" + }, + { + "name" : "fatalAdapter.AF_ASSERT_6", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The source file of the assert" + }, + { + "name" : "line", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Line number of the assert" + }, + { + "name" : "arg1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "First assert argument" + }, + { + "name" : "arg2", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Second assert argument" + }, + { + "name" : "arg3", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Third assert argument" + }, + { + "name" : "arg4", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Fourth assert argument" + }, + { + "name" : "arg5", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Fifth assert argument" + }, + { + "name" : "arg6", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Sixth assert argument" + } + ], + "id" : 16902, + "format" : "Assert in file {}, line {}: {} {} {} {} {} {}", + "annotation" : "An assert happened" + }, + { + "name" : "fileDownlink.DownlinkTimeout", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The source filename" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The destination file name" + } + ], + "id" : 1796, + "format" : "Timeout occurred during downlink of file {} to file {}. Downlink has been canceled.", + "annotation" : "The File Downlink component has detected a timeout. Downlink has been canceled." + }, + { + "name" : "dpCat.CatalogBuildComplete", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + ], + "id" : 3588, + "format" : "Catalog build complete", + "annotation" : "Catalog processing complete" + }, + { + "name" : "dpCat.CatalogFull", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "dir", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "last directory read" + } + ], + "id" : 3606, + "format" : "DpCatalog full during directory {}", + "annotation" : "Catalog is full", + "throttle" : 10 + }, + { + "name" : "SG5.SignalGen_SettingsChanged", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SignalType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 9472, + "format" : "Set Frequency(Hz) {}, Amplitude {f}, Phase {f}, Signal Type {}", + "annotation" : "Signal Generator Settings Changed" + }, + { + "name" : "rateGroup1Comp.RateGroupStarted", + "severity" : "DIAGNOSTIC", + "formalParams" : [ + ], + "id" : 512, + "format" : "Rate group started.", + "annotation" : "Informational event that rate group has started" + }, + { + "name" : "recvBuffComp.PacketChecksumError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID argument" + } + ], + "id" : 18177, + "format" : "Packet ID {} had checksum error", + "annotation" : "Packet checksum error" + }, + { + "name" : "fileUplink.FileWriteError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The name of the file" + } + ], + "id" : 2307, + "format" : "Could not write to file {}", + "annotation" : "An error occurred writing to a file", + "throttle" : 5 + }, + { + "name" : "dpWriter.BufferTooSmallForData", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "bufferSize", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The incoming buffer size" + }, + { + "name" : "minSize", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The minimum required size" + } + ], + "id" : 4100, + "format" : "Received buffer has size {}; minimum required size is {}", + "annotation" : "Received buffer is too small to hold the data specified in the header", + "throttle" : 10 + }, + { + "name" : "fileManager.ShellCommandStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "command", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The command string" + } + ], + "id" : 2061, + "format" : "Running shell command {}...", + "annotation" : "The File System component began executing a shell command" + }, + { + "name" : "pingRcvr.PR_PingsDisabled", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + ], + "id" : 2560, + "format" : "PingReceiver ping responses disabled", + "annotation" : "Disabled ping responses" + }, + { + "name" : "health.HLTH_PING_INVALID_VALUES", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "entry", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The entry changed" + }, + { + "name" : "warn", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The new warning value" + }, + { + "name" : "fatal", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The new FATAL value" + } + ], + "id" : 8199, + "format" : "Health ping for {} invalid values: WARN {} FATAL {}", + "annotation" : "Report changed ping" + }, + { + "name" : "dpCat.FileHdrDesError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The file" + }, + { + "name" : "stat", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false + } + ], + "id" : 3610, + "format" : "Error deserializing DP {} header stat: {}", + "annotation" : "Error deserializing header data", + "throttle" : 10 + }, + { + "name" : "cmdSeq.CS_JoinWaitingNotComplete", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 1560, + "format" : "Still waiting for sequence file to complete", + "annotation" : "Cannot run new sequence when current sequence file is still running." + }, + { + "name" : "SG4.SignalGen_DpStarted", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 9217, + "format" : "Writing {} DP records" + }, + { + "name" : "fileManager.FileSizeStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file" + } + ], + "id" : 2068, + "format" : "Checking size of file {}...", + "annotation" : "Checking file size" + }, + { + "name" : "SG3.SignalGen_DpsNotConnected", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 8964, + "format" : "DP Ports not connected!" + }, + { + "name" : "cmdDisp.OpCodeDispatched", + "severity" : "COMMAND", + "formalParams" : [ + { + "name" : "Opcode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The opcode dispatched" + }, + { + "name" : "port", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The port dispatched to" + } + ], + "id" : 1281, + "format" : "Opcode 0x{x} dispatched to port {}", + "annotation" : "Op code dispatched event" + }, + { + "name" : "dpCat.CatalogXmitStopped", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "data transmitted" + } + ], + "id" : 3595, + "format" : "Catalog transmission stopped. {} bytes transmitted.", + "annotation" : "Catalog transmission stopped" + }, + { + "name" : "fatalAdapter.AF_ASSERT_3", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The source file of the assert" + }, + { + "name" : "line", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Line number of the assert" + }, + { + "name" : "arg1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "First assert argument" + }, + { + "name" : "arg2", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Second assert argument" + }, + { + "name" : "arg3", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Third assert argument" + } + ], + "id" : 16899, + "format" : "Assert in file {}, line {}: {} {} {}", + "annotation" : "An assert happened" + }, + { + "name" : "cmdSeq.CS_SequenceValid", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "filename", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The sequence file" + } + ], + "id" : 1555, + "format" : "Sequence {} is valid.", + "annotation" : "A sequence passed validation" + }, + { + "name" : "eventLogger.ID_FILTER_NOT_FOUND", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "ID", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID removed" + } + ], + "id" : 2820, + "format" : "ID filter ID {} not found.", + "annotation" : "ID not in filter" + }, + { + "name" : "sendBuffComp.BuffSendParameterUpdated", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID argument" + } + ], + "id" : 9730, + "format" : "BuffSend Parameter {} was updated", + "annotation" : "Report parameter update" + }, + { + "name" : "fileDownlink.FileSent", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The source file name" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The destination file name" + } + ], + "id" : 1794, + "format" : "Sent file {} to file {}", + "annotation" : "The File Downlink component successfully sent a file" + }, + { + "name" : "dpCat.FileSizeError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The file" + }, + { + "name" : "stat", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false + } + ], + "id" : 3615, + "format" : "Error getting file {} size. stat: {}", + "annotation" : "Error getting file size", + "throttle" : 10 + }, + { + "name" : "cmdSeq.CS_FileSizeError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + }, + { + "name" : "size", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Invalid size" + } + ], + "id" : 1541, + "format" : "Sequence file {} too large. Size: {}", + "annotation" : "The sequence file was too large." + }, + { + "name" : "SG1.SignalGen_DpRecordFull", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 8451, + "format" : "DP container full with {} records and {} bytes. Closing DP." + }, + { + "name" : "cmdSeq.CS_RecordInvalid", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + }, + { + "name" : "recordNumber", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The record number" + }, + { + "name" : "error", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The error code" + } + ], + "id" : 1540, + "format" : "Sequence file {}: Record {} invalid. Err: {}", + "annotation" : "The format of a command record was invalid." + }, + { + "name" : "SG2.SignalGen_SettingsChanged", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SignalType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 8704, + "format" : "Set Frequency(Hz) {}, Amplitude {f}, Phase {f}, Signal Type {}", + "annotation" : "Signal Generator Settings Changed" + }, + { + "name" : "pingRcvr.PR_PingReceived", + "severity" : "DIAGNOSTIC", + "formalParams" : [ + { + "name" : "code", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Ping code" + } + ], + "id" : 2561, + "format" : "PingReceiver pinged with code {}", + "annotation" : "Got ping" + }, + { + "name" : "dpCat.CatalogXmitCompleted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "bytes", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "ref" : false, + "annotation" : "data transmitted" + } + ], + "id" : 3596, + "format" : "Catalog transmission completed. {} bytes transmitted.", + "annotation" : "Catalog transmission completed" + }, + { + "name" : "fileUplink.DecodeError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "status", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The sequence index of the out-of-order packet" + } + ], + "id" : 2312, + "format" : "Unable to decode file packet. Status: {}", + "annotation" : "Error decoding file packet" + }, + { + "name" : "fatalAdapter.AF_UNEXPECTED_ASSERT", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The source file of the assert" + }, + { + "name" : "line", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Line number of the assert" + }, + { + "name" : "numArgs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Number of unexpected arguments" + } + ], + "id" : 16903, + "format" : "Unexpected assert in file {}, line {}, args {}", + "annotation" : "An unexpected assert happened" + }, + { + "name" : "fileManager.AppendFileFailed", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "source", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file being read from" + }, + { + "name" : "target", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file to append to" + }, + { + "name" : "status", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The error status" + } + ], + "id" : 2053, + "format" : "Appending {} onto {} failed with status {}", + "annotation" : "The File System component returned status non-zero when trying to append 2 files together" + }, + { + "name" : "dpCat.DpInsertError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "dp", + "type" : { + "name" : "Svc.DpRecord", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The DP" + } + ], + "id" : 3611, + "format" : "Error deserializing DP {}", + "annotation" : "Error inserting entry into list", + "throttle" : 10 + }, + { + "name" : "fileUplink.BadChecksum", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The file name" + }, + { + "name" : "computed", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The computed value" + }, + { + "name" : "read", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The value read" + } + ], + "id" : 2304, + "format" : "Bad checksum value during receipt of file {}: computed 0x{x}, read 0x{x}", + "annotation" : "During receipt of a file, the computed checksum value did not match the stored value" + }, + { + "name" : "cmdSeq.CS_FileInvalid", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + }, + { + "name" : "stage", + "type" : { + "name" : "Svc.CmdSequencer.FileReadStage", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The read stage" + }, + { + "name" : "error", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The error code" + } + ], + "id" : 1539, + "format" : "Sequence file {} invalid. Stage: {} Error: {}", + "annotation" : "The sequence file format was invalid." + }, + { + "name" : "cmdSeq.CS_UnexpectedCompletion", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "opcode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The reported opcode" + } + ], + "id" : 1552, + "format" : "Command complete status received while no sequences active. Opcode: {}", + "annotation" : "A command status came back when no sequence was running" + }, + { + "name" : "recvBuffComp.FirstPacketReceived", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID argument" + } + ], + "id" : 18176, + "format" : "First packet ID {} received", + "annotation" : "First packet received" + }, + { + "name" : "fileDownlink.SendDataFail", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The source filename" + }, + { + "name" : "byteOffset", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Byte offset" + } + ], + "id" : 1799, + "format" : "Failed to send data packet from file {} at byte offset {}.", + "annotation" : "The File Downlink component generated an error when trying to send a data packet." + }, + { + "name" : "fileManager.ShellCommandFailed", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "command", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The command string" + }, + { + "name" : "status", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The status code" + } + ], + "id" : 2052, + "format" : "Shell command {} failed with status {}", + "annotation" : "The File System component executed a shell command that returned status non-zero" + }, + { + "name" : "prmDb.PrmFileSaveComplete", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The number of records saved" + } + ], + "id" : 3333, + "format" : "Parameter file save completed. Wrote {} records.", + "annotation" : "Save of parameter file completed" + }, + { + "name" : "typeDemo.ChoiceSlurryPrmEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.ChoiceSlurry", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + }, + { + "name" : "validity", + "type" : { + "name" : "Fw.ParamValid", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4361, + "format" : "GLUTTON_OF_CHOICE_PRM: {} with validity: {}", + "annotation" : "Multiple choice parameter event via Complex Structure" + }, + { + "name" : "typeDemo.ChoiceEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choice", + "type" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4352, + "format" : "Choice: {}", + "annotation" : "Single choice event" + }, + { + "name" : "dpCat.ProcessingDirectoryComplete", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "loc", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The directory" + }, + { + "name" : "total", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "total data products" + }, + { + "name" : "pending", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "pending data products" + }, + { + "name" : "pending_bytes", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "ref" : false, + "annotation" : "pending data product volume" + } + ], + "id" : 3587, + "format" : "Completed processing directory {}. Total products: {} Pending products: {} Pending bytes: {}", + "annotation" : "Directory Processing complete" + }, + { + "name" : "fileManager.RemoveDirectorySucceeded", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "dirName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the directory" + } + ], + "id" : 2057, + "format" : "Removed directory {} successfully", + "annotation" : "The File System component deleted and existing directory without error" + }, + { + "name" : "cmdDisp.TooManyCommands", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "Opcode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The opcode that overflowed the list" + } + ], + "id" : 1286, + "format" : "Too many outstanding commands. opcode=0x{x}", + "annotation" : "Exceeded the number of commands that can be simultaneously executed" + }, + { + "name" : "SG2.SignalGen_DpsNotConnected", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 8708, + "format" : "DP Ports not connected!" + }, + { + "name" : "rateGroup1Comp.RateGroupCycleSlip", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "cycle", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The cycle where the cycle occurred" + } + ], + "id" : 513, + "format" : "Rate group cycle slipped on cycle {}", + "annotation" : "Warning event that rate group has had a cycle slip" + }, + { + "name" : "typeDemo.ExtraChoicesEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.TooManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4354, + "format" : "Choices: {}", + "annotation" : "Too many choice event via Array" + }, + { + "name" : "cmdSeq.CS_RecordMismatch", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + }, + { + "name" : "header_records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The number of records in the header" + }, + { + "name" : "extra_bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The number of bytes beyond last record" + } + ], + "id" : 1548, + "format" : "Sequence file {} header records mismatch: {} in header, found {} extra bytes.", + "annotation" : "Number of records in header doesn't match number in file" + }, + { + "name" : "typeDemo.ExtraChoicesPrmEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.TooManyChoices", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + }, + { + "name" : "validity", + "type" : { + "name" : "Fw.ParamValid", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4359, + "format" : "EXTRA_CHOICES_PRM: {} with validity: {}", + "annotation" : "Too many choice parameter event via Array" + }, + { + "name" : "health.HLTH_CHECK_ENABLE", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "enabled", + "type" : { + "name" : "Fw.Enabled", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "If health checking is enabled" + } + ], + "id" : 8195, + "format" : "Health checking set to {}", + "annotation" : "Report checking turned on or off" + }, + { + "name" : "dpCat.FileOpenError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "loc", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The directory" + }, + { + "name" : "stat", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "status" + } + ], + "id" : 3607, + "format" : "Unable to open DP file {} status {}", + "annotation" : "Error opening file", + "throttle" : 10 + }, + { + "name" : "fileManager.DirectoryCreateError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "dirName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the directory" + }, + { + "name" : "status", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The error status" + } + ], + "id" : 2048, + "format" : "Could not create directory {}, returned status {}", + "annotation" : "An error occurred while attempting to create a directory" + }, + { + "name" : "dpCat.FileHdrError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The file" + }, + { + "name" : "field", + "type" : { + "name" : "Svc.DpHdrField", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "incorrect value" + }, + { + "name" : "exp", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "expected value" + }, + { + "name" : "act", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "expected value" + } + ], + "id" : 3609, + "format" : "Error reading DP {} header {} field. Expected: {} Actual: {}", + "annotation" : "Error reading header data from DP file", + "throttle" : 10 + }, + { + "name" : "fileDownlink.DownlinkCanceled", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The source file name" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The destination file name" + } + ], + "id" : 1795, + "format" : "Canceled downlink of file {} to file {}", + "annotation" : "The File Downlink component canceled downlink of a file" + }, + { + "name" : "dpCat.ComponentNotInitialized", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 3604, + "format" : "DpCatalog not initialized!", + "annotation" : "Component not initialized error", + "throttle" : 10 + }, + { + "name" : "eventLogger.ID_FILTER_ENABLED", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "ID", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID filtered" + } + ], + "id" : 2817, + "format" : "ID {} is filtered.", + "annotation" : "Indicate ID is filtered" + }, + { + "name" : "dpWriter.InvalidBuffer", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 4096, + "format" : "Received buffer is invalid", + "annotation" : "Received buffer is invalid", + "throttle" : 10 + }, + { + "name" : "fileUplink.InvalidReceiveMode", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "packetType", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The type of the packet received" + }, + { + "name" : "mode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The receive mode" + } + ], + "id" : 2308, + "format" : "Packet type {} received in mode {}", + "annotation" : "The File Uplink component received a packet with a type that was invalid for the current receive mode", + "throttle" : 5 + }, + { + "name" : "dpCat.CatalogXmitStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + ], + "id" : 3594, + "format" : "Catalog transmission started", + "annotation" : "Catalog transmission started" + }, + { + "name" : "fatalAdapter.AF_ASSERT_0", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The source file of the assert" + }, + { + "name" : "line", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Line number of the assert" + } + ], + "id" : 16896, + "format" : "Assert in file {}, line {}", + "annotation" : "An assert happened" + }, + { + "name" : "fileManager.ShellCommandSucceeded", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "command", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The command string" + } + ], + "id" : 2055, + "format" : "Shell command {} succeeded", + "annotation" : "The File System component executed a shell command that returned status zero" + }, + { + "name" : "sendBuffComp.PacketErrorInserted", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID argument" + } + ], + "id" : 9729, + "format" : "Inserted error in packet ID {}", + "annotation" : "Packet checksum error" + }, + { + "name" : "dpWriter.InvalidHeader", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "bufferSize", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The incoming buffer size" + }, + { + "name" : "errorCode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The error code" + } + ], + "id" : 4099, + "format" : "Received buffer of size {}; deserialization of packet header failed with error code {}", + "annotation" : "Error occurred when deserializing the packet header", + "throttle" : 10 + }, + { + "name" : "prmDb.PrmDbFull", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "Id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The parameter ID" + } + ], + "id" : 3330, + "format" : "Parameter DB full when adding ID 0x{x} ", + "annotation" : "Parameter database is full" + }, + { + "name" : "fatalAdapter.AF_ASSERT_4", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The source file of the assert" + }, + { + "name" : "line", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Line number of the assert" + }, + { + "name" : "arg1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "First assert argument" + }, + { + "name" : "arg2", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Second assert argument" + }, + { + "name" : "arg3", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Third assert argument" + }, + { + "name" : "arg4", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Fourth assert argument" + } + ], + "id" : 16900, + "format" : "Assert in file {}, line {}: {} {} {} {}", + "annotation" : "An assert happened" + }, + { + "name" : "fileUplink.UplinkCanceled", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + ], + "id" : 2311, + "format" : "Received CANCEL packet", + "annotation" : "The File Uplink component received a CANCEL packet" + }, + { + "name" : "SG1.SignalGen_DpsNotConnected", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 8452, + "format" : "DP Ports not connected!" + }, + { + "name" : "cmdDisp.OpCodeCompleted", + "severity" : "COMMAND", + "formalParams" : [ + { + "name" : "Opcode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The I32 command argument" + } + ], + "id" : 1282, + "format" : "Opcode 0x{x} completed", + "annotation" : "Op code completed event" + }, + { + "name" : "cmdSeq.CS_FileNotFound", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The sequence file" + } + ], + "id" : 1542, + "format" : "Sequence file {} not found.", + "annotation" : "The sequence file was not found" + }, + { + "name" : "dpCat.ProcessingFile", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The file" + } + ], + "id" : 3586, + "format" : "Processing file {}", + "annotation" : "Processing directory" + }, + { + "name" : "fileManager.RemoveFileStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file" + } + ], + "id" : 2065, + "format" : "Removing file {}...", + "annotation" : "The File System component began deleting an existing file" + }, + { + "name" : "health.HLTH_PING_WARN", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "entry", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The entry passing the warning level" + } + ], + "id" : 8192, + "format" : "Ping entry {} late warning", + "annotation" : "Warn that a ping target is longer than the warning value" + }, + { + "name" : "dpCat.DpXmitInProgress", + "severity" : "WARNING_LO", + "formalParams" : [ + ], + "id" : 3614, + "format" : "Cannot build new catalog while DPs are being transmitted", + "annotation" : "Tried to build catalog while downlink process active", + "throttle" : 10 + }, + { + "name" : "health.HLTH_PING_UPDATED", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "entry", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The entry changed" + }, + { + "name" : "warn", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The new warning value" + }, + { + "name" : "fatal", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The new FATAL value" + } + ], + "id" : 8198, + "format" : "Health ping for {} changed to WARN {} FATAL {}", + "annotation" : "Report changed ping" + }, + { + "name" : "dpWriter.FileWritten", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The number of bytes written" + }, + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The file name" + } + ], + "id" : 4103, + "format" : "Wrote {} bytes to file {}", + "annotation" : "File written" + }, + { + "name" : "cmdSeq.CS_CmdStepped", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "filename", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The sequence file" + }, + { + "name" : "command", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The command that was stepped" + } + ], + "id" : 1557, + "format" : "Sequence {} command {} stepped", + "annotation" : "A command in a sequence was stepped through" + }, + { + "name" : "cmdSeq.CS_SequenceTimeout", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "filename", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The sequence file" + }, + { + "name" : "command", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The command that timed out" + } + ], + "id" : 1556, + "format" : "Sequence {} timed out on command {}", + "annotation" : "A sequence passed validation" + }, + { + "name" : "rateGroup2Comp.RateGroupCycleSlip", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "cycle", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The cycle where the cycle occurred" + } + ], + "id" : 769, + "format" : "Rate group cycle slipped on cycle {}", + "annotation" : "Warning event that rate group has had a cycle slip" + }, + { + "name" : "rateGroup2Comp.RateGroupStarted", + "severity" : "DIAGNOSTIC", + "formalParams" : [ + ], + "id" : 768, + "format" : "Rate group started.", + "annotation" : "Informational event that rate group has started" + }, + { + "name" : "fileManager.FileRemoveError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file" + }, + { + "name" : "status", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The error status" + } + ], + "id" : 2051, + "format" : "Could not remove file {}, returned status {}", + "annotation" : "An error occurred while attempting to remove a file" + }, + { + "name" : "fileManager.MoveFileStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the source file" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the destination file" + } + ], + "id" : 2064, + "format" : "Moving file {} to file {}...", + "annotation" : "The File System component began moving a file to a new location" + }, + { + "name" : "typeDemo.FloatEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "float1", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "float2", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "float3", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "floats", + "type" : { + "name" : "Ref.FloatSet", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4362, + "format" : "Floats: {} {} {} as a set: {}", + "annotation" : "A set of floats in an event" + }, + { + "name" : "fileManager.AppendFileSucceeded", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "source", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file being read from" + }, + { + "name" : "target", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file to append to" + } + ], + "id" : 2054, + "format" : "Appended {} to the end of {}", + "annotation" : "The File System component appended 2 files without error" + }, + { + "name" : "eventLogger.SEVERITY_FILTER_STATE", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "severity", + "type" : { + "name" : "Svc.ActiveLogger.FilterSeverity", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The severity level" + }, + { + "name" : "enabled", + "type" : { + "name" : "bool", + "kind" : "bool", + "size" : 8 + }, + "ref" : false + } + ], + "id" : 2816, + "format" : "{} filter state. {}", + "annotation" : "Dump severity filter state" + }, + { + "name" : "typeDemo.ChoicePairEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.ChoicePair", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4355, + "format" : "Choices: {}", + "annotation" : "Multiple choice event via Structure" + }, + { + "name" : "health.HLTH_PING_WRONG_KEY", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "entry", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The entry passing the warning level" + }, + { + "name" : "badKey", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The incorrect key value" + } + ], + "id" : 8194, + "format" : "Ping entry {} responded with wrong key 0x{x}", + "annotation" : "Declare FATAL since task is no longer responding" + }, + { + "name" : "cmdSeq.CS_PortSequenceStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "filename", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The sequence file" + } + ], + "id" : 1551, + "format" : "Local request for sequence {} started.", + "annotation" : "A local port request to run a sequence was started" + }, + { + "name" : "cmdSeq.CS_InvalidMode", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 1547, + "format" : "Invalid mode", + "annotation" : "The Command Sequencer received a command that was invalid for its current mode." + }, + { + "name" : "fileDownlink.DownlinkPartialFail", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The source filename" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The destination file name" + }, + { + "name" : "startOffset", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Starting file offset in bytes" + }, + { + "name" : "filesize", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Size of source file" + } + ], + "id" : 1798, + "format" : "Error occurred during partial downlink of file {} to file {}. Offset {} greater than or equal to source filesize {}.", + "annotation" : "The File Downlink component has detected a timeout. Downlink has been canceled." + }, + { + "name" : "SG2.SignalGen_DpRecordFull", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 8707, + "format" : "DP container full with {} records and {} bytes. Closing DP." + }, + { + "name" : "fileManager.AppendFileStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "source", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file being read from" + }, + { + "name" : "target", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file to append to" + } + ], + "id" : 2060, + "format" : "Appending file {} to the end of {}...", + "annotation" : "The File System component appended 2 files without error" + }, + { + "name" : "dpCat.FileReadError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The file" + }, + { + "name" : "stat", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "status" + } + ], + "id" : 3608, + "format" : "Error reading DP file {} status {}", + "annotation" : "Error opening file", + "throttle" : 10 + }, + { + "name" : "SG5.SignalGen_DpStarted", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 9473, + "format" : "Writing {} DP records" + }, + { + "name" : "typeDemo.ChoicePairPrmEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.ChoicePair", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + }, + { + "name" : "validity", + "type" : { + "name" : "Fw.ParamValid", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4360, + "format" : "CHOICE_PAIR_PRM: {} with validity: {}", + "annotation" : "Multiple choice parameter event via Structure" + }, + { + "name" : "rateGroup3Comp.RateGroupCycleSlip", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "cycle", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The cycle where the cycle occurred" + } + ], + "id" : 1025, + "format" : "Rate group cycle slipped on cycle {}", + "annotation" : "Warning event that rate group has had a cycle slip" + }, + { + "name" : "prmDb.PrmFileReadError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "stage", + "type" : { + "name" : "Svc.PrmDb.PrmReadError", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The read stage" + }, + { + "name" : "record", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The record that had the failure" + }, + { + "name" : "error", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The error code" + } + ], + "id" : 3334, + "format" : "Parameter file read failed in stage {} with record {} and error {}", + "annotation" : "Failed to read parameter file" + }, + { + "name" : "cmdSeq.CS_FileReadError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + } + ], + "id" : 1538, + "format" : "Error reading sequence file {}", + "annotation" : "The Sequence File Loader could not read the sequence file." + }, + { + "name" : "prmDb.PrmIdUpdated", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "Id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The parameter ID" + } + ], + "id" : 3329, + "format" : "Parameter ID 0x{x} updated", + "annotation" : "Parameter ID updated in database" + }, + { + "name" : "cmdDisp.InvalidCommand", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "Opcode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Invalid opcode" + } + ], + "id" : 1285, + "format" : "Invalid opcode 0x{x} received", + "annotation" : "Received an invalid opcode" + }, + { + "name" : "SG4.SignalGen_DpsNotConnected", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 9220, + "format" : "DP Ports not connected!" + }, + { + "name" : "fileManager.CreateDirectorySucceeded", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "dirName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the directory" + } + ], + "id" : 2056, + "format" : "Created directory {} successfully", + "annotation" : "The File System component created a new directory without error" + }, + { + "name" : "cmdSeq.CS_FileCrcFailure", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The sequence file" + }, + { + "name" : "storedCRC", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The CRC stored in the file" + }, + { + "name" : "computedCRC", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The CRC computed over the file" + } + ], + "id" : 1543, + "format" : "Sequence file {} had invalid CRC. Stored 0x{x}, Computed 0x{x}.", + "annotation" : "The sequence file validation failed" + }, + { + "name" : "SG1.SignalGen_SettingsChanged", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "Frequency", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "Amplitude", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "Phase", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false + }, + { + "name" : "SignalType", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 8448, + "format" : "Set Frequency(Hz) {}, Amplitude {f}, Phase {f}, Signal Type {}", + "annotation" : "Signal Generator Settings Changed" + }, + { + "name" : "cmdSeq.CS_SequenceLoaded", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + } + ], + "id" : 1536, + "format" : "Loaded sequence {}", + "annotation" : "Sequence file was successfully loaded." + }, + { + "name" : "cmdDisp.MalformedCommand", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "Status", + "type" : { + "name" : "Fw.DeserialStatus", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The deserialization error" + } + ], + "id" : 1284, + "format" : "Received malformed command packet. Status: {}", + "annotation" : "Received a malformed command packet" + }, + { + "name" : "SG1.SignalGen_DpStarted", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 8449, + "format" : "Writing {} DP records" + }, + { + "name" : "fileDownlink.DownlinkPartialWarning", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "startOffset", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Starting file offset in bytes" + }, + { + "name" : "length", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Number of bytes to downlink" + }, + { + "name" : "filesize", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Size of source file" + }, + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The source filename" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 100 + }, + "ref" : false, + "annotation" : "The destination file name" + } + ], + "id" : 1797, + "format" : "Offset {} plus length {} is greater than source size {} for partial downlink of file {} to file {}. ", + "annotation" : "The File Downlink component has detected a timeout. Downlink has been canceled." + }, + { + "name" : "dpCat.DirectoryOpenError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "loc", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The directory" + }, + { + "name" : "stat", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "status" + } + ], + "id" : 3584, + "format" : "Unable to process directory {} status {}", + "annotation" : "Error opening directory" + }, + { + "name" : "eventLogger.ID_FILTER_LIST_FULL", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "ID", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID filtered" + } + ], + "id" : 2818, + "format" : "ID filter list is full. Cannot filter {} .", + "annotation" : "Attempted to add ID to full ID filter ID" + }, + { + "name" : "SG4.SignalGen_DpRecordFull", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 9219, + "format" : "DP container full with {} records and {} bytes. Closing DP." + }, + { + "name" : "cmdSeq.CS_ModeSwitched", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "mode", + "type" : { + "name" : "Svc.CmdSequencer.SeqMode", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The new mode" + } + ], + "id" : 1553, + "format" : "Sequencer switched to {} step mode", + "annotation" : "Switched step mode" + }, + { + "name" : "dpBufferManager.NoBuffsAvailable", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "size", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The requested size" + } + ], + "id" : 19456, + "format" : "No available buffers of size {}", + "annotation" : "The BufferManager was unable to allocate a requested buffer", + "throttle" : 10 + }, + { + "name" : "fileUplinkBufferManager.NoBuffsAvailable", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "size", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The requested size" + } + ], + "id" : 17408, + "format" : "No available buffers of size {}", + "annotation" : "The BufferManager was unable to allocate a requested buffer", + "throttle" : 10 + }, + { + "name" : "fileUplink.PacketOutOfOrder", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "packetIndex", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The sequence index of the out-of-order packet" + }, + { + "name" : "lastPacketIndex", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The sequence index of the last packet received before the out-of-order packet" + } + ], + "id" : 2310, + "format" : "Received packet {} after packet {}", + "annotation" : "The File Uplink component encountered an out-of-order packet during file receipt", + "throttle" : 20 + }, + { + "name" : "SG3.SignalGen_DpComplete", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 8962, + "format" : "Writing {} DP records {} bytes total" + }, + { + "name" : "dpWriter.FileWriteError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "status", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The status code returned from the write operation" + }, + { + "name" : "bytesWritten", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The number of bytes successfully written" + }, + { + "name" : "bytesToWrite", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The number of bytes attempted" + }, + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The file" + } + ], + "id" : 4102, + "format" : "Error {} while writing {} of {} bytes to {}", + "annotation" : "An error occurred when writing to a file", + "throttle" : 10 + }, + { + "name" : "fileUplink.FileOpenError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The name of the file" + } + ], + "id" : 2305, + "format" : "Could not open file {}", + "annotation" : "An error occurred opening a file" + }, + { + "name" : "cmdDisp.TestCmd1Args", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "arg1", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "Arg1" + }, + { + "name" : "arg2", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "ref" : false, + "annotation" : "Arg2" + }, + { + "name" : "arg3", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "Arg3" + } + ], + "id" : 1289, + "format" : "TEST_CMD_1 args: I32: {}, F32: {f}, U8: {}", + "annotation" : "This log event message returns the TEST_CMD_1 arguments." + }, + { + "name" : "dpCat.DpCatalogFull", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "dp", + "type" : { + "name" : "Svc.DpRecord", + "kind" : "qualifiedIdentifier" + }, + "ref" : false, + "annotation" : "The DP" + } + ], + "id" : 3613, + "format" : "Catalog full trying to insert DP {}", + "annotation" : "Error inserting entry into list", + "throttle" : 10 + }, + { + "name" : "health.HLTH_CHECK_LOOKUP_ERROR", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "entry", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The entry passing the warning level" + } + ], + "id" : 8197, + "format" : "Couldn't find entry {}", + "annotation" : "Entry was not found" + }, + { + "name" : "prmDb.PrmIdAdded", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "Id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The parameter ID" + } + ], + "id" : 3331, + "format" : "Parameter ID 0x{x} added", + "annotation" : "Parameter ID added to database" + }, + { + "name" : "cmdSeq.CS_CmdStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "filename", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The sequence file" + } + ], + "id" : 1558, + "format" : "Sequence {} started", + "annotation" : "A manual sequence was started" + }, + { + "name" : "dpCat.ProcessingDirectory", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "directory", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The directory" + } + ], + "id" : 3585, + "format" : "Processing directory {}", + "annotation" : "Processing directory" + }, + { + "name" : "dpCat.ProductComplete", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The file" + } + ], + "id" : 3598, + "format" : "Product {} complete", + "annotation" : "Product send complete" + }, + { + "name" : "fileManager.FileSizeSucceeded", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file" + }, + { + "name" : "size", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "ref" : false, + "annotation" : "The size of the file in bytes" + } + ], + "id" : 2066, + "format" : "The size of file {} is {} B", + "annotation" : "File size response" + }, + { + "name" : "dpWriter.InvalidHeaderHash", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "bufferSize", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The incoming buffer size" + }, + { + "name" : "storedHash", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The stored hash value" + }, + { + "name" : "computedHash", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The computed hash value" + } + ], + "id" : 4098, + "format" : "Received a buffer of size {} with an invalid header hash (stored {x}, computed {x})", + "annotation" : "The received buffer has an invalid header hash", + "throttle" : 10 + }, + { + "name" : "cmdDisp.OpCodeRegistered", + "severity" : "DIAGNOSTIC", + "formalParams" : [ + { + "name" : "Opcode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The opcode to register" + }, + { + "name" : "port", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The registration port" + }, + { + "name" : "slot", + "type" : { + "name" : "I32", + "kind" : "integer", + "size" : 32, + "signed" : true + }, + "ref" : false, + "annotation" : "The dispatch slot it was placed in" + } + ], + "id" : 1280, + "format" : "Opcode 0x{x} registered to port {} slot {}" + }, + { + "name" : "cmdSeq.CS_CommandError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + }, + { + "name" : "recordNumber", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The record number" + }, + { + "name" : "opCode", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The opcode" + }, + { + "name" : "errorStatus", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The error status" + } + ], + "id" : 1546, + "format" : "Sequence file {}: Command {} (opcode {}) completed with error {}", + "annotation" : "The Command Sequencer issued a command and received an error status in return." + }, + { + "name" : "fileManager.FileMoveError", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "sourceFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the source file" + }, + { + "name" : "destFileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the destination file" + }, + { + "name" : "status", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The error status" + } + ], + "id" : 2050, + "format" : "Could not move file {} to file {}, returned status {}", + "annotation" : "An error occurred while attempting to move a file" + }, + { + "name" : "typeDemo.ChoicePrmEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choice", + "type" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + }, + { + "name" : "validity", + "type" : { + "name" : "Fw.ParamValid", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4357, + "format" : "CHOICE_PRM: {} with validity: {}", + "annotation" : "Single choice parameter event" + }, + { + "name" : "sendBuffComp.FirstPacketSent", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The ID argument" + } + ], + "id" : 9728, + "format" : "First packet ID {} received", + "annotation" : "First packet send" + }, + { + "name" : "typeDemo.ChoiceSlurryEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "choices", + "type" : { + "name" : "Ref.ChoiceSlurry", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4356, + "format" : "Choices: {}", + "annotation" : "Multiple choice event via Complex Structure" + }, + { + "name" : "health.HLTH_PING_LATE", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "entry", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The entry passing the warning level" + } + ], + "id" : 8193, + "format" : "Ping entry {} did not respond", + "annotation" : "Declare FATAL since task is no longer responding" + }, + { + "name" : "dpBufferManager.ZeroSizeBuffer", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 19457, + "format" : "Received zero size buffer", + "annotation" : "The buffer manager received a zero-sized buffer as a return. Probably undetected empty buffer allocation", + "throttle" : 10 + }, + { + "name" : "prmDb.PrmIdNotFound", + "severity" : "WARNING_LO", + "formalParams" : [ + { + "name" : "Id", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "The parameter ID" + } + ], + "id" : 3328, + "format" : "Parameter ID 0x{x} not found", + "annotation" : "Parameter ID not found in database.", + "throttle" : 5 + }, + { + "name" : "systemResources.FRAMEWORK_VERSION", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "version", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "version string" + } + ], + "id" : 19200, + "format" : "Framework Version: [{}]", + "annotation" : "Version of the git repository." + }, + { + "name" : "fatalAdapter.AF_ASSERT_5", + "severity" : "FATAL", + "formalParams" : [ + { + "name" : "file", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 80 + }, + "ref" : false, + "annotation" : "The source file of the assert" + }, + { + "name" : "line", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Line number of the assert" + }, + { + "name" : "arg1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "First assert argument" + }, + { + "name" : "arg2", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Second assert argument" + }, + { + "name" : "arg3", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Third assert argument" + }, + { + "name" : "arg4", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Fourth assert argument" + }, + { + "name" : "arg5", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false, + "annotation" : "Fifth assert argument" + } + ], + "id" : 16901, + "format" : "Assert in file {}, line {}: {} {} {} {} {}", + "annotation" : "An assert happened" + }, + { + "name" : "cmdDisp.NoOpStringReceived", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "message", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "ref" : false, + "annotation" : "The NO-OP string that is generated" + } + ], + "id" : 1288, + "format" : "Received a NO-OP string={}", + "annotation" : "The command dispatcher has successfully received a NO-OP command from GUI with a string" + }, + { + "name" : "SG2.SignalGen_DpComplete", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 8706, + "format" : "Writing {} DP records {} bytes total" + }, + { + "name" : "fileManager.RemoveDirectoryStarted", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "dirName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the directory" + } + ], + "id" : 2063, + "format" : "Removing directory {}...", + "annotation" : "The File System component began deleting a directory" + }, + { + "name" : "fileUplinkBufferManager.ZeroSizeBuffer", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 17409, + "format" : "Received zero size buffer", + "annotation" : "The buffer manager received a zero-sized buffer as a return. Probably undetected empty buffer allocation", + "throttle" : 10 + }, + { + "name" : "SG5.SignalGen_DpComplete", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + }, + { + "name" : "bytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 9474, + "format" : "Writing {} DP records {} bytes total" + }, + { + "name" : "cmdSeq.CS_TimeContextMismatch", + "severity" : "WARNING_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + }, + { + "name" : "currTimeBase", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "The current time base" + }, + { + "name" : "seqTimeBase", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "ref" : false, + "annotation" : "The sequence time base" + } + ], + "id" : 1550, + "format" : "Sequence file {}: Current time context doesn't match sequence context: base: {} seq: {}", + "annotation" : "The running time base doesn't match the time base in the sequence files" + }, + { + "name" : "typeDemo.ScalarStructEv", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "scalar_argument", + "type" : { + "name" : "Ref.ScalarStruct", + "kind" : "qualifiedIdentifier" + }, + "ref" : false + } + ], + "id" : 4363, + "format" : "ScalarStruct: {}", + "annotation" : "Event for scalar struct" + }, + { + "name" : "dpCat.ComponentNoMemory", + "severity" : "WARNING_HI", + "formalParams" : [ + ], + "id" : 3605, + "format" : "DpCatalog couldn't get memory", + "annotation" : "Component didn't get memory error", + "throttle" : 10 + }, + { + "name" : "cmdSeq.CS_SequenceCanceled", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 60 + }, + "ref" : false, + "annotation" : "The name of the sequence file" + } + ], + "id" : 1537, + "format" : "Sequence file {} canceled", + "annotation" : "A command sequence was successfully canceled." + }, + { + "name" : "fileManager.RemoveFileSucceeded", + "severity" : "ACTIVITY_HI", + "formalParams" : [ + { + "name" : "fileName", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 256 + }, + "ref" : false, + "annotation" : "The name of the file" + } + ], + "id" : 2059, + "format" : "Removed file {} successfully", + "annotation" : "The File System component deleted an existing file without error" + }, + { + "name" : "SG3.SignalGen_DpStarted", + "severity" : "ACTIVITY_LO", + "formalParams" : [ + { + "name" : "records", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "ref" : false + } + ], + "id" : 8961, + "format" : "Writing {} DP records" + } + ], + "telemetryChannels" : [ + { + "name" : "pingRcvr.PR_NumPings", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 2560, + "telemetryUpdate" : "always", + "annotation" : "Number of pings received" + }, + { + "name" : "SG1.PairHistory", + "type" : { + "name" : "Ref.SignalPairSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 8452, + "telemetryUpdate" : "always", + "annotation" : "Last 10 (time, value) pairs of the signal" + }, + { + "name" : "recvBuffComp.Parameter2", + "type" : { + "name" : "I16", + "kind" : "integer", + "size" : 16, + "signed" : true + }, + "id" : 18180, + "telemetryUpdate" : "on change", + "annotation" : "Readback of Parameter2", + "limits" : { + "high" : { + "red" : 3, + "orange" : 2, + "yellow" : 1 + }, + "low" : { + "red" : -3, + "orange" : -2, + "yellow" : -1 + } + } + }, + { + "name" : "systemResources.CPU", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19204, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "SG3.Type", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "id" : 8960, + "telemetryUpdate" : "always", + "annotation" : "Type of the output signal: SINE, TRIANGLE, etc." + }, + { + "name" : "rateGroup3Comp.RgMaxTime", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1024, + "telemetryUpdate" : "on change", + "format" : "{} us", + "annotation" : "Max execution time rate group" + }, + { + "name" : "fileUplink.Warnings", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 2306, + "telemetryUpdate" : "always", + "annotation" : "The total number of warnings issued" + }, + { + "name" : "sendBuffComp.Parameter4", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 9731, + "telemetryUpdate" : "on change", + "annotation" : "Readback of Parameter4" + }, + { + "name" : "SG4.DpBytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 9222, + "telemetryUpdate" : "always", + "annotation" : "DP bytes written" + }, + { + "name" : "SG1.PairOutput", + "type" : { + "name" : "Ref.SignalPair", + "kind" : "qualifiedIdentifier" + }, + "id" : 8450, + "telemetryUpdate" : "always", + "annotation" : "Single (time, value) pair of the signal" + }, + { + "name" : "SG2.Info", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "id" : 8709, + "telemetryUpdate" : "always", + "annotation" : "Composite field of signal information, containing histories, pairs etc" + }, + { + "name" : "fileDownlink.PacketsSent", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1793, + "telemetryUpdate" : "always", + "annotation" : "The total number of packets sent" + }, + { + "name" : "systemResources.CPU_08", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19213, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "fileUplinkBufferManager.NoBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 17411, + "telemetryUpdate" : "on change", + "annotation" : "The number of requests that couldn't return a buffer", + "limits" : { + "high" : { + "red" : 1 + } + } + }, + { + "name" : "recvBuffComp.Sensor2", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 18178, + "telemetryUpdate" : "always", + "annotation" : "Value of Sensor3" + }, + { + "name" : "SG3.History", + "type" : { + "name" : "Ref.SignalSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 8963, + "telemetryUpdate" : "always", + "annotation" : "Last 10 Y values of the signal" + }, + { + "name" : "dpWriter.NumBytesWritten", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "id" : 4097, + "telemetryUpdate" : "on change", + "annotation" : "The number of bytes written" + }, + { + "name" : "SG4.PairOutput", + "type" : { + "name" : "Ref.SignalPair", + "kind" : "qualifiedIdentifier" + }, + "id" : 9218, + "telemetryUpdate" : "always", + "annotation" : "Single (time, value) pair of the signal" + }, + { + "name" : "SG5.PairHistory", + "type" : { + "name" : "Ref.SignalPairSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 9476, + "telemetryUpdate" : "always", + "annotation" : "Last 10 (time, value) pairs of the signal" + }, + { + "name" : "systemResources.CPU_14", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19219, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "dpBufferManager.HiBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 19458, + "telemetryUpdate" : "on change", + "annotation" : "The high water mark of allocated buffers" + }, + { + "name" : "SG2.Output", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 8705, + "telemetryUpdate" : "always", + "format" : "{.4f}", + "annotation" : "Single Y value of the output" + }, + { + "name" : "systemResources.CPU_04", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19209, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "fileDownlink.FilesSent", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1792, + "telemetryUpdate" : "always", + "annotation" : "The total number of files sent" + }, + { + "name" : "SG3.DpRecords", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 8967, + "telemetryUpdate" : "always", + "annotation" : "DP records written" + }, + { + "name" : "SG4.Type", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "id" : 9216, + "telemetryUpdate" : "always", + "annotation" : "Type of the output signal: SINE, TRIANGLE, etc." + }, + { + "name" : "dpMgr.NumSuccessfulAllocations", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 3840, + "telemetryUpdate" : "on change", + "annotation" : "The number of successful buffer allocations" + }, + { + "name" : "typeDemo.ChoicesCh", + "type" : { + "name" : "Ref.ManyChoices", + "kind" : "qualifiedIdentifier" + }, + "id" : 4353, + "telemetryUpdate" : "always", + "annotation" : "Multiple choice channel via Array" + }, + { + "name" : "SG5.History", + "type" : { + "name" : "Ref.SignalSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 9475, + "telemetryUpdate" : "always", + "annotation" : "Last 10 Y values of the signal" + }, + { + "name" : "typeDemo.Float2Ch", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 4358, + "telemetryUpdate" : "always", + "annotation" : "Float output channel 2" + }, + { + "name" : "fileManager.Errors", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 2049, + "telemetryUpdate" : "always", + "annotation" : "The total number of errors" + }, + { + "name" : "systemResources.CPU_01", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19206, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "fileUplinkBufferManager.HiBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 17410, + "telemetryUpdate" : "on change", + "annotation" : "The high water mark of allocated buffers" + }, + { + "name" : "systemResources.MEMORY_USED", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "id" : 19201, + "telemetryUpdate" : "always", + "format" : "{} KB", + "annotation" : "System memory used in KB" + }, + { + "name" : "systemResources.CPU_11", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19216, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "SG1.DpBytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 8454, + "telemetryUpdate" : "always", + "annotation" : "DP bytes written" + }, + { + "name" : "SG5.Type", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "id" : 9472, + "telemetryUpdate" : "always", + "annotation" : "Type of the output signal: SINE, TRIANGLE, etc." + }, + { + "name" : "rateGroup1Comp.RgMaxTime", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 512, + "telemetryUpdate" : "on change", + "format" : "{} us", + "annotation" : "Max execution time rate group" + }, + { + "name" : "SG4.Info", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "id" : 9221, + "telemetryUpdate" : "always", + "annotation" : "Composite field of signal information, containing histories, pairs etc" + }, + { + "name" : "recvBuffComp.Sensor1", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 18177, + "telemetryUpdate" : "always", + "format" : "{.2f}V", + "annotation" : "Value of Sensor1" + }, + { + "name" : "dpWriter.NumErrors", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 4100, + "telemetryUpdate" : "on change", + "annotation" : "The number of errors" + }, + { + "name" : "systemResources.CPU_13", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19218, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "SG4.Output", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 9217, + "telemetryUpdate" : "always", + "format" : "{.4f}", + "annotation" : "Single Y value of the output" + }, + { + "name" : "systemResources.CPU_09", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19214, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "SG3.PairHistory", + "type" : { + "name" : "Ref.SignalPairSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 8964, + "telemetryUpdate" : "always", + "annotation" : "Last 10 (time, value) pairs of the signal" + }, + { + "name" : "cmdDisp.CommandErrors", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1281, + "telemetryUpdate" : "on change", + "annotation" : "Number of command errors" + }, + { + "name" : "sendBuffComp.Parameter3", + "type" : { + "name" : "U8", + "kind" : "integer", + "size" : 8, + "signed" : false + }, + "id" : 9730, + "telemetryUpdate" : "on change", + "annotation" : "Readback of Parameter3" + }, + { + "name" : "fileDownlink.Warnings", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1794, + "telemetryUpdate" : "always", + "annotation" : "The total number of warnings" + }, + { + "name" : "fileUplinkBufferManager.EmptyBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 17412, + "telemetryUpdate" : "on change", + "annotation" : "The number of empty buffers returned", + "limits" : { + "high" : { + "red" : 1 + } + } + }, + { + "name" : "systemResources.NON_VOLATILE_FREE", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "id" : 19203, + "telemetryUpdate" : "always", + "format" : "{} KB", + "annotation" : "System non-volatile available in KB" + }, + { + "name" : "SG1.History", + "type" : { + "name" : "Ref.SignalSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 8451, + "telemetryUpdate" : "always", + "annotation" : "Last 10 Y values of the signal" + }, + { + "name" : "cmdSeq.CS_SequencesCompleted", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1540, + "telemetryUpdate" : "always", + "annotation" : "The number of sequences completed." + }, + { + "name" : "blockDrv.BD_Cycles", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 256, + "telemetryUpdate" : "always", + "annotation" : "Driver cycle count" + }, + { + "name" : "SG2.Type", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "id" : 8704, + "telemetryUpdate" : "always", + "annotation" : "Type of the output signal: SINE, TRIANGLE, etc." + }, + { + "name" : "systemResources.CPU_05", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19210, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "SG5.Info", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "id" : 9477, + "telemetryUpdate" : "always", + "annotation" : "Composite field of signal information, containing histories, pairs etc" + }, + { + "name" : "fileUplink.FilesReceived", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 2304, + "telemetryUpdate" : "always", + "annotation" : "The total number of complete files received" + }, + { + "name" : "cmdSeq.CS_CommandsExecuted", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1539, + "telemetryUpdate" : "always", + "annotation" : "The number of commands executed across all sequences." + }, + { + "name" : "recvBuffComp.PktState", + "type" : { + "name" : "Ref.PacketStat", + "kind" : "qualifiedIdentifier" + }, + "id" : 18176, + "telemetryUpdate" : "always", + "annotation" : "Packet Statistics" + }, + { + "name" : "SG1.DpRecords", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 8455, + "telemetryUpdate" : "always", + "annotation" : "DP records written" + }, + { + "name" : "dpBufferManager.NoBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 19459, + "telemetryUpdate" : "on change", + "annotation" : "The number of requests that couldn't return a buffer", + "limits" : { + "high" : { + "red" : 1 + } + } + }, + { + "name" : "systemResources.PROJECT_VERSION", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "id" : 19222, + "telemetryUpdate" : "always", + "annotation" : "Software project version" + }, + { + "name" : "typeDemo.ChoiceCh", + "type" : { + "name" : "Ref.Choice", + "kind" : "qualifiedIdentifier" + }, + "id" : 4352, + "telemetryUpdate" : "always", + "annotation" : "Single choice channel" + }, + { + "name" : "dpMgr.NumFailedAllocations", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 3841, + "telemetryUpdate" : "on change", + "annotation" : "The number of failed buffer allocations" + }, + { + "name" : "SG2.PairHistory", + "type" : { + "name" : "Ref.SignalPairSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 8708, + "telemetryUpdate" : "always", + "annotation" : "Last 10 (time, value) pairs of the signal" + }, + { + "name" : "rateGroup1Comp.RgCycleSlips", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 513, + "telemetryUpdate" : "on change", + "annotation" : "Cycle slips for rate group" + }, + { + "name" : "typeDemo.ExtraChoicesCh", + "type" : { + "name" : "Ref.TooManyChoices", + "kind" : "qualifiedIdentifier" + }, + "id" : 4354, + "telemetryUpdate" : "always", + "annotation" : "Too many choice channel via Array" + }, + { + "name" : "typeDemo.Float3Ch", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 4359, + "telemetryUpdate" : "always", + "annotation" : "Float output channel 3" + }, + { + "name" : "fileManager.CommandsExecuted", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 2048, + "telemetryUpdate" : "always", + "annotation" : "The total number of commands successfully executed" + }, + { + "name" : "systemResources.CPU_10", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19215, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "systemResources.CPU_12", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19217, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "SG2.DpRecords", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 8711, + "telemetryUpdate" : "always", + "annotation" : "DP records written" + }, + { + "name" : "systemResources.NON_VOLATILE_TOTAL", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "id" : 19202, + "telemetryUpdate" : "always", + "format" : "{} KB", + "annotation" : "System non-volatile available in KB" + }, + { + "name" : "dpWriter.NumBuffersReceived", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 4096, + "telemetryUpdate" : "on change", + "annotation" : "The number of buffers received" + }, + { + "name" : "dpWriter.NumFailedWrites", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 4099, + "telemetryUpdate" : "on change", + "annotation" : "The number of failed writes" + }, + { + "name" : "sendBuffComp.NumErrorsInjected", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 9729, + "telemetryUpdate" : "on change", + "annotation" : "Number of errors injected" + }, + { + "name" : "systemResources.CPU_03", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19208, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "health.PingLateWarnings", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 8192, + "telemetryUpdate" : "always", + "annotation" : "Number of overrun warnings" + }, + { + "name" : "rateGroup2Comp.RgCycleSlips", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 769, + "telemetryUpdate" : "on change", + "annotation" : "Cycle slips for rate group" + }, + { + "name" : "SG5.DpBytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 9478, + "telemetryUpdate" : "always", + "annotation" : "DP bytes written" + }, + { + "name" : "rateGroup2Comp.RgMaxTime", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 768, + "telemetryUpdate" : "on change", + "format" : "{} us", + "annotation" : "Max execution time rate group" + }, + { + "name" : "SG3.Info", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "id" : 8965, + "telemetryUpdate" : "always", + "annotation" : "Composite field of signal information, containing histories, pairs etc" + }, + { + "name" : "typeDemo.ChoicePairCh", + "type" : { + "name" : "Ref.ChoicePair", + "kind" : "qualifiedIdentifier" + }, + "id" : 4355, + "telemetryUpdate" : "always", + "annotation" : "Multiple choice channel via Structure" + }, + { + "name" : "dpMgr.NumDataProducts", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 3842, + "telemetryUpdate" : "on change", + "annotation" : "Number of data products handled" + }, + { + "name" : "dpBufferManager.EmptyBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 19460, + "telemetryUpdate" : "on change", + "annotation" : "The number of empty buffers returned", + "limits" : { + "high" : { + "red" : 1 + } + } + }, + { + "name" : "systemResources.CPU_06", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19211, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "SG5.Output", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 9473, + "telemetryUpdate" : "always", + "format" : "{.4f}", + "annotation" : "Single Y value of the output" + }, + { + "name" : "typeDemo.FloatSet", + "type" : { + "name" : "Ref.FloatSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 4360, + "telemetryUpdate" : "always", + "annotation" : "Float set output channel" + }, + { + "name" : "rateGroup3Comp.RgCycleSlips", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1025, + "telemetryUpdate" : "on change", + "annotation" : "Cycle slips for rate group" + }, + { + "name" : "systemResources.FRAMEWORK_VERSION", + "type" : { + "name" : "string", + "kind" : "string", + "size" : 40 + }, + "id" : 19221, + "telemetryUpdate" : "always", + "annotation" : "Software framework version" + }, + { + "name" : "SG2.History", + "type" : { + "name" : "Ref.SignalSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 8707, + "telemetryUpdate" : "always", + "annotation" : "Last 10 Y values of the signal" + }, + { + "name" : "cmdSeq.CS_Errors", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1538, + "telemetryUpdate" : "always", + "annotation" : "The number of errors that have occurred" + }, + { + "name" : "SG4.PairHistory", + "type" : { + "name" : "Ref.SignalPairSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 9220, + "telemetryUpdate" : "always", + "annotation" : "Last 10 (time, value) pairs of the signal" + }, + { + "name" : "SG1.Type", + "type" : { + "name" : "Ref.SignalType", + "kind" : "qualifiedIdentifier" + }, + "id" : 8448, + "telemetryUpdate" : "always", + "annotation" : "Type of the output signal: SINE, TRIANGLE, etc." + }, + { + "name" : "cmdSeq.CS_LoadCommands", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1536, + "telemetryUpdate" : "always", + "annotation" : "The number of Load commands executed" + }, + { + "name" : "SG1.Output", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 8449, + "telemetryUpdate" : "always", + "format" : "{.4f}", + "annotation" : "Single Y value of the output" + }, + { + "name" : "sendBuffComp.SendState", + "type" : { + "name" : "Ref.SendBuff.ActiveState", + "kind" : "qualifiedIdentifier" + }, + "id" : 9732, + "telemetryUpdate" : "always", + "annotation" : "Readback of Parameter4" + }, + { + "name" : "dpCat.CatalogDps", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 3584, + "telemetryUpdate" : "always", + "annotation" : "Number of data products in catalog" + }, + { + "name" : "SG4.History", + "type" : { + "name" : "Ref.SignalSet", + "kind" : "qualifiedIdentifier" + }, + "id" : 9219, + "telemetryUpdate" : "always", + "annotation" : "Last 10 Y values of the signal" + }, + { + "name" : "dpBufferManager.TotalBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 19456, + "telemetryUpdate" : "on change", + "annotation" : "The total buffers allocated" + }, + { + "name" : "SG3.PairOutput", + "type" : { + "name" : "Ref.SignalPair", + "kind" : "qualifiedIdentifier" + }, + "id" : 8962, + "telemetryUpdate" : "always", + "annotation" : "Single (time, value) pair of the signal" + }, + { + "name" : "fileUplink.PacketsReceived", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 2305, + "telemetryUpdate" : "always", + "annotation" : "The total number of packets received" + }, + { + "name" : "systemResources.CPU_15", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19220, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "recvBuffComp.Parameter1", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 18179, + "telemetryUpdate" : "on change", + "annotation" : "Readback of Parameter1" + }, + { + "name" : "fileUplinkBufferManager.TotalBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 17408, + "telemetryUpdate" : "on change", + "annotation" : "The total buffers allocated" + }, + { + "name" : "dpCat.DpsSent", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 3585, + "telemetryUpdate" : "always", + "annotation" : "Number of data products sent" + }, + { + "name" : "SG4.DpRecords", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 9223, + "telemetryUpdate" : "always", + "annotation" : "DP records written" + }, + { + "name" : "dpWriter.NumSuccessfulWrites", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 4098, + "telemetryUpdate" : "on change", + "annotation" : "The number of successful writes" + }, + { + "name" : "SG2.DpBytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 8710, + "telemetryUpdate" : "always", + "annotation" : "DP bytes written" + }, + { + "name" : "cmdDisp.CommandsDispatched", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1280, + "telemetryUpdate" : "on change", + "annotation" : "Number of commands dispatched" + }, + { + "name" : "typeDemo.ChoiceSlurryCh", + "type" : { + "name" : "Ref.ChoiceSlurry", + "kind" : "qualifiedIdentifier" + }, + "id" : 4356, + "telemetryUpdate" : "always", + "annotation" : "Multiple choice channel via Complex Structure" + }, + { + "name" : "systemResources.CPU_00", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19205, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "systemResources.CPU_02", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19207, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "typeDemo.Float1Ch", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 4357, + "telemetryUpdate" : "always", + "annotation" : "Float output channel 1" + }, + { + "name" : "sendBuffComp.PacketsSent", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "id" : 9728, + "telemetryUpdate" : "always", + "annotation" : "Number of packets sent" + }, + { + "name" : "dpBufferManager.CurrBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 19457, + "telemetryUpdate" : "on change", + "annotation" : "The current number of allocated buffers" + }, + { + "name" : "systemResources.CPU_07", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 19212, + "telemetryUpdate" : "always", + "format" : "{.2f} percent", + "annotation" : "System's CPU Percentage" + }, + { + "name" : "systemResources.MEMORY_TOTAL", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "id" : 19200, + "telemetryUpdate" : "always", + "format" : "{} KB", + "annotation" : "Total system memory in KB" + }, + { + "name" : "SG2.PairOutput", + "type" : { + "name" : "Ref.SignalPair", + "kind" : "qualifiedIdentifier" + }, + "id" : 8706, + "telemetryUpdate" : "always", + "annotation" : "Single (time, value) pair of the signal" + }, + { + "name" : "dpMgr.NumBytes", + "type" : { + "name" : "U64", + "kind" : "integer", + "size" : 64, + "signed" : false + }, + "id" : 3843, + "telemetryUpdate" : "on change", + "annotation" : "Number of bytes handled" + }, + { + "name" : "fileUplinkBufferManager.CurrBuffs", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 17409, + "telemetryUpdate" : "on change", + "annotation" : "The current number of allocated buffers" + }, + { + "name" : "cmdSeq.CS_CancelCommands", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 1537, + "telemetryUpdate" : "always", + "annotation" : "The number of Cancel commands executed" + }, + { + "name" : "SG5.PairOutput", + "type" : { + "name" : "Ref.SignalPair", + "kind" : "qualifiedIdentifier" + }, + "id" : 9474, + "telemetryUpdate" : "always", + "annotation" : "Single (time, value) pair of the signal" + }, + { + "name" : "SG1.Info", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "id" : 8453, + "telemetryUpdate" : "always", + "annotation" : "Composite field of signal information, containing histories, pairs etc" + }, + { + "name" : "SG3.Output", + "type" : { + "name" : "F32", + "kind" : "float", + "size" : 32 + }, + "id" : 8961, + "telemetryUpdate" : "always", + "format" : "{.4f}", + "annotation" : "Single Y value of the output" + }, + { + "name" : "SG5.DpRecords", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 9479, + "telemetryUpdate" : "always", + "annotation" : "DP records written" + }, + { + "name" : "SG3.DpBytes", + "type" : { + "name" : "U32", + "kind" : "integer", + "size" : 32, + "signed" : false + }, + "id" : 8966, + "telemetryUpdate" : "always", + "annotation" : "DP bytes written" + } + ], + "records" : [ + { + "name" : "SG3.DataRecord", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "array" : false, + "id" : 8960, + "annotation" : "Signal generation data product record" + }, + { + "name" : "SG4.DataRecord", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "array" : false, + "id" : 9216, + "annotation" : "Signal generation data product record" + }, + { + "name" : "SG5.DataRecord", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "array" : false, + "id" : 9472, + "annotation" : "Signal generation data product record" + }, + { + "name" : "SG2.DataRecord", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "array" : false, + "id" : 8704, + "annotation" : "Signal generation data product record" + }, + { + "name" : "SG1.DataRecord", + "type" : { + "name" : "Ref.SignalInfo", + "kind" : "qualifiedIdentifier" + }, + "array" : false, + "id" : 8448, + "annotation" : "Signal generation data product record" + } + ], + "containers" : [ + { + "name" : "SG3.DataContainer", + "id" : 8960, + "defaultPriority" : 10, + "annotation" : "Data product container" + }, + { + "name" : "SG4.DataContainer", + "id" : 9216, + "defaultPriority" : 10, + "annotation" : "Data product container" + }, + { + "name" : "SG5.DataContainer", + "id" : 9472, + "defaultPriority" : 10, + "annotation" : "Data product container" + }, + { + "name" : "SG2.DataContainer", + "id" : 8704, + "defaultPriority" : 10, + "annotation" : "Data product container" + }, + { + "name" : "SG1.DataContainer", + "id" : 8448, + "defaultPriority" : 10, + "annotation" : "Data product container" + } + ] +} diff --git a/test/fprime_gds/common/loaders/test_json_loader.py b/test/fprime_gds/common/loaders/test_json_loader.py new file mode 100644 index 00000000..fbd5aea9 --- /dev/null +++ b/test/fprime_gds/common/loaders/test_json_loader.py @@ -0,0 +1,152 @@ +from fprime_gds.common.loaders.json_loader import JsonLoader +from fprime_gds.common.loaders.cmd_json_loader import CmdJsonLoader +from fprime_gds.common.loaders.ch_json_loader import ChJsonLoader +from fprime_gds.common.loaders.event_json_loader import EventJsonLoader +from fprime.common.models.serialize.array_type import ArrayType +from fprime.common.models.serialize.enum_type import EnumType +import fprime.common.models.serialize.numerical_types as numerical_types +from fprime.common.models.serialize.serializable_type import SerializableType +from fprime.common.models.serialize.string_type import StringType + +from pathlib import Path +import pytest +import json +from fprime_gds.common.templates.cmd_template import CmdTemplate +from fprime_gds.common.templates.ch_template import ChTemplate +from fprime_gds.common.templates.event_template import EventTemplate + + +REF_JSON_DICTIONARY = ( + Path(__file__).resolve().parent / "resources" / "RefTopologyDictionary.json" +) + +@pytest.fixture +def loader(): + return JsonLoader(REF_JSON_DICTIONARY) + +@pytest.fixture +def cmd_loader(): + return CmdJsonLoader(REF_JSON_DICTIONARY) + +@pytest.fixture +def event_loader(): + return EventJsonLoader(REF_JSON_DICTIONARY) + +@pytest.fixture +def ch_loader(): + return ChJsonLoader(REF_JSON_DICTIONARY) + +@pytest.fixture +def json_dict_obj(): + with open(REF_JSON_DICTIONARY, "r") as f: + return json.load(f) + + +def test_construct_enum_type(loader): + ref_signal_type = loader.parse_type( + {"name": "Ref.SignalType", "kind": "qualifiedIdentifier"} + ) + assert issubclass(ref_signal_type, EnumType) + assert ref_signal_type.__name__ == "Ref.SignalType" + assert ref_signal_type.ENUM_DICT == { + "TRIANGLE": 0, + "SQUARE": 1, + "SINE": 2, + "NOISE": 3, + } + assert ref_signal_type.REP_TYPE == "I32" + + +def test_construct_array_type(loader): + ref_many_choices = loader.parse_type( + {"name": "Ref.ManyChoices", "kind": "qualifiedIdentifier"} + ) + assert issubclass(ref_many_choices, ArrayType) + assert ref_many_choices.__name__ == "Ref.ManyChoices" + assert ref_many_choices.FORMAT == "{}" + assert ref_many_choices.LENGTH == 2 + assert ref_many_choices.MEMBER_TYPE.ENUM_DICT == { + "ONE": 0, + "TWO": 1, + "RED": 2, + "BLUE": 3, + } + assert ref_many_choices.MEMBER_TYPE.REP_TYPE == "I32" + + +def test_construct_serializable_type(loader): + ref_choice_pair = loader.parse_type( + {"name": "Ref.ChoicePair", "kind": "qualifiedIdentifier"} + ) + assert issubclass(ref_choice_pair, SerializableType) + assert ref_choice_pair.__name__ == "Ref.ChoicePair" + assert ref_choice_pair.MEMBER_LIST[0][0] == "firstChoice" + assert ref_choice_pair.MEMBER_LIST[0][1].ENUM_DICT == { + "ONE": 0, + "TWO": 1, + "RED": 2, + "BLUE": 3, + } + assert ref_choice_pair.MEMBER_LIST[0][1].REP_TYPE == "I32" + assert ref_choice_pair.MEMBER_LIST[0][2] == "{}" + assert ref_choice_pair.MEMBER_LIST[1][0] == "secondChoice" + assert ref_choice_pair.MEMBER_LIST[1][1].ENUM_DICT == { + "ONE": 0, + "TWO": 1, + "RED": 2, + "BLUE": 3, + } + assert ref_choice_pair.MEMBER_LIST[1][1].REP_TYPE == "I32" + assert ref_choice_pair.MEMBER_LIST[1][2] == "{}" + + +def test_construct_primitive_types(loader): + i32_type = loader.parse_type( + {"name": "I32", "kind": "integer", "size": 32, "signed": True} + ) + assert i32_type == numerical_types.I32Type + f64_type = loader.parse_type( + { + "name": "F64", + "kind": "float", + "size": 64, + } + ) + assert f64_type == numerical_types.F64Type + + +def test_construct_cmd_dict(cmd_loader, json_dict_obj): + id_dict, name_dict, versions = cmd_loader.construct_dicts(None) + assert len(id_dict) == len(name_dict) == len(json_dict_obj["commands"]) + assert versions == ("TestVersion", "TestVersion") + + cmd_no_op_string: CmdTemplate = name_dict["cmdDisp.CMD_NO_OP_STRING"] + assert cmd_no_op_string.get_op_code() == 1281 + assert cmd_no_op_string.get_description() == "No-op string command" + assert issubclass(cmd_no_op_string.get_args()[0][2], StringType) + + +def test_construct_event_dict(event_loader, json_dict_obj): + id_dict, name_dict, versions = event_loader.construct_dicts(None) + assert len(id_dict) == len(name_dict) == len(json_dict_obj["events"]) + assert versions == ("TestVersion", "TestVersion") + + event_choice: EventTemplate = name_dict["typeDemo.ChoiceEv"] + assert event_choice.get_id() == 4352 + assert event_choice.get_description() == "Single choice event" + assert event_choice.get_args()[0][0] == "choice" + assert issubclass(event_choice.get_args()[0][2], EnumType) + assert event_choice.get_format_str() == "Choice: {}" + + + +def test_construct_ch_dict(ch_loader, json_dict_obj): + id_dict, name_dict, versions = ch_loader.construct_dicts(None) + assert len(id_dict) == len(name_dict) == len(json_dict_obj["telemetryChannels"]) + assert versions == ("TestVersion", "TestVersion") + + ch_choice: ChTemplate = name_dict["typeDemo.ChoicesCh"] + assert ch_choice.get_id() == 4353 + assert ch_choice.get_ch_desc() == "Multiple choice channel via Array" + assert ch_choice.ch_type_obj.__name__ == "Ref.ManyChoices" + assert ch_choice.ch_type_obj.LENGTH == 2 From cbd87153e52e57d3e335bbf9da1e3ed55eb2a560 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 16:51:51 -0700 Subject: [PATCH 21/28] ignore some spelling --- .github/actions/spelling/excludes.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt index 90231acf..4ee7306e 100644 --- a/.github/actions/spelling/excludes.txt +++ b/.github/actions/spelling/excludes.txt @@ -1,3 +1,5 @@ +pyproject.toml +setup.py ignore$ /html/ (?:^|/)(?i)COPYRIGHT @@ -5,6 +7,7 @@ ignore$ (?:^|/)vendor/ ^\.github/ ^Autocoders/Python/test/.*\.xml$ +RefTopologyDictionary.json /doc/xml/ /third-party/ /third/ @@ -43,5 +46,4 @@ ignore$ \.xlsx$ \.xsd$ \.ico$ -pyproject.toml -setup.py + From d8296fc5ca926b6b7f0d6ff9214d99cc304190b4 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 17:16:53 -0700 Subject: [PATCH 22/28] Code cleanup and formatting --- .../common/loaders/ch_json_loader.py | 36 +++++++----------- .../common/loaders/cmd_json_loader.py | 38 +++++++------------ .../common/loaders/event_json_loader.py | 15 +++----- 3 files changed, 33 insertions(+), 56 deletions(-) diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index c6509b12..acbd3134 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -8,18 +8,17 @@ from fprime_gds.common.templates.ch_template import ChTemplate from fprime_gds.common.loaders.json_loader import JsonLoader +from enum import Enum class ChJsonLoader(JsonLoader): """Class to load python based telemetry channel dictionaries""" - # Field names in the python module files (used to construct dictionaries) - ID_FIELD = "id" - NAME_FIELD = "name" - KIND_FIELD = "kind" - DESC_FIELD = "annotation" - TYPE_FIELD = "type" - FMT_STR_FIELD = "format" + ID = "id" + NAME = "name" + DESC = "annotation" + TYPE = "type" + FMT_STR = "format" LIMIT_FIELD = "limit" LIMIT_LOW = "low" LIMIT_HIGH = "high" @@ -27,15 +26,12 @@ class ChJsonLoader(JsonLoader): LIMIT_ORANGE = "orange" LIMIT_YELLOW = "yellow" - def __init__(self, dict_path: str): - super().__init__(dict_path) - - def construct_dicts(self, dict_path: str): + def construct_dicts(self, _): """ Constructs and returns python dictionaries keyed on id and name Args: - path: Path to JSON dictionary file + _: Unused argument (inherited) Returns: A tuple with two channel dictionaries (python type dict): (id_dict, name_dict). The keys should be the channels' id and @@ -59,33 +55,29 @@ def construct_dicts(self, dict_path: str): ) def construct_template_from_dict(self, channel_dict: dict) -> ChTemplate: - component_name = channel_dict[self.NAME_FIELD].split(".")[0] - channel_name = channel_dict[self.NAME_FIELD].split(".")[1] - channel_type = channel_dict["type"] + component_name = channel_dict[self.NAME].split(".")[0] + channel_name = channel_dict[self.NAME].split(".")[1] + channel_type = channel_dict[self.TYPE] type_obj = self.parse_type(channel_type) - format_str = JsonLoader.preprocess_format_str( - channel_dict.get(self.FMT_STR_FIELD) - ) + format_str = JsonLoader.preprocess_format_str(channel_dict.get(self.FMT_STR)) limit_field = channel_dict.get(self.LIMIT_FIELD) limit_low = limit_field.get(self.LIMIT_LOW) if limit_field else None limit_high = limit_field.get(self.LIMIT_HIGH) if limit_field else None - limit_low_yellow = limit_low.get(self.LIMIT_YELLOW) if limit_low else None limit_low_red = limit_low.get(self.LIMIT_RED) if limit_low else None limit_low_orange = limit_low.get(self.LIMIT_ORANGE) if limit_low else None - limit_high_yellow = limit_high.get(self.LIMIT_YELLOW) if limit_high else None limit_high_red = limit_high.get(self.LIMIT_RED) if limit_high else None limit_high_orange = limit_high.get(self.LIMIT_ORANGE) if limit_high else None return ChTemplate( - channel_dict[self.ID_FIELD], + channel_dict[self.ID], channel_name, component_name, type_obj, ch_fmt_str=format_str, - ch_desc=channel_dict.get(self.DESC_FIELD), + ch_desc=channel_dict.get(self.DESC), low_red=limit_low_red, low_orange=limit_low_orange, low_yellow=limit_low_yellow, diff --git a/src/fprime_gds/common/loaders/cmd_json_loader.py b/src/fprime_gds/common/loaders/cmd_json_loader.py index 1abcb832..d8443ae3 100644 --- a/src/fprime_gds/common/loaders/cmd_json_loader.py +++ b/src/fprime_gds/common/loaders/cmd_json_loader.py @@ -13,26 +13,22 @@ class CmdJsonLoader(JsonLoader): """Class to load xml based command dictionaries""" - MNEMONIC_TAG = "name" + NAME_TAG = "name" OPCODE_TAG = "opcode" DESC_TAG = "annotation" PARAMETERS_TAG = "formalParams" - def __init__(self, dict_path: str): - super().__init__(dict_path) - - def construct_dicts(self, path): + def construct_dicts(self, _): """ Constructs and returns python dictionaries keyed on id and name Args: - path: Path to JSON dictionary file + _: Unused argument (inherited) Returns: - A tuple with two command dictionaries (python type dict): - (id_dict, name_dict). The keys are the events' id and name fields - respectively and the values are CmdTemplate objects + A tuple with two command dictionaries (python type dict): + (id_dict, name_dict). The keys are the events' id and name fields + respectively and the values are CmdTemplate objects """ - id_dict = {} name_dict = {} @@ -49,26 +45,20 @@ def construct_dicts(self, path): ) def construct_template_from_dict(self, cmd_dict: dict) -> CmdTemplate: - cmd_name = cmd_dict.get("name") - + cmd_name = cmd_dict.get(self.NAME_TAG) cmd_comp = cmd_name.split(".")[0] cmd_mnemonic = cmd_name.split(".")[1] - - cmd_opcode = cmd_dict.get("opcode") - - cmd_desc = cmd_dict.get("annotation") - + cmd_opcode = cmd_dict.get(self.OPCODE_TAG) + cmd_desc = cmd_dict.get(self.DESC_TAG) # Parse Arguments cmd_args = [] - for arg in cmd_dict.get("formalParams", []): + for param in cmd_dict.get(self.PARAMETERS_TAG, []): cmd_args.append( ( - arg.get("name"), - arg.get("annotation"), - self.parse_type(arg.get("type")), + param.get("name"), + param.get("annotation"), + self.parse_type(param.get("type")), ) ) - return CmdTemplate( - cmd_opcode, cmd_mnemonic, cmd_comp, cmd_args, cmd_desc - ) + return CmdTemplate(cmd_opcode, cmd_mnemonic, cmd_comp, cmd_args, cmd_desc) diff --git a/src/fprime_gds/common/loaders/event_json_loader.py b/src/fprime_gds/common/loaders/event_json_loader.py index a0b766d8..be84a537 100644 --- a/src/fprime_gds/common/loaders/event_json_loader.py +++ b/src/fprime_gds/common/loaders/event_json_loader.py @@ -6,27 +6,22 @@ @author thomas-bc """ -from fprime_gds.common.data_types import exceptions from fprime_gds.common.templates.event_template import EventTemplate from fprime_gds.common.utils.event_severity import EventSeverity - -# Custom Python Modules from fprime_gds.common.loaders.json_loader import JsonLoader class EventJsonLoader(JsonLoader): """Class to load xml based event dictionaries""" - EVENT_SECT = "events" - - COMP_TAG = "component" NAME_TAG = "name" ID_TAG = "id" SEVERITY_TAG = "severity" FMT_STR_TAG = "format" DESC_TAG = "annotation" + PARAMETERS_TAG = "formalParams" - def construct_dicts(self, path): + def construct_dicts(self, _): """ Constructs and returns python dictionaries keyed on id and name @@ -34,7 +29,7 @@ def construct_dicts(self, path): get_id_dict(path) and get_name_dict(path) Args: - path: Path to the xml dictionary file containing event information + _: Unused argument (inherited) Returns: A tuple with two event dictionaries (python type dict): @@ -57,7 +52,7 @@ def construct_dicts(self, path): ) def construct_template_from_dict(self, event_dict: dict): - event_mnemonic = event_dict.get("name") + event_mnemonic = event_dict.get(self.NAME_TAG) event_comp = event_mnemonic.split(".")[0] event_name = event_mnemonic.split(".")[1] @@ -72,7 +67,7 @@ def construct_template_from_dict(self, event_dict: dict): # Parse arguments event_args = [] - for arg in event_dict.get("formalParams", []): + for arg in event_dict.get(self.PARAMETERS_TAG, []): event_args.append( ( arg.get("name"), From 681b88be243c54713f93010d16093cdfb3a29464 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 17:19:36 -0700 Subject: [PATCH 23/28] Remove "tag" terminology --- .../common/loaders/ch_json_loader.py | 1 - .../common/loaders/cmd_json_loader.py | 16 ++++++------- .../common/loaders/event_json_loader.py | 24 +++++++++---------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index acbd3134..9dcb5966 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -8,7 +8,6 @@ from fprime_gds.common.templates.ch_template import ChTemplate from fprime_gds.common.loaders.json_loader import JsonLoader -from enum import Enum class ChJsonLoader(JsonLoader): diff --git a/src/fprime_gds/common/loaders/cmd_json_loader.py b/src/fprime_gds/common/loaders/cmd_json_loader.py index d8443ae3..adbe5c9a 100644 --- a/src/fprime_gds/common/loaders/cmd_json_loader.py +++ b/src/fprime_gds/common/loaders/cmd_json_loader.py @@ -13,10 +13,10 @@ class CmdJsonLoader(JsonLoader): """Class to load xml based command dictionaries""" - NAME_TAG = "name" - OPCODE_TAG = "opcode" - DESC_TAG = "annotation" - PARAMETERS_TAG = "formalParams" + NAME = "name" + OPCODE = "opcode" + DESC = "annotation" + PARAMETERS = "formalParams" def construct_dicts(self, _): """ @@ -45,14 +45,14 @@ def construct_dicts(self, _): ) def construct_template_from_dict(self, cmd_dict: dict) -> CmdTemplate: - cmd_name = cmd_dict.get(self.NAME_TAG) + cmd_name = cmd_dict.get(self.NAME) cmd_comp = cmd_name.split(".")[0] cmd_mnemonic = cmd_name.split(".")[1] - cmd_opcode = cmd_dict.get(self.OPCODE_TAG) - cmd_desc = cmd_dict.get(self.DESC_TAG) + cmd_opcode = cmd_dict.get(self.OPCODE) + cmd_desc = cmd_dict.get(self.DESC) # Parse Arguments cmd_args = [] - for param in cmd_dict.get(self.PARAMETERS_TAG, []): + for param in cmd_dict.get(self.PARAMETERS, []): cmd_args.append( ( param.get("name"), diff --git a/src/fprime_gds/common/loaders/event_json_loader.py b/src/fprime_gds/common/loaders/event_json_loader.py index be84a537..27a316ea 100644 --- a/src/fprime_gds/common/loaders/event_json_loader.py +++ b/src/fprime_gds/common/loaders/event_json_loader.py @@ -14,12 +14,12 @@ class EventJsonLoader(JsonLoader): """Class to load xml based event dictionaries""" - NAME_TAG = "name" - ID_TAG = "id" - SEVERITY_TAG = "severity" - FMT_STR_TAG = "format" - DESC_TAG = "annotation" - PARAMETERS_TAG = "formalParams" + NAME = "name" + ID = "id" + SEVERITY = "severity" + FMT_STR = "format" + DESC = "annotation" + PARAMETERS = "formalParams" def construct_dicts(self, _): """ @@ -52,22 +52,22 @@ def construct_dicts(self, _): ) def construct_template_from_dict(self, event_dict: dict): - event_mnemonic = event_dict.get(self.NAME_TAG) + event_mnemonic = event_dict.get(self.NAME) event_comp = event_mnemonic.split(".")[0] event_name = event_mnemonic.split(".")[1] - event_id = event_dict[self.ID_TAG] - event_severity = EventSeverity[event_dict[self.SEVERITY_TAG]] + event_id = event_dict[self.ID] + event_severity = EventSeverity[event_dict[self.SEVERITY]] event_fmt_str = JsonLoader.preprocess_format_str( - event_dict.get(self.FMT_STR_TAG, "") + event_dict.get(self.FMT_STR, "") ) - event_desc = event_dict.get(self.DESC_TAG) + event_desc = event_dict.get(self.DESC) # Parse arguments event_args = [] - for arg in event_dict.get(self.PARAMETERS_TAG, []): + for arg in event_dict.get(self.PARAMETERS, []): event_args.append( ( arg.get("name"), From 4471c81906827f8fe58d4428e4f0976e224e1287 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 30 Apr 2024 17:22:54 -0700 Subject: [PATCH 24/28] Exclude dictionary from spelling --- .github/actions/spelling/excludes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt index 6770a45a..244de09e 100644 --- a/.github/actions/spelling/excludes.txt +++ b/.github/actions/spelling/excludes.txt @@ -8,6 +8,7 @@ ignore$ ^\.github/ ^Autocoders/Python/test/.*\.xml$ RefTopologyDictionary.json +dictionary.xml /doc/xml/ /third-party/ /third/ From 6685602c9a079061b1127d0f9d5a93518fb45963 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Thu, 2 May 2024 09:24:15 -0700 Subject: [PATCH 25/28] few review notes --- src/fprime_gds/common/loaders/json_loader.py | 1 - src/fprime_gds/executables/utils.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index 79ea8396..1c5fd120 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -80,7 +80,6 @@ def parse_type(self, type_dict: dict) -> BaseType: return PRIMITIVE_TYPE_MAP[type_name] if type_name == "string": - # REVIEW NOTE: All strings of same size will share the same type. I believe this is good? return StringType.construct_type( f'String_{type_dict.get("size")}', type_dict.get("size") ) diff --git a/src/fprime_gds/executables/utils.py b/src/fprime_gds/executables/utils.py index a5d640fe..fadcd773 100644 --- a/src/fprime_gds/executables/utils.py +++ b/src/fprime_gds/executables/utils.py @@ -204,7 +204,7 @@ def find_dict(root: Path) -> Path: if child.is_file() and child.name.endswith("Dictionary.json") ] # Select json dictionary if available, otherwise use xml dictionary - dicts = json_dicts or xml_dicts + dicts = json_dicts if json_dicts else xml_dicts if not dicts: print( From 47096513a35b2857f7779017d14ff6a9f6054996 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Thu, 2 May 2024 09:24:43 -0700 Subject: [PATCH 26/28] case-insensitive sorting in commandList --- src/fprime_gds/flask/static/addons/commanding/command-input.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fprime_gds/flask/static/addons/commanding/command-input.js b/src/fprime_gds/flask/static/addons/commanding/command-input.js index f34264c5..aa97950c 100644 --- a/src/fprime_gds/flask/static/addons/commanding/command-input.js +++ b/src/fprime_gds/flask/static/addons/commanding/command-input.js @@ -217,7 +217,7 @@ Vue.component("command-input", { * @return {number} -1 or 1 */ function(obj1, obj2) { - if (obj1.full_name <= obj2.full_name) { + if (obj1.full_name.toLowerCase() <= obj2.full_name.toLowerCase()) { return -1; } return 1; From 5eacbf35cb23f35a94bedbe0b4c38a09deb18e4a Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 7 May 2024 15:29:34 -0700 Subject: [PATCH 27/28] Improve error handling --- .../common/data_types/exceptions.py | 27 ++++++---- .../common/loaders/ch_json_loader.py | 33 +++++++++--- .../common/loaders/cmd_json_loader.py | 39 ++++++++++---- .../common/loaders/event_json_loader.py | 39 ++++++++++---- src/fprime_gds/common/loaders/json_loader.py | 51 ++++++++++--------- 5 files changed, 131 insertions(+), 58 deletions(-) diff --git a/src/fprime_gds/common/data_types/exceptions.py b/src/fprime_gds/common/data_types/exceptions.py index c2cda300..a3dba644 100644 --- a/src/fprime_gds/common/data_types/exceptions.py +++ b/src/fprime_gds/common/data_types/exceptions.py @@ -2,10 +2,25 @@ Created on Jan 9, 2015 @author: reder """ + # Exception classes for all controllers modules -class GseControllerException(Exception): +class FprimeGdsException(Exception): + """ + Base Exception for exceptions that need to be handled at the system-level + by the GDS + """ + + pass + + +class GdsDictionaryParsingException(FprimeGdsException): + pass + + +# Note: Gse is the historical name for what is now called the GDS +class GseControllerException(FprimeGdsException): def __init__(self, val): self.except_msg = val super().__init__(val) @@ -27,13 +42,3 @@ def __init__(self, val): class GseControllerParsingException(GseControllerException): def __init__(self, val): super().__init__(f"Parsing error: {str(val)}") - - -class GseControllerMnemonicMismatchException(GseControllerException): - def __init__(self, val1, val2): - super().__init__(f"ID mismatch ({str(val1)}, {str(val2)})!") - - -class GseControllerStatusUpdateException(GseControllerException): - def __init__(self, val): - super().__init__(f"Bad status update mode: {str(val)}!") diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index 9dcb5966..7b22da08 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -8,11 +8,14 @@ from fprime_gds.common.templates.ch_template import ChTemplate from fprime_gds.common.loaders.json_loader import JsonLoader +from fprime_gds.common.data_types.exceptions import GdsDictionaryParsingException class ChJsonLoader(JsonLoader): """Class to load python based telemetry channel dictionaries""" + CHANNELS_FIELD = "telemetryChannels" + ID = "id" NAME = "name" DESC = "annotation" @@ -40,7 +43,12 @@ def construct_dicts(self, _): id_dict = {} name_dict = {} - for ch_dict in self.json_dict["telemetryChannels"]: + if self.CHANNELS_FIELD not in self.json_dict: + raise GdsDictionaryParsingException( + f"Ground Dictionary missing '{self.CHANNELS_FIELD}' field: {str(self.json_file)}" + ) + + for ch_dict in self.json_dict[self.CHANNELS_FIELD]: # Create a channel template object ch_temp = self.construct_template_from_dict(ch_dict) @@ -54,10 +62,23 @@ def construct_dicts(self, _): ) def construct_template_from_dict(self, channel_dict: dict) -> ChTemplate: - component_name = channel_dict[self.NAME].split(".")[0] - channel_name = channel_dict[self.NAME].split(".")[1] - channel_type = channel_dict[self.TYPE] - type_obj = self.parse_type(channel_type) + try: + ch_id = channel_dict[self.ID] + # The below assignment also raises a ValueError if the name does not contain a '.' + component_name, channel_name = channel_dict[self.NAME].split(".") + if not component_name or not channel_name: + raise ValueError() + + type_obj = self.parse_type(channel_dict[self.TYPE]) + except ValueError as e: + raise GdsDictionaryParsingException( + f"Channel dictionary entry malformed, expected name of the form '.' in : {str(channel_dict)}" + ) + except KeyError as e: + raise GdsDictionaryParsingException( + f"{str(e)} key missing from Channel dictionary entry or its associated type in the dictionary: {str(channel_dict)}" + ) + format_str = JsonLoader.preprocess_format_str(channel_dict.get(self.FMT_STR)) limit_field = channel_dict.get(self.LIMIT_FIELD) @@ -71,7 +92,7 @@ def construct_template_from_dict(self, channel_dict: dict) -> ChTemplate: limit_high_orange = limit_high.get(self.LIMIT_ORANGE) if limit_high else None return ChTemplate( - channel_dict[self.ID], + ch_id, channel_name, component_name, type_obj, diff --git a/src/fprime_gds/common/loaders/cmd_json_loader.py b/src/fprime_gds/common/loaders/cmd_json_loader.py index adbe5c9a..03696a09 100644 --- a/src/fprime_gds/common/loaders/cmd_json_loader.py +++ b/src/fprime_gds/common/loaders/cmd_json_loader.py @@ -8,11 +8,14 @@ from fprime_gds.common.templates.cmd_template import CmdTemplate from fprime_gds.common.loaders.json_loader import JsonLoader +from fprime_gds.common.data_types.exceptions import GdsDictionaryParsingException class CmdJsonLoader(JsonLoader): """Class to load xml based command dictionaries""" + COMMANDS_FIELD = "commands" + NAME = "name" OPCODE = "opcode" DESC = "annotation" @@ -32,7 +35,12 @@ def construct_dicts(self, _): id_dict = {} name_dict = {} - for cmd_dict in self.json_dict["commands"]: + if self.COMMANDS_FIELD not in self.json_dict: + raise GdsDictionaryParsingException( + f"Ground Dictionary missing '{self.COMMANDS_FIELD}' field: {str(self.json_file)}" + ) + + for cmd_dict in self.json_dict[self.COMMANDS_FIELD]: cmd_temp = self.construct_template_from_dict(cmd_dict) id_dict[cmd_temp.get_id()] = cmd_temp @@ -45,20 +53,33 @@ def construct_dicts(self, _): ) def construct_template_from_dict(self, cmd_dict: dict) -> CmdTemplate: - cmd_name = cmd_dict.get(self.NAME) - cmd_comp = cmd_name.split(".")[0] - cmd_mnemonic = cmd_name.split(".")[1] - cmd_opcode = cmd_dict.get(self.OPCODE) - cmd_desc = cmd_dict.get(self.DESC) + try: + cmd_comp, cmd_mnemonic = cmd_dict[self.NAME].split(".") + cmd_opcode = cmd_dict[self.OPCODE] + cmd_desc = cmd_dict.get(self.DESC) + except ValueError as e: + raise GdsDictionaryParsingException( + f"Command dictionary entry malformed, expected name of the form '.' in : {str(cmd_dict)}" + ) + except KeyError as e: + raise GdsDictionaryParsingException( + f"{str(e)} key missing from Command dictionary entry: {str(cmd_dict)}" + ) # Parse Arguments cmd_args = [] for param in cmd_dict.get(self.PARAMETERS, []): + try: + param_name = param["name"] + param_type = self.parse_type(param["type"]) + except KeyError as e: + raise GdsDictionaryParsingException( + f"{str(e)} key missing from Command parameter or its associated type in the dictionary: {str(param)}" + ) cmd_args.append( ( - param.get("name"), + param_name, param.get("annotation"), - self.parse_type(param.get("type")), + param_type, ) ) - return CmdTemplate(cmd_opcode, cmd_mnemonic, cmd_comp, cmd_args, cmd_desc) diff --git a/src/fprime_gds/common/loaders/event_json_loader.py b/src/fprime_gds/common/loaders/event_json_loader.py index 27a316ea..f2060b43 100644 --- a/src/fprime_gds/common/loaders/event_json_loader.py +++ b/src/fprime_gds/common/loaders/event_json_loader.py @@ -9,11 +9,14 @@ from fprime_gds.common.templates.event_template import EventTemplate from fprime_gds.common.utils.event_severity import EventSeverity from fprime_gds.common.loaders.json_loader import JsonLoader +from fprime_gds.common.data_types.exceptions import GdsDictionaryParsingException class EventJsonLoader(JsonLoader): """Class to load xml based event dictionaries""" + EVENTS_FIELD = "events" + NAME = "name" ID = "id" SEVERITY = "severity" @@ -39,7 +42,12 @@ def construct_dicts(self, _): id_dict = {} name_dict = {} - for event_dict in self.json_dict.get("events"): + if self.EVENTS_FIELD not in self.json_dict: + raise GdsDictionaryParsingException( + f"Ground Dictionary missing '{self.EVENTS_FIELD}' field: {str(self.json_file)}" + ) + + for event_dict in self.json_dict[self.EVENTS_FIELD]: event_temp = self.construct_template_from_dict(event_dict) id_dict[event_temp.get_id()] = event_temp @@ -52,12 +60,18 @@ def construct_dicts(self, _): ) def construct_template_from_dict(self, event_dict: dict): - event_mnemonic = event_dict.get(self.NAME) - event_comp = event_mnemonic.split(".")[0] - event_name = event_mnemonic.split(".")[1] - - event_id = event_dict[self.ID] - event_severity = EventSeverity[event_dict[self.SEVERITY]] + try: + event_comp, event_name = event_dict[self.NAME].split(".") + event_id = event_dict[self.ID] + event_severity = EventSeverity[event_dict[self.SEVERITY]] + except ValueError as e: + raise GdsDictionaryParsingException( + f"Event dictionary entry malformed, expected name of the form '.' in : {str(event_dict)}" + ) + except KeyError as e: + raise GdsDictionaryParsingException( + f"{str(e)} key missing from Event dictionary entry: {str(event_dict)}" + ) event_fmt_str = JsonLoader.preprocess_format_str( event_dict.get(self.FMT_STR, "") @@ -68,11 +82,18 @@ def construct_template_from_dict(self, event_dict: dict): # Parse arguments event_args = [] for arg in event_dict.get(self.PARAMETERS, []): + try: + arg_name = arg["name"] + arg_type = self.parse_type(arg["type"]) + except KeyError as e: + raise GdsDictionaryParsingException( + f"{str(e)} key missing from Event parameter or its associated type in the dictionary: {str(arg)}" + ) event_args.append( ( - arg.get("name"), + arg_name, arg.get("annotation"), - self.parse_type(arg.get("type")), + arg_type, ) ) diff --git a/src/fprime_gds/common/loaders/json_loader.py b/src/fprime_gds/common/loaders/json_loader.py index 1c5fd120..c55b10a5 100644 --- a/src/fprime_gds/common/loaders/json_loader.py +++ b/src/fprime_gds/common/loaders/json_loader.py @@ -19,6 +19,7 @@ from fprime_gds.common.utils.string_util import preprocess_fpp_format_str from fprime_gds.common.loaders import dict_loader +from fprime_gds.common.data_types.exceptions import GdsDictionaryParsingException PRIMITIVE_TYPE_MAP = { @@ -50,6 +51,7 @@ def __init__(self, json_file: str): An initialized loader object """ super().__init__() + self.json_file = json_file with open(json_file, "r") as f: self.json_dict = json.load(f) @@ -61,19 +63,20 @@ def get_versions(self): A tuple of the framework and project versions """ if "metadata" not in self.json_dict: - # REVIEW NOTE: Should we raise an error instead? - return ("unknown", "unknown") + raise GdsDictionaryParsingException( + f"Dictionary has no metadata field: {self.json_file}" + ) return ( - self.json_dict.get("metadata").get("frameworkVersion", "unknown"), - self.json_dict.get("metadata").get("projectVersion", "unknown"), + self.json_dict["metadata"].get("frameworkVersion", "unknown"), + self.json_dict["metadata"].get("projectVersion", "unknown"), ) def parse_type(self, type_dict: dict) -> BaseType: type_name: str = type_dict.get("name", None) if type_name is None: - raise ValueError( - f"Channel entry in dictionary has no `name` field: {str(type_dict)}" + raise GdsDictionaryParsingException( + f"Dictionary entry has no `name` field: {str(type_dict)}" ) if type_name in PRIMITIVE_TYPE_MAP: @@ -81,7 +84,7 @@ def parse_type(self, type_dict: dict) -> BaseType: if type_name == "string": return StringType.construct_type( - f'String_{type_dict.get("size")}', type_dict.get("size") + f'String_{type_dict["size"]}', type_dict["size"] ) # Check if type has already been parsed @@ -94,10 +97,9 @@ def parse_type(self, type_dict: dict) -> BaseType: if type_name == type_def.get("qualifiedName"): qualified_type = type_def break - - if qualified_type is None: - raise ValueError( - f"Channel entry {type_name} in dictionary has no corresponding type definition." + else: + raise GdsDictionaryParsingException( + f"Dictionary type name has no corresponding type definition: {type_name}" ) if qualified_type.get("kind") == "array": @@ -109,8 +111,8 @@ def parse_type(self, type_dict: dict) -> BaseType: if qualified_type.get("kind") == "struct": return self.construct_serializable_type(type_name, qualified_type) - raise ValueError( - f"Channel entry in dictionary has unknown type {str(type_dict)}" + raise GdsDictionaryParsingException( + f"Dictionary entry has unknown type {str(type_dict)}" ) def construct_enum_type(self, type_name: str, qualified_type: dict) -> EnumType: @@ -128,11 +130,11 @@ def construct_enum_type(self, type_name: str, qualified_type: dict) -> EnumType: """ enum_dict = {} for member in qualified_type.get("enumeratedConstants"): - enum_dict[member.get("name")] = member.get("value") + enum_dict[member["name"]] = member.get("value") enum_type = EnumType.construct_type( type_name, enum_dict, - qualified_type.get("representationType").get("name"), + qualified_type["representationType"].get("name"), ) self.parsed_types[type_name] = enum_type return enum_type @@ -154,7 +156,9 @@ def construct_array_type(self, type_name: str, qualified_type: dict) -> ArrayTyp type_name, self.parse_type(qualified_type.get("elementType")), qualified_type.get("size"), - qualified_type.get("elementType").get("format", "{}"), + JsonLoader.preprocess_format_str( + qualified_type["elementType"].get("format", "{}") + ), ) self.parsed_types[type_name] = array_type return array_type @@ -176,19 +180,20 @@ def construct_serializable_type( """ struct_members = [] for name, member_dict in qualified_type.get("members").items(): - member_type_dict = member_dict.get("type") + member_type_dict = member_dict["type"] member_type_obj = self.parse_type(member_type_dict) # For member arrays (declared inline, so we create a type on the fly) if member_dict.get("size") is not None: member_type_obj = ArrayType.construct_type( - f"Array_{member_type_obj.__name__}_{member_dict.get('size')}", + f"Array_{member_type_obj.__name__}_{member_dict['size']}", member_type_obj, - member_dict.get("size"), - member_dict.get("type").get("format", "{}"), + member_dict["size"], + JsonLoader.preprocess_format_str( + member_dict["type"].get("format", "{}") + ), ) - # TODO: does this need to be preprocessed or something? - fmt_str = ( + fmt_str = JsonLoader.preprocess_format_str( member_type_obj.FORMAT if hasattr(member_type_obj, "FORMAT") else "{}" ) description = member_type_dict.get("annotation", "") @@ -202,7 +207,7 @@ def construct_serializable_type( return ser_type @staticmethod - def preprocess_format_str(format_str: Optional[str]) -> str: + def preprocess_format_str(format_str: Optional[str]) -> Optional[str]: """Preprocess format strings before using them in Python format function Internally, this converts FPP-style format strings to Python-style format strings From 95b19285c3d31952c077b879371a05b83a897713 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 7 May 2024 15:43:11 -0700 Subject: [PATCH 28/28] Sort dictionaries at load time --- src/fprime_gds/common/loaders/ch_json_loader.py | 4 ++-- src/fprime_gds/common/loaders/cmd_json_loader.py | 4 ++-- src/fprime_gds/common/loaders/event_json_loader.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fprime_gds/common/loaders/ch_json_loader.py b/src/fprime_gds/common/loaders/ch_json_loader.py index 7b22da08..cbd83c74 100644 --- a/src/fprime_gds/common/loaders/ch_json_loader.py +++ b/src/fprime_gds/common/loaders/ch_json_loader.py @@ -56,8 +56,8 @@ def construct_dicts(self, _): name_dict[ch_temp.get_full_name()] = ch_temp return ( - id_dict, - name_dict, + dict(sorted(id_dict.items())), + dict(sorted(name_dict.items())), self.get_versions(), ) diff --git a/src/fprime_gds/common/loaders/cmd_json_loader.py b/src/fprime_gds/common/loaders/cmd_json_loader.py index 03696a09..f449f7e1 100644 --- a/src/fprime_gds/common/loaders/cmd_json_loader.py +++ b/src/fprime_gds/common/loaders/cmd_json_loader.py @@ -47,8 +47,8 @@ def construct_dicts(self, _): name_dict[cmd_temp.get_full_name()] = cmd_temp return ( - id_dict, - name_dict, + dict(sorted(id_dict.items())), + dict(sorted(name_dict.items())), self.get_versions(), ) diff --git a/src/fprime_gds/common/loaders/event_json_loader.py b/src/fprime_gds/common/loaders/event_json_loader.py index f2060b43..b94540c7 100644 --- a/src/fprime_gds/common/loaders/event_json_loader.py +++ b/src/fprime_gds/common/loaders/event_json_loader.py @@ -54,8 +54,8 @@ def construct_dicts(self, _): name_dict[event_temp.get_full_name()] = event_temp return ( - id_dict, - name_dict, + dict(sorted(id_dict.items())), + dict(sorted(name_dict.items())), self.get_versions(), )