add health module

This commit is contained in:
2025-01-30 15:57:02 +01:00
parent 9325707fe8
commit f2648fb3b6
6 changed files with 309 additions and 105 deletions

View File

@ -1,6 +1,8 @@
use core::cell::Cell;
use num_enum::TryFromPrimitive;
use satrs::dev_mgmt::{AssemblyCommandingHelper, AssemblyHelperResult};
use satrs::dev_mgmt::{
DevManagerCommandingHelper, DevManagerHelperResult, TransparentDevManagerHook,
};
use satrs::mode::{
Mode, ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender, ModeRequestHandler,
ModeRequestHandlerMpscBounded, ModeRequestReceiver, ModeRequestorAndHandlerMpscBounded,
@ -14,8 +16,8 @@ use satrs::mode_tree::{SequenceTablesMapValue, TargetTablesMapValue};
use satrs::request::{MessageMetadata, RequestId};
use satrs::res_code::ResultU16;
use satrs::subsystem::{
ModeCommandingResult, ModeTreeHelperError, ModeTreeHelperState, StartSequenceError,
SubsystemCommandingHelper, SubsystemHelperResult,
IsChildCommandable, ModeCommandingResult, ModeTreeHelperError, ModeTreeHelperState,
StartSequenceError, SubsystemCommandingHelper, SubsystemHelperResult,
};
use satrs::{
mode::{ModeAndSubmode, ModeReply, ModeRequest},
@ -276,11 +278,21 @@ impl ModeParent for PusModeService {
}
}
#[derive(Debug, Default)]
struct IsCommandableDummy {}
impl IsChildCommandable for IsCommandableDummy {
fn is_commandable(&self, _id: ComponentId) -> bool {
true
}
}
struct AcsSubsystem {
pub mode_node: ModeRequestorAndHandlerMpscBounded,
pub mode_requestor_info: Option<MessageMetadata>,
pub target_mode_and_submode: Option<ModeAndSubmode>,
pub subsystem_helper: SubsystemCommandingHelper,
is_commandable_dummy: IsCommandableDummy,
pub mode_req_mock: ModeRequestHandlerMock,
pub mode_reply_mock: ModeReplyHandlerMock,
}
@ -295,6 +307,7 @@ impl AcsSubsystem {
mode_node,
mode_requestor_info: None,
target_mode_and_submode: None,
is_commandable_dummy: IsCommandableDummy::default(),
subsystem_helper: SubsystemCommandingHelper::default(),
mode_req_mock: ModeRequestHandlerMock::new(Self::id()),
mode_reply_mock: ModeReplyHandlerMock::new(Self::id()),
@ -345,13 +358,19 @@ impl AcsSubsystem {
while let Some(mode_reply) = self.mode_node.try_recv_mode_reply().unwrap() {
received_reply = true;
self.mode_reply_mock.handle_mode_reply(&mode_reply);
let result = self
.subsystem_helper
.state_machine(Some(mode_reply), &self.mode_node);
let result = self.subsystem_helper.state_machine(
Some(mode_reply),
&self.mode_node,
&self.is_commandable_dummy,
);
self.handle_subsystem_helper_result(result);
}
if !received_reply {
let result = self.subsystem_helper.state_machine(None, &self.mode_node);
let result = self.subsystem_helper.state_machine(
None,
&self.mode_node,
&self.is_commandable_dummy,
);
self.handle_subsystem_helper_result(result);
}
}
@ -492,7 +511,7 @@ struct MgmAssembly {
pub mode_node: ModeRequestorAndHandlerMpscBounded,
pub mode_requestor_info: Option<MessageMetadata>,
pub mode_and_submode: ModeAndSubmode,
pub commanding_helper: AssemblyCommandingHelper,
pub commanding_helper: DevManagerCommandingHelper<TransparentDevManagerHook>,
pub mode_req_mock: ModeRequestHandlerMock,
pub mode_reply_mock: ModeReplyHandlerMock,
}
@ -506,7 +525,7 @@ impl MgmAssembly {
mode_node,
mode_requestor_info: None,
mode_and_submode: UNKNOWN_MODE,
commanding_helper: Default::default(),
commanding_helper: DevManagerCommandingHelper::new(TransparentDevManagerHook::default()),
mode_req_mock: ModeRequestHandlerMock::new(Self::id()),
mode_reply_mock: ModeReplyHandlerMock::new(Self::id()),
}
@ -532,18 +551,23 @@ impl MgmAssembly {
while let Some(reply_and_id) = self.mode_node.try_recv_mode_reply()? {
self.mode_reply_mock.handle_mode_reply(&reply_and_id);
match self.commanding_helper.handle_mode_reply(&reply_and_id) {
AssemblyHelperResult::Idle => (),
AssemblyHelperResult::TargetKeepingViolation(_id) => {
// TODO: Check whether enough children are available to keep the mode.
// Otherwise, we command everything OFF, because we can not keep the mode.
}
AssemblyHelperResult::ModeCommandingDone => {
if self.commanding_helper.target_mode().is_some() {
// Complete the mode command.
self.mode_and_submode = self.commanding_helper.target_mode().unwrap();
self.handle_mode_reached(self.mode_requestor_info)?;
Ok(result) => {
match result {
DevManagerHelperResult::Idle => todo!(),
DevManagerHelperResult::Busy => todo!(),
DevManagerHelperResult::ModeCommandingDone => {
if self.commanding_helper.target_mode().is_some() {
// Complete the mode command.
self.mode_and_submode =
self.commanding_helper.target_mode().unwrap();
self.handle_mode_reached(self.mode_requestor_info)?;
}
}
}
}
Err(err) => match err {
satrs::dev_mgmt::DevManagerHelperError::ChildNotInStore => todo!(),
},
}
}
Ok(())
@ -597,13 +621,12 @@ impl ModeRequestHandler for MgmAssembly {
self.mode_req_mock
.start_transition(requestor, mode_and_submode, forced)
.unwrap();
self.commanding_helper
.send_mode_cmd_to_all_children_with_reply_awaition(
requestor.request_id(),
mode_and_submode,
forced,
&self.mode_node,
)?;
self.commanding_helper.send_mode_cmd_to_all_children(
requestor.request_id(),
mode_and_submode,
forced,
&self.mode_node,
)?;
Ok(())
}
@ -660,7 +683,7 @@ impl ModeRequestHandler for MgmAssembly {
struct DeviceManager {
name: &'static str,
pub id: ComponentId,
pub commanding_helper: AssemblyCommandingHelper,
pub commanding_helper: DevManagerCommandingHelper<TransparentDevManagerHook>,
pub mode_node: ModeRequestorAndHandlerMpscBounded,
pub mode_requestor_info: Option<MessageMetadata>,
pub mode_and_submode: ModeAndSubmode,
@ -679,7 +702,7 @@ impl DeviceManager {
id,
mode_node,
mode_requestor_info: None,
commanding_helper: Default::default(),
commanding_helper: DevManagerCommandingHelper::new(TransparentDevManagerHook::default()),
mode_and_submode: UNKNOWN_MODE,
mode_req_mock: ModeRequestHandlerMock::new(id),
mode_reply_mock: ModeReplyHandlerMock::new(id),
@ -715,30 +738,22 @@ impl DeviceManager {
) -> Result<(), ModeError> {
self.mode_reply_mock.handle_mode_reply(mode_reply);
match self.commanding_helper.handle_mode_reply(mode_reply) {
AssemblyHelperResult::Idle => (),
AssemblyHelperResult::TargetKeepingViolation(_id) => {
// TODO: Check whether enough children are available to keep the mode.
// Otherwise, we command everything OFF, because we can not keep the mode.
if self
.commanding_helper
.count_number_of_children_with_target_mode()
.unwrap()
< 1
{
if let Err(_e) = self.start_transition(
MessageMetadata::new(0, self.id()),
ModeAndSubmode::new(DefaultMode::OFF as Mode, 0),
false,
) {}
}
}
AssemblyHelperResult::ModeCommandingDone => {
if self.commanding_helper.target_mode().is_some() {
// Complete the mode command.
self.handle_mode_reached(self.mode_requestor_info)?;
self.mode_and_submode = self.commanding_helper.target_mode().unwrap();
Ok(result) => {
match result {
DevManagerHelperResult::Idle => todo!(),
DevManagerHelperResult::Busy => todo!(),
DevManagerHelperResult::ModeCommandingDone => {
if self.commanding_helper.target_mode().is_some() {
// Complete the mode command.
self.handle_mode_reached(self.mode_requestor_info)?;
self.mode_and_submode = self.commanding_helper.target_mode().unwrap();
}
}
}
}
Err(e) => match e {
satrs::dev_mgmt::DevManagerHelperError::ChildNotInStore => todo!(),
},
}
Ok(())
}
@ -789,13 +804,12 @@ impl ModeRequestHandler for DeviceManager {
self.mode_req_mock
.start_transition(requestor, mode_and_submode, forced)
.unwrap();
self.commanding_helper
.send_mode_cmd_to_all_children_with_reply_awaition(
requestor.request_id(),
mode_and_submode,
forced,
&self.mode_node,
)?;
self.commanding_helper.send_mode_cmd_to_all_children(
requestor.request_id(),
mode_and_submode,
forced,
&self.mode_node,
)?;
Ok(())
}