Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Tester
  4. Test Adapter shuttercontrol v2.0.x

NEWS

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    8.6k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    13
    1
    2.1k

  • Neues Video "KI im Smart Home" - ioBroker plus n8n
    BluefoxB
    Bluefox
    16
    1
    2.8k

Test Adapter shuttercontrol v2.0.x

Geplant Angeheftet Gesperrt Verschoben Tester
rollladenrollladensteuerungshuttercontrol
7.4k Beiträge 332 Kommentatoren 10.6m Aufrufe 253 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • R rde-master

    Hallo,

    ich hätte noch einen Wunsch:

    Könnte man einen Datenpunkt einbauen, der den Status der Beschattung angibt:

    Beispiel:

    1. Beschalltung ausgeschaltet
    2. Himmelsrichtung nicht erreicht
    3. Helligkeit nicht erreicht
    4. innenTemp nicht erreicht
    5. AusenTemp nicht erreicht
    6. Aussperrschutz aktiv
    7. Beschattung aktiv
      .
      .
      .

    Ich frage mich des öfteren, warum jetzt die Beschattung nicht gefahren ist,... und muss dann immer alle Werte kontrollieren.... hier wäre es toll, wenn ich das auf einen Blick sehen könnte...

    Grüße Daniel

    RöstkartoffelR Offline
    RöstkartoffelR Offline
    Röstkartoffel
    schrieb am zuletzt editiert von
    #2392

    @rde-master sagte in Test Adapter shuttercontrol v1.0.x:
    ...

    Ich frage mich des öfteren, warum jetzt die Beschattung nicht gefahren ist,... und muss dann immer alle Werte kontrollieren.... hier wäre es toll, wenn ich das auf einen Blick sehen könnte...

    Grüße Daniel

    geht mir genauso: immer wieder mal die Frage, warum ist die Markise denn jetzt rausgefahren?

    NUC7i3BNH mit Proxmox und ioBroker (VM Debian Buster), Raspi3 (Slave Smartmeter für eHZ easymeter), Hardware CCU2, SMA SB5000TL-21

    1 Antwort Letzte Antwort
    0
    • simatecS simatec

      @lackylacky
      Was genau willst du verzögern?

      L Offline
      L Offline
      lackylacky
      schrieb am zuletzt editiert von
      #2393

      @simatec zuerst, toller adapter von dir, danke!
      ...den Beginn der Beschattung bzw. das Ende der Beschattung!
      aktuell fahren die Jalousien sofort runter wenn an einem bewölkten Tag nur kurz die Sonne raus schaut und ständig rauf/runter wenn an einem schönen Tag kurz Wolken kommen. Hysterese habe ich aktuell auf 50%, diese könnte man noch höher drehen, gilt aber nicht für das runter fahren.
      bis jetzt habe ich über KNX die Beschattung erst aktiviert, wenn zb. für 15min die Sonne herausen ist, selbige für das hochfahren!

      lg.

      HomoranH simatecS A 3 Antworten Letzte Antwort
      0
      • L lackylacky

        @simatec zuerst, toller adapter von dir, danke!
        ...den Beginn der Beschattung bzw. das Ende der Beschattung!
        aktuell fahren die Jalousien sofort runter wenn an einem bewölkten Tag nur kurz die Sonne raus schaut und ständig rauf/runter wenn an einem schönen Tag kurz Wolken kommen. Hysterese habe ich aktuell auf 50%, diese könnte man noch höher drehen, gilt aber nicht für das runter fahren.
        bis jetzt habe ich über KNX die Beschattung erst aktiviert, wenn zb. für 15min die Sonne herausen ist, selbige für das hochfahren!

        lg.

        HomoranH Nicht stören
        HomoranH Nicht stören
        Homoran
        Global Moderator Administrators
        schrieb am zuletzt editiert von Homoran
        #2394

        @lackylacky sagte in Test Adapter shuttercontrol v1.0.x:

        wenn zb. für 15min die Sonne herausen ist, selbige für das hochfahren!

        dann musst du auf einen eigenen Datenpunkt triggern, den du über ein Skript/Blockly mit dem Wert befüllst, wenn die Sonne 15 Minuten am Stück scheint, oder einen fließenden Mittelwert über 15 Minuten überschreitet, oder....

        Je nachdem worauf du da gerade reagierst geht das ggf. auch in der Hardware.
        So bieten HomeMatic Bewegungsmelder an, die geringste Helligkeit der letzten x Messungen anzugeben

        kein Support per PN! - Fragen im Forum stellen - es gibt fast nichts, was nicht auch für andere interessant ist.

        Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

        der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

        L 1 Antwort Letzte Antwort
        0
        • HomoranH Homoran

          @lackylacky sagte in Test Adapter shuttercontrol v1.0.x:

          wenn zb. für 15min die Sonne herausen ist, selbige für das hochfahren!

          dann musst du auf einen eigenen Datenpunkt triggern, den du über ein Skript/Blockly mit dem Wert befüllst, wenn die Sonne 15 Minuten am Stück scheint, oder einen fließenden Mittelwert über 15 Minuten überschreitet, oder....

          Je nachdem worauf du da gerade reagierst geht das ggf. auch in der Hardware.
          So bieten HomeMatic Bewegungsmelder an, die geringste Helligkeit der letzten x Messungen anzugeben

          L Offline
          L Offline
          lackylacky
          schrieb am zuletzt editiert von
          #2395

          @Homoran ja richtig, daß mache ich gerade aktuell, bekomme ja die Verzögerung der Beschattung von der KNX Wetterstation und schreibe diesen Wert in den Helligkeitswert vom Adapter, aber eben nur 0/1... funktionieren tut es so auch, aber ist halt nicht die elegante Art! ;)

          1 Antwort Letzte Antwort
          0
          • L lackylacky

            @simatec zuerst, toller adapter von dir, danke!
            ...den Beginn der Beschattung bzw. das Ende der Beschattung!
            aktuell fahren die Jalousien sofort runter wenn an einem bewölkten Tag nur kurz die Sonne raus schaut und ständig rauf/runter wenn an einem schönen Tag kurz Wolken kommen. Hysterese habe ich aktuell auf 50%, diese könnte man noch höher drehen, gilt aber nicht für das runter fahren.
            bis jetzt habe ich über KNX die Beschattung erst aktiviert, wenn zb. für 15min die Sonne herausen ist, selbige für das hochfahren!

            lg.

            simatecS Offline
            simatecS Offline
            simatec
            Developer Most Active
            schrieb am zuletzt editiert von
            #2396

            @lackylacky
            ich halte immer eine Kombi aus Lichtsensor, Außentemperatur und Innentemperatur für sinnvoll

            • Besuche meine Github Seite
            • Beitrag hat geholfen oder willst du mich unterstützen
            • HowTo Restore ioBroker
            L 1 Antwort Letzte Antwort
            0
            • simatecS simatec

              @lackylacky
              ich halte immer eine Kombi aus Lichtsensor, Außentemperatur und Innentemperatur für sinnvoll

              L Offline
              L Offline
              lackylacky
              schrieb am zuletzt editiert von
              #2397

              @simatec das habe ich mit diesem Adapter jetzt auch realisiert, ändert aber nix bei wechselnder Bewölkung.

              1 Antwort Letzte Antwort
              0
              • L lackylacky

                @simatec zuerst, toller adapter von dir, danke!
                ...den Beginn der Beschattung bzw. das Ende der Beschattung!
                aktuell fahren die Jalousien sofort runter wenn an einem bewölkten Tag nur kurz die Sonne raus schaut und ständig rauf/runter wenn an einem schönen Tag kurz Wolken kommen. Hysterese habe ich aktuell auf 50%, diese könnte man noch höher drehen, gilt aber nicht für das runter fahren.
                bis jetzt habe ich über KNX die Beschattung erst aktiviert, wenn zb. für 15min die Sonne herausen ist, selbige für das hochfahren!

                lg.

                A Offline
                A Offline
                andi2055
                schrieb am zuletzt editiert von andi2055
                #2398

                @lackylacky
                ich nutze für Temperaturen und Sonne jeweils einen Mittelwert von 15 Min und zusätzlich beim Sonnenschutz eine Hysterese von 70%. Funktionierte den ganzen Sommer für mich einwandfrei. Kein unnötiges Hoch- oder Runterfahren.

                Anbei das Script falls das jemand benötigt. Hier aus dem Forum, etwas angepasst durch mich

                // https://forum.iobroker.net/topic/1037/gleitender-durchschnitt-min-max-%C3%BCber-def-zeitraum/82
                // ########################################################################################################
                // Berechnung von gleitendem Durchschnitt, Minimum und Maximum über einen Zeitraum
                // Version 1.4.1
                // ########################################################################################################
                "use strict";
                const idTable = '0_userdata.0.JavaScript.GleitMittelwert.Tabelle'; 
                createState(idTable, '', {type: 'string'});
                //
                //
                //
                // Berechnet Min/Max, Durchschnitt und Median über die letzten 24h.
                // Berechnet Min/Max, Durchschnitt über die letzte 1h.
                //
                // IDs aller benötigten Datenpunkte
                //
                // Als Array im Array mit folgendem Format:
                //  1\.   original Datenpunktname
                //  2\.  neuer Datenpunktname
                //         Beispiel:   javascript.0.Status.Temperatur.Außen
                //                  javascript.0.Status.Luftfeuchtigkeit.Außen
                //  3\.   Beschreibung des Messwertes (zur Erzeugung neue Datenpunkte)
                //         Beispliele:   Temperatur
                //                  Luftfeuchtigkeit
                //   4\.  Einheit (zur Erzeugung neue Datenpunkte)
                //         Beispiele:   °C, %
                //
                //   5\.  Anzahl Nachkommastellen
                //         Beispiele:   0 oder 1 oder 2
                //
                // Ist beliebig erweiterbar und für beliebige Werte nutzbar.
                // Beispiel 1:
                // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Temperatur.Außen','Temperatur','°C'],
                //                 ['hm-rpc.3.CUX9002580.1.HUMIDITY'   ,'javascript.0.Status.Luftfeuchtigkeit.Außen','Luftfeuchtigkeit','%']];
                //
                // Beispiel 2:
                // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Außen.Temperatur','Temperatur','°C'],
                //                 ['hm-rpc.3.CUX9002580.1.HUMIDITY'   ,'javascript.0.Status.Außen.Luftfeuchtigkeit','Luftfeuchtigkeit','%'],
                //                 ['hm-rpc.3.CUX4007637.1.Data'   ,'javascript.0.Status.Außen.Lichtstärke','Lichtstärke','lux']];
                //
                const idData = [['linkeddevices.0.Aussen.KNX_Temperatur','0_userdata.0.Außen.Temperatur','Temperatur','°C',1],
                                ['alias.0.Außen.Helligkeit_links','0_userdata.0.Außen.Helligkeit_links','Helligkeit','L',0],
                                ['alias.0.Außen.Helligkeit_mitte','0_userdata.0.Außen.Helligkeit_mitte','Helligkeit','L',0],
                                ['alias.0.Außen.Helligkeit_rechts','0_userdata.0.Außen.Helligkeit_rechts','Helligkeit','L',0],
                                ['linkeddevices.0.OG.Flur_Temperatur','0_userdata.0.OG.Flur_Temperatur','Temperatur','°C',1],
                                ['linkeddevices.0.EG.Wohn_Temperatur','0_userdata.0.EG.Wohn_Temperatur','Temperatur','°C',1],
                                ['linkeddevices.0.KG.Arbeit_Temperatur','0_userdata.0.KG.Arbeit_Temperatur','Temperatur','°C',1]
                                ];
                 
                //Datenpunkt zur Speicherung aller internen Daten
                const dpData='0_userdata.0.JavaScript.GleitMittelwert.Statistic';
                 
                // ########################################################################################################
                // Implementierung -- hier nichts mehr ändern
                // ########################################################################################################
                 
                // globale Konstanten
                const tc = 3;         // Abtastrate in Minuten
                 
                const statDataLength24 = Math.round((24 * 60) / tc); // Anzahl der Werte für 24h
                const statDataLength1 = Math.round(60 / tc); // Anzahl der Werte für stündlich
                const statDataLength15 = Math.round(15 / tc); // Anzahl der Werte für 15 Min
                 
                // globale Variablen
                var listStatData;  //interne Speicherung aller Werte
                 
                //Funktion zum einmaligem initialisieren aller Datenpunkte
                function initializeStatData() {
                 
                   // Datenpunkt zur Speicherung der internen Werte erzeugen
                   createState(dpData, 0, false, {
                      name: "StatisticData",
                      read: true,
                      write: true,
                      desc: 'Statistische Daten',
                      type: 'string',
                      def: '',
                      role: 'json'        
                   });
                 
                   //internes Array initialisieren
                    var needInit = false;
                   try {
                      listStatData = JSON.parse(getState(dpData).val);
                   } catch (ex) {
                      needInit = true;
                   }
                   if (needInit || !listStatData || (listStatData.length < idData.length)) {
                      listStatData = new Array(idData.length); 
                   }
                   //logDebug('initializeStatData for', dpData, listStatData);
                 
                   for (var i = 0; i < idData.length; i++) {
                        if (!listStatData[i]) { listStatData[i] = {}; }
                        listStatData[i].value       = idData[i][1];
                        listStatData[i].max24h		= idData[i][1] + '.Max_24h';
                        listStatData[i].min24h		= idData[i][1] + '.Min_24h';
                        listStatData[i].mean24h		= idData[i][1] + '.Mean_24h';
                        listStatData[i].median24h	= idData[i][1] + '.Median_24h';
                	listStatData[i].max1h		= idData[i][1] + '.Max_1h';
                	listStatData[i].min1h		= idData[i][1] + '.Min_1h';
                	listStatData[i].mean1h		= idData[i][1] + '.Mean_1h';
                 	listStatData[i].max15		= idData[i][1] + '.Max_15';
                	listStatData[i].min15		= idData[i][1] + '.Min_15';
                	listStatData[i].mean15		= idData[i][1] + '.Mean_15';
                
                	createState(listStatData[i].value, 0, false, {
                            name: idData[i][2],
                            read: true,
                            write: true,
                            desc: idData[i][2]+ ' Aktueller Wert',
                      	    type: 'number',
                            def: 0,
                            unit: idData[i][3],
                            role: 'value'
                	});
                 
                	createState(listStatData[i].max24h, 0, false, {
                            name: 'Maximum_24h',
                            read: true,
                            write: true,
                            desc: idData[i][2] + ' Maximum',
                            type: 'number',
                            def: 0,
                            unit: idData[i][3],
                            role: 'value'
                       });
                 
                       createState(listStatData[i].min24h, 0, false, {
                            name: 'Minimum_24h',
                            read: true,
                            write: true,
                            desc: idData[i][2] + ' Minimum',
                            type: 'number',
                            def: 0,
                	    unit: idData[i][3],
                            role: 'value'
                       });
                 
                       createState(listStatData[i].mean24h, 0, false, {
                            name: 'Mittelwert_24h',
                            read: true,
                            write: true,
                            desc: idData[i][2] + ' Mittelwert',
                            type: 'number',
                            def: 0,
                            unit: idData[i][3],
                            role: 'value'
                      });
                 
                      createState(listStatData[i].median24h, 0, false, {
                            name: 'Median_24h',
                            read: true,
                            write: true,
                            desc: idData[i][2] + ' Median',
                            type: 'number',
                            def: 0,
                	        unit: idData[i][3],
                            role: 'value'
                      });
                 
                      createState(listStatData[i].max1h, 0, false, {
                            name: 'Maximum_1h',
                            read: true,
                            write: true,
                            desc: idData[i][2] + ' Maximum',
                            type: 'number',
                            def: 0,
                            unit: idData[i][3],
                            role: 'value'
                      });
                 
                      createState(listStatData[i].min1h, 0, false, {
                            name: 'Minimum_1h',
                            read: true,
                            write: true,
                            desc: idData[i][2] + ' Minimum',
                            type: 'number',
                            def: 0,
                            unit: idData[i][3],
                            role: 'value'
                      });
                 
                      createState(listStatData[i].mean1h, 0, false, {
                            name: 'Mittelwert_1h',
                            read: true,
                            write: true,
                       	    desc: idData[i][2] + ' Mittelwert',
                            type: 'number',
                            def: 0,
                	    unit: idData[i][3],
                	    role: 'value'
                      });
                 
                       createState(listStatData[i].max15, 0, false, {
                            name: 'Maximum_15',
                            read: true,
                            write: true,
                            desc: idData[i][2] + ' Maximum',
                            type: 'number',
                            def: 0,
                            unit: idData[i][3],
                            role: 'value'
                      });
                 
                      createState(listStatData[i].min15, 0, false, {
                            name: 'Minimum_15',
                            read: true,
                            write: true,
                            desc: idData[i][2] + ' Minimum',
                            type: 'number',
                            def: 0,
                            unit: idData[i][3],
                            role: 'value'
                      });
                 
                      createState(listStatData[i].mean15, 0, false, {
                            name: 'Mittelwert_15',
                            read: true,
                            write: true,
                       	    desc: idData[i][2] + ' Mittelwert',
                            type: 'number',
                            def: 0,
                	    unit: idData[i][3],
                	    role: 'value'
                      });
                
                      if (needInit || !listStatData[i].data || (listStatData[i].data.length != statDataLength24)) {
                            listStatData[i].data	= new Array(statDataLength24);
                 
                            // 1\. Script start: Liste und String-Datenpunkt füllen
                            var x = getState(idData[i][0]).val;
                            for (var j = 0; j < statDataLength24; j++) {
                            listStatData[i].data[j] = x;
                         }
                 
                          //logDebug(listStatData[i], i);
                            setStateDelayed(listStatData[i].value, x, false, 1000);
                            setStateDelayed(listStatData[i].min24h, x, false, 1000);
                            setStateDelayed(listStatData[i].max24h, x, false, 1000);
                            setStateDelayed(listStatData[i].mean24h, x, false, 1000);
                            setStateDelayed(listStatData[i].median24h, x, false, 1000);
                            setStateDelayed(listStatData[i].min1h, x, false, 1000);
                            setStateDelayed(listStatData[i].max1h, x, false, 1000);
                            setStateDelayed(listStatData[i].mean1h, x, false, 1000);
                            setStateDelayed(listStatData[i].min15, x, false, 1000);
                            setStateDelayed(listStatData[i].max15, x, false, 1000);
                            setStateDelayed(listStatData[i].mean15, x, false, 1000);
                      }      
                   }
                   setState(dpData, JSON.stringify(listStatData));         
                }
                 
                //Berechnung der Werte
                 function calcStatData() {
                    if (!listStatData || (idData.length != listStatData.length)) {
                         initializeStatData();
                    }
                     //logDebug('starting calcStatData');
                    var table = []; 
                    for (var i = 0; i < idData.length; i++) {
                       var obj = {};
                       var sensor = listStatData[i].value.split('.');
                       obj.Sensor = sensor[4] + ' ' + sensor[3];
                       listStatData[i].data.pop(); //Remove the last element of an array
                       var x = parseFloat(getState(idData[i][0]).val);
                       obj.Wert = x;
                       listStatData[i].data.unshift(x); //Add new items to the beginning of an array
                       setState(listStatData[i].value, x);
                       var min = x;
                       var max = x;
                       var sum = 0.0;
                       for (var j = 0; j < statDataLength24; j++) {
                          var s = parseFloat(listStatData[i].data[j]);
                          if (s < min) min = s;
                          if (s > max) max = s;
                          sum += s;
                          if (j == (statDataLength1-1)) {
                             setState(listStatData[i].min1h, min);
                             setState(listStatData[i].max1h, max);
                             setState(listStatData[i].mean1h, round(sum / statDataLength1, idData[i][4]));  
                          }
                          if (j == (statDataLength15-1)) {
                             setState(listStatData[i].min15, min);
                             setState(listStatData[i].max15, max);
                             setState(listStatData[i].mean15, round(sum / statDataLength15, idData[i][4]));     
                          }
                       }
                       setState(listStatData[i].min24h, min);
                       setState(listStatData[i].max24h, max);
                       setState(listStatData[i].mean24h, round(sum / statDataLength24, idData[i][4]));   
                       setState(listStatData[i].median24h, round(getMedian(listStatData[i].data), idData[i][4]));
                       obj.Min_24h = min;
                       obj.Max_24h = max;
                       obj.Mean_24h = round(sum / statDataLength24, idData[i][4]);
                       obj.Median_24h = round(getMedian(listStatData[i].data), idData[i][4]);
                       table[i] = obj; 
                    }
                    setState(dpData, JSON.stringify(listStatData));
                    setState(idTable, JSON.stringify(table), true);
                 } 
                 
                function getMedian(args) {
                  if (!args.length) {return 0}
                  var numbers = args.slice(0).sort((a,b) => a - b);
                  var middle = Math.floor(numbers.length / 2);
                  var isEven = numbers.length % 2 === 0;
                  return isEven ? (numbers[middle] + numbers[middle - 1]) / 2 : numbers[middle];
                }
                 
                /**
                 * round a number
                 * @param    value  to round
                 * @param    exp    exponent to round
                 * @returns         the round number
                 */
                function round(value, exp) {
                  if (typeof exp === 'undefined' || +exp === 0)
                    return Math.round(value);
                 
                  value = +value;
                  exp = +exp;
                 
                  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
                    return NaN;
                 
                  // Shift
                  var values = value.toString().split('e');
                  value = Math.round(+(values[0] + 'e' + (values[1] ? (+values[1] + exp) : exp)));
                 
                  // Shift back
                  var values = value.toString().split('e');
                  return +(values[0] + 'e' + (values[1] ? (+values[1] - exp) : -exp));
                }
                 
                initializeStatData();
                
                
                schedule('*/' + tc + ' * * * *', function () {
                   calcStatData();
                });
                
                

                sieht dann so aus. Verwenden tue ich Mean15

                6d16f486-c68c-496c-a090-32c081053ed1-grafik.png

                L M 2 Antworten Letzte Antwort
                1
                • H HoffmannOs

                  @Dominik-F Könntest du mir deine Card Exportieren?

                  Dominik F.D Offline
                  Dominik F.D Offline
                  Dominik F.
                  schrieb am zuletzt editiert von
                  #2399

                  @HoffmannOs

                  welche meinst du genau?

                  1 Antwort Letzte Antwort
                  0
                  • A andi2055

                    @lackylacky
                    ich nutze für Temperaturen und Sonne jeweils einen Mittelwert von 15 Min und zusätzlich beim Sonnenschutz eine Hysterese von 70%. Funktionierte den ganzen Sommer für mich einwandfrei. Kein unnötiges Hoch- oder Runterfahren.

                    Anbei das Script falls das jemand benötigt. Hier aus dem Forum, etwas angepasst durch mich

                    // https://forum.iobroker.net/topic/1037/gleitender-durchschnitt-min-max-%C3%BCber-def-zeitraum/82
                    // ########################################################################################################
                    // Berechnung von gleitendem Durchschnitt, Minimum und Maximum über einen Zeitraum
                    // Version 1.4.1
                    // ########################################################################################################
                    "use strict";
                    const idTable = '0_userdata.0.JavaScript.GleitMittelwert.Tabelle'; 
                    createState(idTable, '', {type: 'string'});
                    //
                    //
                    //
                    // Berechnet Min/Max, Durchschnitt und Median über die letzten 24h.
                    // Berechnet Min/Max, Durchschnitt über die letzte 1h.
                    //
                    // IDs aller benötigten Datenpunkte
                    //
                    // Als Array im Array mit folgendem Format:
                    //  1\.   original Datenpunktname
                    //  2\.  neuer Datenpunktname
                    //         Beispiel:   javascript.0.Status.Temperatur.Außen
                    //                  javascript.0.Status.Luftfeuchtigkeit.Außen
                    //  3\.   Beschreibung des Messwertes (zur Erzeugung neue Datenpunkte)
                    //         Beispliele:   Temperatur
                    //                  Luftfeuchtigkeit
                    //   4\.  Einheit (zur Erzeugung neue Datenpunkte)
                    //         Beispiele:   °C, %
                    //
                    //   5\.  Anzahl Nachkommastellen
                    //         Beispiele:   0 oder 1 oder 2
                    //
                    // Ist beliebig erweiterbar und für beliebige Werte nutzbar.
                    // Beispiel 1:
                    // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Temperatur.Außen','Temperatur','°C'],
                    //                 ['hm-rpc.3.CUX9002580.1.HUMIDITY'   ,'javascript.0.Status.Luftfeuchtigkeit.Außen','Luftfeuchtigkeit','%']];
                    //
                    // Beispiel 2:
                    // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Außen.Temperatur','Temperatur','°C'],
                    //                 ['hm-rpc.3.CUX9002580.1.HUMIDITY'   ,'javascript.0.Status.Außen.Luftfeuchtigkeit','Luftfeuchtigkeit','%'],
                    //                 ['hm-rpc.3.CUX4007637.1.Data'   ,'javascript.0.Status.Außen.Lichtstärke','Lichtstärke','lux']];
                    //
                    const idData = [['linkeddevices.0.Aussen.KNX_Temperatur','0_userdata.0.Außen.Temperatur','Temperatur','°C',1],
                                    ['alias.0.Außen.Helligkeit_links','0_userdata.0.Außen.Helligkeit_links','Helligkeit','L',0],
                                    ['alias.0.Außen.Helligkeit_mitte','0_userdata.0.Außen.Helligkeit_mitte','Helligkeit','L',0],
                                    ['alias.0.Außen.Helligkeit_rechts','0_userdata.0.Außen.Helligkeit_rechts','Helligkeit','L',0],
                                    ['linkeddevices.0.OG.Flur_Temperatur','0_userdata.0.OG.Flur_Temperatur','Temperatur','°C',1],
                                    ['linkeddevices.0.EG.Wohn_Temperatur','0_userdata.0.EG.Wohn_Temperatur','Temperatur','°C',1],
                                    ['linkeddevices.0.KG.Arbeit_Temperatur','0_userdata.0.KG.Arbeit_Temperatur','Temperatur','°C',1]
                                    ];
                     
                    //Datenpunkt zur Speicherung aller internen Daten
                    const dpData='0_userdata.0.JavaScript.GleitMittelwert.Statistic';
                     
                    // ########################################################################################################
                    // Implementierung -- hier nichts mehr ändern
                    // ########################################################################################################
                     
                    // globale Konstanten
                    const tc = 3;         // Abtastrate in Minuten
                     
                    const statDataLength24 = Math.round((24 * 60) / tc); // Anzahl der Werte für 24h
                    const statDataLength1 = Math.round(60 / tc); // Anzahl der Werte für stündlich
                    const statDataLength15 = Math.round(15 / tc); // Anzahl der Werte für 15 Min
                     
                    // globale Variablen
                    var listStatData;  //interne Speicherung aller Werte
                     
                    //Funktion zum einmaligem initialisieren aller Datenpunkte
                    function initializeStatData() {
                     
                       // Datenpunkt zur Speicherung der internen Werte erzeugen
                       createState(dpData, 0, false, {
                          name: "StatisticData",
                          read: true,
                          write: true,
                          desc: 'Statistische Daten',
                          type: 'string',
                          def: '',
                          role: 'json'        
                       });
                     
                       //internes Array initialisieren
                        var needInit = false;
                       try {
                          listStatData = JSON.parse(getState(dpData).val);
                       } catch (ex) {
                          needInit = true;
                       }
                       if (needInit || !listStatData || (listStatData.length < idData.length)) {
                          listStatData = new Array(idData.length); 
                       }
                       //logDebug('initializeStatData for', dpData, listStatData);
                     
                       for (var i = 0; i < idData.length; i++) {
                            if (!listStatData[i]) { listStatData[i] = {}; }
                            listStatData[i].value       = idData[i][1];
                            listStatData[i].max24h		= idData[i][1] + '.Max_24h';
                            listStatData[i].min24h		= idData[i][1] + '.Min_24h';
                            listStatData[i].mean24h		= idData[i][1] + '.Mean_24h';
                            listStatData[i].median24h	= idData[i][1] + '.Median_24h';
                    	listStatData[i].max1h		= idData[i][1] + '.Max_1h';
                    	listStatData[i].min1h		= idData[i][1] + '.Min_1h';
                    	listStatData[i].mean1h		= idData[i][1] + '.Mean_1h';
                     	listStatData[i].max15		= idData[i][1] + '.Max_15';
                    	listStatData[i].min15		= idData[i][1] + '.Min_15';
                    	listStatData[i].mean15		= idData[i][1] + '.Mean_15';
                    
                    	createState(listStatData[i].value, 0, false, {
                                name: idData[i][2],
                                read: true,
                                write: true,
                                desc: idData[i][2]+ ' Aktueller Wert',
                          	    type: 'number',
                                def: 0,
                                unit: idData[i][3],
                                role: 'value'
                    	});
                     
                    	createState(listStatData[i].max24h, 0, false, {
                                name: 'Maximum_24h',
                                read: true,
                                write: true,
                                desc: idData[i][2] + ' Maximum',
                                type: 'number',
                                def: 0,
                                unit: idData[i][3],
                                role: 'value'
                           });
                     
                           createState(listStatData[i].min24h, 0, false, {
                                name: 'Minimum_24h',
                                read: true,
                                write: true,
                                desc: idData[i][2] + ' Minimum',
                                type: 'number',
                                def: 0,
                    	    unit: idData[i][3],
                                role: 'value'
                           });
                     
                           createState(listStatData[i].mean24h, 0, false, {
                                name: 'Mittelwert_24h',
                                read: true,
                                write: true,
                                desc: idData[i][2] + ' Mittelwert',
                                type: 'number',
                                def: 0,
                                unit: idData[i][3],
                                role: 'value'
                          });
                     
                          createState(listStatData[i].median24h, 0, false, {
                                name: 'Median_24h',
                                read: true,
                                write: true,
                                desc: idData[i][2] + ' Median',
                                type: 'number',
                                def: 0,
                    	        unit: idData[i][3],
                                role: 'value'
                          });
                     
                          createState(listStatData[i].max1h, 0, false, {
                                name: 'Maximum_1h',
                                read: true,
                                write: true,
                                desc: idData[i][2] + ' Maximum',
                                type: 'number',
                                def: 0,
                                unit: idData[i][3],
                                role: 'value'
                          });
                     
                          createState(listStatData[i].min1h, 0, false, {
                                name: 'Minimum_1h',
                                read: true,
                                write: true,
                                desc: idData[i][2] + ' Minimum',
                                type: 'number',
                                def: 0,
                                unit: idData[i][3],
                                role: 'value'
                          });
                     
                          createState(listStatData[i].mean1h, 0, false, {
                                name: 'Mittelwert_1h',
                                read: true,
                                write: true,
                           	    desc: idData[i][2] + ' Mittelwert',
                                type: 'number',
                                def: 0,
                    	    unit: idData[i][3],
                    	    role: 'value'
                          });
                     
                           createState(listStatData[i].max15, 0, false, {
                                name: 'Maximum_15',
                                read: true,
                                write: true,
                                desc: idData[i][2] + ' Maximum',
                                type: 'number',
                                def: 0,
                                unit: idData[i][3],
                                role: 'value'
                          });
                     
                          createState(listStatData[i].min15, 0, false, {
                                name: 'Minimum_15',
                                read: true,
                                write: true,
                                desc: idData[i][2] + ' Minimum',
                                type: 'number',
                                def: 0,
                                unit: idData[i][3],
                                role: 'value'
                          });
                     
                          createState(listStatData[i].mean15, 0, false, {
                                name: 'Mittelwert_15',
                                read: true,
                                write: true,
                           	    desc: idData[i][2] + ' Mittelwert',
                                type: 'number',
                                def: 0,
                    	    unit: idData[i][3],
                    	    role: 'value'
                          });
                    
                          if (needInit || !listStatData[i].data || (listStatData[i].data.length != statDataLength24)) {
                                listStatData[i].data	= new Array(statDataLength24);
                     
                                // 1\. Script start: Liste und String-Datenpunkt füllen
                                var x = getState(idData[i][0]).val;
                                for (var j = 0; j < statDataLength24; j++) {
                                listStatData[i].data[j] = x;
                             }
                     
                              //logDebug(listStatData[i], i);
                                setStateDelayed(listStatData[i].value, x, false, 1000);
                                setStateDelayed(listStatData[i].min24h, x, false, 1000);
                                setStateDelayed(listStatData[i].max24h, x, false, 1000);
                                setStateDelayed(listStatData[i].mean24h, x, false, 1000);
                                setStateDelayed(listStatData[i].median24h, x, false, 1000);
                                setStateDelayed(listStatData[i].min1h, x, false, 1000);
                                setStateDelayed(listStatData[i].max1h, x, false, 1000);
                                setStateDelayed(listStatData[i].mean1h, x, false, 1000);
                                setStateDelayed(listStatData[i].min15, x, false, 1000);
                                setStateDelayed(listStatData[i].max15, x, false, 1000);
                                setStateDelayed(listStatData[i].mean15, x, false, 1000);
                          }      
                       }
                       setState(dpData, JSON.stringify(listStatData));         
                    }
                     
                    //Berechnung der Werte
                     function calcStatData() {
                        if (!listStatData || (idData.length != listStatData.length)) {
                             initializeStatData();
                        }
                         //logDebug('starting calcStatData');
                        var table = []; 
                        for (var i = 0; i < idData.length; i++) {
                           var obj = {};
                           var sensor = listStatData[i].value.split('.');
                           obj.Sensor = sensor[4] + ' ' + sensor[3];
                           listStatData[i].data.pop(); //Remove the last element of an array
                           var x = parseFloat(getState(idData[i][0]).val);
                           obj.Wert = x;
                           listStatData[i].data.unshift(x); //Add new items to the beginning of an array
                           setState(listStatData[i].value, x);
                           var min = x;
                           var max = x;
                           var sum = 0.0;
                           for (var j = 0; j < statDataLength24; j++) {
                              var s = parseFloat(listStatData[i].data[j]);
                              if (s < min) min = s;
                              if (s > max) max = s;
                              sum += s;
                              if (j == (statDataLength1-1)) {
                                 setState(listStatData[i].min1h, min);
                                 setState(listStatData[i].max1h, max);
                                 setState(listStatData[i].mean1h, round(sum / statDataLength1, idData[i][4]));  
                              }
                              if (j == (statDataLength15-1)) {
                                 setState(listStatData[i].min15, min);
                                 setState(listStatData[i].max15, max);
                                 setState(listStatData[i].mean15, round(sum / statDataLength15, idData[i][4]));     
                              }
                           }
                           setState(listStatData[i].min24h, min);
                           setState(listStatData[i].max24h, max);
                           setState(listStatData[i].mean24h, round(sum / statDataLength24, idData[i][4]));   
                           setState(listStatData[i].median24h, round(getMedian(listStatData[i].data), idData[i][4]));
                           obj.Min_24h = min;
                           obj.Max_24h = max;
                           obj.Mean_24h = round(sum / statDataLength24, idData[i][4]);
                           obj.Median_24h = round(getMedian(listStatData[i].data), idData[i][4]);
                           table[i] = obj; 
                        }
                        setState(dpData, JSON.stringify(listStatData));
                        setState(idTable, JSON.stringify(table), true);
                     } 
                     
                    function getMedian(args) {
                      if (!args.length) {return 0}
                      var numbers = args.slice(0).sort((a,b) => a - b);
                      var middle = Math.floor(numbers.length / 2);
                      var isEven = numbers.length % 2 === 0;
                      return isEven ? (numbers[middle] + numbers[middle - 1]) / 2 : numbers[middle];
                    }
                     
                    /**
                     * round a number
                     * @param    value  to round
                     * @param    exp    exponent to round
                     * @returns         the round number
                     */
                    function round(value, exp) {
                      if (typeof exp === 'undefined' || +exp === 0)
                        return Math.round(value);
                     
                      value = +value;
                      exp = +exp;
                     
                      if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
                        return NaN;
                     
                      // Shift
                      var values = value.toString().split('e');
                      value = Math.round(+(values[0] + 'e' + (values[1] ? (+values[1] + exp) : exp)));
                     
                      // Shift back
                      var values = value.toString().split('e');
                      return +(values[0] + 'e' + (values[1] ? (+values[1] - exp) : -exp));
                    }
                     
                    initializeStatData();
                    
                    
                    schedule('*/' + tc + ' * * * *', function () {
                       calcStatData();
                    });
                    
                    

                    sieht dann so aus. Verwenden tue ich Mean15

                    6d16f486-c68c-496c-a090-32c081053ed1-grafik.png

                    L Offline
                    L Offline
                    lackylacky
                    schrieb am zuletzt editiert von
                    #2400

                    @andi2055 super, daß schau ich mir mal genauer an! danke dir...

                    1 Antwort Letzte Antwort
                    0
                    • A andi2055

                      @lackylacky
                      ich nutze für Temperaturen und Sonne jeweils einen Mittelwert von 15 Min und zusätzlich beim Sonnenschutz eine Hysterese von 70%. Funktionierte den ganzen Sommer für mich einwandfrei. Kein unnötiges Hoch- oder Runterfahren.

                      Anbei das Script falls das jemand benötigt. Hier aus dem Forum, etwas angepasst durch mich

                      // https://forum.iobroker.net/topic/1037/gleitender-durchschnitt-min-max-%C3%BCber-def-zeitraum/82
                      // ########################################################################################################
                      // Berechnung von gleitendem Durchschnitt, Minimum und Maximum über einen Zeitraum
                      // Version 1.4.1
                      // ########################################################################################################
                      "use strict";
                      const idTable = '0_userdata.0.JavaScript.GleitMittelwert.Tabelle'; 
                      createState(idTable, '', {type: 'string'});
                      //
                      //
                      //
                      // Berechnet Min/Max, Durchschnitt und Median über die letzten 24h.
                      // Berechnet Min/Max, Durchschnitt über die letzte 1h.
                      //
                      // IDs aller benötigten Datenpunkte
                      //
                      // Als Array im Array mit folgendem Format:
                      //  1\.   original Datenpunktname
                      //  2\.  neuer Datenpunktname
                      //         Beispiel:   javascript.0.Status.Temperatur.Außen
                      //                  javascript.0.Status.Luftfeuchtigkeit.Außen
                      //  3\.   Beschreibung des Messwertes (zur Erzeugung neue Datenpunkte)
                      //         Beispliele:   Temperatur
                      //                  Luftfeuchtigkeit
                      //   4\.  Einheit (zur Erzeugung neue Datenpunkte)
                      //         Beispiele:   °C, %
                      //
                      //   5\.  Anzahl Nachkommastellen
                      //         Beispiele:   0 oder 1 oder 2
                      //
                      // Ist beliebig erweiterbar und für beliebige Werte nutzbar.
                      // Beispiel 1:
                      // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Temperatur.Außen','Temperatur','°C'],
                      //                 ['hm-rpc.3.CUX9002580.1.HUMIDITY'   ,'javascript.0.Status.Luftfeuchtigkeit.Außen','Luftfeuchtigkeit','%']];
                      //
                      // Beispiel 2:
                      // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Außen.Temperatur','Temperatur','°C'],
                      //                 ['hm-rpc.3.CUX9002580.1.HUMIDITY'   ,'javascript.0.Status.Außen.Luftfeuchtigkeit','Luftfeuchtigkeit','%'],
                      //                 ['hm-rpc.3.CUX4007637.1.Data'   ,'javascript.0.Status.Außen.Lichtstärke','Lichtstärke','lux']];
                      //
                      const idData = [['linkeddevices.0.Aussen.KNX_Temperatur','0_userdata.0.Außen.Temperatur','Temperatur','°C',1],
                                      ['alias.0.Außen.Helligkeit_links','0_userdata.0.Außen.Helligkeit_links','Helligkeit','L',0],
                                      ['alias.0.Außen.Helligkeit_mitte','0_userdata.0.Außen.Helligkeit_mitte','Helligkeit','L',0],
                                      ['alias.0.Außen.Helligkeit_rechts','0_userdata.0.Außen.Helligkeit_rechts','Helligkeit','L',0],
                                      ['linkeddevices.0.OG.Flur_Temperatur','0_userdata.0.OG.Flur_Temperatur','Temperatur','°C',1],
                                      ['linkeddevices.0.EG.Wohn_Temperatur','0_userdata.0.EG.Wohn_Temperatur','Temperatur','°C',1],
                                      ['linkeddevices.0.KG.Arbeit_Temperatur','0_userdata.0.KG.Arbeit_Temperatur','Temperatur','°C',1]
                                      ];
                       
                      //Datenpunkt zur Speicherung aller internen Daten
                      const dpData='0_userdata.0.JavaScript.GleitMittelwert.Statistic';
                       
                      // ########################################################################################################
                      // Implementierung -- hier nichts mehr ändern
                      // ########################################################################################################
                       
                      // globale Konstanten
                      const tc = 3;         // Abtastrate in Minuten
                       
                      const statDataLength24 = Math.round((24 * 60) / tc); // Anzahl der Werte für 24h
                      const statDataLength1 = Math.round(60 / tc); // Anzahl der Werte für stündlich
                      const statDataLength15 = Math.round(15 / tc); // Anzahl der Werte für 15 Min
                       
                      // globale Variablen
                      var listStatData;  //interne Speicherung aller Werte
                       
                      //Funktion zum einmaligem initialisieren aller Datenpunkte
                      function initializeStatData() {
                       
                         // Datenpunkt zur Speicherung der internen Werte erzeugen
                         createState(dpData, 0, false, {
                            name: "StatisticData",
                            read: true,
                            write: true,
                            desc: 'Statistische Daten',
                            type: 'string',
                            def: '',
                            role: 'json'        
                         });
                       
                         //internes Array initialisieren
                          var needInit = false;
                         try {
                            listStatData = JSON.parse(getState(dpData).val);
                         } catch (ex) {
                            needInit = true;
                         }
                         if (needInit || !listStatData || (listStatData.length < idData.length)) {
                            listStatData = new Array(idData.length); 
                         }
                         //logDebug('initializeStatData for', dpData, listStatData);
                       
                         for (var i = 0; i < idData.length; i++) {
                              if (!listStatData[i]) { listStatData[i] = {}; }
                              listStatData[i].value       = idData[i][1];
                              listStatData[i].max24h		= idData[i][1] + '.Max_24h';
                              listStatData[i].min24h		= idData[i][1] + '.Min_24h';
                              listStatData[i].mean24h		= idData[i][1] + '.Mean_24h';
                              listStatData[i].median24h	= idData[i][1] + '.Median_24h';
                      	listStatData[i].max1h		= idData[i][1] + '.Max_1h';
                      	listStatData[i].min1h		= idData[i][1] + '.Min_1h';
                      	listStatData[i].mean1h		= idData[i][1] + '.Mean_1h';
                       	listStatData[i].max15		= idData[i][1] + '.Max_15';
                      	listStatData[i].min15		= idData[i][1] + '.Min_15';
                      	listStatData[i].mean15		= idData[i][1] + '.Mean_15';
                      
                      	createState(listStatData[i].value, 0, false, {
                                  name: idData[i][2],
                                  read: true,
                                  write: true,
                                  desc: idData[i][2]+ ' Aktueller Wert',
                            	    type: 'number',
                                  def: 0,
                                  unit: idData[i][3],
                                  role: 'value'
                      	});
                       
                      	createState(listStatData[i].max24h, 0, false, {
                                  name: 'Maximum_24h',
                                  read: true,
                                  write: true,
                                  desc: idData[i][2] + ' Maximum',
                                  type: 'number',
                                  def: 0,
                                  unit: idData[i][3],
                                  role: 'value'
                             });
                       
                             createState(listStatData[i].min24h, 0, false, {
                                  name: 'Minimum_24h',
                                  read: true,
                                  write: true,
                                  desc: idData[i][2] + ' Minimum',
                                  type: 'number',
                                  def: 0,
                      	    unit: idData[i][3],
                                  role: 'value'
                             });
                       
                             createState(listStatData[i].mean24h, 0, false, {
                                  name: 'Mittelwert_24h',
                                  read: true,
                                  write: true,
                                  desc: idData[i][2] + ' Mittelwert',
                                  type: 'number',
                                  def: 0,
                                  unit: idData[i][3],
                                  role: 'value'
                            });
                       
                            createState(listStatData[i].median24h, 0, false, {
                                  name: 'Median_24h',
                                  read: true,
                                  write: true,
                                  desc: idData[i][2] + ' Median',
                                  type: 'number',
                                  def: 0,
                      	        unit: idData[i][3],
                                  role: 'value'
                            });
                       
                            createState(listStatData[i].max1h, 0, false, {
                                  name: 'Maximum_1h',
                                  read: true,
                                  write: true,
                                  desc: idData[i][2] + ' Maximum',
                                  type: 'number',
                                  def: 0,
                                  unit: idData[i][3],
                                  role: 'value'
                            });
                       
                            createState(listStatData[i].min1h, 0, false, {
                                  name: 'Minimum_1h',
                                  read: true,
                                  write: true,
                                  desc: idData[i][2] + ' Minimum',
                                  type: 'number',
                                  def: 0,
                                  unit: idData[i][3],
                                  role: 'value'
                            });
                       
                            createState(listStatData[i].mean1h, 0, false, {
                                  name: 'Mittelwert_1h',
                                  read: true,
                                  write: true,
                             	    desc: idData[i][2] + ' Mittelwert',
                                  type: 'number',
                                  def: 0,
                      	    unit: idData[i][3],
                      	    role: 'value'
                            });
                       
                             createState(listStatData[i].max15, 0, false, {
                                  name: 'Maximum_15',
                                  read: true,
                                  write: true,
                                  desc: idData[i][2] + ' Maximum',
                                  type: 'number',
                                  def: 0,
                                  unit: idData[i][3],
                                  role: 'value'
                            });
                       
                            createState(listStatData[i].min15, 0, false, {
                                  name: 'Minimum_15',
                                  read: true,
                                  write: true,
                                  desc: idData[i][2] + ' Minimum',
                                  type: 'number',
                                  def: 0,
                                  unit: idData[i][3],
                                  role: 'value'
                            });
                       
                            createState(listStatData[i].mean15, 0, false, {
                                  name: 'Mittelwert_15',
                                  read: true,
                                  write: true,
                             	    desc: idData[i][2] + ' Mittelwert',
                                  type: 'number',
                                  def: 0,
                      	    unit: idData[i][3],
                      	    role: 'value'
                            });
                      
                            if (needInit || !listStatData[i].data || (listStatData[i].data.length != statDataLength24)) {
                                  listStatData[i].data	= new Array(statDataLength24);
                       
                                  // 1\. Script start: Liste und String-Datenpunkt füllen
                                  var x = getState(idData[i][0]).val;
                                  for (var j = 0; j < statDataLength24; j++) {
                                  listStatData[i].data[j] = x;
                               }
                       
                                //logDebug(listStatData[i], i);
                                  setStateDelayed(listStatData[i].value, x, false, 1000);
                                  setStateDelayed(listStatData[i].min24h, x, false, 1000);
                                  setStateDelayed(listStatData[i].max24h, x, false, 1000);
                                  setStateDelayed(listStatData[i].mean24h, x, false, 1000);
                                  setStateDelayed(listStatData[i].median24h, x, false, 1000);
                                  setStateDelayed(listStatData[i].min1h, x, false, 1000);
                                  setStateDelayed(listStatData[i].max1h, x, false, 1000);
                                  setStateDelayed(listStatData[i].mean1h, x, false, 1000);
                                  setStateDelayed(listStatData[i].min15, x, false, 1000);
                                  setStateDelayed(listStatData[i].max15, x, false, 1000);
                                  setStateDelayed(listStatData[i].mean15, x, false, 1000);
                            }      
                         }
                         setState(dpData, JSON.stringify(listStatData));         
                      }
                       
                      //Berechnung der Werte
                       function calcStatData() {
                          if (!listStatData || (idData.length != listStatData.length)) {
                               initializeStatData();
                          }
                           //logDebug('starting calcStatData');
                          var table = []; 
                          for (var i = 0; i < idData.length; i++) {
                             var obj = {};
                             var sensor = listStatData[i].value.split('.');
                             obj.Sensor = sensor[4] + ' ' + sensor[3];
                             listStatData[i].data.pop(); //Remove the last element of an array
                             var x = parseFloat(getState(idData[i][0]).val);
                             obj.Wert = x;
                             listStatData[i].data.unshift(x); //Add new items to the beginning of an array
                             setState(listStatData[i].value, x);
                             var min = x;
                             var max = x;
                             var sum = 0.0;
                             for (var j = 0; j < statDataLength24; j++) {
                                var s = parseFloat(listStatData[i].data[j]);
                                if (s < min) min = s;
                                if (s > max) max = s;
                                sum += s;
                                if (j == (statDataLength1-1)) {
                                   setState(listStatData[i].min1h, min);
                                   setState(listStatData[i].max1h, max);
                                   setState(listStatData[i].mean1h, round(sum / statDataLength1, idData[i][4]));  
                                }
                                if (j == (statDataLength15-1)) {
                                   setState(listStatData[i].min15, min);
                                   setState(listStatData[i].max15, max);
                                   setState(listStatData[i].mean15, round(sum / statDataLength15, idData[i][4]));     
                                }
                             }
                             setState(listStatData[i].min24h, min);
                             setState(listStatData[i].max24h, max);
                             setState(listStatData[i].mean24h, round(sum / statDataLength24, idData[i][4]));   
                             setState(listStatData[i].median24h, round(getMedian(listStatData[i].data), idData[i][4]));
                             obj.Min_24h = min;
                             obj.Max_24h = max;
                             obj.Mean_24h = round(sum / statDataLength24, idData[i][4]);
                             obj.Median_24h = round(getMedian(listStatData[i].data), idData[i][4]);
                             table[i] = obj; 
                          }
                          setState(dpData, JSON.stringify(listStatData));
                          setState(idTable, JSON.stringify(table), true);
                       } 
                       
                      function getMedian(args) {
                        if (!args.length) {return 0}
                        var numbers = args.slice(0).sort((a,b) => a - b);
                        var middle = Math.floor(numbers.length / 2);
                        var isEven = numbers.length % 2 === 0;
                        return isEven ? (numbers[middle] + numbers[middle - 1]) / 2 : numbers[middle];
                      }
                       
                      /**
                       * round a number
                       * @param    value  to round
                       * @param    exp    exponent to round
                       * @returns         the round number
                       */
                      function round(value, exp) {
                        if (typeof exp === 'undefined' || +exp === 0)
                          return Math.round(value);
                       
                        value = +value;
                        exp = +exp;
                       
                        if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
                          return NaN;
                       
                        // Shift
                        var values = value.toString().split('e');
                        value = Math.round(+(values[0] + 'e' + (values[1] ? (+values[1] + exp) : exp)));
                       
                        // Shift back
                        var values = value.toString().split('e');
                        return +(values[0] + 'e' + (values[1] ? (+values[1] - exp) : -exp));
                      }
                       
                      initializeStatData();
                      
                      
                      schedule('*/' + tc + ' * * * *', function () {
                         calcStatData();
                      });
                      
                      

                      sieht dann so aus. Verwenden tue ich Mean15

                      6d16f486-c68c-496c-a090-32c081053ed1-grafik.png

                      M Offline
                      M Offline
                      Malz1902
                      schrieb am zuletzt editiert von
                      #2401

                      @andi2055 Danke, werde ich mal testen :-)

                      1 Antwort Letzte Antwort
                      0
                      • L Offline
                        L Offline
                        lackylacky
                        schrieb am zuletzt editiert von
                        #2402

                        ich bin jetzt mit meinen KNX Aktoren zu Shuttercontrol umgezogen, jeweils 2 Datenpunkte für Jalousie & Lamelle extra! Läuft soweit mal nicht schlecht, danke nochmal an @andi2055, hab dein Script für die Mittelwerte übernommen und läuft super!
                        meine KNX Aktoren ändern auch nach fahrt, den Wert der aktuellen Position, gleich wie hier bei Shelly beschrieben, deshalb habe ich "Überprüfen des aktuellen Rollladenstatus" aktiviert, im Status wird mir aber immer noch manu_Mode angezeigt und die Jalousien fahren nach Beendigung der Beschattung nicht mehr hoch?

                        F 1 Antwort Letzte Antwort
                        0
                        • L lackylacky

                          ich bin jetzt mit meinen KNX Aktoren zu Shuttercontrol umgezogen, jeweils 2 Datenpunkte für Jalousie & Lamelle extra! Läuft soweit mal nicht schlecht, danke nochmal an @andi2055, hab dein Script für die Mittelwerte übernommen und läuft super!
                          meine KNX Aktoren ändern auch nach fahrt, den Wert der aktuellen Position, gleich wie hier bei Shelly beschrieben, deshalb habe ich "Überprüfen des aktuellen Rollladenstatus" aktiviert, im Status wird mir aber immer noch manu_Mode angezeigt und die Jalousien fahren nach Beendigung der Beschattung nicht mehr hoch?

                          F Offline
                          F Offline
                          FoxRo
                          schrieb am zuletzt editiert von
                          #2403

                          @lackylacky
                          Ich habe das gleiche Setup wie Du mit Jalousien. Bei mir tut Shuttercontrol perfekt, habe aber das Script für Mittelwerte (noch) nicht im Einsatz. Dass da der manu_Mode ausgelöst wird, deutet darauf hin, dass nach Ablauf der 60s Delay und dessen Aktualisieren des Rollladenstatus, nochmals andere Werte zurück kommen. Dafür kanns neben dem effektiven manuellen fahren noch weitere Gründe geben.
                          Ich hatte anfangs grössere Probleme mit dem KNX, weil der ioBroker KNX Adapter den Status der Jalousien nicht korrekt geupdatet hat. Sprich, Shuttercontrol hat nur ein Objekt mit welchem gefahren wird und wo der Status zurückgemeldet wird. Im KNX gibts dafür vielfach zwei. Je nach Aktor, ein Objekt zum Fahren und eines welches den aktuellen Status zurück meldet. Im KNX Adapter gibt es dafür sehr enge Richtlinien, wie die Objekte im ETS benennt werden müssen, damit beim ETS Import in den KNX Adapter das Status Feedback korrekt auf das Fahren-Objekt im ioBroker zurückgeschrieben wird.
                          Hast du mal überprüft, ob die Werte für "Soll" und "Ist" für Höhe und Lamelle im KNX mit den Werten im Shuttercontrol übereinstimmen? Das gibt Dir vielleicht einen Hinweis, in welche Richtung Du suchen solltest.
                          Wünsche Dir viel Erfolg!

                          L 2 Antworten Letzte Antwort
                          0
                          • F FoxRo

                            @lackylacky
                            Ich habe das gleiche Setup wie Du mit Jalousien. Bei mir tut Shuttercontrol perfekt, habe aber das Script für Mittelwerte (noch) nicht im Einsatz. Dass da der manu_Mode ausgelöst wird, deutet darauf hin, dass nach Ablauf der 60s Delay und dessen Aktualisieren des Rollladenstatus, nochmals andere Werte zurück kommen. Dafür kanns neben dem effektiven manuellen fahren noch weitere Gründe geben.
                            Ich hatte anfangs grössere Probleme mit dem KNX, weil der ioBroker KNX Adapter den Status der Jalousien nicht korrekt geupdatet hat. Sprich, Shuttercontrol hat nur ein Objekt mit welchem gefahren wird und wo der Status zurückgemeldet wird. Im KNX gibts dafür vielfach zwei. Je nach Aktor, ein Objekt zum Fahren und eines welches den aktuellen Status zurück meldet. Im KNX Adapter gibt es dafür sehr enge Richtlinien, wie die Objekte im ETS benennt werden müssen, damit beim ETS Import in den KNX Adapter das Status Feedback korrekt auf das Fahren-Objekt im ioBroker zurückgeschrieben wird.
                            Hast du mal überprüft, ob die Werte für "Soll" und "Ist" für Höhe und Lamelle im KNX mit den Werten im Shuttercontrol übereinstimmen? Das gibt Dir vielleicht einen Hinweis, in welche Richtung Du suchen solltest.
                            Wünsche Dir viel Erfolg!

                            L Offline
                            L Offline
                            lackylacky
                            schrieb am zuletzt editiert von lackylacky
                            #2404

                            @FoxRo super, schon mal gut zu wissen, dass es mit KNX funktioniert...
                            Ja richtig, das mit den KNX Status habe ich bei einem anderen Projekt schon gehabt und meine ganzen KNX Adressen umgeschrieben!
                            dh. die KNX Adresse zum fahren wird nach der Fahrt von der Adresse Status aktualisiert.
                            bei den 60s klingelt aber bei mir was, habe Jalousien die länger fahren, dh. es könnte hier das Problem liegen!
                            Danke schon mal!

                            1 Antwort Letzte Antwort
                            0
                            • F FoxRo

                              @lackylacky
                              Ich habe das gleiche Setup wie Du mit Jalousien. Bei mir tut Shuttercontrol perfekt, habe aber das Script für Mittelwerte (noch) nicht im Einsatz. Dass da der manu_Mode ausgelöst wird, deutet darauf hin, dass nach Ablauf der 60s Delay und dessen Aktualisieren des Rollladenstatus, nochmals andere Werte zurück kommen. Dafür kanns neben dem effektiven manuellen fahren noch weitere Gründe geben.
                              Ich hatte anfangs grössere Probleme mit dem KNX, weil der ioBroker KNX Adapter den Status der Jalousien nicht korrekt geupdatet hat. Sprich, Shuttercontrol hat nur ein Objekt mit welchem gefahren wird und wo der Status zurückgemeldet wird. Im KNX gibts dafür vielfach zwei. Je nach Aktor, ein Objekt zum Fahren und eines welches den aktuellen Status zurück meldet. Im KNX Adapter gibt es dafür sehr enge Richtlinien, wie die Objekte im ETS benennt werden müssen, damit beim ETS Import in den KNX Adapter das Status Feedback korrekt auf das Fahren-Objekt im ioBroker zurückgeschrieben wird.
                              Hast du mal überprüft, ob die Werte für "Soll" und "Ist" für Höhe und Lamelle im KNX mit den Werten im Shuttercontrol übereinstimmen? Das gibt Dir vielleicht einen Hinweis, in welche Richtung Du suchen solltest.
                              Wünsche Dir viel Erfolg!

                              L Offline
                              L Offline
                              lackylacky
                              schrieb am zuletzt editiert von lackylacky
                              #2405

                              @FoxRo ich habe jetzt folgendes festgestellt!
                              die Jalousien, die in der früh nur die Lamellen öffnen 0% und die Höhe unten lassen 100% werden von SC nur mit den Datenpunkt Lamelle angesteuert. Da sich aber dadurch auch die Höhe ändert wird der DP Höhe auf manu_Mode geschalten!

                              F 1 Antwort Letzte Antwort
                              0
                              • L lackylacky

                                @FoxRo ich habe jetzt folgendes festgestellt!
                                die Jalousien, die in der früh nur die Lamellen öffnen 0% und die Höhe unten lassen 100% werden von SC nur mit den Datenpunkt Lamelle angesteuert. Da sich aber dadurch auch die Höhe ändert wird der DP Höhe auf manu_Mode geschalten!

                                F Offline
                                F Offline
                                FoxRo
                                schrieb am zuletzt editiert von
                                #2406

                                @lackylacky Das ist sehr seltsam und irgendwie unlogisch, dass Deine Aktoren eine andere Höhe melden, wenn doch nur die Lamelle verstellt wird.
                                Ich habe das bei meinen JRA/S8.230.2.1 Jal./Rol.Akt.man.8f,230V,REG Aktoren von ABB nachgeprüft und da wird die Höhe nicht verändert, wenn sich die Lamelle öffnet oder schliesst. Weder wenn Shuttercontrol über das Lamellenobjekt die Lamelle verstellt, noch wenn ich mittels Taster im Step-Betrieb die Lamelle verstelle.
                                Habe auch im ETS geschaut, ob ich da so ein Verhalten einstellen könnte - sehe da für meine Aktoren aber nichts offensichtliches, wie ich dieses Verhalten einstellen könnte.
                                Was für ein Aktor betreibst Du? Verhält sich Dein Aktor auch so, wenn Du im Taster-Step Betrieb die Lamelle öffnest / schliesst?

                                L 1 Antwort Letzte Antwort
                                0
                                • F FoxRo

                                  @lackylacky Das ist sehr seltsam und irgendwie unlogisch, dass Deine Aktoren eine andere Höhe melden, wenn doch nur die Lamelle verstellt wird.
                                  Ich habe das bei meinen JRA/S8.230.2.1 Jal./Rol.Akt.man.8f,230V,REG Aktoren von ABB nachgeprüft und da wird die Höhe nicht verändert, wenn sich die Lamelle öffnet oder schliesst. Weder wenn Shuttercontrol über das Lamellenobjekt die Lamelle verstellt, noch wenn ich mittels Taster im Step-Betrieb die Lamelle verstelle.
                                  Habe auch im ETS geschaut, ob ich da so ein Verhalten einstellen könnte - sehe da für meine Aktoren aber nichts offensichtliches, wie ich dieses Verhalten einstellen könnte.
                                  Was für ein Aktor betreibst Du? Verhält sich Dein Aktor auch so, wenn Du im Taster-Step Betrieb die Lamelle öffnest / schliesst?

                                  L Offline
                                  L Offline
                                  lackylacky
                                  schrieb am zuletzt editiert von
                                  #2407

                                  @FoxRo ja hab es nochmal überprüft, auch bei Lamelle step ändert sich die Höhe mit, egal ob mit Taster oder über Wert. Ich habe die JUNG 2316.16REG HE im Einsatz, habe in der ETS aber auch nichts gefunden ob man das ev. einstellen kann! hab da momenta keine Idee wie ich das mit SC hinbekommen könnte, ev. müsste SC die Höhe auch nochmal ansteuern um dann den Wert zurück lesen zu können?

                                  F 1 Antwort Letzte Antwort
                                  0
                                  • L lackylacky

                                    @FoxRo ja hab es nochmal überprüft, auch bei Lamelle step ändert sich die Höhe mit, egal ob mit Taster oder über Wert. Ich habe die JUNG 2316.16REG HE im Einsatz, habe in der ETS aber auch nichts gefunden ob man das ev. einstellen kann! hab da momenta keine Idee wie ich das mit SC hinbekommen könnte, ev. müsste SC die Höhe auch nochmal ansteuern um dann den Wert zurück lesen zu können?

                                    F Offline
                                    F Offline
                                    FoxRo
                                    schrieb am zuletzt editiert von
                                    #2408

                                    @lackylacky Das ist ziemlich ärgerlich, dass sich der Aktor so "künstlich genau" verhält. Was zwar physikalisch stimmt, fällt Dir hier auf die Füsse.
                                    Somit geht der Einsatz mit Shuttercontrol nur mittels Workaround oder wenn von JUNG evtl eine andere Firmware bekommst.
                                    Als kurzfristiger Workaround könntest evtl neben den Lamellen auch die Höhe ein wenig öffnen. Vielleicht meldet dann der Aktor wiederum die angeforderte Position zurück womit der SC im Automodus bleibt. Alternativ könntest die aktive Rückmeldung der Jalousiehöhe im Aktor auf passiv stellen. Somit wird diese Position beim Lamellen Fahren nicht aktualisiert. Problem ist dann aber, dass ein manueller Move von SC nicht festgestellt werden kann, mit entsprechenden Folgen für den Beschattungsmodus und die Tür-Trigger Funktion.
                                    Eine andere Möglichkeit wäre evtl. dass man im KNX Adapter die Objektverknüpfung zwischen Fahr- und Statusobjekt beim Höhen-Objekt aufbricht und die Statusrückmeldung über ein Script und eigenem neuen Statusobjekt laufen lässt. Diesen eigenen Status verknüpfst dann im KNX Aktor wiederum mit dem Fahrobjekt. Im Script updatest den Status für die Höhe nur, wenn die Änderung grösser ist, als wenn nur die Lamelle bewegst (zb. >5%). Nachteil hier - nach einem KNX - ETS komplett Import muss diese Verknüpfung von Hand wieder nachgezogen werden. Bei einem Import mit der Option "nur neue Objekte" sollten die Verknüpfung bestehen bleiben. evtl macht es Sinn, im ETS dann auch das Statusobjekt umzubenennen, damit es nicht automatisch mit dem Fahren-Objekt verknüpft wird.
                                    Andere Möglichkeiten sehe ich im Moment auch nicht und Aktor tauschen fällt wohl aus Preisgründen weg, was ich durchaus nachvollziehen kann. :money_mouth_face:

                                    L 1 Antwort Letzte Antwort
                                    0
                                    • 2 2hot4you

                                      @Conquest

                                      Meine VIS sieht so aus :grin:

                                      jalousie.PNG

                                      H Offline
                                      H Offline
                                      HoffmannOs
                                      schrieb am zuletzt editiert von
                                      #2409

                                      @2hot4you würdest du mir auch nen Export bereitstellen? LG

                                      2 1 Antwort Letzte Antwort
                                      0
                                      • H HoffmannOs

                                        @2hot4you würdest du mir auch nen Export bereitstellen? LG

                                        2 Online
                                        2 Online
                                        2hot4you
                                        schrieb am zuletzt editiert von
                                        #2410

                                        @HoffmannOs

                                        Wovon ? 🤷‍♂️

                                        MichMeinM 1 Antwort Letzte Antwort
                                        0
                                        • 2 2hot4you

                                          @HoffmannOs

                                          Wovon ? 🤷‍♂️

                                          MichMeinM Offline
                                          MichMeinM Offline
                                          MichMein
                                          schrieb am zuletzt editiert von MichMein
                                          #2411

                                          @2hot4you sagte in Test Adapter shuttercontrol v1.0.x:

                                          @HoffmannOs

                                          Wovon ? 🤷‍♂️

                                          Davon vermutlich, zumindest hat @HoffmannOs darauf referenziert.

                                          Gruß Michael
                                          Sofern Beiträge hilfreich für Dich sind, nutze das Voting unten rechts.

                                          H 2 2 Antworten Letzte Antwort
                                          0
                                          Antworten
                                          • In einem neuen Thema antworten
                                          Anmelden zum Antworten
                                          • Älteste zuerst
                                          • Neuste zuerst
                                          • Meiste Stimmen


                                          Support us

                                          ioBroker
                                          Community Adapters
                                          Donate

                                          812

                                          Online

                                          32.4k

                                          Benutzer

                                          81.5k

                                          Themen

                                          1.3m

                                          Beiträge
                                          Community
                                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                                          ioBroker Community 2014-2025
                                          logo
                                          • Anmelden

                                          • Du hast noch kein Konto? Registrieren

                                          • Anmelden oder registrieren, um zu suchen
                                          • Erster Beitrag
                                            Letzter Beitrag
                                          0
                                          • Home
                                          • Aktuell
                                          • Tags
                                          • Ungelesen 0
                                          • Kategorien
                                          • Unreplied
                                          • Beliebt
                                          • GitHub
                                          • Docu
                                          • Hilfe