Control application: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
|||
| Line 31: | Line 31: | ||
== Architecture == | == Architecture == | ||
=== Startup of the application === | |||
The startup uses a two-layer approach: | |||
1. main() - Simple error handler wrapper that calls run() and exits with code 1 on errors | |||
2. run() - The actual initialization orchestrator that performs the major steps | |||
==== Phase 1: Command Line & Configuration ==== | |||
- Parses command line arguments (help, version, config file path) | |||
- Default config: /etc/aquarium_control/aquarium_control.toml | |||
- Loads configuration and creates ExecutionConfig (boolean flags determining which modules to run) | |||
Phase 2: System Setup | |||
- Initializes logging system | |||
- Logs version information and executable hash | |||
- Verifies root/administrator privileges (required for hardware access) | |||
- Publishes process ID to file for client communication | |||
Phase 3: Database & Hardware | |||
- Connects to MySQL database | |||
- Creates component-specific SQL interfaces (Schedule, Balling, Refill, Heating, Feed, Data) | |||
- Validates database schema and version compatibility | |||
- Initializes hardware components if configured: | |||
- RGB LEDs, GPIO handlers | |||
- Tank level switches | |||
- I2C interfaces | |||
- Atlas Scientific sensors | |||
- DHT temperature/humidity sensors | |||
Phase 4: Communication Channels | |||
- Creates the Channels struct containing ~30+ inter-thread communication channels | |||
- Uses custom AquaSender/AquaReceiver wrappers for MPSC channels | |||
- Establishes bidirectional and unidirectional message paths between all modules | |||
Phase 5: Component Initialization | |||
- Instantiates all system components: | |||
- Data loggers, sensor managers, relay managers | |||
- Food injection, mineral dosing (balling), water injection/refill | |||
- Heating/ventilation control | |||
- Monitors, watchdog, schedule checker | |||
- IPC messaging system (Linux) | |||
Phase 6: Thread Spawning | |||
- Uses std::thread::scope for guaranteed cleanup | |||
- Spawns threads conditionally based on ExecutionConfig flags | |||
- Critical: 3-second startup delay (lines 1082-1089) allows sensors to acquire first data before control loops activate | |||
Key Architecture | |||
The Channels module (src/launch/channels.rs) acts as a central wiring diagram, with the Signal Handler serving as the main event coordinator. The application includes a detailed Mermaid diagram (lines 323-403) showing all inter-thread relationships. | |||
The ExecutionConfig decouples configuration from execution - threads only receive flags about which modules are active, not the full config. | |||
All components then enter their main execution loops, communicating through the established channel network. | |||
=== Threads === | |||
The application spawns the following threads: | The application spawns the following threads: | ||
{| class="wikitable" style="margin:auto" | {| class="wikitable" style="margin:auto" | ||
Revision as of 11:53, 8 January 2026
The main control application of Aquarium control implements the following features:
- Data acquisition of water temperature, pH and conductivity
- Data acquisition of ambient temperature and humidity
- Refill control for fresh water
- Feed control
- Water temperature control using air ventilation and heater
- Balling mineral dosing
The control of the relays for operating the devices can use two different modes:
- Using an Arduino-based relay actuation
- Using the GPIO of the Raspberry Pi (requires additional hardware)
Additionally, the main control application implements the following supporting features:
- Version comparison between database and application
- Configuration using a Rust .toml configuration file
- Logging
- Command interface to receive instructions from outside of the application via a POSIX message queue
- Storage of recorded data in SQL database
- File-based communication to RAM-disk
- Usage of simulator to run with simulated sensor data for development purposes
- Schedule checks to limit the hour of day of operating certain actuators
- Communication with HW Watchdog
The application is written in Rust and is automatically started using systemd.
The documentation of the software is available here.
Development for the main control application requires the setup of the development environment.
There is a release procedure which is highly recommended to be followed also by anyone developing the SW further.
Architecture
Startup of the application
The startup uses a two-layer approach:
1. main() - Simple error handler wrapper that calls run() and exits with code 1 on errors 2. run() - The actual initialization orchestrator that performs the major steps
Phase 1: Command Line & Configuration
- Parses command line arguments (help, version, config file path) - Default config: /etc/aquarium_control/aquarium_control.toml - Loads configuration and creates ExecutionConfig (boolean flags determining which modules to run)
Phase 2: System Setup - Initializes logging system - Logs version information and executable hash - Verifies root/administrator privileges (required for hardware access) - Publishes process ID to file for client communication
Phase 3: Database & Hardware - Connects to MySQL database - Creates component-specific SQL interfaces (Schedule, Balling, Refill, Heating, Feed, Data) - Validates database schema and version compatibility - Initializes hardware components if configured: - RGB LEDs, GPIO handlers - Tank level switches - I2C interfaces - Atlas Scientific sensors - DHT temperature/humidity sensors
Phase 4: Communication Channels - Creates the Channels struct containing ~30+ inter-thread communication channels - Uses custom AquaSender/AquaReceiver wrappers for MPSC channels - Establishes bidirectional and unidirectional message paths between all modules
Phase 5: Component Initialization - Instantiates all system components: - Data loggers, sensor managers, relay managers - Food injection, mineral dosing (balling), water injection/refill - Heating/ventilation control - Monitors, watchdog, schedule checker - IPC messaging system (Linux)
Phase 6: Thread Spawning - Uses std::thread::scope for guaranteed cleanup - Spawns threads conditionally based on ExecutionConfig flags - Critical: 3-second startup delay (lines 1082-1089) allows sensors to acquire first data before control loops activate
Key Architecture
The Channels module (src/launch/channels.rs) acts as a central wiring diagram, with the Signal Handler serving as the main event coordinator. The application includes a detailed Mermaid diagram (lines 323-403) showing all inter-thread relationships.
The ExecutionConfig decouples configuration from execution - threads only receive flags about which modules are active, not the full config.
All components then enter their main execution loops, communicating through the established channel network.
Threads
The application spawns the following threads:
| Thread name | Purpose |
|---|---|
| signal_handler | Receiving signals from the operating system |
| schedule_check | Polling the database to capture changes of the actuator channel. Informing other threads about it. |
| sensor_manager | Data acquisition |
| relay_manager | Actuation of relays |
| data_logger | Recording of data |
| tank_level_switch | Postprocessing of tank level switch position signal |
| refill | Fresh water refill control |
| heating | Heating control |
| ventilation | Ventilation control |
| balling | Balling mineral dosing control |
| watchdog | Sending alive signal to Raspberry Pi hardware watchdog |
| monitors | Diagnostics (not implemented as of January, 2026) |
| messaging | Receiving communication via message queue |
| memory | Monitoring memory utilization |
| ds18b20 | Recording data from DS18B20 temperature sensor |
| feed | Feed control |
| i2c_interface | Communication via I2C |
| atlas_scientific | Recording data from Atlas Scientific temperature sensor |
| dht | Recording data from DHT sensor |
| publish_pid | Writing PID to lock file |