diff --git a/src/config.rs b/src/config.rs index e9c08a2..180f131 100644 --- a/src/config.rs +++ b/src/config.rs @@ -283,6 +283,8 @@ pub mod ctrl_err { pub const IMAGE_NOT_FOUND_FOR_COPY: ResultU16 = ResultU16::new(GroupId::Controller as u8, 5); #[resultcode] pub const INVALID_LOGFILE_PATH: ResultU16 = ResultU16::new(GroupId::Controller as u8, 6); + #[resultcode] + pub const IO_ERROR: ResultU16 = ResultU16::new(GroupId::Controller as u8, 7); pub const CTRL_ERR_RESULTS: &[ResultU16Info] = &[ INVALID_CMD_FORMAT_EXT, @@ -292,6 +294,7 @@ pub mod ctrl_err { FILESYSTEM_COPY_ERROR_EXT, IMAGE_NOT_FOUND_FOR_COPY_EXT, INVALID_LOGFILE_PATH_EXT, + IO_ERROR_EXT, ]; } diff --git a/src/controller.rs b/src/controller.rs index 1436253..88a62b6 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -14,6 +14,7 @@ use satrs::{ }; use serde::{Deserialize, Serialize}; use std::env::temp_dir; +use std::io; use std::{ path::{Path, PathBuf}, process::Command, @@ -21,8 +22,8 @@ use std::{ }; use ops_sat_rs::config::ctrl_err::{ - FILESYSTEM_COPY_ERROR, IMAGE_NOT_FOUND_FOR_COPY, INVALID_LOGFILE_PATH, - SHELL_CMD_EXECUTION_FAILURE, SHELL_CMD_INVALID_FORMAT, SHELL_CMD_IO_ERROR, + FILESYSTEM_COPY_ERROR, INVALID_LOGFILE_PATH, IO_ERROR, SHELL_CMD_EXECUTION_FAILURE, + SHELL_CMD_INVALID_FORMAT, SHELL_CMD_IO_ERROR, }; use crate::requests::CompositeRequest; @@ -38,7 +39,9 @@ pub struct ShellCmd<'a> { pub enum ActionId { StopExperiment = 1, DownlinkLogfile = 2, - DownlinkImages = 3, + /// Standard command to download the images made by the camera. It moves all image related + /// files inside the home folder into the toGroundLP (low priority to ground download) folder. + DownlinkImagesByMoving = 3, ExecuteShellCommandBlocking = 4, } @@ -140,41 +143,29 @@ impl ExperimentController { self.handle_shell_command_execution(&requestor, &action_req); } ActionId::DownlinkLogfile => self.handle_downlink_logfile(&requestor, &action_req), - // downlink images, default will be the last image, otherwise specified counting down (2 = second to last image, etc.) - ActionId::DownlinkImages => self.handle_downlink_cam_image(&requestor, &action_req), + ActionId::DownlinkImagesByMoving => { + let result = self.handle_downlink_cam_image_by_moving(&requestor, &action_req); + if let Err(e) = result { + send_completion_failure(IO_ERROR, Some(e.to_string().into())); + } + } } } - pub fn handle_downlink_cam_image( + pub fn handle_downlink_cam_image_by_moving( &self, requestor: &MessageMetadata, action_req: &ActionRequest, - ) { - log::info!("copying images into low priority downlink folder"); - let image_path_result = match &action_req.variant { - ActionRequestVariant::VecData(data) => { - let index = data[0]; - get_latest_image(index as usize) - } - _ => get_latest_image(0), - }; - match image_path_result { - Ok(image_path) => self.handle_file_copy( - requestor, - action_req, - &image_path, - &self.paths.to_ground_dir, - ), - Err(e) => { - log::warn!("could not retrieve image path: {}", e); - self.send_completion_failure( - requestor, - action_req, - IMAGE_NOT_FOUND_FOR_COPY, - Some(e.to_string().into()), - ); - } - } + ) -> io::Result<()> { + log::info!("moving images into low priority downlink folder"); + let num_moved_files = move_images_inside_home_dir_to_low_prio_ground_dir( + &HOME_PATH, + &self.paths.to_ground_low_prio_dir, + )?; + log::info!("moved {} image files", num_moved_files); + // TODO: Trigger event containing the number of moved files? + self.send_completion_success(requestor, action_req); + Ok(()) } pub fn handle_downlink_logfile(&self, requestor: &MessageMetadata, action_req: &ActionRequest) { @@ -318,6 +309,38 @@ impl ExperimentController { } } +pub fn move_images_inside_home_dir_to_low_prio_ground_dir( + home_dir: &Path, + low_prio_target_dir: &Path, +) -> io::Result { + let mut moved_files = 0; + for dir_entry_result in std::fs::read_dir(home_dir)? { + if let Ok(dir_entry) = &dir_entry_result { + if let Ok(file_type) = dir_entry.file_type() { + if file_type.is_file() { + let path_name = dir_entry.file_name(); + let path_name_str = path_name.to_string_lossy(); + if path_name_str.contains("img_msec_") { + let mut target_path = PathBuf::new(); + target_path.push(low_prio_target_dir); + target_path.push(path_name); + log::info!( + "moving image file from {:?} to {:?}", + dir_entry, + target_path + ); + std::fs::rename(dir_entry.path(), target_path)?; + moved_files += 1; + } + + log::info!("found image file: {:?}", dir_entry); + } + } + } + } + Ok(moved_files) +} + // TODO no idea if this works in any way shape or form pub fn get_latest_image(index: usize) -> Result { // Get the most recently modified file diff --git a/src/handlers/camera.rs b/src/handlers/camera.rs index db21f9c..0c3c3c9 100644 --- a/src/handlers/camera.rs +++ b/src/handlers/camera.rs @@ -230,6 +230,7 @@ impl Ims100BatchHandler { { log::error!("sending data reply unexpectedly failed: {e}"); } + self.create_metadata_file(¶m); } Err(e) => match e { CameraError::TakeImageError(ref err_str) => { @@ -261,6 +262,10 @@ impl Ims100BatchHandler { } } + pub fn create_metadata_file(&mut self, _param: &CameraPictureParameters) { + // TODO: Implement + } + pub fn send_completion_success(&self, requestor: &MessageMetadata, action_req: &ActionRequest) { let result = self.action_reply_tx.send(GenericMessage::new_action_reply( *requestor,