Expand description
Contains the main functionality for feeding the fish Implements the main control logic for automated and manual fish feeding.
This module contains the Feed struct, which runs as a dedicated thread to manage all
aspects of the feeding process. It is responsible for executing scheduled feed profiles,
responding to external commands (e.g., from aquarium_client or the web server), and ensuring
that feeding operations are performed safely and reliably.
§Key Components
-
FeedStruct: The central state machine for the feeding subsystem. It holds the configuration, communication channels, and internal state flags likeexecution_blocked. -
execute()Method: The main thread loop. It continuously performs the following actions:- Checks for external commands (
Start,Stop,Execute,Quit). - If active, periodically queries the database for overdue feed schedules.
- Uses a configurable strategy to select a single profile if multiple are overdue.
- Executes the selected profile by calling the
FoodInjectionTrait. - Logs the feed event to the database.
- Pings the database to keep the connection alive.
- Checks for external commands (
-
execute_feed()Method: A private helper that orchestrates a single feeding event. It retrieves the feed pattern from the database, actuates the feeder via theFoodInjectionTrait, and logs the event.
§Design and Architecture
The Feed module is designed to be a robust, testable, and decoupled component.
-
Dependency Injection: The module relies on traits for its core dependencies:
FoodInjectionTrait: An abstraction for the physical act of dispensing food. This allows for mock implementations in tests without needing real hardware.DatabaseInterfaceFeedTrait: An abstraction for all database operations, enabling the use of a mock database during testing.
-
State Management: The module maintains an internal state to handle various conditions:
feed_inhibited: A flag to temporarily pause scheduled feeding based onStart/Stopcommands.execution_blocked: A critical safety flag. If any part of a feeding process fails (e.g., cannot write to the database), this flag is set totrue, preventing all further feeding operations until it is reset by an external command. This prevents unintended behavior due to a faulty system state.
-
Concurrency Control: It uses an
Arc<Mutex<i32>>to coordinate with other device-actuating modules, ensuring that only one major physical action (like feeding or dosing) occurs at a time. -
Scheduling Strategy: When multiple scheduled feeds are found in the past, a configurable strategy (
strategy_multiple_schedule_entries_in_past) is used to decide which one to execute (e.g., the oldest, the newest, or none).
§Example Flow
- The
execute()loop starts. - It checks the database and finds a feed profile was scheduled for 10 minutes ago.
- It calls
execute_feed()with the profile ID. execute_feed()retrieves the pattern.- It calls
food_injection.inject_food(), which communicates with theRelayManagerto turn the feeder relay on and then off. - After injection, it writes a record of the event to the
feedlogtable. - Finally, it updates the
feedscheduletable to mark the entry as completed or to reschedule it if it’s a repeating event.
Structs§
- Feed
- Contains the configuration and the implementation for the feed control. Thread communication is as follows: