eive-tmtc/eive_tmtc/pus_tm/event_handler.py

178 lines
7.5 KiB
Python
Raw Permalink Normal View History

2023-02-01 11:17:04 +01:00
import logging
2023-02-01 19:43:25 +01:00
import datetime
2023-02-08 11:51:55 +01:00
import sys
2024-04-10 17:34:54 +02:00
import base64
2022-12-01 11:14:28 +01:00
2024-04-10 17:34:54 +02:00
from eive_tmtc.config.definitions import PRINT_RAW_EVENTS_B64_STR
2022-12-01 11:14:28 +01:00
from eive_tmtc.config.events import get_event_dict
2022-11-29 16:53:29 +01:00
from eive_tmtc.config.object_ids import get_object_ids
from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.pus_tm.verification_handler import generic_retval_printout
2023-01-27 15:42:00 +01:00
from eive_tmtc.tmtc.acs.subsystem import AcsMode
2023-07-21 11:47:37 +02:00
from eive_tmtc.tmtc.core import SdState, SdCardSelect
2023-11-10 19:23:06 +01:00
from tmtccmd.pus.s200_fsfw_mode import Mode
from tmtccmd.pus.s201_fsfw_health import FsfwHealth
2023-11-10 19:23:06 +01:00
from tmtccmd.pus.s5_fsfw_event import Service5Tm
2022-12-01 11:14:28 +01:00
from tmtccmd.fsfw import EventInfo
2023-01-16 17:45:46 +01:00
from spacepackets.ccsds.time import CdsShortTimestamp
2023-02-01 11:17:04 +01:00
_LOGGER = logging.getLogger(__name__)
2022-03-04 11:02:10 +01:00
2023-06-19 17:16:00 +02:00
def handle_event_packet( # noqa C901: Complexity okay here
raw_tm: bytes, pw: PrintWrapper
): # noqa C901: Complexity okay here
2024-04-10 17:34:54 +02:00
if PRINT_RAW_EVENTS_B64_STR:
print(f"PUS Event TM Base64: {base64.b64encode(raw_tm)}")
2024-05-06 11:23:31 +02:00
tm = Service5Tm.unpack(data=raw_tm, timestamp_len=CdsShortTimestamp.TIMESTAMP_SIZE)
2022-03-04 14:27:19 +01:00
event_dict = get_event_dict()
event_def = tm.event_definition
info = event_dict.get(event_def.event_id)
2022-03-07 11:26:44 +01:00
if info is None:
2023-02-01 11:17:04 +01:00
_LOGGER.warning(f"Event ID {event_def.event_id} has no information")
2022-03-07 11:26:44 +01:00
info = EventInfo()
info.name = "Unknown event"
2022-03-04 14:27:19 +01:00
obj_ids = get_object_ids()
obj_id_obj = obj_ids.get(event_def.reporter_id)
2022-03-04 14:27:19 +01:00
if obj_id_obj is None:
2023-02-01 11:17:04 +01:00
_LOGGER.warning(f"Object ID 0x{event_def.reporter_id.hex(sep=',')} has no name")
obj_name = event_def.reporter_id.hex(sep=",")
2022-03-04 14:27:19 +01:00
else:
obj_name = obj_id_obj.name
2024-05-06 11:23:31 +02:00
timestamp = CdsShortTimestamp.unpack(tm.timestamp)
2023-06-19 17:16:00 +02:00
generic_event_string = (
2023-09-12 13:48:38 +02:00
f"Object {obj_name} generated Event {info.name} (ID: {event_def.event_id:#04x})"
2024-05-06 11:23:31 +02:00
f" at {timestamp.as_date_time()}"
2023-06-19 17:16:00 +02:00
)
2023-02-01 20:42:21 +01:00
_LOGGER.info(generic_event_string)
2023-05-24 13:44:45 +02:00
pw.file_logger.info(
2023-09-12 13:48:38 +02:00
f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}:"
f" {generic_event_string}"
2022-08-22 14:02:07 +02:00
)
2023-02-18 13:12:12 +01:00
specific_handler = False
2022-10-11 15:38:31 +02:00
if info.name == "MODE_TRANSITION_FAILED":
reason = generic_retval_printout(event_def.param1)
2022-10-11 15:38:31 +02:00
for string in reason:
pw.dlog(f"Reason from event parameter 1: {string}")
pw.dlog(f"Mode, sequence or table: {event_def.param2:#08x}")
2023-02-18 13:12:12 +01:00
specific_handler = True
2022-08-22 11:47:12 +02:00
if info.name == "SUPV_UPDATE_PROGRESS" or info.name == "WRITE_MEMORY_FAILED":
2022-08-22 10:47:10 +02:00
additional_event_info = f"Additional info: {info.info}"
2022-08-22 11:47:12 +02:00
context = (
2023-09-12 13:48:38 +02:00
f"Progress Percent: {event_def.param1 >> 24 & 0xff} | Sequence Count:"
f" {event_def.param1 & 0xffff} | Bytes Written: {event_def.param2}"
2022-08-22 11:47:12 +02:00
)
2022-08-22 10:47:10 +02:00
pw.dlog(additional_event_info)
pw.dlog(context)
2023-02-18 13:12:12 +01:00
specific_handler = True
2022-10-10 11:20:57 +02:00
if info.name == "MODE_INFO":
2023-02-18 13:12:12 +01:00
specific_handler = True
2022-10-10 17:32:05 +02:00
mode_name = "Unknown"
2022-10-11 14:24:13 +02:00
if obj_name == "ACS_SUBSYSTEM":
2023-02-03 14:21:22 +01:00
acs_mode = AcsMode(event_def.param1)
pw.dlog(f"ACS Mode: {acs_mode!r}")
elif obj_name == "ACS_CONTROLLER_ID":
mode_name = Mode(event_def.param1)
submode = AcsMode(event_def.param2)
pw.dlog(f"Mode: {mode_name!r}")
pw.dlog(f"ACS Mode: {submode!r}")
2022-10-11 14:24:13 +02:00
else:
if event_def.param1 == Mode.OFF:
2022-10-11 14:24:13 +02:00
mode_name = "Off"
elif event_def.param1 == Mode.ON:
2022-10-11 14:24:13 +02:00
mode_name = "On"
elif event_def.param1 == Mode.NORMAL:
2022-10-11 14:24:13 +02:00
mode_name = "Normal"
elif event_def.param1 == Mode.RAW:
2022-10-11 14:24:13 +02:00
mode_name = "Raw"
2023-02-18 13:12:12 +01:00
pw.dlog(
2023-06-19 17:16:00 +02:00
f"Mode Number {event_def.param1}, Mode Name {mode_name}, "
f"Submode: {event_def.param2}"
2023-02-18 13:12:12 +01:00
)
2023-04-17 18:40:27 +02:00
if info.name == "INDIVIDUAL_BOOT_COUNTS":
boot_count_00 = (event_def.param1 >> 16) & 0xFFFF
boot_count_01 = event_def.param1 & 0xFFFF
boot_count_10 = (event_def.param2 >> 16) & 0xFFFF
boot_count_11 = event_def.param2 & 0xFFFF
pw.dlog(f"Boot count 0 0: {boot_count_00}")
pw.dlog(f"Boot count 0 1: {boot_count_01}")
pw.dlog(f"Boot count 1 0: {boot_count_10}")
pw.dlog(f"Boot count 1 1: {boot_count_11}")
if info.name == "REBOOT_COUNTER":
boot_count = (event_def.param1 << 32) | event_def.param2
pw.dlog(f"Total boot count: {boot_count}")
2023-06-23 02:05:04 +02:00
if info.name == "VERSION_INFO" or info.name == "FIRMWARE_INFO":
2023-02-18 13:12:12 +01:00
specific_handler = True
2023-02-08 11:51:55 +01:00
ver_major = (event_def.param1 >> 24) & 0xFF
ver_minor = (event_def.param1 >> 16) & 0xFF
ver_rev = (event_def.param1 >> 8) & 0xFF
has_git_sha = bool(event_def.param1 & 0xFF)
2023-02-08 11:47:37 +01:00
git_sha = ""
if has_git_sha:
2023-02-08 11:51:55 +01:00
p2_as_bytes = event_def.param2.to_bytes(4, sys.byteorder)
2023-02-08 11:47:37 +01:00
git_sha = p2_as_bytes.decode("ascii")
2023-06-23 02:05:04 +02:00
if info.name == "VERSION_INFO":
name = "OBSW version: "
else:
name = "Firmware version: "
pw.dlog(f"{name} v{ver_major}.{ver_minor}.{ver_rev}")
2023-02-08 11:47:37 +01:00
if has_git_sha:
pw.dlog(f"Git SHA first four letters: {git_sha}")
2023-02-18 13:12:12 +01:00
if info.name == "CLOCK_SET":
specific_handler = True
2023-02-01 19:43:25 +01:00
old_time = event_def.param1
new_time = event_def.param2
old_time_dt = datetime.datetime.fromtimestamp(old_time, datetime.timezone.utc)
new_time_dt = datetime.datetime.fromtimestamp(new_time, datetime.timezone.utc)
pw.dlog(f"Old time (UTC): {old_time_dt}")
pw.dlog(f"New time (UTC): {new_time_dt}")
2024-04-08 13:35:06 +02:00
if info.name == "CLOCK_DUMP_LEGACY":
specific_handler = True
# param 1 is timeval seconds, param 2 is timeval subsecond milliseconds
time = event_def.param1 + event_def.param2 / 1000.0
time_dt = datetime.datetime.fromtimestamp(time, datetime.timezone.utc)
pw.dlog(f"Current time: {time_dt}")
2024-04-10 17:27:24 +02:00
if (
info.name == "CLOCK_DUMP"
or info.name == "CLOCK_DUMP_BEFORE_SETTING_TIME"
or info.name == "CLOCK_DUMP_AFTER_SETTING_TIME"
):
2023-02-18 13:12:12 +01:00
specific_handler = True
2024-04-08 13:24:40 +02:00
# param 1 is timeval seconds, param 2 is timeval subsecond microseconds
time = event_def.param1 + event_def.param2 / 1000000.0
2023-02-01 19:43:25 +01:00
time_dt = datetime.datetime.fromtimestamp(time, datetime.timezone.utc)
2024-04-10 17:27:24 +02:00
pw.dlog(f"Clock dump event {info.name}. Current time: {time_dt}")
2023-07-21 11:36:01 +02:00
if info.name == "ACTIVE_SD_INFO":
sd_0_state = (event_def.param2 >> 16) & 0xFFFF
sd_1_state = event_def.param2 & 0xFFFF
2023-07-21 11:47:37 +02:00
active_sd = event_def.param1
try:
active_sd = SdCardSelect(event_def.param1)
sd_0_state = SdState((event_def.param2 >> 16) & 0xFFFF)
sd_1_state = SdState(event_def.param2 & 0xFFFF)
except IndexError:
_LOGGER.error(f"Received invalid event fields for event {event_def}")
finally:
pw.dlog(
2023-07-26 12:54:13 +02:00
f"Active SD card {active_sd!r} | SD 0 State {sd_0_state!r} | SD 1 "
f"State {sd_1_state!r}"
2023-07-21 11:47:37 +02:00
)
2023-02-18 13:12:12 +01:00
if info.name == "HEALTH_INFO":
specific_handler = True
2023-02-01 20:11:47 +01:00
health = FsfwHealth(event_def.param1)
pw.dlog(f"{obj_name}: {health!r}")
2023-02-18 13:12:12 +01:00
if info.name == "CHANGING_MODE":
mode = event_def.param1
submode = event_def.param2
2023-02-19 03:48:30 +01:00
pw.dlog(f"Mode Number {mode}, Submode: {submode}")
2023-02-18 13:12:12 +01:00
if not specific_handler:
2023-06-19 17:16:00 +02:00
additional_event_info = (
f"Additional info: {info.info} | P1: {event_def.param1} | "
f"P2: {event_def.param2}"
)
2023-02-18 13:12:12 +01:00
pw.dlog(additional_event_info)
2022-08-22 14:02:07 +02:00
if not specific_handler:
2023-01-30 17:26:48 +01:00
# printer.handle_long_tm_print(packet_if=tm.pus_tm, info_if=tm.pus_tm)
pass