| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@@ -1,4 +1,5 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import re
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import enum
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import logging
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				from pathlib import Path
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				from typing import List, Optional, Dict
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -15,6 +16,25 @@ SUBSYSTEM_ID_NAMESPACE = "SUBSYSTEM_ID"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				EVENT_NAME_IDX = 1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class Severity(enum.IntEnum):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    INFO = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    LOW = 1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    MEDIUM = 2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    HIGH = 3
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def severity_str_to_enum(severity: str) -> Severity | None:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if severity == "INFO":
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return Severity.INFO
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if severity == "LOW":
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return Severity.LOW
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if severity == "MEDIUM":
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return Severity.MEDIUM
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if severity == "HIGH":
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return Severity.HIGH
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class SubsystemDefinitionParser(FileParser):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def __init__(self, file_list):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        super().__init__(file_list)
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -69,8 +89,8 @@ class EventParser(FileParser):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.set_moving_window_mode(moving_window_size)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.interfaces = interface_list
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.count = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.my_id = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.current_id = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.current_group_id = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.current_unique_id = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.mib_table: EventDictT = dict()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.obsw_root_path: Optional[Path] = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.last_lines = ["", "", ""]
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -96,8 +116,8 @@ class EventParser(FileParser):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            # For now, it is assumed that there is only going to be one subsystem ID per
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            # class / source file
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.current_id = self.interfaces[subsystem_id_assignment_match.group(1)][0]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.my_id = self.return_number_from_string(self.current_id)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.current_group_id = self.interfaces[subsystem_id_assignment_match.group(1)][0]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.current_group_id = self.return_number_from_string(self.current_group_id)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            except KeyError as e:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                print(f"Key not found: {e}")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # Now try to look for event definitions. Moving windows allows multi line event definitions
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -156,17 +176,28 @@ class EventParser(FileParser):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if event_full_match:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            name = event_match.group(EVENT_NAME_IDX)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if macro_api_match:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                full_id = (self.my_id * 100) + self.return_number_from_string(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    event_full_match.group(2)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                severity = event_full_match.group(3)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                severity_num = severity_str_to_enum(severity)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if severity_num is None:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    raise ValueError(f"Unknown severity: {severity}")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                full_id = (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    (severity_num << 30)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    | (self.current_group_id << 16)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    | self.return_number_from_string(event_full_match.group(2))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                severity = event_full_match.group(4)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                severity_num = severity_str_to_enum(severity)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if severity_num is None:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    raise ValueError(f"Unknown severity: {severity}")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if event_full_match.group(1) == "EV_REPLY_INVALID_SIZE":
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    print(f"Group 3: {event_full_match.group(3)}")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                full_id = (self.my_id * 100) + self.return_number_from_string(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    event_full_match.group(3)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                full_id = (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    (severity_num << 30)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    | (self.current_group_id << 16)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    | self.return_number_from_string(event_full_match.group(3))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                severity = event_full_match.group(4)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if self.obsw_root_path is not None:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                file_name = file_name.relative_to(self.obsw_root_path)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if self.mib_table.get(full_id) is not None:
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -254,13 +285,15 @@ def export_to_csv(filename: Path, event_list: EventDictT, col_sep: str):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def write_translation_source_file(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    event_list: EventDictT, date_string: str, filename: Path = "translateEvents.cpp"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    event_list: EventDictT,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    date_string: str,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    filename: Path = Path("translateEvents.cpp"),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    with open(filename, "w") as out:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        definitions = ""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        # Look up table to avoid duplicate events
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lut = dict()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        function = "const char *translateEvents(Event event) {\n  switch ((event & 0xFFFF)) {\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        function = "const char *translateEvents(Event event) {\n  switch (event) {\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for entry in event_list.items():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            event_id = entry[0]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            event_value = entry[1]
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -272,8 +305,8 @@ def write_translation_source_file(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                _LOGGER.warning(f"Name: {name}, Event Entry: {event_value}")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                name = f"{name}_{event_id}"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                _LOGGER.info(f"Created unique name {name}")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            definitions += f"const char *{name}_STRING " f'= "{name}";\n'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            function += f"    case ({event_id}):\n      " f"return {name}_STRING;\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            definitions += f'const char *{name}_STRING = "{name}";\n'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            function += f"    case ({event_id}):\n      return {name}_STRING;\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            lut.update({name: event_value})
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        function += '    default:\n      return "UNKNOWN_EVENT";\n'
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        out.write(
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -286,7 +319,7 @@ def write_translation_source_file(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        out.write(definitions + "\n" + function + "  }\n  return 0;\n}\n")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def write_translation_header_file(filename: Path = "translateEvents.h"):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def write_translation_header_file(filename: Path = Path("translateEvents.h")):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    with open(filename, "w") as out:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        out.write(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            f"#ifndef FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_\n"
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |