Port to ESP32
This commit is contained in:
120
tools/dev_https_server.py
Normal file
120
tools/dev_https_server.py
Normal file
@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Ad-hoc Flask HTTPS Server for LED Controller Webapp
|
||||
Serves the webapp over HTTPS (required for Web Bluetooth API)
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from flask import Flask, send_from_directory, send_file
|
||||
from pathlib import Path
|
||||
|
||||
# Configuration
|
||||
HOST = '0.0.0.0' # Listen on all interfaces
|
||||
PORT = 5000 # HTTPS port
|
||||
DEBUG = True
|
||||
|
||||
# Get webapp directory (one level up from tools/)
|
||||
SCRIPT_DIR = Path(__file__).parent
|
||||
WEBAPP_DIR = SCRIPT_DIR.parent / 'webapp'
|
||||
|
||||
# Verify webapp directory exists
|
||||
if not WEBAPP_DIR.exists():
|
||||
print(f"❌ ERROR: Webapp directory not found at {WEBAPP_DIR}")
|
||||
print(f" Please run this script from the base repository directory")
|
||||
sys.exit(1)
|
||||
|
||||
# Create Flask app
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
"""Serve index.html"""
|
||||
return send_file(WEBAPP_DIR / 'index.html')
|
||||
|
||||
@app.route('/app/<path:filename>')
|
||||
def serve_app(filename):
|
||||
"""Serve files from app/ directory"""
|
||||
return send_from_directory(WEBAPP_DIR / 'app', filename)
|
||||
|
||||
@app.route('/css/<path:filename>')
|
||||
def serve_css(filename):
|
||||
"""Serve files from css/ directory"""
|
||||
return send_from_directory(WEBAPP_DIR / 'css', filename)
|
||||
|
||||
@app.route('/data/<path:filename>')
|
||||
def serve_data(filename):
|
||||
"""Serve files from data/ directory"""
|
||||
return send_from_directory(WEBAPP_DIR / 'data', filename)
|
||||
|
||||
@app.route('/favicon.ico')
|
||||
def favicon():
|
||||
"""Serve favicon"""
|
||||
return send_file(WEBAPP_DIR / 'data' / 'favicon.ico')
|
||||
|
||||
def print_banner():
|
||||
"""Print startup banner with instructions"""
|
||||
print("=" * 70)
|
||||
print(" 🚀 LED Controller HTTPS Development Server")
|
||||
print("=" * 70)
|
||||
print()
|
||||
print("📱 Web Bluetooth requires HTTPS!")
|
||||
print(" This server provides a self-signed certificate for development.")
|
||||
print()
|
||||
print("🌐 Access the webapp at:")
|
||||
print(f" https://localhost:{PORT}")
|
||||
print(f" https://127.0.0.1:{PORT}")
|
||||
print(f" https://<your-ip>:{PORT}")
|
||||
print()
|
||||
print("⚠️ Browser Security Warning:")
|
||||
print(" You'll see a 'Not Secure' warning - this is normal!")
|
||||
print(" Click 'Advanced' → 'Proceed to localhost' (or similar)")
|
||||
print()
|
||||
print("🔧 To stop the server: Press Ctrl+C")
|
||||
print("=" * 70)
|
||||
print()
|
||||
|
||||
def get_local_ip():
|
||||
"""Get local IP address for convenience"""
|
||||
import socket
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.connect(("8.8.8.8", 80))
|
||||
ip = s.getsockname()[0]
|
||||
s.close()
|
||||
return ip
|
||||
except:
|
||||
return "unknown"
|
||||
|
||||
if __name__ == '__main__':
|
||||
print_banner()
|
||||
|
||||
# Print local IP for convenience
|
||||
local_ip = get_local_ip()
|
||||
if local_ip != "unknown":
|
||||
print(f"💡 Your local IP: {local_ip}")
|
||||
print(f" Access from phone: https://{local_ip}:{PORT}")
|
||||
print()
|
||||
|
||||
print("🔄 Starting HTTPS server...")
|
||||
print()
|
||||
|
||||
try:
|
||||
# Run with ad-hoc SSL context (self-signed certificate)
|
||||
# Flask will automatically generate a certificate
|
||||
app.run(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
debug=DEBUG,
|
||||
ssl_context='adhoc' # Auto-generate self-signed cert
|
||||
)
|
||||
except OSError as e:
|
||||
if "Address already in use" in str(e):
|
||||
print(f"❌ ERROR: Port {PORT} is already in use!")
|
||||
print(f" Try a different port or stop the other service.")
|
||||
sys.exit(1)
|
||||
else:
|
||||
raise
|
||||
except KeyboardInterrupt:
|
||||
print("\n\n👋 Server stopped by user")
|
||||
sys.exit(0)
|
||||
Reference in New Issue
Block a user