pub struct DataLogger {Show 22 fields
config: DataLoggerConfig,
lock_error_get_timestamp: bool,
lock_error_output_state_refill_in_progress: bool,
lock_error_output_state_heating_is_on: bool,
lock_error_output_state_ventilation_is_on: bool,
lock_error_output_signal_water_temperature: bool,
lock_error_output_signal_pH: bool,
lock_error_output_signal_conductivity: bool,
lock_error_output_signal_ambient_temperature: bool,
lock_error_output_signal_humidity: bool,
lock_error_output_state_tank_level_switch_position: bool,
lock_error_output_state_tank_level_switch_invalid: bool,
lock_error_output_state_tank_level_switch_position_stabilized: bool,
lock_error_output_signal_water_temperature_filtered: bool,
lock_error_output_signal_pH_filtered: bool,
lock_error_output_signal_conductivity_filtered: bool,
lock_error_output_timestamp: bool,
pub lock_warn_inapplicable_command_signal_handler: bool,
pub lock_error_channel_receive_termination: bool,
pub last_ping_instant: Instant,
pub database_ping_interval: Duration,
lock_error_mutex_signal_manager: bool,
}Expand description
Contains the configuration and the implementation for regular data logging to SQL database and writing to the file (in RAM disk). Thread communication is as follows:
Fields§
§config: DataLoggerConfigconfiguration data for the data logger
lock_error_get_timestamp: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to create the timestamp
lock_error_output_state_refill_in_progress: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write refill in progress to disk
lock_error_output_state_heating_is_on: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write heating is on to disk
lock_error_output_state_ventilation_is_on: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write ventilation is on to disk
lock_error_output_signal_water_temperature: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write water temperature to disk
lock_error_output_signal_pH: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write pH to disk
lock_error_output_signal_conductivity: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write conductivity to disk
lock_error_output_signal_ambient_temperature: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write ambient temperature to disk
lock_error_output_signal_humidity: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write humidity to disk
lock_error_output_state_tank_level_switch_position: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write tank level switch position to disk
lock_error_output_state_tank_level_switch_invalid: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write tank level switch invalid to disk
lock_error_output_state_tank_level_switch_position_stabilized: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write tank level switch position stabilized to disk
lock_error_output_signal_water_temperature_filtered: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write temperature filtered to disk
lock_error_output_signal_pH_filtered: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write pH filtered to disk
lock_error_output_signal_conductivity_filtered: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write conductivity filtered to disk
lock_error_output_timestamp: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to write timestamp to disk
lock_warn_inapplicable_command_signal_handler: boolan inhibition flag to avoid flooding the log file with repeated messages about having received an inapplicable command
lock_error_channel_receive_termination: boolan inhibition flag to avoid flooding the log file with repeated messages about failure to receive termination signal via the channel
last_ping_instant: Instantrecording when the last database ping happened
database_ping_interval: Durationdatabase ping interval
lock_error_mutex_signal_manager: boolImplementations§
Source§impl DataLogger
impl DataLogger
Sourcepub fn new(
config: DataLoggerConfig,
database_ping_interval: Duration,
) -> Result<DataLogger, DataLoggerError>
pub fn new( config: DataLoggerConfig, database_ping_interval: Duration, ) -> Result<DataLogger, DataLoggerError>
Creates a new DataLogger instance.
This constructor initializes the data logger module with its configuration.
If output_to_disk is enabled, it validates that all required output file
paths are non-empty and then resets each file by writing an empty string to it.
It also initializes many internal “lock” flags designed to prevent log flooding.
§Arguments
config- Configuration data for the data logger, defining logging intervals, filter coefficients, output file paths, and other operational parameters.database_ping_interval- ADurationinstance, providing the interval to ping the database.
§Returns
A Result containing a new, initialized DataLogger instance on success.
§Errors
This function will return a DataLoggerError if output_to_disk is enabled and:
- Any of the configured output filenames are empty (
OutputFilenameEmpty). - It fails to write to (and thus reset) any of the configured output files,
which could be due to permission issues or an invalid path (
FileResetFailure).
Sourcefn output_signal(
&self,
signal: f32,
signal_type: AquariumSignal,
output_file_name: &String,
inhibit_error_log: bool,
) -> bool
fn output_signal( &self, signal: f32, signal_type: AquariumSignal, output_file_name: &String, inhibit_error_log: bool, ) -> bool
Outputs a non-binary sensor signal to a specified file, typically located on a RAM disk.
This private helper function converts a floating-point signal into a human-readable
string format (determined by signal_type) and attempts to write it to the given
output_file_name. The operation only proceeds if output_to_disk is enabled in
the data logger’s configuration.
Error logging for writing failures is managed by the inhibit_error_log flag,
preventing a flood of repetitive error messages.
§Arguments
signal- Thef32sensor value to be written to the file.signal_type- AnAquariumSignalenum variant, used to determine the correct formatting for thesignalvalue (e.g., number of decimal places).output_file_name- A reference to theStringcontaining the full path to the output file.inhibit_error_log- A boolean flag that, iftrue, will prevent this specific error from being logged to the console/main log if a write operation fails.
§Returns
true if an error occurred during the file write operation; false otherwise (including
when output_to_disk is false and no write is attempted).
Sourcefn output_state(
&self,
state: bool,
state_description_true: &str,
state_description_false: &str,
output_file_name: &String,
inhibit_error_log: bool,
) -> bool
fn output_state( &self, state: bool, state_description_true: &str, state_description_false: &str, output_file_name: &String, inhibit_error_log: bool, ) -> bool
Outputs a boolean (binary) signal’s state to a specified file, typically located on a RAM disk.
This private helper function converts a boolean state into a descriptive string
(e.g., “ON”/“OFF”, “HIGH”/“LOW”) using provided labels and attempts to write it
to the given output_file_name. This operation only occurs if output_to_disk
is enabled in the data logger’s configuration.
Error logging for writing failures is controlled by the inhibit_error_log flag,
preventing a flood of repetitive error messages.
§Arguments
state- Theboolvalue of the binary signal (e.g.,truefor ON,falsefor OFF).state_description_true- The string label to write to the file whenstateistrue.state_description_false- The string label to write to the file whenstateisfalse.output_file_name- A reference to theStringcontaining the full path to the output file.inhibit_error_log- A boolean flag that, iftrue, will prevent this specific error from being logged to the console/main log if a write operation fails.
§Returns
true: If an error occurred during the file write operation.false: If the write-operation was successful or ifoutput_to_diskis disabled.
Sourcefn output_timestamp(
&self,
timestamp: NaiveDateTime,
output_file_name: &String,
inhibit_error_log: bool,
) -> bool
fn output_timestamp( &self, timestamp: NaiveDateTime, output_file_name: &String, inhibit_error_log: bool, ) -> bool
Outputs a NaiveDateTime timestamp to a specified file, typically located on a RAM disk.
This private helper function converts a NaiveDateTime into its string representation
and attempts to write it to the given output_file_name. This operation only occurs
if output_to_disk is enabled in the data logger’s configuration.
Error logging for writing failures is controlled by the inhibit_error_log flag,
preventing a flood of repetitive error messages.
§Arguments
timestamp- TheNaiveDateTimevalue to be written to the file.output_file_name- A reference to theStringcontaining the full path to the output file.inhibit_error_log- A boolean flag that, iftrue, will prevent this specific error from being logged to the console/main log if a write operation fails.
§Returns
true: If an error occurred during the file write operation.false: If the write-operation was successful or ifoutput_to_diskis disabled.
Sourcefn update_signals(
&mut self,
refill_status_live: &mut bool,
refill_status_for_database: &mut bool,
refill_reset_for_database: bool,
heater_status: &mut bool,
ventilation_status: &mut bool,
data_logger_mutexes: &DataLoggerMutexes,
)
fn update_signals( &mut self, refill_status_live: &mut bool, refill_status_for_database: &mut bool, refill_reset_for_database: bool, heater_status: &mut bool, ventilation_status: &mut bool, data_logger_mutexes: &DataLoggerMutexes, )
Retrieves current ON/OFF status signals from Refill, Heating, and Ventilation control modules via channels.
This function sends a RequestSignal command to each of the specified
control modules (Refill, Heating, Ventilation) and updates the provided
status flags based on their responses. It also tracks channel disconnection
status to prevent repeated errors.
§Arguments
refill_status- A mutable reference for indicating if the refill is in progress.heater_status- A mutable reference for indicating the heater state.ventilation_status- A mutable reference for indicating the ventilation state.
Sourcefn update_sensor_manager_signals(
&mut self,
mutex_sensor_manager_signals: Arc<Mutex<SensorManagerSignals>>,
water_temperature_opt: &mut Option<f32>,
ph_opt: &mut Option<f32>,
conductivity_opt: &mut Option<f32>,
ambient_temperature_opt: &mut Option<f32>,
humidity_opt: &mut Option<f32>,
)
fn update_sensor_manager_signals( &mut self, mutex_sensor_manager_signals: Arc<Mutex<SensorManagerSignals>>, water_temperature_opt: &mut Option<f32>, ph_opt: &mut Option<f32>, conductivity_opt: &mut Option<f32>, ambient_temperature_opt: &mut Option<f32>, humidity_opt: &mut Option<f32>, )
Retrieves current sensor readings from the SensorManager via a shared mutex and outputs them to files.
This private helper function locks the mutex_sensor_manager_signals to get the latest
readings for water temperature, pH, conductivity, ambient temperature, and humidity.
It updates the corresponding Option<f32> variables with the retrieved values and then
calls output_signal to write these readings to their respective configured files on disk.
If the mutex lock fails, an error is logged, and the function returns without updating the values.
§Arguments
mutex_sensor_manager_signals- AnArc<Mutex<SensorManagerSignals>>holding the latest sensor readings.water_temperature_opt- A mutable reference to anOption<f32>where the retrieved water temperature will be stored.ph_opt- A mutable reference to anOption<f32>where the retrieved pH value will be stored.conductivity_opt- A mutable reference to anOption<f32>where the retrieved conductivity value will be stored.ambient_temperature_opt- A mutable reference to anOption<f32>where the retrieved ambient temperature will be stored.humidity_opt- A mutable reference to anOption<f32>where the retrieved humidity will be stored.
Sourcefn update_tank_level_switch_signals(
&mut self,
mutex_tank_level_switch_signals: &Arc<Mutex<TankLevelSwitchSignals>>,
tank_level_switch_position_opt: &mut Option<bool>,
tank_level_switch_position_stabilized_opt: &mut Option<bool>,
tank_level_switch_invalid_opt: &mut Option<bool>,
)
fn update_tank_level_switch_signals( &mut self, mutex_tank_level_switch_signals: &Arc<Mutex<TankLevelSwitchSignals>>, tank_level_switch_position_opt: &mut Option<bool>, tank_level_switch_position_stabilized_opt: &mut Option<bool>, tank_level_switch_invalid_opt: &mut Option<bool>, )
Retrieves current signals from the TankLevelSwitch via a shared mutex and outputs them to files.
This private helper function locks the mutex_tank_level_switch_signals to get the latest
state for the switch’s position, its stabilized position, and its invalid status.
It updates the corresponding Option<bool> variables with the retrieved values and then
calls output_state to write these states to their respective configured files on disk.
If the mutex lock fails, the Option variables are set to None.
§Arguments
mutex_tank_level_switch_signals- AnArc<Mutex<TankLevelSwitchSignals>>holding the latest switch states.tank_level_switch_position_opt- A mutable reference to anOption<bool>for the switch’s current position.tank_level_switch_position_stabilized_opt- A mutable reference to anOption<bool>for the switch’s stabilized position.tank_level_switch_invalid_opt- A mutable reference to anOption<bool>for the switch’s invalid status.
Sourcefn calculate_filtered_signals(
&mut self,
water_temperature: Option<f32>,
ph: Option<f32>,
conductivity: Option<f32>,
filter_water_temperature: &mut IIRFilter,
filter_pH: &mut IIRFilter,
filter_conductivity: &mut IIRFilter,
) -> (Option<f32>, Option<f32>, Option<f32>)
fn calculate_filtered_signals( &mut self, water_temperature: Option<f32>, ph: Option<f32>, conductivity: Option<f32>, filter_water_temperature: &mut IIRFilter, filter_pH: &mut IIRFilter, filter_conductivity: &mut IIRFilter, ) -> (Option<f32>, Option<f32>, Option<f32>)
Calculates filtered values for water temperature, pH, and conductivity, then outputs them to files.
This private helper function takes raw (unfiltered) sensor readings. For each valid reading,
it applies its corresponding IIRFilter to smooth the data. The resulting filtered values
are then stored in new Option<f32> variables and written to their designated files on disk.
If a raw reading is None, no filtering or output occurs for that signal.
§Arguments
water_temperature- The measured water temperature, wrapped in anOption.ph- The measured pH value, wrapped in anOption.conductivity- The measured conductivity value, wrapped in anOption.
§Returns
A tuple (Option<f32>, Option<f32>, Option<f32>) containing the filtered
water temperature, pH, and conductivity values, respectively. Each value is
Some if the corresponding input was valid and filtered, or None otherwise.
Sourcefn update_timestamp(&mut self, conn: &mut PooledConn) -> NaiveDateTime
fn update_timestamp(&mut self, conn: &mut PooledConn) -> NaiveDateTime
Retrieves the current timestamp, either from the SQL database or generated locally by the application.
This private helper function determines the timestamp source based on the use_sql_timestamp
configuration setting. If use_sql_timestamp is true, it attempts to fetch the timestamp
from the connected SQL database. If that fails, it falls back to using a locally generated
timestamp and logs an error. If use_sql_timestamp is false, it always uses a local timestamp.
The chosen timestamp is also written to a configured file on the disk.
§Arguments
conn- A mutable reference to an active SQL database connection, used if the SQL timestamp option is enabled.
§Returns
A NaiveDateTime representing the current timestamp, sourced either from the database or the local system.
Sourcefn confirm_quit_and_wait_for_termination_command(
&mut self,
data_logger_channels: &mut DataLoggerChannels,
)
fn confirm_quit_and_wait_for_termination_command( &mut self, data_logger_channels: &mut DataLoggerChannels, )
Confirms the application’s readiness to quit and then waits for a specific termination command from the signal handler.
This function is called when the thread has received the Quit-command from the signal handler. It first sends a confirmation back to the signal handler, indicating that this component is ready to proceed with shutdown.
After confirming, it enters a loop, continuously listening for an InternalCommand::Terminate
signal from the signal_handler. This ensures that the application’s internal threads,
which might be listening to this component’s channels, stop receiving commands.
§Arguments
data_logger_channels- A mutable reference to the struct that contains the channels.
Sourcepub fn execute(
&mut self,
data_injection: &mut impl DataInjectionTrait,
sql_interface_data: SqlInterfaceData,
data_logger_channels: &mut DataLoggerChannels,
data_logger_mutexes: DataLoggerMutexes,
)
pub fn execute( &mut self, data_injection: &mut impl DataInjectionTrait, sql_interface_data: SqlInterfaceData, data_logger_channels: &mut DataLoggerChannels, data_logger_mutexes: DataLoggerMutexes, )
Executes the main control loop for the data logger module.
This function runs continuously, acting as the central data collection and logging hub for
the application.
Before entering the loop, the function will set up Infinite Impulse Response (IIR) filters
for various sensor signals.
The IIR filters for water temperature, pH, and conductivity are initialized
with available data and a 1-second time step.
It performs the following key tasks in a recurring cycle:
- Signal Retrieval: Gathers current status (ON/OFF) from control modules (Refill, Heating, Ventilation) via channels.
- Sensor Data Acquisition: Reads raw sensor values (temperatures, pH, conductivity, ambient conditions, tank level switch states) from shared mutexes, which are updated by other sensor-reading threads.
- Signal Filtering: Applies IIR (Infinite Impulse Response) filters to sensor signals (e.g., water temperature, pH, conductivity) to produce smoothed values.
- Timestamping: Determines the current timestamp, either from the SQL database or generated locally, based on configuration.
- DataFrame Construction: Assembles all collected and processed data into a comprehensive
RecorderDataFrame. - Data Injection & Disk Output: Transfers the
RecorderDataFrameto the SQL database (via thedata_injectiontrait) and writes various individual signal/state values to designated files on a RAM disk (if configured). - Cycle Management: Calculates the execution time of the current cycle and idles for the remaining duration to meet the configured
logging_interval, ensuring precise data logging frequency. It warns if the cycle time is exceeded. - Responsiveness: Remains responsive to
Quitcommands from the signal handler during idle periods to enable graceful shutdown.
The loop continues indefinitely until a Quit command is received from the signal handler.
Upon receiving Quit, it performs a graceful exit sequence: sending confirmation back
to the signal handler and then waiting for a Terminate command before finally exiting the thread.
§Arguments
data_injection- An object implementing theDataInjectionTrait, used for transferring the collectedRecorderDataFrameto the SQL database or a mock data structure during testing.sql_interface_data- ASqlInterfaceDatainstance, providing the direct interface for writingRecorderDataFrames to the SQL database.data_logger_channels- ADataLoggerChannelsstruct, containing all thempscsender and receiver channels necessary for inter-thread communication with other modules and the signal handler.data_logger_mutexes- ADataLoggerMutexesstruct, providing access to sharedArc<Mutex>protected sensor data and device states.
Trait Implementations§
Source§impl DatabasePingTrait for DataLogger
impl DatabasePingTrait for DataLogger
Source§fn get_ping_interval(&self) -> Duration
fn get_ping_interval(&self) -> Duration
Source§fn get_last_ping_instant(&self) -> Instant
fn get_last_ping_instant(&self) -> Instant
Source§fn update_last_ping_instant(&mut self)
fn update_last_ping_instant(&mut self)
Source§fn check_timing_and_ping_database(
&mut self,
database_interface: &mut (impl Pingable + ?Sized),
)
fn check_timing_and_ping_database( &mut self, database_interface: &mut (impl Pingable + ?Sized), )
Source§impl ProcessExternalRequestTrait for DataLogger
impl ProcessExternalRequestTrait for DataLogger
Source§fn process_external_request(
&mut self,
rx_from_signal_handler: &mut AquaReceiver<InternalCommand>,
_: Option<&mut AquaReceiver<InternalCommand>>,
) -> (bool, bool, bool)
fn process_external_request( &mut self, rx_from_signal_handler: &mut AquaReceiver<InternalCommand>, _: Option<&mut AquaReceiver<InternalCommand>>, ) -> (bool, bool, bool)
Checks for and processes new commands relevant to the Data Logger module from external channels.
This is the specialized implementation of ProcessExternalRequestTrait for the DataLogger.
It delegates directly to process_external_request_without_messaging, indicating
that the DataLogger only processes commands from the signal handler and
ignores any input from a messaging channel.
§Arguments
rx_from_signal_handler- A reference to the receiver end of the channel for commands originating from the signal handler._- This parameter is ignored, as theDataLoggerdoes not process messages from a messaging channel.
§Returns
A tuple (bool, bool, bool) indicating the status of commands received:
- The first
boolistrueif aQuitcommand was received; otherwisefalse. - The second
boolis alwaysfalse(no “Start” commands processed). - The third
boolis alwaysfalse(no “Stop” commands processed).
Source§impl WaitForTerminationTrait for DataLogger
impl WaitForTerminationTrait for DataLogger
Source§fn get_warn_lock_mut(&mut self) -> &mut bool
fn get_warn_lock_mut(&mut self) -> &mut bool
Method connects the default trait implementation with the specific implementation accessing the warn-lock.
Source§fn get_error_lock_mut(&mut self) -> &mut bool
fn get_error_lock_mut(&mut self) -> &mut bool
Method connects the default trait implementation with the specific implementation for accessing the error-lock.