422 lines
9.9 KiB
Markdown
422 lines
9.9 KiB
Markdown
# 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.
|
|
```json
|
|
{
|
|
"type": "interval",
|
|
"enabled": true,
|
|
"interval_minutes": 120,
|
|
"duration_ms": 15000,
|
|
"speed_percent": 70
|
|
}
|
|
```
|
|
|
|
#### 2. Time of Day Schedule
|
|
Waters daily at a specific time.
|
|
```json
|
|
{
|
|
"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.
|
|
```json
|
|
{
|
|
"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
|
|
```bash
|
|
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")
|
|
|
|
```bash
|
|
# 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 schedule
|
|
- `plant_watering/schedule/summary` - Summary of all schedules
|
|
|
|
Summary format:
|
|
```json
|
|
{
|
|
"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
|
|
|
|
```bash
|
|
# 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**:
|
|
```json
|
|
{
|
|
"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**:
|
|
```json
|
|
{
|
|
"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`
|
|
|
|
```bash
|
|
# Request current time
|
|
mosquitto_pub -h <broker> -t "plant_watering/commands/get_time" -m "1"
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"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:
|
|
```json
|
|
{
|
|
"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`
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
# 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`
|
|
|
|
```bash
|
|
# 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**:
|
|
```json
|
|
{
|
|
"schedule_id": 0,
|
|
"duration_ms": 20000,
|
|
"speed": 80
|
|
}
|
|
```
|
|
|
|
## Example Configurations
|
|
|
|
### Example 1: Morning and Evening Watering
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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:
|
|
```bash
|
|
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:
|
|
```bash
|
|
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:
|
|
|
|
1. Edit `scheduler.c` in the `scheduler_init()` function:
|
|
```c
|
|
// 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
|
|
1. Check if time is synchronized
|
|
2. Verify schedule is enabled
|
|
3. Check holiday mode is off
|
|
4. Verify schedule configuration is valid
|
|
5. Check pump isn't in cooldown period
|
|
6. 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_time` command 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
|
|
|
|
1. **Test Schedules**: Use manual trigger to test before relying on schedule
|
|
2. **Start Simple**: Begin with one schedule and add more as needed
|
|
3. **Monitor Execution**: Watch MQTT topics to confirm schedules work
|
|
4. **Use Holiday Mode**: Don't delete schedules when going away
|
|
5. **Stagger Schedules**: If using multiple pumps, offset times to reduce load
|
|
6. **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 |