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

Starthilfe bei Code Erweiterung.

-Nicole-

Neues Mitglied
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:

Sempervivum

Senior HTML'ler
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.
Der Grund ist, dass ich diese komplizierten Berechnungen mit Modulo, Division und Multiplikation nicht verstanden habe und versuche habe, es zu vereinfachen, damit ich es für das dritte Relais erweitern konnte.

Was meinst Du eigentlich, wenn Du von "Zeiten" sprichst. Die Eingabefelder, wo bei mir im Moment Minus-Zeichen drin sind oder die Zahlenwerte, die angezeigt werden?
 

-Nicole-

Neues Mitglied
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.
 

Sempervivum

Senior HTML'ler
So, ich denke, ich habe das mit der Zählung wieder ein Stück besser verstanden und einige Fehler behoben:
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 / 2 * nrRelais; 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 / 2 * nrRelais;) 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 / 2 * nrRelais; 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];
            });
        }
Das ganze ist zwar ziemlich trickreich programmiert, aber für mich schlecht lesbar und änderbar.
 

Sempervivum

Senior HTML'ler
PS: Ich denke, ich habe jetzt auch die Funktion renew verstanden und konnte sie korrigieren:
Code:
        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 < nrRelais; 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[nrRelais];
            });
        }
 

-Nicole-

Neues Mitglied
Habe es gerade getestet,

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

Das gibt es doch nicht :confused:
 

Sempervivum

Senior HTML'ler
Ich habe jetzt das Problem, dass ich die Hardware nicht habe und das meiste nicht testen kann.
Ich hänge noch Mal einen neuen Screenshot mit dem Tab für das dritte Relais an:
zeitschaltuhr2.png
Was ich dort sehe:
Die Zeiten sind bunt.
Der ON/OFF-Status ist nicht sichtbar. Ich vermute, deshalb nicht, weil er von der Hardware kommt.

Kannst Du vielleicht einen Screenshot posten, wie es bei dir aussieht?

Und wir sollten noch Mal einen Versuch mit console.log machen und zwar mit dem renew weil dieses zyklisch statt findet, so dass wir in jedem Fall etwas zu sehen bekommen sollten:
Code:
        function renew(ev) {
            if (ev) ev = ev.currentTarget.id.slice(3, 4);
            fetch(`timer?tog=${ev}`).then(resp => {
                return resp.json();
            }).then(array => {
                console.log(array); // <--
                for (var i = 0; i < nrRelais; 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[nrRelais];
            });
        }

Für mich ist es jetzt spät genug, ich sage gute Nacht!
 

-Nicole-

Neues Mitglied
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 !
 

Tronjer

Senior HTML'ler
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;
    });
}
 

Tronjer

Senior HTML'ler
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.
 

Mickbaer

Neues Mitglied
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

Sempervivum

Senior HTML'ler
Ich hatte die Erweiterung mit Nicole zusammen dann später abgeschlossen. Es waren dann im Endergebnis nur ein oder zwei Konstanten, die man ändern musste, um die Anzahl der Relais zu ändern.
War recht aufwendig, hat sich aber gelohnt.
Bei uns genau so, denn der ursprüngliche Code war leider überhaupt nicht änderungsfreundlich. Und ich hatte die Hardware nicht, so dass ich selber nicht debuggen konnte.
 

Mike_armada

Neues Mitglied
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
 
Werbung:
Oben