Struct Refill

Source
pub struct Refill {
Show 23 fields pub config: RefillConfig, pub refill_errors: RefillErrorStates, lock_info_stop_command_received: bool, lock_info_start_command_received: bool, lock_info_refill_check_volume_last_24h: bool, lock_info_refill_check_count_last_24h: bool, lock_info_refill_check_volume_last_hour: bool, lock_info_refill_check_count_last_hour: bool, lock_info_refill_check_interval_last_refill: bool, lock_error_read_duration_since_last_refill: bool, lock_error_check_empty: bool, lock_error_read_refill_volume_last_24h: bool, lock_error_read_refill_count_last_24h: bool, lock_error_read_refill_volume_last_hour: bool, lock_error_read_refill_count_last_hour: bool, lock_error_channel_send_schedule_check: bool, lock_error_channel_receive_schedule_check: bool, lock_error_channel_send_monitors: 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, last_sent_monitor_view: Option<RefillMonitorView>,
}
Expand description

Contains the configuration and the implementation for the refill control. Thread communication of this component is as follows:

graph LR refill[Refill control] --> water_injection[Water Injection] tank_level_switch[Tank Level Switch] -.-> refill tank_level_switch -.-> water_injection water_injection --> relay_manager[Relay Manager] relay_manager --> water_injection refill --> signal_handler[Signal Handler] signal_handler --> refill signal_handler --> water_injection refill --> schedule_check[Schedule Check] schedule_check --> refill refill -.-> data_logger[Data Logger] messaging[Messaging] --> refill
Communication channel to and from the relay manager is forwarded to implementation of WaterInjectionTrait. Communication channel to and from data logger is forwarded to implementation of WaterInjectionTrait. Signal handler is communicating both directly with refill as well with implementation of WaterInjectionTrait. Tank level switch calculation communicates both directly with refill control and with implementation of WaterInjectionTrait.

Architecture of the component is as follows:

graph LR execute --> calc_tank_level_switch_position_stabilized; execute --> get_sql_refill_data; execute_refill --> process_external_request; execute --> check_error_condition_switch_stuck_high; execute --> process_external_request; execute --> update_tank_level_switch_signals; execute_refill --> update_tank_level_switch_signals; execute --> check_volume_count_time_limits; execute --> execute_refill;

Fields§

§config: RefillConfig

configuration of refill control Attribute is public because access from within test cases.

§refill_errors: RefillErrorStates

struct of type RefillErrors which includes flags for different kind of errors

§lock_info_stop_command_received: bool

inhibition flag to avoid flooding the log file with repeated messages about stop command being received

§lock_info_start_command_received: bool

inhibition flag to avoid flooding the log file with repeated messages about start command being received

§lock_info_refill_check_volume_last_24h: bool

inhibition flag to avoid flooding the log file with repeated messages about refill volume check of last 24h

§lock_info_refill_check_count_last_24h: bool

inhibition flag to avoid flooding the log file with repeated messages about refill count check of last 24h

§lock_info_refill_check_volume_last_hour: bool

inhibition flag to avoid flooding the log file with repeated messages about refill volume check of last hour

§lock_info_refill_check_count_last_hour: bool

inhibition flag to avoid flooding the log file with repeated messages about refill count check of last hour

§lock_info_refill_check_interval_last_refill: bool

inhibition flag to avoid flooding the log file with repeated messages about refill interval check

§lock_error_read_duration_since_last_refill: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to read duration since the last refill

§lock_error_check_empty: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to check if the refill log table is empty

§lock_error_read_refill_volume_last_24h: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to read refill volume of last 24h from SQL database

§lock_error_read_refill_count_last_24h: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to read refill count of last 24h from SQL database

§lock_error_read_refill_volume_last_hour: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to read refill volume of last hour from SQL database

§lock_error_read_refill_count_last_hour: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to read refill count of last hour from SQL database

§lock_error_channel_send_schedule_check: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to request to schedule check via the channel

§lock_error_channel_receive_schedule_check: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to receive from schedule check via the channel

§lock_error_channel_send_monitors: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to send view to monitor

§lock_warn_inapplicable_command_signal_handler: bool

inhibition flag to avoid flooding the log file with repeated messages about having received not applicable command from the signal handler

§lock_error_channel_receive_termination: bool

inhibition flag to avoid flooding the log file with repeated messages about failure to receive from the signal handler via the channel

§last_ping_instant: Instant

recording when the last database ping happened

§database_ping_interval: Duration

database ping interval

§last_sent_monitor_view: Option<RefillMonitorView>

The last monitor view sent, to avoid sending redundant data.

Implementations§

Source§

impl Refill

Source

pub fn new(config: RefillConfig, database_ping_interval: Duration) -> Refill

Creates a new Refill control instance.

This constructor initializes the freshwater refill control module with its specified configuration and a dedicated SQL database interface. It sets up various internal error flags to the default (inactive) state and initializes many “lock” flags to false. These lock flags are crucial during operation to prevent log files from being flooded with repetitive error or warning messages.

§Arguments
  • config - Configuration data for the refill control, loaded from a TOML file. This includes parameters such as refill limits, intervals, and pump flow rates.
  • database_ping_interval - A Duration instance, providing the interval to ping the database.
§Returns

A new Refill struct, ready to manage the aquarium’s freshwater refill system.

Source

fn get_refill_stats_data( &mut self, refill_stats_data: &mut RefillStatsData, sql_interface_refill: &mut dyn DatabaseInterfaceRefillTrait, )

Retrieves comprehensive historic refill data from the SQL database and updates the provided container. This helper function queries the sql_interface_refill for various statistics crucial for refill control:

  • Duration since the last refill operation.
  • Total volume and count of refills in the last 24 hours.
  • Total volume and count of refills in the last hour.

It populates the refill_stats_data struct with these values. Errors encountered during database communication are logged and cause the error_sql_get_historic_data_failed flag in refill_errors to be set, potentially inhibiting further refills. Internal lock flags prevent log flooding.

§Arguments
  • refill_stats_data - A mutable reference to a RefillStatsData struct, which will be populated with the retrieved historical data.
Source

fn check_error_condition_switch_stuck_high( &mut self, duration_since_last_refill: u64, )

Checks if the duration since the last refill operation exceeds a configurable safety limit, indicating a potential “switch stuck high” error.

This private helper function compares the duration_since_last_refill with max_duration_since_last_refill from the configuration. If the elapsed time is longer than the configured maximum, it implies that the water level switch might be stuck in a “high” position, preventing detection of low water levels and thus inhibiting refills. The corresponding error flag in refill_errors is set if this condition is met. This helps to detect and log a critical fault condition.

§Arguments
  • duration_since_last_refill - The duration (in seconds) that has passed since the last refill operation.
Source

fn calc_inhibition_flag( &mut self, current_state: bool, start_command_received: bool, stop_command_received: bool, ) -> bool

Calculates the inhibition flag for the refill control based on received start and stop commands.

This private helper function determines the current operational state (inhibited or active) of the refill control. A Stop command will inhibit refilling, while a Start command will activate it. The Start command takes precedence over Stop if both are received simultaneously. It uses internal lock flags to prevent log flooding from repeated info messages.

§Arguments
  • current_state - The current boolean value of the inhibition flag (true if inhibited, false if active) before processing new commands.
  • start_command_received - A flag indicating whether a Start command was received from an external source in the current cycle.
  • stop_command_received - A flag indicating whether a Stop command was received from an external source in the current cycle.
§Returns

A bool representing the new state of the inhibition flag after processing the commands.

Source

fn check_volume_count_time_limits( &mut self, sql_refill_data: &RefillStatsData, refill_channels: &mut RefillChannels, ) -> bool

Checks if historical refill data (volume, count, and time interval) exceeds configured limitations.

This private helper function performs a series of checks against the RefillConfig’s maximum permitted values for:

  • Total refill volume within the last 24 hours.
  • Total refill count within the last 24 hours.
  • Total refill volume within the last hour.
  • Total refill count within the last hour.
  • Minimum time interval since the last refill operation.

If any limit is exceeded, an informational message is logged (once per transgression thanks to internal lock flags), indicating a potential issue that might inhibit further refills.

§Arguments
  • sql_refill_data - A reference to a RefillStatsData struct containing the historic refill data retrieved from the SQL database.
  • tx_refill_to_monitors - The sender part of the channel for communication to the monitors.
§Returns

true if any of the configured volume, count, or time limits are exceeded; false otherwise.

Source

pub fn execute( &mut self, mutex_device_scheduler_refill: Arc<Mutex<i32>>, refill_channels: &mut RefillChannels, water_injection: &mut impl WaterInjectionTrait, mutex_tank_level_switch_signals_clone_for_refill: Arc<Mutex<TankLevelSwitchSignals>>, mutex_refill_status: Arc<Mutex<RefillStatus>>, sql_interface_refill: Box<dyn DatabaseInterfaceRefillTrait + Sync + Send>, )

Executes the main control loop for the refill module.

This function runs continuously, managing the aquarium’s freshwater refill system until a termination signal is received. It periodically checks the tank water level, assesses historical refill data against configured limits, and initiates refill operations when necessary and permitted by schedules.

Key Operations:

  • Initial Wait: Observes an initial waiting period after application startup before active control begins.
  • Sensor Data Acquisition: Reads raw and stabilized tank level switch signals from a shared mutex.
  • SQL Data Retrieval: Fetches historical refill data (counts, volumes, last refill time) from the database.
  • Safety Checks: Verifies if refill operations are within configured limits (max count/volume per hour/24h) and checks for a “tank level switch stuck high” error.
  • Schedule & External Control: Communicates with the ScheduleCheck module and responds to Start/Stop commands to inhibit or enable refilling.
  • Water Injection: If all conditions are met (low water, within limits, allowed by schedule, not inhibited), it triggers water injection via the WaterInjectionTrait.
  • Data Logging Communication: Periodically communicates the refill pump status to the DataLogger.
  • Cycle Management: Maintains a fixed cycle time, sleeping as necessary, and warning if execution duration exceeds the cycle limit.
  • Graceful Shutdown: Responds to Quit and Terminate commands from the signal handler, ensuring a safe shutdown.
§Arguments
  • mutex_device_scheduler_refill - A clone of the Arc<Mutex<i32>> used to coordinate device actuation across the application, preventing conflicts and tracking activity counts.
  • refill_channels - A struct containing all sender and receiver channels for communication with modules like RelayManager, SignalHandler, DataLogger, ScheduleCheck, and Messaging.
  • water_injection - A mutable reference to an object implementing WaterInjectionTrait, responsible for the physical control of the refill pump.
  • mutex_tank_level_switch_signals_clone_for_refill - The Arc<Mutex<TankLevelSwitchSignals>> containing the latest tank level switch readings (raw and stabilized).
  • sql_interface_refill - The specific SQL interface for refill-related database operations.

Trait Implementations§

Source§

impl DatabasePingTrait for Refill

Source§

fn get_ping_interval(&self) -> Duration

Gets the interval at which the resource should be pinged.
Source§

fn get_last_ping_instant(&self) -> Instant

Gets the timestamp of the last successful ping.
Source§

fn update_last_ping_instant(&mut self)

Updates the timestamp of the last successful ping.
Source§

fn check_timing_and_ping_database( &mut self, database_interface: &mut (impl Pingable + ?Sized), )

Pings the database.
Source§

impl ProcessExternalRequestTrait for Refill

Source§

fn process_external_request( &mut self, rx_from_signal_handler: &mut AquaReceiver<InternalCommand>, rx_from_messaging_opt: Option<&mut AquaReceiver<InternalCommand>>, ) -> (bool, bool, bool)

Checks for and processes new commands relevant to the Refill control module from external channels.

This is the specialized implementation of ProcessExternalRequestTrait for the Refill module. In addition to handling standard “Quit”, “Start”, and “Stop” commands, it specifically intercepts the InternalCommand::ResetAllErrors command from the messaging channel to reset the refill control’s internal error states.

§Arguments
  • rx_from_signal_handler - A reference to the receiver end of the channel for commands originating from the signal handler.
  • rx_from_messaging_opt - An Option containing a reference to the receiver end of the channel for commands from the messaging system. This channel is optional.
§Returns

A tuple (bool, bool, bool) indicating the status of specific commands received:

  • The first bool is true if a Quit command was received from the signal handler; otherwise false.
  • The second bool is true if a Start command was received from messaging; otherwise false.
  • The third bool is true if a Stop command was received from messaging; otherwise false.
Source§

impl WaitForTerminationTrait for Refill

Source§

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

Method connects the default trait implementation with the specific implementation for accessing the error-lock.

Source§

fn wait_for_termination( &mut self, rx_waiting_thread_from_signal_handler: &mut AquaReceiver<InternalCommand>, sleep_duration: Duration, origin: &str, )

Implements the graceful shutdown wait loop for several threads (default implementation). Read more

Auto Trait Implementations§

§

impl Freeze for Refill

§

impl RefUnwindSafe for Refill

§

impl Send for Refill

§

impl Sync for Refill

§

impl Unpin for Refill

§

impl UnwindSafe for Refill

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T