PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ESP32: website Buttons um-designen



HaWe
20.06.2020, 14:00
hallo,
ich versuche gerade ein webserver-html-example für meine Zecke umzudesignen, kann aber leider kein html...
Der Beispielcode funktioniert, aber ich möchte nicht pro LED je 1 Button, der wechselweise eine LED an- oder ausschaltet,
sondern jeweils 2 getrennte Buttons pro LED nebeneinander, je einer für an und einer für aus.
Auch soll sich nicht mehr die Farbe des Buttons je nach led-status ändern (der aktuelle LED-Zustand wird ja oberhalb des betr. Buttons angezeigt).
Wer kann mir das bitte umschreiben?

Funktion String SendHTML(uint8_t led1stat,uint8_t led2stat){} ab Codezeile 208



//----------------------------------------------------------
String SendHTML(uint8_t led1stat,uint8_t led2stat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>LED Control</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
ptr +=".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";

ptr +=".button-on {background-color: #3498db;}\n";
ptr +=".button-on:active {background-color: #2980b9;}\n";
ptr +=".button-off {background-color: #34495e;}\n";
ptr +=".button-off:active {background-color: #2c3e50;}\n";

ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<h1>ESP32 Web Server</h1>\n";
ptr +="<h3>Using Station(STA) Mode</h3>\n";

if(led1stat)
{ptr +="<p>LED1 Status: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n";}
else
{ptr +="<p>LED1 Status: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n";}

if(led2stat)
{ptr +="<p>LED2 Status: ON</p><a class=\"button button-off\" href=\"/led2off\">OFF</a>\n";}
else
{ptr +="<p>LED2 Status: OFF</p><a class=\"button button-on\" href=\"/led2on\">ON</a>\n";}

ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}


Komplettcode von der ESP32 github repo (library examples):



// Create A Simple ESP32 Web Server In Arduino IDE
// https://lastminuteengineers.com/creating-esp32-web-server-arduino-ide/

#include <WiFi.h>
#include <WiFiClient.h>
#include <ESPmDNS.h>
#include <ArduinoOTA.h>
#include <WebServer.h>
#include <WiFiServer.h>


/*Put your SSID & Password*/
const char* ssid = "WLAN"; // Enter SSID here
const char* password = "1865844"; //Enter Password here


char www_username[64] = "admin";
char www_password[64] = "esp32";




#define this_ip_4 202 // <<< static webserver ip (4th byte)
IPAddress this_ip(192, 168, 2, this_ip_4); // <<< static local IP of this ESP-webserver
IPAddress gateway(192, 168, 2, 1); // <<< LAN Gateway IP
IPAddress subnet(255, 255, 255, 0); // <<< LAN Subnet Mask



#define wwwport 8008
#define lanport 8081
WebServer webserver(wwwport); // router http port www
WiFiServer wifiserver(lanport); // router wifi port lan



// allows you to set the realm of authentication Default:"Login Required"
const char* www_realm = "Custom Auth Realm";
// the Content of the HTML response in case of Unautherized Access Default:empty
String authFailResponse = "Authentication Failed";


uint8_t LED1pin = LED_BUILTIN;
bool LED1status = LOW;

uint8_t LED2pin = 12;
bool LED2status = LOW;



//----------------------------------------------------------
void handleNotFound() {

String message = "File Not Found\n\n";
message += "URI: ";
message += webserver.uri();
message += "\nMethod: ";
message += (webserver.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += webserver.args();
message += "\n";

for (uint8_t i = 0; i < webserver.args(); i++) {
message += " " + webserver.argName(i) + ": " + webserver.arg(i) + "\n";
}

webserver.send(404, "text/plain", message);

}





//----------------------------------------------------------
void setup() {
Serial.begin(115200);
delay(1000);

pinMode(LED1pin, OUTPUT);
pinMode(LED2pin, OUTPUT);

Serial.println("Connecting to ");
Serial.println(ssid);

//connect to your local wi-fi network
WiFi.begin(ssid, password);
WiFi.config(this_ip, gateway, subnet); // static IP

//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());


ArduinoOTA.begin();
webserver.on("/", []() {
if (!webserver.authenticate(www_username, www_password))
//Basic Auth Method with Custom realm and Failure Response
//return webserver.requestAuthentication(BASIC_AUTH, www_realm, authFailResponse);
//Digest Auth Method with realm="Login Required" and empty Failure Response
//return webserver.requestAuthentication(DIGEST_AUTH);
//Digest Auth Method with Custom realm and empty Failure Response
//return webserver.requestAuthentication(DIGEST_AUTH, www_realm);
//Digest Auth Method with Custom realm and Failure Response
{
return webserver.requestAuthentication(DIGEST_AUTH, www_realm, authFailResponse);
}
handle_OnConnect();
});

/*
webserver.on("/inline", []() {
webserver.send(200, "text/plain", "this works as well");
});
*/

webserver.on("/led1on", handle_led1on);
webserver.on("/led1off", handle_led1off);
webserver.on("/led2on", handle_led2on);
webserver.on("/led2off", handle_led2off);
webserver.onNotFound(handle_NotFound);

webserver.begin();

Serial.println("HTTP webserver started");
}



//----------------------------------------------------------
void loop() {
ArduinoOTA.handle();

webserver.handleClient();
if(LED1status)
{digitalWrite(LED1pin, HIGH);}
else
{digitalWrite(LED1pin, LOW);}

if(LED2status)
{digitalWrite(LED2pin, HIGH);}
else
{digitalWrite(LED2pin, LOW);}
}



//----------------------------------------------------------
void handle_OnConnect() {
LED1status = LOW;
LED2status = LOW;
Serial.println("GPIO13 Status: OFF | GPIO12 Status: OFF");
webserver.send(200, "text/html", SendHTML(LED1status,LED2status));
}

//----------------------------------------------------------
void handle_led1on() {
LED1status = HIGH;
Serial.println("GPIO13 Status: ON");
webserver.send(200, "text/html", SendHTML(true,LED2status));
}

//----------------------------------------------------------
void handle_led1off() {
LED1status = LOW;
Serial.println("GPIO13 Status: OFF");
webserver.send(200, "text/html", SendHTML(false,LED2status));
}

//----------------------------------------------------------
void handle_led2on() {
LED2status = HIGH;
Serial.println("GPIO12 Status: ON");
webserver.send(200, "text/html", SendHTML(LED1status,true));
}

//----------------------------------------------------------
void handle_led2off() {
LED2status = LOW;
Serial.println("GPIO12 Status: OFF");
webserver.send(200, "text/html", SendHTML(LED1status,false));
}

//----------------------------------------------------------
void handle_NotFound(){
String message = "File Not Found\n\n";
message += "URI: ";
message += webserver.uri();
message += "\nMethod: ";
message += (webserver.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += webserver.args();
message += "\n";

for (uint8_t i = 0; i < webserver.args(); i++) {
message += " " + webserver.argName(i) + ": " + webserver.arg(i) + "\n";
}

webserver.send(404, "text/plain", message);
//webserver.send(404, "text/plain", "Not found");
}

//----------------------------------------------------------
String SendHTML(uint8_t led1stat,uint8_t led2stat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>LED Control</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
ptr +=".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";

ptr +=".button-on {background-color: #3498db;}\n";
ptr +=".button-on:active {background-color: #2980b9;}\n";
ptr +=".button-off {background-color: #34495e;}\n";
ptr +=".button-off:active {background-color: #2c3e50;}\n";

ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<h1>ESP32 Web Server</h1>\n";
ptr +="<h3>Using Station(STA) Mode</h3>\n";

if(led1stat)
{ptr +="<p>LED1 Status: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n";}
else
{ptr +="<p>LED1 Status: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n";}

if(led2stat)
{ptr +="<p>LED2 Status: ON</p><a class=\"button button-off\" href=\"/led2off\">OFF</a>\n";}
else
{ptr +="<p>LED2 Status: OFF</p><a class=\"button button-on\" href=\"/led2on\">ON</a>\n";}

ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}


PS,
den Farbwechsel zumindest kann man durch auskommentieren der 4 Zeilen verhindern:

/*
ptr +=".button-on {background-color: #3498db;}\n";
ptr +=".button-on:active {background-color: #2980b9;}\n";
ptr +=".button-off {background-color: #34495e;}\n";
ptr +=".button-off:active {background-color: #2c3e50;}\n";

Jetzt braucht man nur noch 2 getrennte on/off Buttons pro LED
*/

Moppi
21.06.2020, 07:36
Hallo!

Ich versuche mal etwas auf die Sprünge zu helfen:


if(led1stat) {ptr +="<p>LED1 Status: ON</p><a class=\"button button-off\" href=\"/led1off\">OFF</a>\n";}
else {ptr +="<p>LED1 Status: OFF</p><a class=\"button button-on\" href=\"/led1on\">ON</a>\n";}

Dass Du nur den einen oder anderen Button bekommst, liegt hier an "IF ... ELSE ...". #
Je nach Status "led1stat" bekommst Du dadurch den Button "button button-off" oder "button button-on".
Wenn Du "IF" und "ELSE" entfernst bekommst Du beide Buttons dargestellt.

Außerdem werden Absätze zur Formatierung eingesetzt: "<p>....</p>"

So wird "LED1 Status: ON" in einem Absatz geschrieben, der dazugehörige Link, der als Button formatiert wird, aber nicht:

"<p>...</p>"
"Button-Link"
"<p>...</p>"
"Button-Link"

Etwas merkwürdige Strukturierung, aber .. na ja .... Normal würde man einen Text und den dazugehörigen Link in einen Absatz setzen:

"<p>Linktext: <a class=".." href="...">...</a></p>"

Um die als Buttons getarnten Links, nach dem Schema, oben nebeneinander zu bekommen:

"<p>Linktext: <a class=".." href="...">...</a>&nbsp;&nbsp;Linktext: <a class=".." href="...">...</a></p>"

Die beiden "&nbsp;" sind Platzhalter.

Oder so auch eine Möglichkeit:

"<p>Linktext: <a class=".." href="...">...</a><a class=".." href="...">...</a></p>"
Einen Text und dann beide Buttons nebeneinander.
Allerdings kann es sein, dass die Zeile im Browser umgebrochen wird, dann würden die Buttons untereinander rutschen.

Den Autor kontaktieren, um ein anderes Layout bereit zu stellen oder selber umfrickeln.


MfG

HaWe
21.06.2020, 11:44
danke für die Antwort!
Habe es erst nicht verstanden, aber jetzt durch rumprobieren doch hingekriegt mit je 2 Buttons:



//----------------------------------------------------------
String SendHTML(uint8_t led1stat,uint8_t led2stat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>LED Control</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
ptr +=".button {display: block;width: 80px;background-color: #3498db;border: none; color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";

ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<h1>ESP32 Web Server</h1>\n";
ptr +="<h3>Using Station(STA) Mode</h3>\n";

ptr+="<p>";
if(led1stat) {ptr +="LED1 Status: ON ";}
else {ptr +=" LED1 Status: OFF ";}
{ptr +="<a class=\"button button-off\" href=\"/led1off\">OFF</a>";}
{ptr +="<a class=\"button button-on\" href=\"/led1on\">ON</a>";}
ptr+="</p>";

ptr+="<p>";
if(led2stat) {ptr +="LED2 Status: ON ";}
else {ptr +=" LED2 Status: OFF";}
{ptr +="<a class=\"button button-off\" href=\"/led2off\">OFF</a>";}
{ptr +="<a class=\"button button-on\" href=\"/led2on\">ON</a>";}
ptr+="</p>";

ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}


seltsamerweise schreibt er jetzt aber immer noch alles in einzelne Zeilen untereinander -
wie kriegt man pro LED jeweils den Status-String und die beiden Buttons in 1 Zeile?

HaWe
02.07.2020, 12:29
warum werden denn nun die Buttons oben samt Textstring immer paarweise untereinander gemalt und nicht nebeneinander? Es ist doch kein Zeilenumbruch dazwischen, und jeweils 2 werden samt Textstring immer durch <p>...</p> zusammengefasst, dann müssten sie doch nebeneinander stehen...?

Moppi
02.07.2020, 21:07
Im Absatz dürfen Zeilen umgebrochen werden, warum denn nicht? Deshalb nehme ich für so etwas gerne Tabellen nach dem Schema: Tabelle->Zeile->Zellen
Wenn dann noch die Breite für die Zeile und/oder die Zellen festgelegt wird, wird es nicht mehr umgebrochen.
Allerdings kann man zwei Buttons auch in einen Container packen (<div>..</div>) und den mit einer festen Breite versehen, so dass die Buttons nebeneinander stehen bleiben.

MfG

HaWe
02.07.2020, 21:42
Ich verstehe es nicht:

warum wird denn hier

ptr+="<p>";
if(led1stat) {ptr +="LED1 Status: ON ";}
else {ptr +=" LED1 Status: OFF ";}
{ptr +="<a class="button button-off" href="/led1off">OFF</a>";}
{ptr +="<a class="button button-on" href="/led1on">ON</a>";}
ptr+="</p>";
jetzt alles untereinander gesetzt und nicht nebeneinander?

Moppi
03.07.2020, 06:54
Bei HTML orientiert sich alles immer am Endgerät, also am Display. Deshalb ist die erste Frage, ob die Buttons nebeneinander auf dem Display angezeigt werden können. Wenn das theoretisch gerade so passt, dass die beiden Buttons genau so breit sind, wie das Display, dann wird zu 99.9% umgebrochen und der zweite Button rutscht eine Zeile tiefer. Dazu muss man sich mehr mit HTML auseinandersetzen. Zu den HTML-Elementen gehören noch innere und äußere Rahmen, die zur Breite des Elements addiert werden. Wenn das nicht zur Displaybreite passt, wird umgebrochen. So ungefähr kann man sich das vorstellen.

Probeweise kann das "<p>" ersetzt werden durch "<div>" und das "</p>" durch "</div>".
"<div>" gibst Du eine feste Breite, versuchsweise mit: "<div style='width:1000px'>".

Das ist noch keine Endlösung, aber irgendwie musst Du Dich da heran tasten.

MfG

HaWe
03.07.2020, 09:59
vom Platz her passt es dicke, es gäbe also überhaupt keinen Anlass, dass html hier selbstständig Zeilenumbrüche einfügt.
Lade das Programm doch mal bitte selber hoch und gucke, was bei dir dargestellt wird.

PS,
die url habe ich im (riesigen) Windows-Browser aufgerufen

jcrypter
03.07.2020, 10:40
Wie sieht denn der Quelltext der HTML-Seite im Browser aus?

edit: wenn das css aus deinem ursprünglichen posts noch immer drin ist: display:block sorgt dafür, dass jeder "button", eigenlich ja nur ein Link, als block Element interpretiert wird. Und die ziehen sich über die ganze Seite und erzeugen einen Zeilenumbruch.

HaWe
03.07.2020, 11:21
ja klar, der Rest des Codes war gleich geblieben - lösche das gleich mal raus und gucke, was passiert!

- - - Aktualisiert - - -

UPDATE:

Jawohl, DARAN lag's! :D
vielen Dank!

- ERLEDIGT -