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

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

Richi

Neues Mitglied
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)
 
Werbung:
var anTime = document.getElementById("AN").addEventListener(event, this.value);

var anTime = document.getElementById("AN").value;
 
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.
 
Werbung:
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
 
Werbung:
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.
 
Dann dürfte es ja kein Problem sein den String am ":" zu splitten und dann die beiden resultierenden Einzelwerte als Integer zu verarbeiten.
 
Werbung:
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?
 
Code:
function submitVal(name, val) {
  var xhttp = new XMLHttpRequest();
  xhttp.open('GET', 'set?' + name + '=' + val, true);
  xhttp.send();
}
 
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***
 
Werbung:
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.
 
@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
 
@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:
Werbung:
Struct tm enthält in C++ die Kalenderzeit, mit der Suchmaschiene deiner Wahl findest du für was es gut ist.

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.
Das klappt natürlich nicht mit dem Vergleich zweier cstring.
Für die Abfrage ob ich aktuell im Zeitraum bin würde ich mit Integer arbeiten.

Einschaltzeit von der Webseite in ein int umwandeln.
C++:
  String myTime = "12:11";
  myTime.replace(":", "");
  int ein = myTime.toInt();
  Serial.println(ein); // Ausgabe: 1211

Die Abfrage würde dann so aussehen.
C++:
int Uhrzeit = 1216;
int ein = 1211;
int aus = 1255;
if (Uhrzeit >= ein && Uhrzeit < aus) Serial.println("Im Zeitraum");

C++:
#include <ESP8266WiFi.h>
#include <time.h>          // Im EspCore enthalten

const uint32_t SYNC_INTERVAL = 24;                                             // NTP Sync Interval in Stunden einstellen

struct tm tm;

const char* const PROGMEM NTP_SERVER[] = {"fritz.box", "de.pool.ntp.org", "at.pool.ntp.org", "ch.pool.ntp.org", "ptbtime1.ptb.de", "europe.pool.ntp.org"};

void setupTime() {                              // deinen NTP Server einstellen (von 0 - 5 aus obiger Liste) alternativ lassen sich durch Komma getrennt bis zu 3 Server angeben
  configTime("CET-1CEST,M3.5.0,M10.5.0/3", NTP_SERVER[1]);  // Zeitzone einstellen https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
}

int localTime() {
  static int zeit;
  static time_t lastsec;
  time_t now = time(&now);
  localtime_r(&now, &tm);
  if (tm.tm_sec != lastsec) {
    lastsec = tm.tm_sec;
    if (!(time(&now) % (SYNC_INTERVAL * 3600))) {
      setupTime();
    }
    zeit = tm.tm_hour * 100 + tm.tm_min;
  }
  return zeit;
}

const char* ssid = "Netzwerkname";             // << kann bis zu 32 Zeichen haben
const char* password = "PasswortvomNetzwerk";  // << mindestens 8 Zeichen jedoch nicht länger als 64 Zeichen

void setup() {
  Serial.begin(115200);
  Serial.println();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  setupTime();
}

void loop() {
  int ein = 839;
  int aus = 1255;
  static uint32_t previousMillis;
  uint32_t currentMillis {millis()};
  if (currentMillis - previousMillis >= 1000) {
    previousMillis = currentMillis;
    Serial.println(localTime());
    int Uhrzeit = localTime();
    if (Uhrzeit >= ein && Uhrzeit < aus) Serial.println("Im Zeitraum");
  }
}
 
Code:
if (Uhrzeit >= ein && Uhrzeit < aus) Serial.println("Im Zeitraum");
Und genau mit dieser Zeile ist es eben nicht getan bei mir.
Ich hab jetzt eine Woche an einem Messalgorytmus getüftelt um die Zeitformate miteinander zu vergleichen.
Es ich ohne Wochentage Arbeite und natürlich eine Zeitverdrehung geben kann wenn ich zB: die AN Zeit bei 22:34Uhr liegt und die AUS Zeit bei 0:10Uhr dann ist AUS < AN. Das selbe gild ja für die Minutenbereiche, wenn die AN und AUS Stunde gleich ist, auch. Hat mir echt ein wenig Kopfzerbrechen bereitet. Aber heut scheine ich es vollendet bekommen zu haben. Zumindest schaltet er richtig in sämtlichen Zeit Varianten.
 
Zurück
Oben