diff --git a/README.md b/README.md index 049e766..3ef6b7a 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,53 @@ # 🌱 Auto Garden -> Automated garden monitoring and control system using Raspberry Pi Pico W +> Automated climate control system using Raspberry Pi Pico W with web interface and scheduling ## Overview -This project automates garden monitoring using a Raspberry Pi Pico W with temperature sensors, Discord notifications, and AC control for climate management. +This project provides automated climate monitoring and control using a Raspberry Pi Pico W. Features dual-zone temperature monitoring, AC/heater control, time-based scheduling, and a web interface for easy management. ## Features -- βœ… WiFi connectivity with auto-reconnect -- βœ… Inside/Outside temperature monitoring (DS18B20 sensors) -- βœ… Discord notifications for temperature readings -- βœ… Separate alert channel for critical temperatures -- βœ… Temperature logging to CSV file -- βœ… Configurable alert thresholds -- βœ… Automated AC control with temperature swing logic -- βœ… Relay control via opto-coupler for 110V AC -- 🚧 Humidity monitoring (planned) -- 🚧 Soil moisture monitoring (planned) -- 🚧 Additional relay control for fans, heaters (planned) +- **Core Features** + - βœ… WiFi connectivity with auto-reconnect and static IP + - βœ… Inside/Outside temperature monitoring (DS18B20 sensors) + - βœ… Web interface for monitoring and configuration + - βœ… Discord notifications for all system events + - βœ… Temperature logging to CSV file + - βœ… Configurable alert thresholds + - βœ… Exception recovery (system won't crash permanently) + - βœ… Graceful shutdown with Ctrl+C + +- **Climate Control** + - βœ… Automated AC control with temperature swing logic + - βœ… Automated heater control with separate swing settings + - βœ… Short-cycle protection for both AC and heater + - βœ… Dual relay control via opto-coupler for 110V AC + - βœ… Mutual exclusion (AC and heater never run simultaneously) + +- **Scheduling System** + - βœ… 4 configurable time-based schedules per day + - βœ… Each schedule sets different AC/heater targets + - βœ… Automatic mode with schedule following + - βœ… Temporary hold mode (auto-resumes after configurable time) + - βœ… Permanent hold mode (manual control until restart) + - βœ… Schedule configuration persists through reboots + - βœ… Hold modes reset to Automatic on restart (safety feature) + +- **Web Interface** + - βœ… Real-time temperature display + - βœ… AC/Heater status indicators + - βœ… Manual temperature override + - βœ… Schedule editor (4 time slots) + - βœ… Mode control buttons (Automatic/Temp Hold/Perm Hold) + - βœ… Countdown timer for temporary holds + - βœ… Mobile-responsive design + - βœ… Auto-refresh dashboard (30 seconds) + +- **Planned Features** + - 🚧 Humidity monitoring (DHT22/SHT31) + - 🚧 Soil moisture monitoring + - 🚧 Additional relay control for fans, grow lights ## Quick Start @@ -27,9 +56,9 @@ This project automates garden monitoring using a Raspberry Pi Pico W with temper **Required Components:** - Raspberry Pi Pico W -- DS18B20 temperature sensors (waterproof recommended) +- 2x DS18B20 temperature sensors (waterproof recommended) - 4.7kΞ© resistor (pull-up for 1-Wire bus) -- Opto-coupler relay module (3.3V logic, 110V AC rated) +- 2-channel opto-coupler relay module (3.3V logic, 110V AC rated) - Momentary button (optional, for easy reset) See the [Items Needed Wiki](https://gitea.rcs1.top/sickprodigy/Auto-Garden/wiki/Items-Needed-for-the-Project) for full parts list. @@ -49,27 +78,32 @@ Yellow (Data) β†’ GP10 (Inside) - Pin 14 Add 4.7kΞ© resistor between Data line and 3.3V ``` -**⚠️ Important:** The 4.7kΞ© pull-up resistor is **required** for reliable 1-Wire communication. While it may work without it occasionally, you'll experience intermittent failures, communication errors, and unreliable readings. +**⚠️ Important:** The 4.7kΞ© pull-up resistor is **required** for reliable 1-Wire communication. -**Opto-Coupler Relay Module:** +**2-Channel Opto-Coupler Relay Module:** ```text Low Voltage Side (Pico): -GP15 (Pin 20) β†’ IN (Signal) +GP15 (Pin 20) β†’ IN1 (AC Control Signal) +GP14 (Pin 19) β†’ IN2 (Heater Control Signal) 3.3V (Pin 36) β†’ VCC GND β†’ GND -High Voltage Side (AC Unit): +High Voltage Side - Relay 1 (AC Unit): NO (Normally Open) β†’ AC Control Wire 1 COM (Common) β†’ AC Control Wire 2 + +High Voltage Side - Relay 2 (Heater): +NO (Normally Open) β†’ Heater Control Wire 1 +COM (Common) β†’ Heater Control Wire 2 ``` **Note:** Most opto-coupler modules work with standard logic: -- `relay.on()` = relay energized (NO closes) = AC ON -- `relay.off()` = relay de-energized (NC closes) = AC OFF +- `relay.on()` = relay energized (NO closes) = Device ON +- `relay.off()` = relay de-energized (NC closes) = Device OFF -If your AC behavior is inverted (turns on when it should be off), your module may be active LOWβ€”see troubleshooting section. +If behavior is inverted, your module may be active LOWβ€”see troubleshooting. **Optional Reset Button:** @@ -77,8 +111,6 @@ If your AC behavior is inverted (turns on when it should be off), your module ma RUN pin β†’ Button β†’ GND ``` -Pressing button grounds RUN and resets the Pico. - ### 3. Software Setup **Install MicroPython:** @@ -89,7 +121,7 @@ Pressing button grounds RUN and resets the Pico. **IDE Setup:** -- Recommended: VS Code with [MicroPico extension](https://marketplace.visualstudio.com/items?itemName=paulober.pico-w-go) by paulober +- Recommended: VS Code with [MicroPico extension](https://marketplace.visualstudio.com/items?itemName=paulober.pico-w-go) - Alternative: Thonny IDE ### 4. Configuration @@ -105,7 +137,7 @@ secrets = { } ``` -**Configure sensors and AC in `main.py`:** +**Sensor Configuration in `main.py`:** ```python # Sensor configuration @@ -123,17 +155,33 @@ SENSOR_CONFIG = { 'alert_low': 68.0 } } - -# AC Controller options -relay_pin = 15 -min_run_time = 300 # Minimum 5 minutes run time -min_off_time = 180 # Minimum 3 minutes off time - -# AC Monitor options -target_temp = 75.0 # Target temperature in Β°F -temp_swing = 2.0 # Β±2Β°F swing (AC on at 77Β°F, off at 73Β°F) ``` +**Default Climate Settings (auto-saved to config.json):** + +```python +# Default config (created on first boot) +{ + "ac_target": 77.0, # AC target temperature (Β°F) + "ac_swing": 1.0, # AC turns on at 78Β°F, off at 76Β°F + "heater_target": 72.0, # Heater target temperature (Β°F) + "heater_swing": 2.0, # Heater turns on at 70Β°F, off at 74Β°F + "temp_hold_duration": 3600, # Temporary hold lasts 1 hour (3600 seconds) + "schedule_enabled": true, # Schedules active by default + "schedules": [ # 4 time-based schedules + { + "time": "06:00", + "name": "Morning", + "ac_target": 75.0, + "heater_target": 72.0 + }, + # ... 3 more schedules + ] +} +``` + +All settings can be changed via the web interface and persist through reboots. + ### 5. Upload & Run Upload all files to your Pico: @@ -142,190 +190,296 @@ Upload all files to your Pico: / β”œβ”€β”€ main.py β”œβ”€β”€ secrets.py +β”œβ”€β”€ config.json # Auto-generated on first boot └── scripts/ - β”œβ”€β”€ air_conditioning.py + β”œβ”€β”€ air_conditioning.py # AC/Heater controller classes β”œβ”€β”€ discord_webhook.py β”œβ”€β”€ monitors.py β”œβ”€β”€ networking.py - └── temperature_sensor.py + β”œβ”€β”€ scheduler.py # Schedule system with hold timer + β”œβ”€β”€ temperature_sensor.py + └── web_server.py # Web interface ``` -The Pico will auto-start `main.py` on boot. +The Pico will auto-start `main.py` on boot and be accessible at **** ## Project Structure ```text Auto-Garden/ -β”œβ”€β”€ main.py # Entry point, configuration, monitor setup +β”œβ”€β”€ main.py # Entry point, configuration, system initialization β”œβ”€β”€ secrets.py # WiFi & Discord credentials (gitignored) β”œβ”€β”€ secrets.example.py # Template for secrets.py +β”œβ”€β”€ config.json # Persistent configuration (auto-generated) └── scripts/ - β”œβ”€β”€ air_conditioning.py # AC controller with short-cycle protection + β”œβ”€β”€ air_conditioning.py # AC & Heater controllers with short-cycle protection β”œβ”€β”€ discord_webhook.py # Discord notification handling β”œβ”€β”€ monitors.py # Monitor base class & implementations β”œβ”€β”€ networking.py # WiFi connection management - └── temperature_sensor.py # DS18B20 sensor interface + β”œβ”€β”€ scheduler.py # Schedule system with temporary/permanent hold modes + β”œβ”€β”€ temperature_sensor.py # DS18B20 sensor interface + └── web_server.py # Web interface for monitoring and control ``` ## How It Works ### Temperature Monitoring -- **Every 10 seconds:** Check temperatures, send alerts if out of range -- **Every 30 seconds:** Regular temperature reports to Discord + log to file +- **Every 10 seconds:** Check temperatures +- **Every 30 seconds:** Send temperature reports to Discord + log to CSV +- **Instant alerts:** High/low temperature warnings to separate Discord channel -**Discord Channels:** +**Discord Notifications:** -- `discord_webhook_url`: Regular temperature updates, connection status +- `discord_webhook_url`: Regular updates, status changes, system events - `discord_alert_webhook_url`: Critical temperature alerts (Inside sensor only) -### AC Control Logic +**Example Discord Messages:** -- **Every 30 seconds:** Check inside temperature and decide AC state -- **Temperature swing:** Creates a "dead band" to prevent rapid cycling - - Example: Target 75Β°F with 2Β°F swing - - AC turns **ON** when temp > 77Β°F - - AC turns **OFF** when temp < 73Β°F - - Between 73-77Β°F: maintains current state +```text +πŸ“Š Inside: 75.2Β°F | AC: OFF | Heater: OFF +πŸ“Š Outside: 68.5Β°F | AC: OFF | Heater: OFF +πŸ”₯ Inside temp HIGH: 81.0Β°F +Schedule 'Morning' applied - AC: 75Β°F, Heater: 72Β°F +⏸️ HOLD Mode - Manual override: AC: 77F +/- 1F | Heater: 72F +/- 2F +⏰ Temporary hold expired - Automatic mode resumed +``` + +### Climate Control Logic + +**AC Control:** + +- Target: 77Β°F with 1Β°F swing +- AC turns **ON** when temp > 78Β°F (77 + 1) +- AC turns **OFF** when temp < 76Β°F (77 - 1) +- Between 76-78Β°F: maintains current state (dead band prevents cycling) + +**Heater Control:** + +- Target: 72Β°F with 2Β°F swing +- Heater turns **ON** when temp < 70Β°F (72 - 2) +- Heater turns **OFF** when temp > 74Β°F (72 + 2) +- Between 70-74Β°F: maintains current state **Short-Cycle Protection:** -- Minimum run time (default 5 min) prevents AC from turning off too quickly -- Minimum off time (default 3 min) protects compressor from rapid restarts +- Minimum run time: 30 seconds (prevents rapid off) +- Minimum off time: 5 seconds (protects compressor/heater elements) +- AC and heater never run simultaneously (mutual exclusion) + +### Scheduling System + +**Automatic Mode (Default):** + +- Schedules apply at configured times (e.g., 06:00, 12:00, 18:00, 22:00) +- AC and heater targets update automatically +- System follows the most recent schedule until next one applies + +**Temporary Hold Mode:** + +- Activated by manual temperature changes or "⏸️ Temp Hold" button +- Pauses schedules for configurable duration (default: 1 hour) +- Web UI shows countdown timer: "45 min remaining" +- Auto-resumes to Automatic mode when timer expires +- Can be manually resumed with "▢️ Resume" button + +**Permanent Hold Mode:** + +- Activated by "πŸ›‘ Perm Hold" button +- Completely disables schedules (manual control only) +- Stays disabled until "▢️ Enable Schedules" clicked or Pico reboots +- No countdown timer + +**Hold Reset on Boot:** + +- All hold modes reset to Automatic on Pico restart/power cycle +- Safety feature ensures schedules always resume after power loss +- Temperature targets, swing values, and schedules persist + +### Web Interface + +Access at **** + +**Dashboard (auto-refreshes every 30s):** + +- Current inside/outside temperatures +- AC/Heater status indicators +- Next scheduled temperature change +- Current mode banner with countdown (if in Temporary Hold) +- Manual temperature override form +- Mode control buttons + +**Schedule Editor:** + +- Configure 4 time-based schedules +- Set time (HH:MM format), name, AC target, heater target for each +- Form validation (prevents heater > AC, invalid times) +- No auto-refresh (prevents losing edits) + +**Mode Control:** + +- **βœ… Automatic Mode:** Schedules active, temps adjust based on time + - Buttons: [⏸️ Temp Hold] [πŸ›‘ Perm Hold] +- **⏸️ Temporary Hold:** Manual override with countdown timer + - Buttons: [▢️ Resume] [πŸ›‘ Perm Hold] +- **πŸ›‘ Permanent Hold:** Manual control only, schedules disabled + - Button: [▢️ Enable Schedules] ### WiFi Monitoring -- **Every 5 seconds:** Check WiFi connection status +- **Every 5 seconds:** Check WiFi connection - **LED Indicator:** - - Slow blink (1 sec on/off): Connected - - Fast blink (0.2 sec): Disconnected -- **Auto-reconnect:** Attempts reconnection every 60 seconds if disconnected + - Solid ON: Connected + - Blinking: Reconnecting +- **Auto-reconnect:** Attempts every 60 seconds if disconnected +- **Static IP:** Always accessible at ## Temperature Logs Logs are saved to `/temp_logs.csv` on the Pico: ```csv -2025-11-05 14:30:00,Inside,28000012,72.50 -2025-11-05 14:30:00,Outside,28000034,45.30 +2025-11-08 14:30:00,Inside,28000012,72.50 +2025-11-08 14:30:00,Outside,28000034,45.30 ``` Format: `timestamp,location,sensor_id,temperature_f` ## Customization -All configuration is centralized in `main.py`: +### Via Web Interface (Recommended) -**Sensor Settings:** +- Navigate to +- Adjust AC/Heater targets and swing values +- Edit schedules (times, names, targets) +- Settings persist through reboots -- Pin assignments -- Alert thresholds (high/low) -- Labels +### Via config.json -**AC Settings:** +```json +{ + "ac_target": 77.0, + "ac_swing": 1.5, // Change swing range + "heater_target": 72.0, + "heater_swing": 2.5, + "temp_hold_duration": 7200, // 2 hours (in seconds) + "schedules": [ /* ... */ ] +} +``` -- Relay pin -- Target temperature -- Temperature swing (dead band) -- Minimum run/off times +### Via main.py (Advanced) -**Monitor Intervals:** +```python +# Relay pins +ac_relay_pin = 15 +heater_relay_pin = 14 -- Temperature check/report intervals -- WiFi check interval -- AC control interval +# Sensor pins +SENSOR_CONFIG = { + 'inside': {'pin': 10, ...}, + 'outside': {'pin': 11, ...} +} + +# Monitor intervals +check_interval=10 # Temperature check frequency +report_interval=30 # Discord report frequency +``` ## Safety Notes ⚠️ **High Voltage Warning:** -- Opto-couplers isolate the Pico from AC voltage -- Never connect GPIO pins directly to 110V AC -- Ensure your opto-coupler module is rated for your voltage -- Test relay switching with a multimeter before connecting AC -- Consider hiring a licensed electrician if uncomfortable with AC wiring +- Opto-couplers isolate Pico from AC voltage +- Never connect GPIO directly to 110V AC +- Ensure relay module is rated for your voltage +- Test with multimeter before connecting AC loads +- Consider hiring licensed electrician if uncomfortable -**Compressor Protection:** +**Compressor/Heater Protection:** -- Always use minimum run/off times (defaults are safe) -- Minimum 3 minutes off time protects compressor bearings -- Minimum 5 minutes run time prevents short cycling +- Always use minimum run/off times +- Minimum 5s off time protects compressor bearings +- Minimum 30s run time prevents short cycling +- AC and heater mutual exclusion prevents simultaneous operation -## Future Expansion +**System Reliability:** -### Planned Features - -- **Humidity Sensors:** DHT22 or SHT31 for air humidity monitoring -- **Soil Moisture:** Capacitive sensors for plant watering automation -- **Additional Relays:** Control for fans, heaters, grow lights -- **Smart Ventilation:** Auto-open windows when outside air is optimal -- **Light Monitoring:** LDR or BH1750 for day/night cycles - -### Adding More Sensors - -To add a new temperature sensor: - -First Add to `SENSOR_CONFIG` in `main.py`: - -```python -'greenhouse': { - 'pin': 12, - 'label': 'Greenhouse', - 'alert_high': 90.0, - 'alert_low': 50.0 -} -``` - -Second Add a `TemperatureMonitor` to the monitors list: - -```python -TemperatureMonitor( - sensor=sensors['greenhouse'], - label=SENSOR_CONFIG['greenhouse']['label'], - check_interval=10, - report_interval=30, - alert_high=SENSOR_CONFIG['greenhouse']['alert_high'], - alert_low=SENSOR_CONFIG['greenhouse']['alert_low'], - log_file="/temp_logs.csv", - send_alerts_to_separate_channel=False -) -``` +- Exception recovery prevents permanent crashes +- Graceful shutdown (Ctrl+C) safely turns off AC/heater +- Hold modes reset on reboot (schedules always resume) +- Static IP ensures web interface always accessible ## Troubleshooting +**Web interface not loading:** + +- Verify Pico is connected to WiFi (LED should be solid) +- Check static IP is +- Look for "Web Interface: " in serial console +- Try accessing from same WiFi network + **No temperature readings:** -- Check 4.7kΞ© pull-up resistor is connected between data line and 3.3V +- Check 4.7kΞ© pull-up resistor between data line and 3.3V - Verify sensor wiring (VDD to 3.3V, not 5V) - Check GPIO pin numbers in `SENSOR_CONFIG` -- Run `sensor.scan_sensors()` to detect connected sensors +- Run `sensor.scan_sensors()` in REPL to detect sensors **WiFi not connecting:** - Verify SSID/password in `secrets.py` - Check 2.4GHz WiFi (Pico W doesn't support 5GHz) -- Look for connection messages in serial console -- LED should blink slowly when connected +- LED should be solid when connected +- Check serial console for connection status **Discord messages not sending:** -- Verify webhook URLs are correct +- Verify webhook URLs in `secrets.py` - Test webhooks with curl/Postman first -- Check Pico has internet access +- Check Pico has internet access (ping test) +- Look for error messages in serial console -**AC not switching:** +**AC/Heater not switching:** -- Verify relay pin number (default GP15) -- Test relay manually: `Pin(15, Pin.OUT).off()` should activate it +- Verify relay pin numbers (default GP15/GP14) +- Test relay manually in REPL: `Pin(15, Pin.OUT).on()` - Check if module is active LOW or active HIGH - Ensure opto-coupler has 3.3V power - Look for LED on relay module (should light when active) -- Verify minimum run/off times haven't locked out switching +- Check minimum run/off times haven't locked out switching -**AC behavior inverted:** +**AC/Heater behavior inverted:** -- Your opto-coupler is likely active LOW -- In `air_conditioning.py`, swap `relay.on()` and `relay.off()` calls +- Your opto-coupler is active LOW +- In `air_conditioning.py`, swap `relay.on()` and `relay.off()` calls in both ACController and HeaterController classes + +**Schedules not applying:** + +- Check NTP time sync: "Time synced with NTP server" in serial +- Verify schedule times in HH:MM format (24-hour) +- Ensure "βœ… Automatic Mode" is active (not in hold) +- Check serial console for "Schedule Applied: [name]" messages + +**Temporary hold not auto-resuming:** + +- Check `temp_hold_duration` in config.json (in seconds) +- Look for "⏰ Temporary hold expired" in serial console +- ScheduleMonitor runs every 60 seconds, may take up to 1 min extra +- Verify timer countdown appears in web UI banner + +**System keeps crashing:** + +- Check for recent code changes +- Look for exception messages in serial console +- System should auto-recover from most errors (5s pause, then retry) +- If persistent, check memory usage with `gc.mem_free()` + +**Config changes not saving:** + +- Verify web form submissions redirect to dashboard/schedule page +- Check for "Settings persisted to disk" in serial console +- Ensure config.json has write permissions +- Try manual edit of config.json and reboot ## Contributing