diff --git a/Scripts/web_server.py b/Scripts/web_server.py index 18d6e66..8775830 100644 --- a/Scripts/web_server.py +++ b/Scripts/web_server.py @@ -80,7 +80,8 @@ class TempWebServer: 'heater_target': 80.0, 'heater_swing': 2.0, 'schedules': [], - 'schedule_enabled': False + 'schedule_enabled': False, + 'permanent_hold': False } def _handle_schedule_update(self, request, sensors, ac_monitor, heater_monitor, schedule_monitor): @@ -97,33 +98,74 @@ class TempWebServer: # Load current config config = self._load_config() - # Check if this is a "Resume Schedule" request - if params.get('resume_schedule') == 'true': + # ===== START: Handle mode actions ===== + mode_action = params.get('mode_action', '') + + if mode_action == 'resume': + # Resume automatic scheduling config['schedule_enabled'] = True + config['permanent_hold'] = False - # Save to file if self._save_config_to_file(config): - print("▶️ Schedule resumed") + print("▶️ Schedule resumed - Automatic mode") - # Reload schedule monitor if schedule_monitor: schedule_monitor.reload_config(config) - # Send Discord notification try: from scripts.discord_webhook import send_discord_message - message = "▶️ Schedule resumed - Automatic temperature control active" - send_discord_message(message) + send_discord_message("▶️ Schedule resumed - Automatic temperature control active") except: pass return self._get_status_page(sensors, ac_monitor, heater_monitor, show_success=True) - # Otherwise, handle normal schedule update - # Update schedule enabled status - config['schedule_enabled'] = params.get('schedule_enabled') == 'on' + elif mode_action == 'temporary_hold': + # Enter temporary hold (pause schedules temporarily) + config['schedule_enabled'] = False + config['permanent_hold'] = False + + if self._save_config_to_file(config): + print("⏸️ Temporary hold activated") + + if schedule_monitor: + schedule_monitor.reload_config(config) + + try: + from scripts.discord_webhook import send_discord_message + send_discord_message("⏸️ Temporary hold - Schedules paused, manual control active") + except: + pass + + return self._get_status_page(sensors, ac_monitor, heater_monitor, show_success=True) - # Parse schedules + elif mode_action == 'permanent_hold': + # Enter permanent hold (disable schedules permanently) + config['schedule_enabled'] = False + config['permanent_hold'] = True + + if self._save_config_to_file(config): + print("🛑 Permanent hold activated") + + if schedule_monitor: + schedule_monitor.reload_config(config) + + try: + from scripts.discord_webhook import send_discord_message + send_discord_message("🛑 Permanent hold - Schedules disabled, manual control only") + except: + pass + + return self._get_status_page(sensors, ac_monitor, heater_monitor, show_success=True) + # ===== END: Handle mode actions ===== + + elif mode_action == 'save_schedules': + # Just fall through to schedule parsing below + pass + # ===== END: Handle mode actions ===== + + # ===== START: Handle schedule configuration save ===== + # Parse schedules from form schedules = [] for i in range(4): time_key = 'schedule_{}_time'.format(i) @@ -144,22 +186,22 @@ class TempWebServer: # Save to file if self._save_config_to_file(config): - print("Schedule settings saved") + print("Schedule configuration saved") - # Reload schedule monitor config if schedule_monitor: schedule_monitor.reload_config(config) # Send Discord notification try: from scripts.discord_webhook import send_discord_message - status = "enabled" if config['schedule_enabled'] else "disabled" - message = "📅 Schedules updated ({}) - {} schedules configured".format( - status, len(schedules) + mode = "automatic" if config.get('schedule_enabled') else "hold" + message = "📅 Schedules updated ({} mode) - {} schedules configured".format( + mode, len(schedules) ) send_discord_message(message) except: pass + # ===== END: Handle schedule configuration save ===== except Exception as e: print("Error updating schedule: {}".format(e)) @@ -209,7 +251,8 @@ class TempWebServer: # ===== START: Disable scheduling and enter HOLD mode ===== if config.get('schedule_enabled'): config['schedule_enabled'] = False - print("⏸️ Schedule disabled - entering HOLD mode") + config['permanent_hold'] = False # ✅ ADD THIS - ensure it's temporary + print("⏸️ Schedule disabled - entering TEMPORARY HOLD mode") # Reload schedule monitor to disable it if schedule_monitor: @@ -279,22 +322,26 @@ class TempWebServer: # Load config config = self._load_config() - # **NEW: Check if in HOLD mode** - is_hold_mode = not config.get('schedule_enabled', False) and len(config.get('schedules', [])) > 0 + # ===== START: Determine schedule status display ===== + has_schedules = len([s for s in config.get('schedules', []) if s.get('time')]) > 0 - # Build schedule display - if is_hold_mode: - schedule_status = "HOLD MODE" - schedule_color = "#f39c12" # Orange color for hold - schedule_icon = "⏸️" - elif config.get('schedule_enabled'): - schedule_status = "ENABLED" - schedule_color = "#2ecc71" - schedule_icon = "✅" - else: - schedule_status = "DISABLED" + if not has_schedules: + schedule_status = "NO SCHEDULES" schedule_color = "#95a5a6" schedule_icon = "⚠️" + elif config.get('schedule_enabled'): + schedule_status = "AUTOMATIC" + schedule_color = "#2ecc71" + schedule_icon = "✅" + elif config.get('permanent_hold', False): + schedule_status = "PERMANENT HOLD" + schedule_color = "#e74c3c" + schedule_icon = "🛑" + else: + schedule_status = "TEMPORARY HOLD" + schedule_color = "#f39c12" + schedule_icon = "⏸️" + # ===== END: Determine schedule status display ===== # Build schedule cards schedule_cards = "" @@ -316,8 +363,8 @@ class TempWebServer: """.format( - time=schedule.get('time', 'N/A'), - name=schedule.get('name', 'Unnamed'), + time=time_value, # Use decoded value + name=name_value, # Use decoded value ac_temp=schedule.get('ac_target', 'N/A'), heater_temp=schedule.get('heater_target', 'N/A') ) @@ -343,14 +390,17 @@ class TempWebServer: outside_temp_str = "{:.1f}".format(outside_temp) if isinstance(outside_temp, float) else str(outside_temp) # ===== START: Add HOLD mode banner ===== - # Check if in HOLD mode (schedules exist but are disabled) - is_hold_mode = not config.get('schedule_enabled', False) and len(config.get('schedules', [])) > 0 - hold_banner = "" - if is_hold_mode: + if config.get('permanent_hold', False): + hold_banner = """ +
+ 🛑 PERMANENT HOLD - Schedules disabled (Manual control only) +
+ """ + elif not config.get('schedule_enabled', False) and has_schedules: hold_banner = """
- ⏸️ HOLD MODE ACTIVE - Manual settings in use (Schedule paused) + ⏸️ TEMPORARY HOLD - Manual override active (Schedule paused)
""" # ===== END: Add HOLD mode banner ===== @@ -683,38 +733,94 @@ class TempWebServer: while len(schedules) < 4: schedules.append({'time': '', 'name': '', 'ac_target': 77.0, 'heater_target': 80.0}) - enabled_checked = 'checked' if config.get('schedule_enabled') else '' + # ===== START: Determine current mode ===== + # Check if schedules exist + has_schedules = len([s for s in schedules if s.get('time')]) > 0 - # Check if in HOLD mode - is_hold_mode = not config.get('schedule_enabled', False) and len(config.get('schedules', [])) > 0 + # Determine mode based on config + if not has_schedules: + current_mode = "no_schedules" # No schedules configured yet + elif config.get('schedule_enabled'): + current_mode = "automatic" # Schedules are running + elif config.get('permanent_hold', False): + current_mode = "permanent_hold" # User disabled schedules permanently + else: + current_mode = "temporary_hold" # Manual override (HOLD mode) + # ===== END: Determine current mode ===== - # Build header with toggle or resume button - if is_hold_mode: - # Show Resume Schedule button instead of toggle - header = """ -
-

⚙️ Edit Schedules

- + # ===== START: Build mode control buttons ===== + if current_mode == "no_schedules": + # No mode buttons if no schedules configured + mode_buttons = """ +
+ ℹ️ Configure schedules below, then choose a mode
""" - else: - # Show toggle switch for enable/disable - header = """ -
-

⚙️ Edit Schedules

- + elif current_mode == "automatic": + # Automatic mode active + mode_buttons = """ +
+
+ ✅ Automatic Mode Active +
+
+ Temperatures automatically adjust based on schedule +
+
+ + +
- """.format(enabled_checked=enabled_checked) + """ + elif current_mode == "temporary_hold": + # Temporary hold (manual override) + mode_buttons = """ +
+
+ ⏸️ Temporary Hold Active +
+
+ Manual settings in use - Schedule paused +
+
+ + +
+
+ """ + else: # permanent_hold + # Permanent hold (schedules disabled by user) + mode_buttons = """ +
+
+ 🛑 Permanent Hold Active +
+
+ Schedules disabled - Manual control only +
+
+ +
+
+ """ + # ===== END: Build mode control buttons ===== form = """
- {header} - """.format(header=header) +

⚙️ Schedule Configuration

+ + {mode_buttons} + """.format(mode_buttons=mode_buttons) for i, schedule in enumerate(schedules[:4]): form += """ @@ -746,7 +852,7 @@ class TempWebServer: form += """
- +
"""