[GELOEST] übergabe zweier Werte aus Text Elementen via Button - Hilfe

  • Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Richi

Neues Mitglied
26 September 2020
20
0
1
37
Hallo,
ich mal wieder,
ich habe seid meinem letzten Post ein paar erweiterungen erfolgreich implementiert, stehe nun aber wieder vor einem Fehler der sich mir nur schwierig erklärt.
Es geht wieder um meine Zeitschaltuhr und Ihre Werte die sie mir an den Skript senden soll:
schaltuhr.jpg
Sie sieht nun mitlerweile genau so aus (nochmals Danke an Sempervivum).
Der Haken der mir die Elemente Aktiviert funktioniert ebenfalls.
Allerdings bekomme ich es nicht hin das mir der "Speicher" Button die beiden Werte der Zeiten richtig an den Skript übermittelt, oder der Skript diese mir richtig an den ESP sendet.
Jedenfalls zeigt der mir diese Werte immer mit "0" an.
Hier mal die Codes:
HTML:
<ul class='timer'>
<li><input type="checkbox" id="timeakti" onclick="timeAktiv()"/>Zeitschaltuhr aktivieren </li>
<li>Einschaltzeit: <input type="text" size="2" placeholder="16.00" pattern="[0-9]+.[0-9]{5}" title="Einschaltzeit" id="AN" disabled="true" /></li>
<li>Ausschaltzeit: <input type="text" size="2" placeholder="23.00" pattern="[0-9]+.[0-9]{5}" title="Ausschaltzeit" id="AUS" disabled="true" /></li>

<li><input type="submit" value="Speichern" id="save" onclick="timeSave()" disabled="true"/></li>
</ul>


SKRIPT:
//#################### Aktivierung aller Elemente ############################
function timeAktiv(){
var checkBox = document.getElementById("timeakti");
if(checkBox.checked == true){
document.getElementById("AN").disabled=false;
document.getElementById("AUS").disabled=false;
document.getElementById("save").disabled=false;
}else{
document.getElementById("AN").disabled=true;
document.getElementById("AUS").disabled=true;
document.getElementById("save").disabled=true;
}
}
//#################### auslesen der Werte und übergabe an ESP #################
function timeSave(){
event.preventDefault();
var anTime = document.getElementById("AN").addEventListener(event, this.value); <------- diese
var ausTime = document.getElementById("AUS").addEventListener(event, this.value); <------- und diese
submitVal('x', anTime);
submitVal('y', ausTime);
}


Es geht mir um die beiden Zeilen mit "<-----" wo ich markiert habe, dort vermute ich den Fehler.
In einem anderen Code Teil habe ich eine "ähnliche" Funktion mit "onchange" realisiert, diese hat aber nur ein Feld und keinen Button.
Das geht wunderbar. Hier allerdings wollte ich es erst übertragen wenn der Speicher-Button gedrückt wird. Komme aber nicht drauf
wie ich zwei Felder damit auslesen bzw. übertragen kann. Habe schon ein paar Varianten versucht, der ESP zeigt mir aber immer "0".
Wenn jemand Tips oder einen Link zu einem ähnlichen Beispiel hat, gerne her damit.
Und wenn wer bessere Lösungen hat ebenfalls her damit.
BY THE WAY, ist die "timeAktiv-Funktion" der Elemente so conform geschrieben? Oder gibts da andere Wege? Hab nichts besseres dazu gefunden. (funktioniert aber so)
 

m.scatello

Senior HTML'ler
15 Februar 2017
1.353
163
63
var anTime = document.getElementById("AN").addEventListener(event, this.value);

var anTime = document.getElementById("AN").value;
 
  • Like
Reaktionen: Richi

Richi

Neues Mitglied
26 September 2020
20
0
1
37
WOW, Danke, so klappt es schonmal Super.
Allerdings bekomme ich die "nachpunkt" Werte nicht. Glaube das muss ich mit einem Array oder so lösen.
Zumindest empfange ich schonmal was. Ich Probier weiter.
 

Richi

Neues Mitglied
26 September 2020
20
0
1
37
Warum nicht Type Time?

Wenn ich es mit type="time" mache hab ich zwar ein Zeiteingabe fenster, dies überträgt mir aber die Werte so "12:34".
Nun ist dann die Frage wie man die " : " da wieder weg bekommt da ich die Werte der Stunden und Minuten zum weiter verarbeiten einzeln benötige als "integer". Aktuell muss ich sie mir aus einem "float" in zwei "int" umrechnen.
Mit dem " : " dazwischen will dies nicht klappen
 

Richi

Neues Mitglied
26 September 2020
20
0
1
37
die HTML sendet es über einen java skript an meinen ESP dieser läuft mit "C".
Und bekommt den Eingabewert in einem "String" den ich zuerstmal in einen float übergebe und dann in zwei integer zerlege.
 

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.096
406
83
67
Mit Javascript ist das Zerlegen des Strings einfacher:
Müsste dann in deiner Funktion submitVal so aussehen:
Code:
function submitVal(type, val) {
    const splitVal = val.split(':');
    const hour = splitVal[0],
        min = splitVal[1];
    // jetzt liegen Stunden und Minuten vor und können an
    // den Server geschickt werden
}

BTW: Du hast nach Verbesserungsvorschlägen gefragt. Deine beiden Aufrufe von submitVal() lassen vermuten, dass Du zwei Requests an den Server schickst. Das könnte man vorteilhaft in einem Request zusammen fassen, der alle Werte abschickt.
 

Richi

Neues Mitglied
26 September 2020
20
0
1
37
Ja die beiden submitVal() kümmern sich ja je um eine Zeit AN/AUS und diese beiden Zweiten zerleg ich in je H/M

Code:
if(server.argName(i) == "x") {
float   anTime = strtof(server.arg(i).c_str(), NULL);
int     anTimeH = anTime;
float   anRechner = anTime - anTimeH;
int     anTimeM = anRechner * 100 + 0.5;


die 4 davor gesetzten float und int hab ich nur mal dazu geschrieben damit ihr es besser seht, die werden an anderer Stelle definiert.
Dies ist jetzt mein Rechenweg. Wie gesagt ich bin in HTML und JAVA absoluter anfänger und bin froh das ich Aktuell Elemente auf der Webside platzieren kann und eine funktion dazu bekomme die mir das alles an den ESP schickt.
Ich bin weit weg von perfekt, aber dennoch läuft es.


Deine beiden Aufrufe von submitVal() lassen vermuten, dass Du zwei Requests an den Server schickst.
Das könnte man vorteilhaft in einem Request zusammen fassen, der alle Werte abschickt.
würdest du mir auch sagen WIE?
 

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.096
406
83
67
Ich nehme an, Du schickst die Werte mit Ajax an den Server. Dafür gibt es mehrere Varianten. Poste mal deine Funktion submitVal, dann man man es dir sicher leicht erklären.
 

Richi

Neues Mitglied
26 September 2020
20
0
1
37
Code:
function submitVal(name, val) {
  var xhttp = new XMLHttpRequest();
  xhttp.open('GET', 'set?' + name + '=' + val, true);
  xhttp.send();
}
 

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.096
406
83
67
Also XMLHttpRequest. Selber bevorzuge ich fetch aber damit geht es natürlich auch:
Code:
function submitVal(onTime, offTime) {
    const splitOnTime = onTime.split(':');
    const onHour = splitOnTime[0],
        onMin = splitOnTime[1];
    // Genau so für die offTime
    const params = `onHour=${onHour}&onMin=${onMin}&offHour=${offHour}&offMin=${offMin}`;
    var xhttp = new XMLHttpRequest();
    xhttp.open('GET', 'set?' + params, true);
    xhttp.send();
}
Dabei habe ich einen Template-String benutzt, siehe z. B. hier:
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Richi

Sempervivum

Senior HTML'ler
18 Oktober 2016
2.096
406
83
67
PS: Da hatte ich noch einen Fehler drin, so ist es richtig:
Code:
    const onHour = splitOnTime[0],
        onMin = splitOnTime[1];
In dem vollständigen Code oben habe ich es auch korrigiert.
 
  • Like
Reaktionen: Richi

Richi

Neues Mitglied
26 September 2020
20
0
1
37
Da ändere ich ja aber den submitVal(), dieser ist aber noch für eine Reihe anderer übergaben zuständig.
Dann müsste ich das eher in meine "timeSave" funktion eintragen,
***SIEHE erster POST letzter Skript Teil***
 

Fips

Neues Mitglied
22 Dezember 2019
19
1
3
36
Wenn ich es mit type="time" mache hab ich zwar ein Zeiteingabe fenster, dies überträgt mir aber die Werte so "12:34".
Nun ist dann die Frage wie man die " : " da wieder weg bekommt da ich die Werte der Stunden und Minuten zum weiter verarbeiten einzeln benötige als "integer". Aktuell muss ich sie mir aus einem "float" in zwei "int" umrechnen.
Mit dem " : " dazwischen will dies nicht klappen
Deswegen verbiegst du dich beim Html & Javascript!

Wo es das Arduino Framework doch so einfach macht.

Beispiel:
C++:
void setup() {
  Serial.begin(115200);
  delay(100);

  String responce = "12:41";
  uint8_t hour = responce.toInt();
  uint8_t minute = responce.substring(3).toInt();
  Serial.println(hour);
  Serial.println(minute);

  String myTime = "16:33";
  myTime.replace(":", "");
  int number = myTime.toInt();
  Serial.println(number);
}

void loop() {}


In meinen Zeitschaltuhren vergleiche ich die aktuelle Zeit mit der Schaltzeit einfach so wie ich sie von der Webseite bekomme.

Pseudocode:
C++:
  struct tm tm;
  String switchTime = "15:09";
  char buf[6];
  sprintf(buf, "%.2d:%.2d", tm.tm_hour, tm.tm_min);
  if (!switchTime.compareTo(buf)) digitalWrite(5, HIGH);


Nebenbei:
Wenn du eh neu bist, in Javascript, fang gar nicht erst mit Ajax an.
Nimm die fetch Api, siehe #14.

Damit ist "nur senden" eine Zeile Code.

fetch('/set?' + name + '=' + val');

Senden und Antwort vom Esp emfangen ab zwei Zeile Code möglich.

const responce = await fetch('/set?' + name + '=' + val');
const json = await responce.json();

Ajax macht nur noch Sinn, wenn du unbedingt die fast ausgestorbenen IE Nutzer mit berücksichtigen musst.
 
  • Like
Reaktionen: Richi

Richi

Neues Mitglied
26 September 2020
20
0
1
37
@Fips
ja diese Zeitschaltuhr kenne ich, das ist also von dir? Echt klasse, dies hat mich ja überhaupt erst auf die Idee gebracht in mein Projekt überhaupt soetwas einzubauen.
Ich bin noch lange kein Crack in sachen Arduino und ESP und noch ganz weit weg von Java und HTML.
Ich wollte eigentlcih nur eine kleine Lichterkette realisieren wozu ich aus Leistungsgründen auf einen ESP umsteigen musste darüber bin ich überhaupt erst auf die ganze WebInterface sache gekommen und da nutze ich ebenfalls nur eine vorgefertigte Seite aus einem Beispiel Sketch.
Die Lib nennst sich "ws2812fx" und dort unter Examples das "esp8266_webinterface". Darauf baue ich auf.
Allerdings scheint dieses Beispiel im Code ebenfalls nicht besonders gut zu sein. Da es im APMode beim ESP ständig reboots und Speicher Zugriffsfehler erzeugt. Aber da kenne ich mich ebenfalls garnicht aus und versuche das beste draus zu machen.
Ich werd mich aber mit deinen Code Beispielen mal auseinander setzten und versuche ihn zu implementieren.
DANKE nochmals
 

Richi

Neues Mitglied
26 September 2020
20
0
1
37
@Fips

anTimeH = server.arg(i).toInt();
anTimeM = server.arg(i).substring(3).toInt();

Damit hab ich es nun ganz simpel geschafft meine Zeiten zu zerlegen.
Was mir so ärger gemacht hat war das "c_str()" wo ich einfach nicht zuordnen konnte.
Jetzt weis ich das der mir die ganzen const char Fehler erzeugt hat.
Jetzt hab ich jeweils die Zahlen in passenden Wert ohne rumzurechnen. DANKE


Was ich aber hier nicht verstehe:
Pseudocode:
C++:
struct tm tm;
String switchTime = "15:09";
char buf[6];
sprintf(buf, "%.2d:%.2d", tm.tm_hour, tm.tm_min);
if (!switchTime.compareTo(buf)) digitalWrite(5, HIGH);

Ich bekomme meine Zeit im Format "HH:MM" von der LIB "NTPCClient" über die funktion "timeClient.getFormattedTime()",
Ursprünglich hat er sie mir so übergeben "HH:MM:SS", dies hab ich aber direkt in der LIB auf "HH:MM" gekürzt.Wie muss ich die nun in deinen Code Teil einbinden?

C++:
struct tm tm;     //<--- was macht das?
//String switchTime = "15:09";      <--wie übergeb ich die Zeit aus dem timeClient?
String switchTime = timeClient.getFormattedTime();   //<-- beim einsetzen bringt er mir Fehler "error: crosses initialization of  'String switchTime' "
// der timeClient sendet es mir so "return hoursStr + ":" + minuteStr;"   <--- wie bekomm ich das in den switchTime String?
char buf[6];
sprintf(buf, "%.2d:%.2d", tm.tm_hour, tm.tm_min);
if (!switchTime.compareTo(buf))[S] digitalWrite(5, HIGH);[/S] //<--- ich schallte keinen ausgang sondern
//verweise in ein Menü, wenn die Zeit passt muss ich "menu = lastrun;" übergeben wenn nicht "menu = 66;"


wie vergleicht du mit diesem Code ob du in der Zeit liegst?
Wenn ich zB:
"anZeit 12:34" & "ausZeit 14:45" Einstelle
Muss ich doch vergleichen, liege ich bereits IN diesem Wert oder nicht.
Klar wäre es einfach nur die Zeiten zu vergleichen und dann zu Aktivieren/Deaktivieren wenn sie übereinstimme
aber wenn ich es Aktiviere wärend ich in dem Bereich bin, startet es ja nicht.
Ich habe dazu eine StateMachine erstellt (meine erste), diese hat aber noch zwei kleine Logik fehler.
 
Zuletzt bearbeitet: