Bladeren bron

vibecoded html page

faqmoroz 1 week geleden
bovenliggende
commit
555337694e
3 gewijzigde bestanden met toevoegingen van 224 en 6 verwijderingen
  1. 214 4
      HTTPServer.cpp
  2. 8 1
      HTTPServer.h
  3. 2 1
      minolta_remote_v1.ino

+ 214 - 4
HTTPServer.cpp

@@ -44,6 +44,11 @@ void HTTPServer::setupWiFiAP(const char* ssid, const char* password,
 /// </summary>
 void HTTPServer::setupRoutes()
 {
+    // Root endpoint - serves home page
+    server->on("/", HTTP_GET, [this](AsyncWebServerRequest *request) {
+        handleRoot(request);
+    });
+
     // Focus endpoint
     server->on("/api/focus", HTTP_GET, [this](AsyncWebServerRequest *request) {
         handleFocus(request);
@@ -65,11 +70,216 @@ void HTTPServer::setupRoutes()
     });
 
     // Health check endpoint
-    server->on("/get", HTTP_GET, [this](AsyncWebServerRequest *request) {
+    server->on("/api/healthcheck", HTTP_GET, [this](AsyncWebServerRequest *request) {
         handleHealthCheck(request);
     });
 }
 
+/// <summary>
+/// Handles GET / request to serve the home page.
+/// Returns a simple HTML interface for controlling the camera remote.
+/// Provides buttons for focus, photo capture, reset, and multiple shot controls.
+/// </summary>
+void HTTPServer::handleRoot(AsyncWebServerRequest *request)
+{
+    const char* html = R"rawliteral(
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Minolta Remote Control</title>
+    <style>
+        * { margin: 0; padding: 0; box-sizing: border-box; }
+        body { 
+            font-family: Arial, sans-serif; 
+            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+            min-height: 100vh;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            padding: 20px;
+        }
+        .container { 
+            background: white; 
+            border-radius: 15px;
+            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
+            padding: 30px;
+            max-width: 500px;
+            width: 100%;
+        }
+        h1 { 
+            text-align: center;
+            color: #333;
+            margin-bottom: 30px;
+            font-size: 28px;
+        }
+        .section {
+            margin-bottom: 25px;
+            padding-bottom: 25px;
+            border-bottom: 1px solid #eee;
+        }
+        .section:last-child { border-bottom: none; }
+        .section h2 {
+            color: #667eea;
+            font-size: 16px;
+            margin-bottom: 15px;
+        }
+        button {
+            width: 100%;
+            padding: 12px 20px;
+            margin-bottom: 10px;
+            font-size: 16px;
+            font-weight: bold;
+            border: none;
+            border-radius: 8px;
+            cursor: pointer;
+            transition: all 0.3s ease;
+        }
+        .btn-focus {
+            background: #4CAF50;
+            color: white;
+        }
+        .btn-focus:hover { background: #45a049; }
+        .btn-photo {
+            background: #2196F3;
+            color: white;
+        }
+        .btn-photo:hover { background: #0b7dda; }
+        .btn-reset {
+            background: #f44336;
+            color: white;
+        }
+        .btn-reset:hover { background: #da190b; }
+        .input-group {
+            display: flex;
+            gap: 10px;
+            margin-bottom: 10px;
+        }
+        input {
+            flex: 1;
+            padding: 10px;
+            border: 1px solid #ddd;
+            border-radius: 4px;
+            font-size: 14px;
+        }
+        .btn-multiple {
+            background: #FF9800;
+            color: white;
+        }
+        .btn-multiple:hover { background: #e68900; }
+        .status {
+            margin-top: 20px;
+            padding: 15px;
+            border-radius: 8px;
+            text-align: center;
+            display: none;
+        }
+        .status.success {
+            background: #d4edda;
+            color: #155724;
+            display: block;
+        }
+        .status.error {
+            background: #f8d7da;
+            color: #721c24;
+            display: block;
+        }
+    </style>
+</head>
+<body>
+    <div class="container">
+        <h1>📷 Minolta Remote</h1>
+        
+        <div class="section">
+            <h2>Basic Controls</h2>
+            <button class="btn-focus" onclick="sendRequest('/api/focus')">🎯 Focus</button>
+            <button class="btn-photo" onclick="sendRequest('/api/takePhoto')">📸 Take Photo</button>
+            <button class="btn-reset" onclick="sendRequest('/api/reset')">🔄 Reset</button>
+        </div>
+        
+        <div class="section">
+            <h2>Photo Hold Duration</h2>
+            <input type="number" id="msec" min="100" max="5000" value="1000" placeholder="Duration (ms)">
+            <button class="btn-photo" onclick="takePhotoWithDelay()">📸 Take with Delay</button>
+        </div>
+        
+        <div class="section">
+            <h2>Multiple Shots</h2>
+            <div class="input-group">
+                <input type="number" id="count" min="1" max="100" value="3" placeholder="Count">
+                <input type="number" id="delay" min="100" max="5000" value="500" placeholder="Delay (ms)">
+            </div>
+            <div class="input-group">
+                <input type="number" id="msecMulti" min="100" max="5000" value="1000" placeholder="Duration (ms)">
+            </div>
+            <button class="btn-multiple" onclick="multipleShoot()">🎬 Multiple Shots</button>
+        </div>
+        
+        <div id="status" class="status"></div>
+    </div>
+
+    <script>
+        function sendRequest(endpoint) {
+            fetch(endpoint)
+                .then(response => {
+                    if (response.ok) {
+                        showStatus('✓ Success: ' + endpoint, 'success');
+                    } else {
+                        showStatus('✗ Error: ' + response.statusText, 'error');
+                    }
+                })
+                .catch(error => showStatus('✗ Connection Error', 'error'));
+        }
+
+        function takePhotoWithDelay() {
+            const msec = document.getElementById('msec').value;
+            fetch('/api/takePhoto?msec=' + msec)
+                .then(response => {
+                    if (response.ok) {
+                        showStatus('✓ Photo taken (' + msec + 'ms)', 'success');
+                    } else {
+                        showStatus('✗ Error taking photo', 'error');
+                    }
+                })
+                .catch(error => showStatus('✗ Connection Error', 'error'));
+        }
+
+        function multipleShoot() {
+            const count = document.getElementById('count').value;
+            const delay = document.getElementById('delay').value;
+            const msec = document.getElementById('msecMulti').value;
+            
+            if (count < 1 || count > 100) {
+                showStatus('✗ Count must be between 1 and 100', 'error');
+                return;
+            }
+            
+            fetch('/api/multiple?count=' + count + '&delay=' + delay + '&msec=' + msec)
+                .then(response => {
+                    if (response.ok) {
+                        showStatus('✓ ' + count + ' shots queued', 'success');
+                    } else {
+                        showStatus('✗ Error taking photos', 'error');
+                    }
+                })
+                .catch(error => showStatus('✗ Connection Error', 'error'));
+        }
+
+        function showStatus(message, type) {
+            const status = document.getElementById('status');
+            status.textContent = message;
+            status.className = 'status ' + type;
+            
+            setTimeout(() => {
+                status.className = 'status';
+            }, 3000);
+        }
+    </script>
+</body>
+</html>
+)rawliteral";
+    request->send(200, "text/html", html);
+}
+
 /// <summary>
 /// Handles GET /api/focus request to perform a half press (focus) operation.
 /// Logs the request, activates the camera focus, and responds with success.
@@ -138,13 +348,13 @@ void HTTPServer::handleMultiple(AsyncWebServerRequest *request)
 }
 
 /// <summary>
-/// Handles GET /get request as a simple health check endpoint.
+/// Handles GET /api/healthcheck request as a simple health check endpoint.
 /// Returns a plain text "Is working" response to verify server connectivity.
 /// </summary>
 void HTTPServer::handleHealthCheck(AsyncWebServerRequest *request)
 {
-    onRequestStart("get");
-    onRequestEnd("get");
+    onRequestStart("api/healthcheck");
+    onRequestEnd("api/healthcheck");
     request->send(200, "text/plain", "Is working");
 }
 

+ 8 - 1
HTTPServer.h

@@ -22,6 +22,13 @@ private:
     /// <summary>Registers all HTTP API endpoints and their handlers</summary>
     void setupRoutes();
     
+    /// <summary>
+    /// Handles GET / request to serve the home page.
+    /// Returns a simple HTML control interface for the camera remote.
+    /// </summary>
+    /// <param name="request">Async web server request object</param>
+    void handleRoot(AsyncWebServerRequest *request);
+    
     /// <summary>
     /// Handles GET /api/focus request to perform a half press (focus).
     /// </summary>
@@ -50,7 +57,7 @@ private:
     void handleMultiple(AsyncWebServerRequest *request);
     
     /// <summary>
-    /// Handles GET /get request as a health check endpoint.
+    /// Handles GET /api/healthcheck request as a health check endpoint.
     /// </summary>
     /// <param name="request">Async web server request object</param>
     void handleHealthCheck(AsyncWebServerRequest *request);

+ 2 - 1
minolta_remote_v1.ino

@@ -18,11 +18,12 @@
 /// - GPIO2 (LED_BUILTIN) - Status LED indicator
 /// 
 /// API Endpoints:
+/// - GET / - Home page with web interface for camera control
 /// - GET /api/focus - Perform a half press (focus)
 /// - GET /api/takePhoto[?msec=duration] - Take a photo
 /// - GET /api/reset - Release the shutter
 /// - GET /api/multiple?count=n&delay=ms[&msec=duration] - Take multiple photos
-/// - GET /get - Health check
+/// - GET /api/healthcheck - Health check endpoint
 /// </summary>
 
 #include <ArduinoJson.h>