Sfoglia il codice sorgente

separate html pages for setup and control

master
gituser 1 settimana fa
parent
commit
9d8ea803fe
4 ha cambiato i file con 356 aggiunte e 268 eliminazioni
  1. 1
    0
      .settings/org.eclipse.core.resources.prefs
  2. 340
    0
      HtmlPages.h
  3. 11
    265
      LEDLamp.ino
  4. 4
    3
      sloeber.ino.cpp

+ 1
- 0
.settings/org.eclipse.core.resources.prefs Vedi File

@@ -1,2 +1,3 @@
eclipse.preferences.version=1
encoding/HtmlPages.h=UTF-8
encoding/LEDLamp.ino=UTF-8

+ 340
- 0
HtmlPages.h Vedi File

@@ -0,0 +1,340 @@
/*
* HtmlPage.h
*
* Created on: 08.06.2026
* Author: FSmilari
*/

#ifndef HTMLPAGES_H_
#define HTMLPAGES_H_

#include <WString.h>

const String getSetupPage(String macAddress) {

String html =
R"rawliteral(
<!DOCTYPE html>
<html>

<script>
function togglePassword() {
const pass = document.getElementById("pass");
const eye = document.querySelector(".toggle-eye");
if (pass.type === "password") {
pass.type = "text";
eye.textContent = "❌";
} else {
pass.type = "password";
eye.textContent = "👁";
}
}
</script>

<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Wemos LEDLamp Setup</title>

<style>
body {
margin: 0;
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #1e1e2f, #2b5876);
color: white;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
* {
box-sizing: border-box;
}
.card {
background: rgba(255,255,255,0.08);
backdrop-filter: blur(10px);
padding: 25px;
border-radius: 16px;
width: 90%;
max-width: 360px;
box-shadow: 0 8px 20px rgba(0,0,0,0.3);
animation: fadeIn 0.8s ease;
}
h2 {
margin-top: 0;
text-align: center;
}
.info {
font-size: 12px;
opacity: 0.8;
margin-top: 8px;
margin-bottom: 15px;
text-align: center;
}
input {
width: 100%;
padding: 12px;
margin: 8px 0px;
border-radius: 10px;
border: none;
outline: none;
font-size: 14px;
transition: 0.2s;
}
input:focus {
transform: scale(1.02);
}
button {
width: 100%;
padding: 12px;
margin-top: 10px;
border: none;
border-radius: 10px;
background: #00c6ff;
color: white;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
}
button:hover {
background: #0072ff;
transform: translateY(-2px);
}
.mac {
font-size: 11px;
text-align: center;
margin-bottom: 15px;
opacity: 0.7;
word-break: break-all;
}
.pw-wrapper {
position: relative;
width: 100%;
margin: 8px 0;
}
.pw-wrapper input {
width: 100%;
padding: 12px 40px 12px 12px; /* Platz für Icon rechts */
border-radius: 10px;
border: none;
outline: none;
font-size: 14px;
box-sizing: border-box;
}
.toggle-eye {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
font-size: 16px;
opacity: 0.6;
user-select: none;
transition: 0.2s;
}
.toggle-eye:hover {
opacity: 1;
}
@keyframes fadeIn {
from {opacity: 0; transform: translateY(10px);}
to {opacity: 1; transform: translateY(0);}
}
</style>
</head>

<body>

<div class="card">
<h2>Wemos LEDLamp Setup</h2>
<div class="mac">Device: )rawliteral"
+ macAddress
+ R"rawliteral(</div>

<form action="/save" method="POST">
<input name="ssid" placeholder="WLAN Name (SSID)">

<div class="pw-wrapper">
<input id="pass" name="pass" type="password" placeholder="Passwort">
<span class="toggle-eye" onclick="togglePassword()">👁</span>
</div>

<button type="submit">Speichern & Verbinden</button>
</form>
<div class="info">Verbinde den LEDLamp Wemos mit einem WLAN Netzwerk</div>

</body>
</html>
)rawliteral";

return html;
}


const String getSTAControlPage(String macAddress) {
String html =
R"rawliteral(
<!DOCTYPE html>
<html>

<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Wemos LEDLamp Control</title>

<style>
body {
margin: 0;
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #1e1e2f, #2b5876);
color: white;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
* {
box-sizing: border-box;
}
.card {
background: rgba(255,255,255,0.08);
backdrop-filter: blur(10px);
padding: 25px;
border-radius: 16px;
width: 90%;
max-width: 360px;
box-shadow: 0 8px 20px rgba(0,0,0,0.3);
animation: fadeIn 0.8s ease;
}
h2 {
margin-top: 0;
text-align: center;
}
.info {
font-size: 12px;
opacity: 0.8;
margin-bottom: 15px;
text-align: center;
}
input {
width: 100%;
padding: 12px;
margin: 8px 0;
border-radius: 10px;
border: none;
outline: none;
font-size: 14px;
transition: 0.2s;
}
input:focus {
transform: scale(1.02);
}
button {
width: 100%;
padding: 12px;
margin-top: 10px;
border: none;
border-radius: 10px;
background: #00c6ff;
color: white;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
}
button:hover {
background: #0072ff;
transform: translateY(-2px);
}
.mac {
font-size: 11px;
text-align: center;
margin-bottom: 15px;
opacity: 0.7;
word-break: break-all;
}
@keyframes fadeIn {
from {opacity: 0; transform: translateY(10px);}
to {opacity: 1; transform: translateY(0);}
}
</style>
</head>

<body>

<div class="card">
<h2>Wemos LEDLamp Control</h2>
<div class="mac">Device: )rawliteral"
+ macAddress
+ R"rawliteral(</div>

<div class="btn-row">
<button type="button" onclick="ledOn()">LED EIN</button>
<button type="button" onclick="ledOff()">LED AUS</button>
</div>

<script>
let ws;
function connectWS() {
ws = new WebSocket("ws://" + location.hostname + ":81/");
ws.onopen = () => {
console.log("WebSocket connected");
};
ws.onmessage = (e) => {
console.log("ESP:", e.data);
};
ws.onclose = () => {
console.log("WS disconnected → reconnect");
setTimeout(connectWS, 1000);
};
}
connectWS();
function ledOn() {
if (ws && ws.readyState === 1) {
ws.send("/ledOn");
}
}
function ledOff() {
if (ws && ws.readyState === 1) {
ws.send("/ledOff");
}
}
</script>

</body>
</html>
)rawliteral";

return html;
}


#endif /* HTMLPAGES_H_ */

+ 11
- 265
LEDLamp.ino Vedi File

@@ -4,6 +4,7 @@
#include <EEPROM.h>
#include <DNSServer.h>
#include "States.h"
#include "HtmlPages.h"

AppState state = STATE_BOOT;
unsigned long connectStart = 0;
@@ -44,238 +45,20 @@ void loadConfig() {
}

// ---------- CAPTIVE PORTAL PAGE ----------
void handleRoot() {
void handleSetupPage() {
String mac = WiFi.macAddress();

String html =
R"rawliteral(
<!DOCTYPE html>
<html>

<script>
function togglePassword() {
const pass = document.getElementById("pass");
const eye = document.querySelector(".toggle-eye");
if (pass.type === "password") {
pass.type = "text";
eye.textContent = "❌";
} else {
pass.type = "password";
eye.textContent = "👁";
}
}
</script>

<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Wemos Setup</title>

<style>
body {
margin: 0;
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #1e1e2f, #2b5876);
color: white;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}

* {
box-sizing: border-box;
}

.card {
background: rgba(255,255,255,0.08);
backdrop-filter: blur(10px);
padding: 25px;
border-radius: 16px;
width: 90%;
max-width: 360px;
box-shadow: 0 8px 20px rgba(0,0,0,0.3);
animation: fadeIn 0.8s ease;
}

h2 {
margin-top: 0;
text-align: center;
}

.info {
font-size: 12px;
opacity: 0.8;
margin-bottom: 15px;
text-align: center;
}

input {
width: 100%;
padding: 12px;
margin: 8px 0;
border-radius: 10px;
border: none;
outline: none;
font-size: 14px;
transition: 0.2s;
}

input:focus {
transform: scale(1.02);
}

button {
width: 100%;
padding: 12px;
margin-top: 10px;
border: none;
border-radius: 10px;
background: #00c6ff;
color: white;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
}

button:hover {
background: #0072ff;
transform: translateY(-2px);
}

.mac {
font-size: 11px;
text-align: center;
margin-bottom: 15px;
opacity: 0.7;
word-break: break-all;
}

.pw-wrapper {
position: relative;
width: 100%;
margin: 8px 0;
}
.pw-wrapper input {
width: 100%;
padding: 12px 40px 12px 12px; /* Platz für Icon rechts */
border-radius: 10px;
border: none;
outline: none;
font-size: 14px;
box-sizing: border-box;
}
.toggle-eye {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
font-size: 16px;
opacity: 0.6;
user-select: none;
transition: 0.2s;
}
.toggle-eye:hover {
opacity: 1;
}

@keyframes fadeIn {
from {opacity: 0; transform: translateY(10px);}
to {opacity: 1; transform: translateY(0);}
}
</style>
</head>

<body>

<div class="card">

<h2>Wemos Setup</h2>

<div class="mac">Device: )rawliteral"
+ mac
+ R"rawliteral(</div>

<form action="/save" method="POST">

<input name="ssid" placeholder="WLAN Name (SSID)">

<div class="pw-wrapper">
<input id="pass" name="pass" type="password" placeholder="Passwort">
<span class="toggle-eye" onclick="togglePassword()">👁</span>
</div>

<button type="submit">Speichern & Verbinden</button>
</form>

<div class="btn-row">
<button type="button" onclick="ledOn()">LED EIN</button>
<button type="button" onclick="ledOff()">LED AUS</button>
</div>

</div>

<script>

let ws;

function connectWS() {
ws = new WebSocket("ws://" + location.hostname + ":81/");

ws.onopen = () => {
console.log("WebSocket connected");
};

ws.onmessage = (e) => {
console.log("ESP:", e.data);
};

ws.onclose = () => {
console.log("WS disconnected → reconnect");
setTimeout(connectWS, 1000);
};
}

connectWS();

function ledOn() {
if (ws && ws.readyState === 1) {
ws.send("/ledOn");
}
}

function ledOff() {
if (ws && ws.readyState === 1) {
ws.send("/ledOff");
}
}

function togglePassword() {
const pass = document.getElementById("pass");
const eye = document.querySelector(".toggle-eye");

if (pass.type === "password") {
pass.type = "text";
eye.textContent = "🚫";
} else {
pass.type = "password";
eye.textContent = "👁";
}
String html = getSetupPage(mac);
webServer.send(200, "text/html", html);
}

</script>

</body>
</html>
)rawliteral";

// ---------- Wemos Control PAGE ----------
void handleSTAControlPage() {
String mac = WiFi.macAddress();
String html = getSTAControlPage(mac);
webServer.send(200, "text/html", html);
}


// ---------- SAVE ----------
void handleSave() {
String ssid = webServer.arg("ssid");
@@ -314,7 +97,7 @@ void startAP() {
dnsServer.start(DNS_PORT, "*", apIP);

// Webserver Routes
webServer.on("/", handleRoot);
webServer.on("/", handleSetupPage);
webServer.on("/save", HTTP_POST, handleSave);
webServer.onNotFound(handleNotFound);

@@ -323,41 +106,6 @@ void startAP() {
Serial.println("Captive Portal gestartet");
}

// ---------- CONNECT STA ----------
bool connectSTA() {
WiFi.mode(WIFI_STA);
WiFi.begin(config.ssid, config.pass);

Serial.println();
Serial.print("Verbinde mit WLAN: ");
Serial.println(config.ssid);

int tries = 0;
while (WiFi.status() != WL_CONNECTED && tries < 20) {
delay(500);
Serial.print(".");
tries++;
}

if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.println("\nVerbunden!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());

webServer.on("/", handleRoot);
webServer.on("/save", HTTP_POST, handleSave);
webServer.begin();

webSocket.begin();
webSocket.onEvent(webSocketEvent);
Serial.println("WebSocket gestartet auf Port 81");

return true;
}

return false;
}

void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) {

@@ -403,7 +151,6 @@ void setState(AppState newState) {
}

void handleBoot() {

if (config.valid) {
WiFi.mode(WIFI_STA);
WiFi.begin(config.ssid, config.pass);
@@ -416,7 +163,6 @@ void handleBoot() {
}

void handleConnecting() {

if (WiFi.status() == WL_CONNECTED) {
startSTAWebServer();
setState(STATE_STA_MODE);
@@ -456,7 +202,7 @@ void startSTAWebServer()
Serial.println("Starte STA Services");

// Webseite
webServer.on("/", handleRoot);
webServer.on("/", handleSTAControlPage);

// optional
webServer.on("/save", HTTP_POST, handleSave);

+ 4
- 3
sloeber.ino.cpp Vedi File

@@ -2,7 +2,7 @@
//This is a automatic generated file
//Please do not modify this file
//If you touch this file your change will be overwritten during the next build
//This file has been generated on 2026-06-08 17:59:19
//This file has been generated on 2026-06-08 18:48:53

#include "Arduino.h"
#include "Arduino.h"
@@ -11,14 +11,15 @@
#include <EEPROM.h>
#include <DNSServer.h>
#include "States.h"
#include "HtmlPages.h"

void saveConfig() ;
void loadConfig() ;
void handleRoot() ;
void handleSetupPage() ;
void handleSTAControlPage() ;
void handleSave() ;
void handleNotFound() ;
void startAP() ;
bool connectSTA() ;
void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) ;
void setState(AppState newState) ;
void handleBoot() ;

Loading…
Annulla
Salva