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

Starthilfe bei Code Erweiterung.

-Nicole-

Neues Mitglied
Guten Tag zusammen,

ich bin die Neue :smile:

Leider habe ich auch gleich mein erstes Problem.
Ich hoffe das mir ein Profi von Euch weiter helfen kann.

Um was geht es genau ?
Ich habe aus dem Internet eine Zeitschaltuhr die ich von 2 auf 3 Relais erweitern muss.
Soweit funktioniert auch alles, bis auf das aktualisieren der Zeiten im Tab Relais 3.

Bedeutet, wenn man auf das Tab Relais 3 drückt kann ich keine Zeiten sehen !
Bei Tab 1 und 2 funktioniert es ohne Fehler.
Was genau mache ich falsch ?


Code:
<!DOCTYPE HTML> <!-- For more information visit: https://fipsok.de -->
<html lang="de">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="style.css">
    <title>Dual Zeitschaltuhr</title>
    <style>
      main, #bu, .tab button, input:checked + label {
        color: #15dfdf;
      }
      div {
        display: flex;
      }
      span {
        padding: 0.5em;
      }
      input {
        height: auto;
        font-weight: bold;
      }
      label {
        font-size: .9em;
      }
      svg {
        height: 4em;
      }
      * + [id*=ak]{
        margin-top: .6em;
      }
      div+span {
        margin-left: 3em;
      }
      input + label {
        color: #777;
        font-style: italic;
      }
      #tog0,#tog1,#tog2 {
        margin: .7em 1.2em;
        cursor: pointer;
        color: #777;
      }
      time {
        text-shadow: 2px 2px 2px black;
        font-size: 1.3em;
        font-weight: bold;
        margin: auto;
      }
      .note:after {
        content: "Schaltzeiten gespeichert";
        color: #777;
      }
      #bu {
        background-color: #333;
        border: outset #555;
      }
      .tab {
        overflow: hidden;
      }
      .tab button {
        background-color: #999;
        border: none;
        margin-top: 0em;
        transition: 0.8s;
        border-top-right-radius: .5em;
        border-top-left-radius: .5em;
      }
      .tab button:hover {
        background-color: #666;
      }
      .tab button.active {
        background-color: #333;
      }
      .tabcontent {
        display: none;
        padding: .5em .7em .5em .1em;
        box-shadow: 5px 3px 10px #4e4d4d;
        background-color: #333;
      }
      .tabcontent input {
        background-color: inherit;
        font-size: 3em;
        color: inherit;
        border: solid #555;
      }
      .tabcontent [name^=bu] {
        width: 2em;
        cursor: pointer;
      }
      .none {
        color: #777 !important;
      }
      @media only screen and (max-width: 600px) {
        .tabcontent input,input {
          font-size: 2.4em;
          width: auto;
          border: none;
        }
        .tab button,#bu {
          width: 7em;
        }
        #tog1,#tog2, {
          margin: .7em .9em 0 1.2em;
        }
        div+span {
          margin-left: .2em;
        }
      }
    </style>
    <script>
      var count = 10;                    <!-- Anzahl Schaltzeiten (analog Sketch) einstellen 2 bis 40 -->
      var d = document;
      d.addEventListener('DOMContentLoaded', () => {
        dom(), renew();
        d.querySelector('#bu').addEventListener('click', () => {
          let arr = [], formData = new FormData();
          formData.append('sTime', Array.from(d.querySelectorAll('input[type=time]')).map(x => x.value != 0 ? x.value : 0));
          for (let i = 0; i < count; i++) {
            let x = 0;
            d.querySelectorAll(`input[name=c${i}]`).forEach((el, i) => { if (el.checked) x = x | (1 << i) });
            arr.push(x);
          }
          formData.append(`sDay`, arr);
          send(formData);
        });
        d.querySelector('#tab1').addEventListener('click', openTab);
        d.querySelector('#tab2').addEventListener('click', openTab);
        d.querySelector('#tab3').addEventListener('click', openTab);
        d.querySelector('#tog0').addEventListener('click', renew);
        d.querySelector('#tog1').addEventListener('click', renew);
        d.querySelector('#tog2').addEventListener('click', renew);
        for (var i = 0; i < count;) d.querySelector(`[name=bu${i++}]`).addEventListener('click', setActive);
      },send(), setInterval(renew, 1000));
      function dom() {
        var buf = '';
        for (var i = 0; i < count*2; i++) {
          buf += `${i%2 ? `<span> -- </span>` : `<div id="ak${i/2}"><span name="bu${i/2}"></span>`}<input type="time" name="sz${i}" value="">${i%2 ? `</div><span id="t${i/2|0}">` : ""}`;
          if (i%2) {
            ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'].forEach(v => {
              buf += `<input type="checkbox" name="c${(i-1)/2}"><label>${v} </label>`;
            });
            buf += "</span>";
          }
          if (i == (count%2 ? count : count-1)) {
            d.querySelector('#ctab1').insertAdjacentHTML('beforeend', buf);
            buf = '';
          }if (i == count*2-1) d.querySelector('#ctab2').insertAdjacentHTML('beforeend', buf);
        }
      }
      function setActive() {
        let formData = new FormData();
        formData.append(this.parentNode.id.substr(2, 5), this.textContent == 'ON' ? '0' : '1');
        send(formData);
      }
      function send(arg) {
        fetch('/timer', {
          method: 'post',
          body: arg
        }).then(resp => {
          if (resp.ok) {
            if(arg && arg.has('sTime'))  {
              let el = d.querySelector('u').classList;
              el.add('note');
              setTimeout(() => {
                el.remove('note');
              }, 5e3);
            }
          }
          return resp.json();
        }).then(array => {
          if (array.length > count) {
            array.forEach((v, i) => {
              if (i < count*2) d.querySelector(`[name=sz${i}]`).value = v;
              if (i == count*2) getActive(v);
              if (i > count*2) {
                let el = d.getElementsByName(`c${i - count * 2 - 1}`);
                for (let k in el) {
                  v & (1 << k) ? el[k].checked = true : el.checked = false;
                }
              }
            });
          }
          else {
            getActive(array);
          }
        });
      }
      function getActive(arg) {
          for (var i = 0; i < count; i++) {
          d.querySelector(`[name=bu${i}]`).textContent = (arg[i]%2 ? 'ON' : 'OFF');
          let el = d.getElementById(`ak${i}`).classList;
          arg[i]%2 ? el.remove("none") : el.add("none");
          d.getElementById(`t${i}`).childNodes.forEach(v => {arg[i]%2 ? v.classList.remove("none") : v.classList.add("none")});
        }
      }
      function openTab() {
        let a = event.target.id.charAt(3)%2+1;
        d.getElementById(`ctab${a}`).style.display = "none";
        d.getElementById(`tab${a}`).classList.remove("active");
        d.getElementById('c' + event.target.id).style.display = "block";
        event.target.classList.add("active")
      }
      function renew(ev) {
        if (ev) ev = ev.currentTarget.id.slice(3, 4);
        fetch(`timer?tog=${ev}`).then(resp => {
          return resp.json();
        }).then(array => {
          for (var i = 0; i < 2; i++) {
            d.getElementById(`color${i}`).style.fill=array[i] == 0 ? '' : '#ff0';
            d.getElementById(`on${i}`).style.visibility=array[i] == 0 ? 'hidden' : 'visible';
          }
          d.querySelector('time').innerHTML = array[2];
        });
      }
    </script>
  </head>
  <body>
    <h2>Zeitschaltuhr</h2>
    <main>
      <div class="tab">
        <button class="button active" id="tab1">⏳ Relais 1</button>
        <button class="button" id="tab2">⏳ Relais 2</button>
        <button class="button" id="tab3">⏳ Relais 3</button>
        <time>00:00:00</time>
      </div>
      <div id="ctab1" class="tabcontent" style="display: block;">
      </div>
      <div id="ctab2" class="tabcontent">
     </div>
      <div id="ctab3" class="tabcontent">
      </div>
      </div>
    </main>
    <div>
      <button class="button" id="bu">⏰ Speichern</button>
      <div id="tog0">
        R1
        <svg viewBox="0 0 486 486">
          <g id="color0">
            <use xlink:href="#body"/>
            <use id="on0" xlink:href="#beam"/>
          </g>
        </svg>
      </div>
      <div id="tog1">
        R2
        <svg viewBox="0 0 486 486">
        <g id="color1">
          <use xlink:href="#body"/>
          <use id="on1" xlink:href="#beam"/>
      </g>
          </svg>
        </div>
        <div id="tog2">
          R3
          <svg viewBox="0 0 486 486">
     <g id="color2">
            <use xlink:href="#body"/>
            <use id="on2" xlink:href="#beam"/>
          </g>
        </svg>
      </div>
    </div>
    <u></u>
    <svg style="display: none;">

    </svg>
  </body>
</html>

Ich glaube ich muss in diesem Bereich noch das ctab 3 einfügen.

Code:
if (i == (count%2 ? count : count-1)) {
            d.querySelector('#ctab1').insertAdjacentHTML('beforeend', buf);
            buf = '';
          }if (i == count*2-1) d.querySelector('#ctab2').insertAdjacentHTML('beforeend', buf);
        }
      }

Leider weiß ich es aber nicht genau.

Es wäre sehr nett wenn mir jemand von Euch sagen könnte was ich falsch mache.

Vielen Dank im Voraus
Nicole
 
Werbung:
Hallo Sempervivum,

vielen Dank :smile:

Hier mal der Link zum gesamten Code.
Bitte etwas runter Scrollen da ist der ganze Code zu finden.
Code

Meiner Meinung nach ist mein Problem in der index.html Datei.
Ich versuche schon sehr lange das ganze zu ändern, leider habe ich es nicht geschafft.

Ich hoffe Ihr könnt mir weiter helfen.

Vielen Dank für eure Mühe.
 
Werbung:
Hmm,

ich kann keinen Pfeil finden bzw. sehen :confused:
Du meinst schon ganz oben bei meinem Ersten Beitrag im Code ?
 
Hallo,

entschuldigung das es etwas gedauert hat.

Ich habe das ganze jetzt so getestet wie Du es mir gesagt hast.
Nur leider kann ich nicht wirklich etwas feststellen.

Wenn ich oben auf die Tabs klicke, sehe ich in der Console keine Änderung.
Eine Änderung ist nur zu sehen, wenn ich unten auf die Lampen klicke.
Dann kommt in der Console eine 1 für Relais an oder eine 0 für Relais aus.

Oder muss ich etwas anderes Testen ?
 
Werbung:
Danke für deine Mühe,

es ist richtig es ist schon ein Aufwand das ganze zu erweitern !

Die ganzen anderen Code Bereiche habe ich ja schon geändert und es funktioniert ohne Fehler.
Mein Problem liegt nur im index.html Bereich.

Weshalb bist Du dir eigentlich so sicher, dass der Fehler nicht hier liegen kann ?

Code:
if (i == (count%2 ? count : count-1)) {
            d.querySelector('#ctab1').insertAdjacentHTML('beforeend', buf);
            buf = '';
          }if (i == count*2-1) d.querySelector('#ctab2').insertAdjacentHTML('beforeend', buf);
        }
      }

Hier ist #ctab1 und #ctab2 zu finden aber #ctab3 fehlt !
Wenn ich #ctab2 gegen #ctab3 tauche kann ich die Zeiten im #ctab2 nicht mehr sehen dafür aber in #ctab3.

Somit denke ich das das Problem hier liegt.
Nur weis ich leider nicht wie ich das #ctab3 richtig mit einbinde?

Ich habe deine Änderungen getestet, leider ist immer noch nichts zu sehen wenn ich oben auf die taps klicke.
Jetzt ist aber etwas zu sehen, wenn ich unten auf Speichern klicke.
Wenn ich die Uhrzeit 20.00 Einstelle und auf Speichern drücke gibt er mir das so im Log aus "20.00".
 
Zuletzt bearbeitet:
Ja, ich habe das Script erweitert !

Jetzt ist es möglich das Relais über die dritte Lampe unten zu schalten.
Aber auch hier kann man beim schalten nur eine 0 oder 1 sehen.

Wie die Daten aussehen wissen wir ja bereits entweder 0 für aus oder 1 für an.
 
Das tab3 ( Relais 3) und auch unten die dritte Lampe für Relais 3 wird bei mir richtig angezeigt.
Es geht rein um die Schaltzeiten diese kann ich bei Relais 3 nicht sehen und auch nicht einstellen.

Wenn Du den Code von ganz oben kopierst und speicherst und mit dem Browser aufrufst siehst Du sofort den Fehler wenn du die 3 Tabs oben durch klickst.

Bei tab1, tab2 funktioniert es wie es sein soll, bei tab3 sind die Schaltzeiten nicht zu sehen.
 
Werbung:
Erst einmal vielen Dank für deine Mühe !

Du hast recht, jetzt funktioniert es schon etwas besser.
Aber leider hat er uns jetzt andere Sachen zerschossen.

Du hast ja ganz schön viel geändert wie ich gesehen habe o_O
Was hat er uns zerschossen ?

Speichern funktioniert jetzt nicht mehr.
Unter tab1 sind nur noch einzelne Schaltzeiten zu finden.
Unter tab 2 und tab 3 sind keine Schaltzeiten zu sehen.
Vor den Schaltzeiten steh normal ON oder OFF das ist auch weg.

Die Relais unten kann ich aber noch schalten.

Kann ich sonst noch was testen das dir weiter hilft ?
 
Danke für den neuen Code !
Es wird immer besser !

Was funktioniert noch nicht ?

Die Zeiten kann ich jetzt unter tab 1 und tab 2 sehen unter tab 3 nicht.
Zusätzlich sind die Zeiten ausgeblendet, sie sind da aber Grau normal sind diese ja hervorgehoben und farbig.
Die On/OFF Funktion wo man die einzelnen Zeiten an der linken Seite an oder aus machen kann sind da aber man kann diese nicht aktivieren oder deaktivieren.
Der Speicher Button ganz unten ist ohne Funktion.

Was ich noch nicht ganz verstehe ist, warum schreibst Du die Relais Funktion so groß um ?
Die Relais haben ja fehlerfrei funktioniert, es war lediglich die Zeiten Anzeige im tab 3 das Problem.
Ich glaube das es nur ein ganz kleines Problem ist.
An der Relais Funktionen würde ich nichts verändern, da es bestens funktioniert hat.
 
Zuletzt bearbeitet:
Ok, dann ist das verständlich :wink:

Genau, ich meine die Eingabefelder wo bei dir die Minus-Zeichen drin sind.
Unter tab3 sind keine Minus-Zeichen, keine Zahlenwerte und auch ganz vorne das OFF ist nicht zu sehen.
 
Werbung:
Habe es gerade getestet,

leider hat sich absolut nichts verändert :eek:
Alles gleich wie im letzten Code.

Das gibt es doch nicht :confused:
 
Hallo,

danke für deine große Mühe !

Ich habe jetzt nochmals mit dem log getestet.
Folgendes habe ich rausgefunden.

Wenn ich Links auf OFF klicke sagt er mir folgendes im Log.

Code:
[Error] Unhandled Promise Rejection: TypeError: undefined is not a function (near '...array.forEach...')
    (anonyme Funktion) (index.html:175)
    promiseReactionJob

Wenn ich unten auf Speichern klicke sagt er mir folgendes.

Code:
[Error] Failed to load resource: the server responded with a status of 400 (Bad Request) (timer, line 0)

[Error] Unhandled Promise Rejection: SyntaxError: The string did not match the expected pattern.
    (anonyme Funktion)
    promiseReactionJob

Du hast Recht, ich habe es gerade getestet, der ON/OFF-Status ist nicht sichtbar weil er von der Hardware kommt.
Somit ist die Darstellung bei Dir in Ordnung !
 
Beim 400er ist der Request falsch formuliert. Vielleicht fehlt etwas im Header. Dafür gibt es Tools wie Postman.

Außerdem sollten Fehler im Fetch-Request abgefangen werden.

Pattern:
Javascript:
myFunc() {
  return fetch('my-url')
    .then((resp) =>  {
      if (!resp.ok) {
        throw resp.json();
      }
      return resp.json();
    })
    .then(() => {
      // success
    })
    .catch(e => {
      // error
      return e;
    });
}
 
Werbung:
Das würde einen crash verhindern, aber das Problem mit dem bad request nicht lösen.

Was ich an deiner Stelle tun würde: Das Script auseinander nehmen und Stück für Stück neu aufbauen, um zu verstehen, wie es funktioniert.
 
Werbung:
OK, da hatte ich das System mit den Indizes noch nicht richtig verstanden. Und jetzt versucht, zu korrigieren. Versuche, ob dies besser ist:
Code:
        var count = 10;                    // Anzahl Schaltzeiten(analog Sketch) einstellen 2 bis 40
        var nrRelais = 3;
        var d = document;
        var cTabIds = ['#ctab1', '#ctab2', '#ctab3'];
        d.addEventListener('DOMContentLoaded', () => {
            dom(), renew();
            d.querySelector('#bu').addEventListener('click', () => {
                let arr = [], formData = new FormData();
                formData.append('sTime', Array.from(d.querySelectorAll('input[type=time]')).map(x => x.value != 0 ? x.value : 0));
                for (let i = 0; i < count; i++) {
                    let x = 0;
                    d.querySelectorAll(`input[name=c${i}]`).forEach((el, i) => { if (el.checked) x = x | (1 << i) });
                    arr.push(x);
                }
                formData.append(`sDay`, arr);
                send(formData);
            });
            d.querySelector('#tab1').addEventListener('click', openTab);
            d.querySelector('#tab2').addEventListener('click', openTab);
            d.querySelector('#tab3').addEventListener('click', openTab);
            d.querySelector('#tog0').addEventListener('click', renew);
            d.querySelector('#tog1').addEventListener('click', renew);
            d.querySelector('#tog2').addEventListener('click', renew);
            for (var i = 0; i < count;) d.querySelector(`[name=bu${i++}]`).addEventListener('click', setActive);
        }, send(), setInterval(renew, 1000));
        function dom() {
            var i = 0;
            for (var iRelais = 0; iRelais < nrRelais; iRelais++) {
                var buf = '';
                for (var iTime = 0; iTime < count; iTime++) {
                    buf += `${i % 2 ? `<span> -- </span>` : `<div id="ak${i / 2}"><span name="bu${i / 2}"></span>`}<input type="time" name="sz${i}" value="">${i % 2 ? `</div><span id="t${i / 2 | 0}">` : ""}`;
                    if (i % 2) {
                        ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'].forEach(v => {
                            buf += `<input type="checkbox" name="c${(i - 1) / 2}"><label>${v} </label>`;
                        });
                        buf += "</span>";
                    }
                    i++;
                }
                d.querySelector(cTabIds[iRelais]).insertAdjacentHTML('beforeend', buf);
            }
        }
        function setActive() {
            let formData = new FormData();
            formData.append(this.parentNode.id.substr(2, 5), this.textContent == 'ON' ? '0' : '1');
            send(formData);
        }
        function send(arg) {
            fetch('/timer', {
                method: 'post',
                body: arg
            }).then(resp => {
                if (resp.ok) {
                    if (arg && arg.has('sTime')) {
                        let el = d.querySelector('u').classList;
                        el.add('note');
                        setTimeout(() => {
                            el.remove('note');
                        }, 5e3);
                    }
                }
                return resp.json();
            }).then(array => {
                if (array.length > count) {
                    array.forEach((v, i) => {
                        if (i < count * 2) d.querySelector(`[name=sz${i}]`).value = v;
                        if (i == count * 2) getActive(v);
                        if (i > count * 2) {
                            let el = d.getElementsByName(`c${i - count * 2 - 1}`);
                            for (let k in el) {
                                v & (1 << k) ? el[k].checked = true : el.checked = false;
                            }
                        }
                    });
                }
                else {
                    getActive(array);
                }
            });
        }
        function getActive(arg) {
            for (var i = 0; i < count; i++) {
                d.querySelector(`[name=bu${i}]`).textContent = (arg[i] % 2 ? 'ON' : 'OFF');
                let el = d.getElementById(`ak${i}`).classList;
                arg[i] % 2 ? el.remove("none") : el.add("none");
                d.getElementById(`t${i}`).childNodes.forEach(v => { arg[i] % 2 ? v.classList.remove("none") : v.classList.add("none") });
            }
        }
        function openTab() {
            for (var i = 0; i < nrRelais; i++) {
                d.getElementById(`ctab${i + 1}`).style.display = "none";
                d.getElementById(`tab${i + 1}`).classList.remove("active");
            }
            d.getElementById('c' + event.target.id).style.display = "block";
            event.target.classList.add("active")
        }
        function renew(ev) {
            if (ev) ev = ev.currentTarget.id.slice(3, 4);
            fetch(`timer?tog=${ev}`).then(resp => {
                return resp.json();
            }).then(array => {
                for (var i = 0; i < 2; i++) {
                    d.getElementById(`color${i}`).style.fill = array[i] == 0 ? '' : '#ff0';
                    d.getElementById(`on${i}`).style.visibility = array[i] == 0 ? 'hidden' : 'visible';
                }
                d.querySelector('time').innerHTML = array[2];
            });
        }

Wie ist dies zu verstehen:
Meinst Du die Darstellung auf der HTML-Seite? Die sieht bei mir einwandfrei aus.
Anhang anzeigen 5414
Es kann jedoch sein, dass im Zusammenspiel mit der Hardware Fehler auftreten und dadurch die Darstellung zerschossen wird.
Hallo, das ist eine sehr schöne SchaltUhr, die ich gerne für meine Wassersteuerung benutzen möchte.
Ich habe mich durch den Code debuged um ihn zu verstehen, was da alles gemacht wird.
War recht aufwendig, hat sich aber gelohnt.
Ich habe die DualSchaltUhr im ersten Schritt auf 3 Schaltkanäle, erfolgreich erweitert.
Für alle die es interessiert, hänge hier mal mein Ergebniss dran.
Ich habe absichtlich alle seriellen debugprints und meine ergänzten Kommentare dringelassen,
damit Andere es auch lesen und verstehen können.
Viel spaß beim benutzen,
über kommentare würde ich mich freuen.
Gruß Mickbaer
 

Anhänge

  • MehrfachSchaltuhr.zip
    102,1 KB · Aufrufe: 6
  • 1.JPG
    1.JPG
    33,2 KB · Aufrufe: 8
  • 2.JPG
    2.JPG
    32,4 KB · Aufrufe: 8
  • 3.JPG
    3.JPG
    34,3 KB · Aufrufe: 8
Hallo in die Runde.
Finde super was Fips da gemacht hat mit der Wochenzeitschaltuhr, mir war aber auch gleich bewusst das 2 Relais für mich auch zu wenig sind. Selber hätte ich das nicht ändern können, deshalb mal google gefragt und das hier gefunden.
Und das hast du Mickbaer super hinbekommen!
Meine frage jetzt mal könntest du vielleicht eine liste machen was du geändert hast, ich bräuchte das mit 8x Relais?
Gruß Mike
 
Zurück
Oben