pub(crate) fn run() -> Result<(), StartupError>Expand description
The main entry point of the Aquarium Control application.
This function initializes and orchestrates all modules of the control system. It performs the following high-level steps:
- Sets up global logging and handles command-line arguments for configuration file selection.
- Checks if the user has provided specific command line parameters and acts accordingly.
- Checks if the user has root privileges.
- Loads the application configuration from the specified
.tomlfile. - Publishes the application’s Process ID (PID) to a file and sets up a custom panic hook for cleanup.
- Performs version checks against the database to ensure compatibility.
- Initializes all SQL database interfaces and validates database readiness.
- Sets up all inter-thread communication channels (
mpsc). - Initializes all application modules (sensors, controls, managers) with their respective configurations and channels/mutexes.
- Spawns each module in its own dedicated thread within a
std::thread::scopefor structured concurrency. - Manages the initial data acquisition phase, waiting for sensors to provide first readings before control loops become fully active.
This function is responsible for the overall lifecycle of the application, including graceful startup and panic handling.
§Returns
An empty Result (Ok(())) on a graceful shutdown. This occurs if the user
provides a command-line flag like -h or if the application is terminated
normally by the signal handler.
§Errors
Returns a StartupError if any part of the initialization or setup fails.
This error enum covers a wide range of potential issues, including:
StartupError::Config: If the configuration file is invalid or cannot be parsed.StartupError::LoggingSetupFailure: If the logger cannot be initialized (e.g., due to file permissions).StartupError::NotRoot: If the application is run without the necessary root privileges.StartupError::PidCheckError: If another instance is already running or the PID file cannot be written.StartupError::Database: If any database connection, query, or setup fails.StartupError::GpioHandlerSetupFailure: If the GPIO interface cannot be initialized on the target hardware.- And various other setup failures for specific modules.
Global thread communication is as follows:
graph LR
tank_level_switch -.-> refill[Refill]
refill --> relay_manager[Controllino]
relay_manager --> refill
sensor_manager[SensorManager] -.-> data_logger[DataLogger]
refill -.-> data_logger
signal_handler[SignalHandler] --> refill
refill --> signal_handler
signal_handler --> tank_level_switch
tank_level_switch --> signal_handler
signal_handler --> tcp_communication[TcpCommunication]
tcp_communication --> signal_handler
signal_handler --> relay_manager
relay_manager --> signal_handler
balling[Balling] --> signal_handler
signal_handler --> balling
feed[Feed] --> signal_handler
signal_handler --> feed
heating[Heating] --> signal_handler
signal_handler --> heating
ventilation[Ventilation] --> signal_handler
signal_handler --> ventilation
relay_manager --> tcp_communication
sensor_manager --> tcp_communication
tcp_communication --> sensor_manager
atlas_scientific --> tcp_communication
tcp_communication --> atlas_scientific
tank_level_switch --> tcp_communication
tcp_communication --> tank_level_switch
balling --> relay_manager
relay_manager --> balling
feed --> relay_manager
relay_manager --> feed
atlas_scientific -.-> data_logger
heating -.-> data_logger
atlas_scientific -.-> heating
heating --> relay_manager
relay_manager --> heating
tank_level_switch -.-> heating
sensor_manager -.-> heating
tank_level_switch -.-> data_logger
ventilation -.-> data_logger
signal_handler --> data_logger
data_logger --> signal_handler
ventilation --> relay_manager
atlas_scientific -.-> ventilation
relay_manager --> ventilation
monitors[Monitors] --> relay_manager
relay_manager --> monitors
monitors --> refill
refill --> monitors
monitors --> signal_handler
signal_handler --> monitors
ventilation --> schedule_check[ScheduleCheck]
schedule_check --> ventilation
heating --> schedule_check
schedule_check --> heating
refill --> schedule_check
schedule_check --> refill
balling --> schedule_check
schedule_check --> balling
signal_handler --> schedule_check
schedule_check --> signal_handler
signal_handler --> messaging[Messaging]
signal_handler --> sensor_manager
signal_handler --> watchdog
sensor_manager --> signal_handler
signal_handler --> atlas_scientific
atlas_scientific --> signal_handler
atlas_scientific --> i2c_interface[I2C interface]
i2c_interface --> atlas_scientific
dht -.-> sensor_manager
messaging --> refill
messaging --> ventilation
messaging --> heating
messaging --> balling
messaging --> feed
messaging --> monitors
messaging --> watchdog