Schaltzustand auf Webseite ohne refresh darstellen

Hallo, ich lasse mir per webserver folgenden code darstellen, ein Kamerabild (es wird aller 200 ms per JS aktualisiert), zwei Buttons (AUF, ZU), noch zwei Buttons (STOP, AUTO) und ein Button als "Statuszeile".

Ich lasse die Seite aller 10 sec neu laden um die Statuszeile zu aktualisieren (Tor ist auf/zu, mit jeweils anderer Hintergrundfarbe). Ist es möglich auf das Refresh der kompletten Seite zu verzichten und nur die Statuszeile zu aktualisieren?

Hat vielleicht jemand ein einfaches Beispiel, das ich nachvollziehen kann?

MfG.

<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>
<html>
 <head>
  <meta content='text/html; charset=ISO-8859-1' http-equiv='content-type'>
  <meta http-equiv='refresh' content='10'/>
  <style>div.td{display:table-cell;padding:0px;}</style>
  <script language='Javascript' type='text/javascript'>
   if (parent.frames.length) top.location.href = document.location;
   var timeout = 200;
   function reload(element){
    setTimeout('reloadImg("' + element.id + '")',timeout);
   }
   function reloadImg(id){
    var obj = document.getElementById(id);
    var cameraIP = obj.src.split('&t=');
    var date = new Date();
    obj.src = cameraIP[0] + '&t=' + Math.floor(date.getTime()/timeout);
   }
  </script>
  <title>Tor&ouml;ffner</title>
 </head>
 <body>
  <center>
   <div>
    <form action='tast'>
     <input type=image id='tast' value='tast' src='http://cameraip:port/snapshot.cgi?user=***&pwd=***' width=90% onload='reload(this)' onerror='reload(this)'>
    </form>
   </div>
   

   <div>
    <div class='td'>
     <form action='auf'>
      <input value='AUF' style='BACKGROUND-COLOR: DarkGray; width:45vw;height:20vh; font-size: 10vw;' type='submit'>
     </form>
    </div>
    <div class='td'>
     <form action='zu'>
      <input value='ZU' style='BACKGROUND-COLOR: DarkGray; width:45vw;height:20vh; font-size: 10vw;' type='submit'>
     </form>
    </div>
   </div>
   <div>
    <div class='td'>
     <form action='stop'>
      <input value='STOP' style='BACKGROUND-COLOR: DarkGray; width:45vw;height:20vh; font-size: 10vw;' type='submit'>
     </form>
    </div>
    <div class='td'>
     <form action='auto'>
      <input value='AUTO' style='BACKGROUND-COLOR: DarkGray; width:45vw;height:20vh; font-size: 10vw;' type='submit'>
     </form>
    </div>
   </div>
   <input value='Das Tor ist offen.' style='BACKGROUND-COLOR: #FF5050; width:90vw;height:10vh; font-size: 5vw;' type='submit'>
  </center>
 </body>
</html>

Schau Dir mal AJAX oder Fetch an, um nur die Werte zu aktualisieren oder Websockets, damit der Server pushen kann.

Gruß Tommy

Hi

Meine HTML/PHP/JavaScript-Basteleien sind schon einige Jahre her, würde aber vom JavaScript regelmäßig eine PHP aufrufen, Die mir die benötigte Information gibt.
Diese dann als Button-Text aktualisiert (per JavaScript).

Gleiches müsste sich auch mit dem Bild machen lassen ... hatte vor mehreren Jahren eine Kamera 'von Außen greifbar' gemacht - da lag der Vater über Monate im Krankenhaus - mir ist aber nicht mehr bekannt, ob ich Da das Bild per JavaScript aktualisieren konnte.

MfG

Das Bild kannst Du auch aktualisieren.

Warum willst Du den Umweg über PHP gehen? Das kann der Arduino mit Ethernet bzw. der ESP8266 auch allein.

Gruß Tommy

Hi

Aus purer Unwissenheit :wink:
Meine µC hatten noch keinen Kontakt zur großen weiten Welt und einen ESP8266 beherberge ich noch nicht.
(Einzig Kommunikation via CAN-Modulen, Das klappt aber ganz gut)

MfG

danke, habe was passendes gefunden, müsste AJAX sein. Jetzt geht es...

<!DOCTYPE html>
<html>
<body>
<script>
function sendData(led) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("LEDState").innerHTML =
      this.responseText;
    }
  };
  xhttp.open("GET", "setLED?LEDstate="+led, true);
  xhttp.send();
}

setInterval(function() {
  // Call a function repetatively with 2 Second interval
  getData();
}, 2000); //2000mSeconds update rate

function getData() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("ADCValue").innerHTML =
      this.responseText;
    }
  };
  xhttp.open("GET", "readADC", true);
  xhttp.send();
}
</script>

<script language='Javascript' type='text/javascript'>
   if (parent.frames.length) top.location.href = document.location;
   var timeout = 200;
   function reload(element){
    setTimeout('reloadImg("' + element.id + '")',timeout);
   }
   function reloadImg(id){
    var obj = document.getElementById(id);
    var cameraIP = obj.src.split('&t=');
    var date = new Date();
    obj.src = cameraIP[0] + '&t=' + Math.floor(date.getTime()/timeout);
   }
</script>

<style type="text/css">
	.btn {background-color:lightgreen;cursor:pointer;width:45vw;height:20vh;font-size:10vw;}
	.btn {background-color:darkgray;cursor:pointer;width:45vw;height:20vh;font-size:10vw;}
</style>

<title>Toröffner</title>
<center>

<div>
	<input onclick="sendData(0)" type=image id='tast' src='http://spunky1a.spdns.de:91/snapshot.cgi?user=admin&pwd=' width=90% onload='reload(this)' onerror='reload(this)'>
</div>


<div>
	<button class="btn" type="button" onclick="sendData(1)">AUF</button>
	<button class="btn" type="button" onclick="sendData(2)">ZU</button>
</div>


<div>
	<button class="btn" type="button" onclick="sendData(3)">STOP</button>
	<button class="btn" type="button" onclick="sendData(4)">AUTO</button>
</div>


<div>
	ADC Value is : <span id="ADCValue">0</span>

	LED State is : <span id="LEDState">NA</span>
</div>

</center>
</body>
</html>

wie kann ich es anstellen, den style (button-Farbe) von außerhalb (NodeMCU) zu beeinflussen.

also so:

Normal ist der Button grau
ich drücke den Button und es wird ein Befehl auf dem µC ausgeführt
der µC gibt eine Rückmeldung "Befehl angekommen"
jetzt soll der Button kurz grün aufleuchten, dann wieder grau

wie kann man das machen?

MfG.

Da solltest Du in einem JS-/CSS-Forum nachfragen.

Gruß Tommy

ich würde es etwas einfacher machen:

beim Feuern des Buttons zu begin des JavaScript die Button-Farbe ändern, und je nach Erfolg/Misserfolg des Requests die Buttonfarbe wieder zurückändern.

Das wäre wesentlich einfacher, als nach einem Button-Click den NodeMCU im Halbsekunden-Rhythmus erneut zu fragen, ob der Button wieder umgeschaltet werden soll...

danke, hab ich so gemacht, funktioniert gut.

Ich habe sowas für meine Rolladen-Steuerung gemacht. Du steckst die Abfrage in einen unsichtbaren iFrame, der kann sich dann beliebig oft refreshen - man sieht ihn ja nicht. Über Javascript aus einem Timer holst du dir die Ergebnisse aus dem iFrame in die Hauptseite. Ich benutze übrigens platzsparende SVG-Icons und Symbole (im Gegensatz zu Pixelgrafiken).

Das funktioniert alles ohne Internetverbindung.

qualidat:
Du steckst die Abfrage in einen unsichtbaren iFrame, der kann sich dann beliebig oft refreshen - man sieht ihn ja nicht. Über Javascript aus einem Timer holst du dir die Ergebnisse aus dem iFrame in die Hauptseite.

AJAX, Fetch, Websockets ? Alles Quatsch!

Richtige Männer machen sowas unsichtbar!

Toller Tip heutzutage!

Hi

Toller Tip, den tollen Tip als tollen Tip zu bezeichnen.

Wenn's nicht für Mehr reicht: Danke für Deinen Beitrag.
Sollte Es doch für Mehr reichen: Beispiel?

In diesem Sinne ... richtige Männer ...

postmaster-ino:
Hi

Toller Tip, den tollen Tip als tollen Tip zu bezeichnen.

Wenn's nicht für Mehr reicht: Danke für Deinen Beitrag.
Sollte Es doch für Mehr reichen: Beispiel?

In diesem Sinne ... richtige Männer ...

@postmaster-ino

Ich arbeite nur noch mit der Fetch.api.
Alle meine ESp…. senden und empfangen mit fetch.
Am besten erklärt finde ich das hier fetch API
Gerne zeige ich dir auch wie ich das verwende!

Gruß Fips

Hi

Das Angebot nehme ich gerne an - wobei Das wohl für mich wie 'Perlen vor die Säue' wäre (zumindest zur Zeit, da Nichts mit ESP).
Für das andere Volk, was hier mit liest, könnte Das aber ein Gewinn sein!

MfG

Derfips:
Ich arbeite nur noch mit der Fetch.api.
Alle meine ESp…. senden und empfangen mit fetch.
Am besten erklärt finde ich das hier fetch API
Gerne zeige ich dir auch wie ich das verwende!

Das wäre für alle bestimmt interessant, zumal diese API noch etwas neu ist.

Gruß Tommy

Mal ein stark gekürztes Beispiel um die Onboard Led des Esp32 zu toggeln.

void handleRoot() {
  if (server.hasArg("")) {
    digitalWrite(2, !digitalRead(2));
  }
  server.send(200, "text/html", "<button onclick=\"fetch('?=')\">LED</button>");
}

Funktioniert, aber Html und Javascript sollten eigentlich nicht mehr vermischt werden.

Drei Button und die Antwort vom Server als Json Array.

window.addEventListener("load", function() {
	document.querySelector("#push").addEventListener("click", function() {detail('flag1');});
	document.querySelector("#led").addEventListener("click", function() {detail('led');});
	document.querySelector("#minmax").addEventListener("click", function() {detail('flag');});
	}); 
function detail(text) {
  fetch('http://hostname.e9nr6jt1h0fxpnem.myfritz.net:80/' + text).then(function (response) {
    return response.json();
  }).then(function (array) {
    if (array[0] != '0') {
      document.querySelector('#minmax').innerHTML = 'Max rücksetzen';
      document.querySelector('#flag').innerHTML = 'Min um ' + array[1];
    } 
    else {
      document.querySelector('#minmax').innerHTML = 'Min rücksetzen';
      document.querySelector('#flag').innerHTML = 'Max um ' + array[1];
    }
    if (array[2] != '0') {
      document.querySelector('#push').innerHTML = 'Push Off';
	  document.querySelector('#push').classList.add('buttonon');
    } 
    else {
      document.querySelector('#push').innerHTML = 'Push On';
	  document.querySelector('#push').classList.remove('buttonon');
    }
    if (array[3] != '0') {
      document.querySelector('#led').innerHTML = 'LED On';
	  document.querySelector('#led').classList.remove('buttonon');
    } 
    else {
      document.querySelector('#led').innerHTML = 'LED Off';
	  document.querySelector('#led').classList.add('buttonon');
    }
    document.querySelector('#mischen').innerHTML = array[4];
  });
}
document.addEventListener('DOMContentLoaded', detail('detail'));

Einmal in der Sekunde die Daten vom BME280 holen und Antwort vom Server als Json Objekt.

function renew() {
    fetch('http://hostname.e9nr6jt1h0fxpnem.myfritz.net:80/schlaf').then(function (response) {
      return response.json();
    }).then(function (obj) {
      document.querySelector('#Bme0').innerHTML = obj['Bme0'];
      document.querySelector('#Bme1').innerHTML = obj['Bme1'];
      document.querySelector('#Bme2').innerHTML = obj['Bme2'];
      document.querySelector('#Bme3').innerHTML = obj['Bme3'];
    });
}
document.addEventListener('DOMContentLoaded', renew);
setInterval(renew, 1000);

Mittels Fetch per 'POST' an Server senden.

function once(arg1) {
  fetch('/admin/once', {
    method: 'POST',
    body: arg1
  }).then(function (resp) {
    return resp.json();
  }).then(function (obj) {
   ........code......
  });
}

@postmaster-ino

Jetzt aber schnell einen ESP gekauft und ausprobieren.

Gruß Fips

Hi

Habe noch genügend andere offene Baustellen mit den 'normalen' Arduinos offen und entdecke hier im Forum fast täglich neue Spielereien dazu
(jetzt gerade spiele ich mit einem Sketch von combie, Quelle Klick - habe eine kleine Spielerei mit Servos (bisher nur unabhängige Bewegungen) und werde Das wohl zum Umbau meines Klassen-Versuch 'modifizieren' - wenn mir dort auch nicht alle Zeilen klar sind)

Danke Dir für die Beispiele, da kommen Erinnerungen, wenn meine Welt aber wohl bei HTML, PHP(+mySQL) und JavaScript stehen blieb.

MfG

@Fips: Danke für die Beispiele. Sieht kürzer aus, als AJAX. Nur AJAX habe ich mittlerweile fertig vorliegen und muss es nur noch für die jeweilige Anwendung auf Serverseite anpassen.
Wenn ich mal Zeit habe, werde ich mir das aber nochmal tiefer anschauen.

Gruß Tommy

aber wesentlich "kürzer" als XMLHttpRequest ist das auch nicht. Und sehe ich das Richtig, IE kann kein Fetch?

Wer benutzt schon IE?

Gruß Tommy