Files
WS2812B-LED-RC-Controller/tools/dev_https_server.py
2026-01-05 21:01:26 +01:00

121 lines
3.5 KiB
Python

#!/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)