Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. [gelöst] on Funktion u.Daten Array nimmt immer letzten Wert

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    [gelöst] on Funktion u.Daten Array nimmt immer letzten Wert

    This topic has been deleted. Only users with topic management privileges can see it.
    • Codierknecht
      Codierknecht Developer Most Active @haus-automatisierung last edited by Codierknecht

      @haus-automatisierung sagte in on Funktion und Daten Array nimmt immer letzten Wert...:

      Das ist Quatsch so

      Was ist Quatsch?
      Ein Array wird nach meinem Kenntnisstand mit eckigen Klammern notiert.
      In diesem Fall ein Array mit Objekten.

      Wo ist da mein Denkfehler?

      haus-automatisierung 1 Reply Last reply Reply Quote 0
      • haus-automatisierung
        haus-automatisierung Developer Most Active @Codierknecht last edited by

        @codierknecht sagte in on Funktion und Daten Array nimmt immer letzten Wert...:

        Wo ist da ein Denkfehler?

        Dass es dann so aussehen müsste.

        const datenpunkt = [
            {
                id_wert : 'shelly.1.SHPLG-S#C38D1F#1.Relay0.Energy'/*Energy*/,
                name    : 'ScooterCharger'
            },
            {
                id_wert : 'shelly.1.SHPLG-S#B529B7#1.Relay0.Energy'/*Energy*/,
                name    : 'editPC'
            }
        ];
        

        Aber ist schon okay wie es war. Nur ist dann ein Objekt und kein Array. Das war aber eh nicht die Fragestellung.

        1 Reply Last reply Reply Quote 0
        • Ro75
          Ro75 @etv last edited by

          @etv versuche es mal so:

          const arrayListe1 = ['shelly.1.SHPLG-S#C38D1F#1.Relay0.Energy','shelly.1.SHPLG-S#B529B7#1.Relay0.Energy'];
          
          on({id: arrayListe1, change: 'ne'}, function (dp) {
              for(let i = 0; i < arrayListe1.length; i++) {
                  console.log(getState(arrayListe1[i]).val);
              }
          });
          

          Ro75.

          Codierknecht 1 Reply Last reply Reply Quote 0
          • haus-automatisierung
            haus-automatisierung Developer Most Active last edited by

            Ich würde generell die Stuktur von datenpunkte überdenken. Da sind ja redundante Informationen drin. z.B. die Objekt-ID als Key nutzen. Dann kann man darin noch weitere Attribute speichern (falls nötig) und kommt auch leichter an die Meta-Daten:

            const datenpunkt = {
                'shelly.1.SHPLG-S#C38D1F#1.Relay0.Energy': {
                    name: 'ScooterCharger'
                },
                'shelly.1.SHPLG-S#B529B7#1.Relay0.Energy': {
                    name: 'editPC'
                },
            };
             
            // Init
            for (const objId in datenpunkt) {
                on({ id: objId, change: 'ne' }, (obj) => {
                    const name = datenpunkt[obj.id].name;
            
                    fn_akumuliere(obj.state.val, name);
                    log('====================================' + name);
                });
            }
            
            // ...
            
            etv 1 Reply Last reply Reply Quote 1
            • Codierknecht
              Codierknecht Developer Most Active @Ro75 last edited by Codierknecht

              Hier stand jetzt tatsächlich Quatsch 😁

              1 Reply Last reply Reply Quote 0
              • etv
                etv @haus-automatisierung last edited by etv

                @haus-automatisierung , der "doppelte Name" stand da bei meinem x'ten Versuch drinnen, weil ich irgendwie den Namen nicht mehr rausbekommen hab - den brauch ich unten aber, um die richtigen Ordner der Daten zu erreichen.

                @Ro75, das reicht leider nicht, da ich eben dann weiter unten meine Daten in den einzelnen id's zugeordnete Ordner speichere - dazu brauch ich aber eben den Namen des auslösenden Objektes und zwar in "Reinschrift" = mein vergebener Name, sonst hab ich nur mehr Ordner mit shelly.1.SHPLG-S#B529BXXX und keine Ahnung, wo ich dann welchen Verbrauch sehe...

                Die Variablen Definition mit const hat leider nix gebracht.

                Hier nochmal der Code den ich aktuell hab, ohne die "verwirrenden Zeilen"

                var root = '0_userdata.0.Logging.Kleinverbraucher.';
                var datenpunkt={
                    'ScooterCharger':{
                        id_wert : 'shelly.1.SHPLG-S#C38D1F#1.Relay0.Energy'/*Energy*/,
                        name    : 'ScooterCharger'
                    },
                    'editPC':{
                        id_wert : 'shelly.1.SHPLG-S#B529B7#1.Relay0.Energy'/*Energy*/,
                        name    : 'editPC'
                    }
                };
                
                // Init
                for (was in datenpunkt) {
                    on({id: datenpunkt[was].id_wert, change:'ne'}, function (obj) {
                        helper = obj.state.val; // der neue gelesene Wert aus dem shelly
                        was = datenpunkt[was].name; // welcher Shelly hat ausgelöst als Klarname - das ist eben im Hauptteil NICHT mehr richtig vorhanden, sondern IMMER "editPC"
                        fn_akumuliere(helper, was);
                })};
                
                // Hauptteil
                function fn_akumuliere(obj, was) {
                 
                    if (debug){log('========== Update ausgelöst von '+ was +'...')}
                    neuer_Wert = obj; // der neue gelesene Wert aus dem shelly
                    alter_Wert = getState(root+was+'.internal_counter').val; // hier wird eben aus dem WAS Klarnamen der richtige Datenspeicher Ordner des jeweiligen Shelly ausgewählt
                    if (debug){log('========== alter Wert: '+ alter_Wert)}
                    if (debug){log('========== neuer Wert: '+ neuer_Wert)}
                    diff = neuer_Wert - alter_Wert; // macht da jetzt augenscheinlich keinen Sinn, wird aber zum Abfangen eines reset des shelly Wertes verwendet, z.B. wenn er ausgesteckt war...
                        if (debug){log('========== Differenz '+ diff +' wird addiert...')}
                        helper = getState(root+was+'.1-DAY').val;
                        setState(root+was+'.1-DAY', (helper + diff), true);
                }; // Ende Function / Hauptteil
                

                Wie gesagt, das Problem ist, dass es IMMER im Ordner

                0_userdata.0.Logging.Kleinverbraucher.editPC.1-DAY
                

                gespeichert wird, auch wenn der ScooterCharger ausgelöst hat, also "verliere" ich irgendwo die Verbindung zwischen auslösendem Objekt und den Zuordnungen im Array (oder wie das da oben auch immer heißen mag...)

                Liebe Grüße
                Tom

                PS: ich verwende diese Arrays öfter, jedoch leider noch nie mit einer ON Funktion gemeinsam...

                Ro75 Codierknecht 2 Replies Last reply Reply Quote 0
                • Ro75
                  Ro75 @etv last edited by Ro75

                  @etv sagte in on Funktion und Daten Array nimmt immer letzten Wert...:

                  das reicht leider nicht, da ich eben dann weiter unten meine Daten in den einzelnen id's zugeordnete Ordner speichere

                  dann eben so:

                  const arrayListe1 = ['shelly.1.SHPLG-S#C38D1F#1.Relay0.Energy','shelly.1.SHPLG-S#B529B7#1.Relay0.Energy'];
                  const arrayListe1DP = ['ScooterCharger','editPC'];
                  
                  on({id: arrayListe1, change: 'ne'}, function (dp) {
                      for(let i = 0; i < arrayListe1.length; i++) {
                          console.log(getState(arrayListe1[i]).val);
                          console.log(getState(arrayListe1DP[i]).val); 
                      }
                  });
                  

                  Ro75.

                  etv 1 Reply Last reply Reply Quote 1
                  • Codierknecht
                    Codierknecht Developer Most Active @etv last edited by Codierknecht

                    @etv sagte in on Funktion und Daten Array nimmt immer letzten Wert...:

                    also "verliere" ich irgendwo die Verbindung zwischen auslösendem Objekt und den Zuordnungen im Array (oder wie das da oben auch immer heißen mag...)

                    Kann ja auch nicht.
                    In der Schleife erzeugst Du zwar einen Trigger für jedes der Objekte. Aber im Trigger selbst ist nur noch das Objekt (bzw. dessen ID) bekannt. Der Bezug zu .name ist da nicht mehr vorhanden.

                    Das Beispiel von @haus-automatisierung behebt diesen Mangel, denn dort hast Du noch immer das Array als Konstante und kannst im Trigger mit datenpunkt[obj.id].name den Namen ermitteln.

                    1 Reply Last reply Reply Quote 1
                    • etv
                      etv @Ro75 last edited by

                      @ro75 ...aja, auch eine sehr gute Idee!

                      etv 1 Reply Last reply Reply Quote 0
                      • etv
                        etv @etv last edited by

                        Ich hab es!!
                        Hab nun in meinen alten Backups ein Script gefunden, welches ich vor Jahren für das automatische EIN/AUS diverse Geräte in Abhängigkeit von Anwesenheit und Helligkeit draußen geschrieben hab (oder von irgendwo hier im Forum zusammen gebastelt...) und in diesem Script mache ich es "richtig rum"...

                        Anbei nun das gesamte Script falls es noch wer "studieren" möchte.

                        // Kleinverbraucher Logging - V1.0 - 07.10.2024
                        // Kopie vom ersten Scrit dieser Art, IONIQ5 Logging...
                        // Teil der neuen Logging Scripte - klein, leicht und auf meine Bedürfnisse zugeschnitten
                        // 2do:::::::::::::::::::::::::::::::::::::::::
                        // createState in der History automatisieren...
                        
                        var debug = true;
                        var root = '0_userdata.0.Logging.Kleinverbraucher.';
                        var was, neuer_Wert, alter_Wert, diff, helper, tag, monat, jahr, wochentag;
                        // WAS soll geloggt werden?
                        const datenpunkt={
                            'ScooterCharger':{
                                id_wert : 'shelly.1.SHPLG-S#C38D1F#1.Relay0.Energy'/*Energy*/
                            },
                            'editPC':{
                                id_wert : 'shelly.1.SHPLG-S#B529B7#1.Relay0.Energy'/*Energy*/
                            }
                        };
                        
                        // Init
                        fn_init();
                        // Funktion initialize für die Subscribes
                        function fn_init() {for (was in datenpunkt) {fn_on_Schleifen(was)}};
                        
                        // Hauptteil
                        function fn_on_Schleifen(was){
                            on({id: datenpunkt[was].id_wert, change:'ne'}, function (obj) {
                                // abfangen von Änderungen kurz nach Mitternacht - da erfolgen ja die ganzen Transfers
                                if (compareTime("00:00", "00:01", "between")){
                                    if (debug){log('========== Update ausgelöst von '+ was +' aber es ist Mitternacht, daher Abbruch')}
                                    return;
                                }
                                if (debug){log('========== Update ausgelöst von '+ was +'...')}
                                neuer_Wert = obj.state.val;
                                alter_Wert = getState(root+was+'.internal_counter').val;
                                if (debug){log('========== alter Wert: '+ alter_Wert)}
                                if (debug){log('========== neuer Wert: '+ neuer_Wert)}
                                diff = neuer_Wert - alter_Wert;
                                // ist diff gleuch Null, dann Abbruch...
                                if (diff === 0) {
                                    if (debug){log('========== Objekt Update ohne Änderung ... exit!')}
                                    return;
                                }
                                // wenn diff negativ ist, dann hat ein reset des Counter stattgefunden
                                // ist es positiv, wird der Wert dazu gezählt
                                if (diff < 0) {
                                    if (debug){log('========== RESET erkannt - Differenz ist negativ: '+ diff)}
                                    // check auf neuer Wert = 0, dann wird 0,00000001 addiert um den INIT abzufangen
                                    if (neuer_Wert === 0){neuer_Wert = 0.0000000001}
                                    setState(root+was+'.internal_counter', neuer_Wert, true);
                                } else {
                                     // check auf alter Wert genau 0 - dann wird dieser Wert gerade zum ersten Mal gelesen....
                                    if (alter_Wert === 0){
                                        if (debug){log('========== INIT erkannt - alter Wert genau 0, daher wurde noch nie ein Wert gelesen/geschrieben.')}
                                        // nun wird ohne Addition der neue Wert im Counter gespeichert
                                        setState(root+was+'.internal_counter', neuer_Wert, true);
                                        return; // und Abbruch, weil wir sind fertig...denke ich...
                                    }
                                    if (debug){log('========== Differenz '+ diff +' wird addiert...')}
                                    helper = getState(root+was+'.1-DAY').val;
                                    setState(root+was+'.1-DAY', (helper + diff), true);
                                    helper = getState(root+was+'.2-WEEK').val;
                                    setState(root+was+'.2-WEEK', (helper + diff), true);
                                    helper = getState(root+was+'.3-MONTH').val;
                                    setState(root+was+'.3-MONTH', (helper + diff), true);
                                    helper = getState(root+was+'.4-YEAR').val;
                                    setState(root+was+'.4-YEAR', (helper + diff), true);
                                    setState(root+was+'.internal_counter', neuer_Wert, true);
                                }
                            }); // Ende on
                        }; // Ende Hauptteil
                        
                        // Tages-/Wochen-/Monats-/Jahreswechsel
                        // läuft jeden Tag um Punkt 00:00:01
                        clearSchedule(sh_Tageswechel);
                        var sh_Tageswechel = schedule('1 0 0 * * *', fn_Tageswechsel);
                        
                        //fn_Tageswechsel();
                        function fn_Tageswechsel(){
                            // erst mal das neue Datum holen UND zwar in eizelnen Variablen
                            tag = formatDate(new Date(), 'TT');
                            monat = formatDate(new Date(), 'MM');
                            jahr = parseInt(formatDate(new Date(), 'YYYY'));
                            wochentag = formatDate(new Date(), 'W');
                            // Start der Schleife für ALLE Datenpunkte in dieser Kategorie
                            for (was in datenpunkt) {
                                log('Schleife START');
                                // nun check auf die ganzen Wechsel, wobei Jahr vor Monat vor Tag
                                // Check auf JAHRESWECHSEL
                                if ((monat == '01') && (tag == '01')){
                                    jahr = jahr - 1;
                                    log('========== JAHRESWECHSEL erkannt: '+datenpunkt[was].id_wert +' ==========');
                                    // 1. Jahresverbrauch in HISTORY schreiben
                                    setState(root+was+'.HISTORY.'+ jahr, getState(root+was+'.4-YEAR').val, true);
                                    // 2. Jahresverbrauch in .BEFORE schreiben
                                    setState(root+was+'.4-YEAR.BEFORE', getState(root+was+'.4-YEAR').val, true);
                                    setState(root+was+'.4-YEAR', 0, true);   
                                } // Ende Jahreswechsel
                                // Check auf MONATSWECHSEL
                                if (tag == '01'){
                                    // if (monat == '01'){jahr = jahr - 1}
                                    helper = parseInt(monat);
                                    helper = helper - 1; // wir brauchen ja den Vormonat
                                    if (helper === 0){helper = 12}
                                    if (helper < 10) {monat = '0' + helper.toFixed(0)}
                                    else {monat = helper.toFixed(0)}
                                    log('========== MONATSWECHSEL erkannt: '+datenpunkt[was].id_wert +' ==========');
                                    // 1. Monatsverbrauch in HISTORY schreiben
                                    setState(root+was+'.HISTORY.'+ jahr +'.' + monat, getState(root+was+'.3-MONTH').val, true);
                                    // 2. Monatsverbrauch in .BEFORE schreiben
                                    setState(root+was+'.3-MONTH.BEFORE', getState(root+was+'.3-MONTH').val, true);
                                    setState(root+was+'.3-MONTH', 0, true);
                                } // Ende Monatswechsel
                                // Check auf Wochenwechsel
                                if (wochentag == 'Mo'){
                                    log('========== WOCHENWECHSEL erkannt: '+datenpunkt[was].id_wert +' ==========');
                                    // 1. Wochenverbrauch in .BEFORE schreiben
                                    setState(root+was+'.2-WEEK.BEFORE', getState(root+was+'.2-WEEK').val, true);
                                    setState(root+was+'.2-WEEK', 0, true);            
                                } // Ende Wochenwechsel
                                // Tageswechsel - der kommt - no na - IMMER dran...
                                setState(root+was+'.1-DAY.BEFORE', getState(root+was+'.1-DAY').val, true);
                                setState(root+was+'.1-DAY', 0, true);
                            } // Ende for-Schleife
                        } // Ende Tages-/Wochen-/Monats-/Jahreswechsel
                        // ENDE Script
                        
                        

                        Im Prinzip das Ersatz Script für den guten alten Betriebsstundenzähler von @looxer01 .
                        Ich hab das Programm geliebt und bis heute in Betrieb, aber es macht mir Sorge, dass immer mehr Fehler im Prorammcode angezeigt werden (rote Wellenlinien) und es irgendwann nicht mehr geht. Viele der Funktionen hab ich in seinem Script nie verwendet - eigentlich hauptsächlich das aufsummieren von Verbräuchen - und so hab ich mir nun das eigene kleine und schlanke Script geschrieben, bevor das alte "absemmelt" 😎

                        Liebe Grüße
                        Tom

                        PS: @Ro75 : für deine Methode hab ich schon einen Anwendungsfall! Danke für diese Idee...

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post

                        Support us

                        ioBroker
                        Community Adapters
                        Donate

                        543
                        Online

                        31.8k
                        Users

                        80.0k
                        Topics

                        1.3m
                        Posts

                        javascript
                        4
                        14
                        497
                        Loading More Posts
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes
                        Reply
                        • Reply as topic
                        Log in to reply
                        Community
                        Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                        The ioBroker Community 2014-2023
                        logo