feat: Refactor request handling to include config parameter and improve error logging
This commit is contained in:
parent
9c7ca86d86
commit
b712c19740
@ -1,5 +1,5 @@
|
|||||||
import socket
|
import socket
|
||||||
import time
|
import time # type: ignore
|
||||||
import json
|
import json
|
||||||
|
|
||||||
class TempWebServer:
|
class TempWebServer:
|
||||||
@ -22,7 +22,7 @@ class TempWebServer:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Failed to start web server: {}".format(e))
|
print("Failed to start web server: {}".format(e))
|
||||||
|
|
||||||
def check_requests(self, sensors, ac_monitor=None, heater_monitor=None, schedule_monitor=None):
|
def check_requests(self, sensors, ac_monitor, heater_monitor, schedule_monitor, config):
|
||||||
"""Check for incoming requests (call in main loop)."""
|
"""Check for incoming requests (call in main loop)."""
|
||||||
if not self.socket:
|
if not self.socket:
|
||||||
return
|
return
|
||||||
@ -32,7 +32,7 @@ class TempWebServer:
|
|||||||
request = conn.recv(1024).decode('utf-8')
|
request = conn.recv(1024).decode('utf-8')
|
||||||
|
|
||||||
if 'POST /update' in request:
|
if 'POST /update' in request:
|
||||||
response = self._handle_update(request, sensors, ac_monitor, heater_monitor, schedule_monitor)
|
response = self._handle_update(request, sensors, ac_monitor, heater_monitor, schedule_monitor, config)
|
||||||
|
|
||||||
elif 'GET /schedule' in request:
|
elif 'GET /schedule' in request:
|
||||||
response = self._get_schedule_editor_page(sensors, ac_monitor, heater_monitor)
|
response = self._get_schedule_editor_page(sensors, ac_monitor, heater_monitor)
|
||||||
@ -42,7 +42,7 @@ class TempWebServer:
|
|||||||
return
|
return
|
||||||
|
|
||||||
elif 'POST /schedule' in request:
|
elif 'POST /schedule' in request:
|
||||||
response = self._handle_schedule_update(request, sensors, ac_monitor, heater_monitor, schedule_monitor)
|
response = self._handle_schedule_update(request, sensors, ac_monitor, heater_monitor, schedule_monitor, config)
|
||||||
# If handler returns a redirect response, send it raw and exit
|
# If handler returns a redirect response, send it raw and exit
|
||||||
if isinstance(response, str) and response.startswith('HTTP/1.1 303'):
|
if isinstance(response, str) and response.startswith('HTTP/1.1 303'):
|
||||||
conn.sendall(response.encode('utf-8'))
|
conn.sendall(response.encode('utf-8'))
|
||||||
@ -61,6 +61,18 @@ class TempWebServer:
|
|||||||
if response is None:
|
if response is None:
|
||||||
response = self._get_status_page(sensors, ac_monitor, heater_monitor, schedule_monitor)
|
response = self._get_status_page(sensors, ac_monitor, heater_monitor, schedule_monitor)
|
||||||
|
|
||||||
|
# ===== START: Send response =====
|
||||||
|
print("DEBUG: Sending response ({} bytes)".format(len(response)))
|
||||||
|
try:
|
||||||
|
conn.send(response.encode('utf-8')) # ← Changed to 'conn'
|
||||||
|
print("DEBUG: Response sent successfully")
|
||||||
|
except Exception as e:
|
||||||
|
print("ERROR: Failed to send response: {}".format(e))
|
||||||
|
finally:
|
||||||
|
conn.close() # ← Changed to 'conn'
|
||||||
|
print("DEBUG: Client connection closed")
|
||||||
|
# ===== END: Send response =====
|
||||||
|
|
||||||
conn.send('HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nConnection: close\r\n\r\n')
|
conn.send('HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nConnection: close\r\n\r\n')
|
||||||
conn.sendall(response.encode('utf-8'))
|
conn.sendall(response.encode('utf-8'))
|
||||||
conn.close()
|
conn.close()
|
||||||
@ -75,6 +87,9 @@ class TempWebServer:
|
|||||||
"""Save configuration to config.json file (atomic write)."""
|
"""Save configuration to config.json file (atomic write)."""
|
||||||
try:
|
try:
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
print("DEBUG: Saving config with {} schedules".format(len(config.get('schedules', []))))
|
||||||
|
|
||||||
# Write to temp file first
|
# Write to temp file first
|
||||||
with open('config.tmp', 'w') as f:
|
with open('config.tmp', 'w') as f:
|
||||||
json.dump(config, f)
|
json.dump(config, f)
|
||||||
@ -91,7 +106,9 @@ class TempWebServer:
|
|||||||
print("Settings saved to config.json")
|
print("Settings saved to config.json")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error saving config: {}".format(e))
|
print("❌ Error saving config: {}".format(e))
|
||||||
|
import sys
|
||||||
|
sys.print_exception(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _load_config(self):
|
def _load_config(self):
|
||||||
@ -110,7 +127,7 @@ class TempWebServer:
|
|||||||
'permanent_hold': False
|
'permanent_hold': False
|
||||||
}
|
}
|
||||||
|
|
||||||
def _handle_schedule_update(self, request, sensors, ac_monitor, heater_monitor, schedule_monitor):
|
def _handle_schedule_update(self, request, sensors, ac_monitor, heater_monitor, schedule_monitor, config):
|
||||||
"""Handle schedule form submission."""
|
"""Handle schedule form submission."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -122,9 +139,6 @@ class TempWebServer:
|
|||||||
key, value = pair.split('=', 1)
|
key, value = pair.split('=', 1)
|
||||||
params[key] = value.replace('+', ' ')
|
params[key] = value.replace('+', ' ')
|
||||||
|
|
||||||
# Load current config
|
|
||||||
config = self._load_config()
|
|
||||||
|
|
||||||
# ===== START: Handle mode actions =====
|
# ===== START: Handle mode actions =====
|
||||||
mode_action = params.get('mode_action', '')
|
mode_action = params.get('mode_action', '')
|
||||||
|
|
||||||
@ -196,12 +210,18 @@ class TempWebServer:
|
|||||||
# ===== START: Handle schedule configuration save =====
|
# ===== START: Handle schedule configuration save =====
|
||||||
# Parse schedules (4 slots)
|
# Parse schedules (4 slots)
|
||||||
schedules = []
|
schedules = []
|
||||||
|
has_any_schedule_data = False # Track if user submitted ANY schedule data
|
||||||
|
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
time_key = 'schedule{}_time'.format(i)
|
time_key = 'schedule{}_time'.format(i)
|
||||||
name_key = 'schedule{}_name'.format(i)
|
name_key = 'schedule{}_name'.format(i)
|
||||||
ac_key = 'schedule{}_ac'.format(i)
|
ac_key = 'schedule{}_ac'.format(i)
|
||||||
heater_key = 'schedule{}_heater'.format(i)
|
heater_key = 'schedule{}_heater'.format(i)
|
||||||
|
|
||||||
|
# Check if this schedule slot has data (even if just a name/temp)
|
||||||
|
if time_key in params or name_key in params or ac_key in params or heater_key in params:
|
||||||
|
has_any_schedule_data = True
|
||||||
|
|
||||||
if time_key in params and params[time_key]:
|
if time_key in params and params[time_key]:
|
||||||
# URL decode the time (converts %3A back to :)
|
# URL decode the time (converts %3A back to :)
|
||||||
schedule_time = params[time_key].replace('%3A', ':')
|
schedule_time = params[time_key].replace('%3A', ':')
|
||||||
@ -231,7 +251,13 @@ class TempWebServer:
|
|||||||
}
|
}
|
||||||
schedules.append(schedule)
|
schedules.append(schedule)
|
||||||
|
|
||||||
config['schedules'] = schedules
|
# Only update schedules if user submitted schedule form data
|
||||||
|
if has_any_schedule_data:
|
||||||
|
config['schedules'] = schedules
|
||||||
|
print("Updating schedules: {} schedules configured".format(len(schedules)))
|
||||||
|
else:
|
||||||
|
# No schedule data in form - preserve existing schedules
|
||||||
|
print("No schedule data in request - preserving existing schedules")
|
||||||
|
|
||||||
# ===== START: Validate all schedules =====
|
# ===== START: Validate all schedules =====
|
||||||
for i, schedule in enumerate(schedules):
|
for i, schedule in enumerate(schedules):
|
||||||
@ -280,7 +306,7 @@ class TempWebServer:
|
|||||||
# Safety: avoid rendering an error page here; just redirect
|
# Safety: avoid rendering an error page here; just redirect
|
||||||
return 'HTTP/1.1 303 See Other\r\nLocation: /schedule\r\n\r\n'
|
return 'HTTP/1.1 303 See Other\r\nLocation: /schedule\r\n\r\n'
|
||||||
|
|
||||||
def _handle_update(self, request, sensors, ac_monitor, heater_monitor, schedule_monitor):
|
def _handle_update(self, request, sensors, ac_monitor, heater_monitor, schedule_monitor, config):
|
||||||
"""Handle form submission and update settings."""
|
"""Handle form submission and update settings."""
|
||||||
try:
|
try:
|
||||||
body = request.split('\r\n\r\n')[1] if '\r\n\r\n' in request else ''
|
body = request.split('\r\n\r\n')[1] if '\r\n\r\n' in request else ''
|
||||||
@ -291,9 +317,6 @@ class TempWebServer:
|
|||||||
key, value = pair.split('=', 1)
|
key, value = pair.split('=', 1)
|
||||||
params[key] = float(value)
|
params[key] = float(value)
|
||||||
|
|
||||||
# Load current config
|
|
||||||
config = self._load_config()
|
|
||||||
|
|
||||||
# ===== START: Validate Heat <= AC =====
|
# ===== START: Validate Heat <= AC =====
|
||||||
# Get the values that will be set
|
# Get the values that will be set
|
||||||
new_heater_target = params.get('heater_target', config.get('heater_target', 80.0))
|
new_heater_target = params.get('heater_target', config.get('heater_target', 80.0))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user