Slider und Switch Zustand auf Website in JSON Datei schreiben/lesen

Status
Dieses Thema wurde gelöst! Zur Lösung gehen…

tiluhe

Grünschnabel
Hallo,

als blutiger Neuling möchte ich gerne ein kleines Projekt umsetzen. Zum Verständnis beschreib ich das mal:
Ich habe einen ESP32 Mikrocontroller so programmiert, dass er per Relais die Stromzufuhr zur Kaffeemaschine an- und abschalten kann und dass er auf Knopfdruck das Mahlwerk einer Espressomühle für eine festgelegte Zeitdauer einschaltet. Über WLAN kann ich auf den ESP32 zugreifen und den Zustand des Relais bzw. die Mahlzeit verändern. Im Heimnetz funktioniert das gut, nur leider da der Internetzugang bei uns im Haus nicht über DSL geht habe ich Internet über einen LTE Surfstick in der Fritzbox. Leider ist es Mobilfunkbetreiberseitig nicht möglich über das Internet auf das Heimnetz zuzugreifen (auch nicht mit Dyndns). Deswegen wollte ich nun einen Umweg gehen und habe den ESP32 nicht mehr als Webserver in Betrieb, sondern als HTTP Client. Er fragt jede Minute den Zustand von zwei Variablen (boolean: "machineOn" und int "grindTime") ab, die ich in einer .json-Datei auf einem Webserver gespeichert habe. Das funktioniert.

Was noch fehlt: die dazu passende sehr einfache Seite, die ich dann mit meinem Handy aufrufe und über die ich von überall via Internet die Kaffemaschine einschalten kann, damit sie vorgeheizt ist, wenn ich zuhause ankomme :) Das ganze ist ein Lernprojekt bei dem es mir mehr ums Verstehen und in die Materie eintauchen geht, als dass es mir wirklich unsterblich wichtig ist von überall die Kaffemaschine anschalten zu können... aber jetzt hab ich schonmal angefangen und würde es auch gerne zu ende bringen :)

Das Frontend der Seite hab ich erstellt, nur bin ich damit überfordert den Zustand bzw. Wert des Switches und des Sliders bei Veränderung auszulesen und in die JSON zu schreiben. Ich habe versucht das zu googeln, aber bin damit nicht weitergekommen, weil das irgendwie immer zu anderen Zwecken genutzt wird :)

Ich glaube für jemand, der sich mit HTML und Java auskennt ist das vermutlich ein Klacks, ich bin leider hoffnungslos überfordert!
Vielleicht gibt es auch eine einfachere Möglichkeit als JSON zum Datenaustausch zwischen ESP32 und der Website, auch dafür bin ich ganz offen!



<!DOCTYPE html> <html> <head> <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0"> <title>Coffee</title> <link href="styles/style.css" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Amatic+SC:wght@700&display=swap" rel="stylesheet"> </head> <body> <h1>Cappucino Zentrale</h1> <img src="images/cappucino.jpg" alt="cappucino"> <h2>Stromzufuhr Kaffemaschine:</h2> <!-- Rounded switch --> <label class="switch"> <input type="checkbox" id="machineOnSwitch"> <span class="slider round"></span> </label> <h2>Mahlzeit Kaffemühle:</h2> <div class="slidecontainer"> <input type="range" min="16000" max="18000" value="17000" class="slider" id="grindTimeSlider" oninput="this.nextElementSibling.value = this.value"> <output>16000</output> ms <h1 id="sliderWert"></h1> </div> <script src="scripts/main.js"></script> </body> </html>

ich würde mich sehr über Hilfe freuen!
Danke schonmal und liebe Grüße,
Tim
 
Zuletzt bearbeitet:
Versuche dieses Javascript:
Code:
        const machineOnSw = document.getElementById('machineOnSwitch');
        const grindTimeSl = document.getElementById('grindTimeSlider');
        function sendIt() {
            const machineOn = machineOnSw.checked;
            const grindTime = grindTimeSl.value;
            fetch("thread467-arduino-kaffeemaschine.php",
                {
                    method: "POST",
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        machineOn: machineOn,
                        grindTime: grindTime
                    })
                })
                .then(function (res) {
                    return res.text();
                }).then(function (text) {
                    console.log(text);
                })
                .catch(function (res) { console.log(res) })
        }
        machineOnSw.addEventListener('change', sendIt);
        grindTimeSl.addEventListener('change', sendIt);
und dieses PHP-Skript in store-json.php auf dem Server:
Code:
<?php
$json = file_get_contents("php://input");
echo $json;
file_put_contents('kaffeemaschine.json', $json);
Es trägt den Zustand des Schalters und des Slider JSON-kodiert in die Datei kaffeemaschine.json ein.
 
Zuletzt bearbeitet:
Vielen Dank für die schnelle Antwort Sempervivum! Es klappt schon fast! Seit Stunden probiere ich daran rum und wenn man weiß wie es geht, so schnell... :p Danke Danke Danke!

grindTime wird korrekt in die json geschrieben, bei machineOn wird allerdings egal für welchen Zustand des Schalters stets on übermittelt, woran könnte das liegen?

Jetzt muss nur noch beim Aufruf der Seite die aktuell gespeichrten Werte von machineOn und grindTime aus der json gelesen werden, wie ist das möglich?
 
okay, das Problem mit machineOn hab ich gelöst:
Statt "machineOnSw.value" muss es heißen machineOnSw.checked,
dann wird true oder flase in die Variable geschrieben!
 
und noch ein seltsames Problem:
wenn ich über die Website etwas ändere, so ändert sich die .json-Datei auf dem Server nicht sofort!
Das ist klar ersichtlich, wenn man www.coffee.djanetskis.de/coffee.json geöffnet hat und nach einer Änderung die Seite neu lädt.

Wenn ich dann coffee.json mit FileZilla herunterlade, bekomme ich aber die aktuellen Werte und dann ist es auch auf www.coffee.djanetskis.de/coffee.json geändert. Was könnte FileZilla bewirken, dass die Datei dann aktualisiert wird? Wird die Datei vom Hoster vielleicht erst bei Abfrage über FileZilla wirklich wieder vom eigentlichen Server geholt und davor eine Version aus irgendeinem Zwischenspeicher bei der Abfrage abgegeben? Ich bin ratlos!
 
Zuletzt bearbeitet:
Ah! Ich musste den Varnish-Cache auf dem Server deaktivieren, jetzt werden die Änderungen stets sofort übernommen! Falls mal jemand über das selbe Problem stolpert.. ;)
 
Jetzt muss nur noch beim Aufruf der Seite die aktuell gespeichrten Werte von machineOn und grindTime aus der json gelesen werden, wie ist das möglich?
Ich dachte, die Aufgabe hättest Du schon gelöst, weil Du früher schriebst:
habe den ESP32 nicht mehr als Webserver in Betrieb, sondern als HTTP Client. Er fragt jede Minute den Zustand von zwei Variablen (boolean: "machineOn" und int "grindTime") ab, die ich in einer .json-Datei auf einem Webserver gespeichert habe. Das funktioniert.
Du brauchst ja nur die neue JSON-Datei abzufragen, die das PHP-Skript aktualisiert.
 
Ich dachte, die Aufgabe hättest Du schon gelöst, weil Du früher schriebst:

Du brauchst ja nur die neue JSON-Datei abzufragen, die das PHP-Skript aktualisiert.
Ja das funktioniert.

Ich meine, wenn die Website via Browser oder Handy zum Einstellen der Werte aufgerufen wird, muss sie den "Ist-Zustand" der Werte abfragen, da sonst bei Anschalten der Maschine grindTime auf 16000 (Initialwert des Sliders) gesetzt wird.
Es soll aber den Wert, den es bei Aufruf der Seite hatte beibehalten. Deshalb müsste immer bei Aufbau der Seite die json Ausgelesen werden und damit machineOnSw.checked und grindTimeSl.value mit den aktuell gespeicherten Werten initialisiert werden.
 
Wenn ich das richtig sehe, liegt die JSON-Datei ja auf dem selben Server wie die HTML-Seite. Dann kannst Du sie direkt mit PHP einlesen und den Status der beiden Elemente entspr. setzen.
Am Anfang der (jetzt PHP-)Datei die Werte bereit stellen:
Code:
<?php
$status = json_decode(file_get_contents('kaffeemaschine.json'), true);
$machineOn = $status['machineOn'];
$checked = '';
if ($machineOn) {
    $checked = ' checked';
}
$grindTime = $status['grindTime'];
?>
Und dann den Status der Elemente entspr. setzen:
Code:
    <label class="switch">
        <input type="checkbox" id="machineOnSwitch"<?php echo $checked; ?>>
        <span class="slider round"></span>
    </label>
    <h2>Mahlzeit Kaffemühle:</h2>
    <div class="slidecontainer">
        <input type="range" min="16000" max="18000" value="<?php echo $grindTime; ?>" class="slider" id="grindTimeSlider"
            oninput="this.nextElementSibling.value = this.value">
        <h1 id="sliderWert"></h1>
    </div>
 
Danke nochmals!

Bisher klappt es so leider noch nicht. Vielleicht mache ich auch etwas falsch.

Ich habe eine neue Datei start.php im selben Verzeichnis erstellt und den code von oben eingefügt. In der index.html habe ich dann den Status der Elemente entsp. gesetzt. Allerdings startet die Seite nun immer mit machineOn=true und grindTime=17000, egal was in der json hinterlegt ist.
 
Status
Dieses Thema wurde gelöst! Zur Lösung gehen…
Zurück