9.9 KiB
Scheduler Module
The scheduler module provides flexible time-based automation for the plant watering system, with NVS persistence and full MQTT control.
Features
- Multiple Schedule Types:
- Interval-based (every X minutes)
- Time of day (daily at specific time)
- Day-specific (specific days at specific time)
- Per-Pump Scheduling: Up to 4 independent schedules per pump
- NTP Time Synchronization: Automatic internet time sync
- Holiday Mode: Pause all schedules without deleting them
- MQTT Configuration: Full remote control and monitoring
- NVS Persistence: Schedules survive power cycles
- Manual Override: Test schedules without waiting
- No External Dependencies: Built-in JSON handling
Schedule Configuration
Schedule Types
1. Interval Schedule
Waters every X minutes from the last run time.
{
"type": "interval",
"enabled": true,
"interval_minutes": 120,
"duration_ms": 15000,
"speed_percent": 70
}
2. Time of Day Schedule
Waters daily at a specific time.
{
"type": "time_of_day",
"enabled": true,
"hour": 6,
"minute": 30,
"duration_ms": 20000,
"speed_percent": 80
}
3. Days and Time Schedule
Waters on specific days at a specific time.
{
"type": "days_time",
"enabled": true,
"hour": 18,
"minute": 0,
"days_mask": 42,
"duration_ms": 25000,
"speed_percent": 75
}
Days Mask Values
- Sunday: 1 (bit 0)
- Monday: 2 (bit 1)
- Tuesday: 4 (bit 2)
- Wednesday: 8 (bit 3)
- Thursday: 16 (bit 4)
- Friday: 32 (bit 5)
- Saturday: 64 (bit 6)
Common masks:
- Daily: 127 (all days)
- Weekdays: 62 (Mon-Fri)
- Weekends: 65 (Sat-Sun)
- Mon/Wed/Fri: 42
MQTT Topics
Schedule Configuration
Configure individual schedules for each pump.
Topic: plant_watering/schedule/[pump_id]/[schedule_id]/config
- pump_id: 1 or 2
- schedule_id: 0-3
Example: Configure pump 1, schedule 0 for daily 6:30 AM watering
mosquitto_pub -h <broker> -t "plant_watering/schedule/1/0/config" -m '{
"type": "time_of_day",
"enabled": true,
"hour": 6,
"minute": 30,
"duration_ms": 20000,
"speed_percent": 80
}'
View All Schedules
Get all configured schedules on demand.
Topic: plant_watering/commands/get_schedules
Payload: Any value (e.g., "1")
# Request all schedules
mosquitto_pub -h <broker> -t "plant_watering/commands/get_schedules" -m "1"
# Monitor the responses
mosquitto_sub -h <broker> -t "plant_watering/schedule/+/+/current" -t "plant_watering/schedule/summary" -v
Response Topics:
plant_watering/schedule/[pump_id]/[schedule_id]/current- Each configured scheduleplant_watering/schedule/summary- Summary of all schedules
Summary format:
{
"total_schedules": 4,
"active_schedules": 3,
"holiday_mode": false,
"time_sync": true
}
View Pump Schedules
Get schedules for a specific pump.
Topic: plant_watering/schedule/[pump_id]/get
Payload: Any value
# Get all schedules for pump 1
mosquitto_pub -h <broker> -t "plant_watering/schedule/1/get" -m "1"
# Get all schedules for pump 2
mosquitto_pub -h <broker> -t "plant_watering/schedule/2/get" -m "1"
Schedule Status
The system publishes schedule status after configuration and periodically.
Topic: plant_watering/schedule/[pump_id]/[schedule_id]/status
Response:
{
"pump_id": 1,
"schedule_id": 0,
"type": "time_of_day",
"enabled": true,
"hour": 6,
"minute": 30,
"duration_ms": 20000,
"speed_percent": 80,
"next_run": 1706522400,
"next_run_str": "2024-01-29 06:30:00",
"last_run": 1706436000
}
Global Scheduler Status
Published every minute when connected.
Topic: plant_watering/schedule/status
Format:
{
"holiday_mode": false,
"time_sync": true,
"active_schedules": 3,
"time": 1706436000
}
Current System Time
Check or monitor the device's current time.
Get Time (On Demand)
- Topic:
plant_watering/commands/get_time - Payload: Any value (e.g., "1")
- Response Topic:
plant_watering/system/time
# Request current time
mosquitto_pub -h <broker> -t "plant_watering/commands/get_time" -m "1"
Response:
{
"timestamp": 1706436000,
"datetime": "2024-01-28 14:32:45 MST",
"timezone": "MST7MDT,M3.2.0,M11.1.0",
"synced": true
}
Periodic Time (Every Minute)
- Topic:
plant_watering/system/current_time
Format:
{
"timestamp": 1706436000,
"datetime": "2024-01-28 14:32:00 MST",
"day_of_week": 0,
"hour": 14,
"minute": 32
}
Holiday Mode
Pause all schedules without deleting them.
Topic: plant_watering/commands/holiday_mode
Payload: on or off
# Enable holiday mode
mosquitto_pub -h <broker> -t "plant_watering/commands/holiday_mode" -m "on"
# Disable holiday mode
mosquitto_pub -h <broker> -t "plant_watering/commands/holiday_mode" -m "off"
Manual Time Setting
If NTP is unavailable, set time manually.
Topic: plant_watering/schedule/time/set
Payload: Unix timestamp (as string)
# Set current time
mosquitto_pub -h <broker> -t "plant_watering/schedule/time/set" -m "$(date +%s)"
Manual Schedule Trigger
Test schedules without waiting.
Topic: plant_watering/schedule/[pump_id]/trigger
# Trigger all enabled schedules for pump 1
mosquitto_pub -h <broker> -t "plant_watering/schedule/1/trigger" -m "1"
Schedule Execution Notification
Published when a schedule executes.
Topic: plant_watering/schedule/[pump_id]/executed
Format:
{
"schedule_id": 0,
"duration_ms": 20000,
"speed": 80
}
Example Configurations
Example 1: Morning and Evening Watering
# Morning watering at 6:30 AM
mosquitto_pub -h <broker> -t "plant_watering/schedule/1/0/config" -m '{
"type": "time_of_day",
"enabled": true,
"hour": 6,
"minute": 30,
"duration_ms": 15000,
"speed_percent": 70
}'
# Evening watering at 6:30 PM
mosquitto_pub -h <broker> -t "plant_watering/schedule/1/1/config" -m '{
"type": "time_of_day",
"enabled": true,
"hour": 18,
"minute": 30,
"duration_ms": 15000,
"speed_percent": 70
}'
Example 2: Every 2 Hours During Day
# Interval watering every 2 hours
mosquitto_pub -h <broker> -t "plant_watering/schedule/2/0/config" -m '{
"type": "interval",
"enabled": true,
"interval_minutes": 120,
"duration_ms": 10000,
"speed_percent": 60
}'
Example 3: Weekday Morning Watering
# Water Monday-Friday at 7:00 AM
mosquitto_pub -h <broker> -t "plant_watering/schedule/1/2/config" -m '{
"type": "days_time",
"enabled": true,
"hour": 7,
"minute": 0,
"days_mask": 62,
"duration_ms": 20000,
"speed_percent": 80
}'
Example 4: Different Weekend Schedule
# Weekend watering at 9:00 AM with longer duration
mosquitto_pub -h <broker> -t "plant_watering/schedule/1/3/config" -m '{
"type": "days_time",
"enabled": true,
"hour": 9,
"minute": 0,
"days_mask": 65,
"duration_ms": 30000,
"speed_percent": 75
}'
Disable/Enable Schedules
To disable a schedule without deleting it:
mosquitto_pub -h <broker> -t "plant_watering/schedule/1/0/config" -m '{
"type": "time_of_day",
"enabled": false,
"hour": 6,
"minute": 30,
"duration_ms": 20000,
"speed_percent": 80
}'
To completely remove a schedule:
mosquitto_pub -h <broker> -t "plant_watering/schedule/1/0/config" -m '{
"type": "disabled"
}'
Time Zone Configuration
The scheduler uses Mountain Time (MST/MDT) by default. To change:
- Edit
scheduler.cin thescheduler_init()function:
// Set timezone (adjust as needed)
setenv("TZ", "PST8PDT,M3.2.0,M11.1.0", 1); // Pacific Time
setenv("TZ", "EST5EDT,M3.2.0,M11.1.0", 1); // Eastern Time
setenv("TZ", "CST6CDT,M3.2.0,M11.1.0", 1); // Central Time
setenv("TZ", "GMT0BST,M3.5.0,M10.5.0", 1); // UK Time
Serial Monitor Output
The system status is printed to serial every 30 seconds, including:
I (xxxxx) MAIN: Scheduler: 2 active, Holiday: OFF, DateTime: 2024-01-28 14:32:45
Troubleshooting
Time Not Synchronized
- Check internet connection
- Verify NTP servers are accessible
- Manual set time as workaround
- Check serial output for sync status
Schedule Not Executing
- Check if time is synchronized
- Verify schedule is enabled
- Check holiday mode is off
- Verify schedule configuration is valid
- Check pump isn't in cooldown period
- Monitor execution notifications on MQTT
Schedule Executes at Wrong Time
- Verify timezone setting
- Check system time is correct
- Remember schedules won't run twice within 60 seconds
- Use
get_timecommand to verify device time
Integration with Automation
The scheduler can work alongside moisture-based automation:
- Schedules provide baseline watering
- Moisture sensors can trigger additional watering
- Both respect motor safety limits (max runtime, cooldown)
Best Practices
- Test Schedules: Use manual trigger to test before relying on schedule
- Start Simple: Begin with one schedule and add more as needed
- Monitor Execution: Watch MQTT topics to confirm schedules work
- Use Holiday Mode: Don't delete schedules when going away
- Stagger Schedules: If using multiple pumps, offset times to reduce load
- Monitor Time Sync: Ensure device maintains correct time
Implementation Notes
- No External Dependencies: The scheduler uses built-in JSON parsing instead of cJSON library
- Time Check Interval: Schedules are checked every 30 seconds
- Execution Window: Schedules execute within 60 seconds of target time
- NTP Servers: Uses pool.ntp.org, time.nist.gov, and time.google.com
- Persistence: Schedule configurations saved to NVS, runtime info is not persisted
Limitations
- Maximum 4 schedules per pump (8 total)
- Minimum resolution is 1 minute
- Schedules check every 30 seconds (may be up to 30s late)
- All times are in configured timezone
- Requires accurate system time (NTP or manual)
- Simple JSON parser has basic error handling