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. Skripten / Logik
  4. JavaScript
  5. Konstantes Dimmen bei gedrückter Taste

NEWS

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    10
    1
    138

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    24
    1
    1.4k

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

Konstantes Dimmen bei gedrückter Taste

Geplant Angeheftet Gesperrt Verschoben JavaScript
8 Beiträge 5 Kommentatoren 766 Aufrufe 4 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.
  • KeromidaK Offline
    KeromidaK Offline
    Keromida
    schrieb am zuletzt editiert von Keromida
    #1

    Hallo zusammen!

    Ich bin hier leider nicht wirklich fündig geworden und benötige Hilfe bei der Programmierung einer kontinuierlichen Dimmfunktion solange eine Taste gedrückt bleibt. D.h. ich möchte gerne bei gedrückter Taste von 0 bis 100 variabel Dimmen können. Hierfür habe ich mir die Tradfri Dimmer gekauft, welche die Zustände 1001 (Aus, Taste wird gehalten), 1002 (Aus, Taste gedrückt), 1003 (Aus, Taste nach 1001 losgelassen), sowie das Pendent abgebildet auf 200X.

    Geplant war eigentlich das ganze in einem Switch/If-Statement den Tastenzustand abzufragen und über eine While-Schleife das ganze so lange laufen zu lassen bis entweder 100% bzw. 0% erreicht sind oder die Taste vorher losgelassen wird. Hierfür habe ich mir eine Funktion geschrieben, die das theoretisch können sollte.

    function setLevel(SwitchState){
        if(SwitchState == 1001){
            while(Level_Value <= 100){
                Level_Value = getState("deconz.0.Lights.1.level").val + 1;
                console.log(Level_Value);
                setState("deconz.0.Lights.1.level", Level_Value);
            }
        }
        else{
            return;
        }
    }
    

    Die Funktion wird auch aufgerufen, jedoch ändert sich die Lichtintensität nicht. Lege ich das was innerhalb der While-Schleife liegt außerhalb hin, so wird der Wert um 1% erhöht. Das ganze stellt hier nur ein Example dar, da ich erst die Grundfunktionalität zum laufen kriegen will. Die Abfrage ob die Taste losgelassen wurde fehlt hier. Hat hier jemand einen Tipp woran es liegt? Besten Dank!

    Viele Grüße
    Keromida

    K paul53P AsgothianA 3 Antworten Letzte Antwort
    0
    • KeromidaK Keromida

      Hallo zusammen!

      Ich bin hier leider nicht wirklich fündig geworden und benötige Hilfe bei der Programmierung einer kontinuierlichen Dimmfunktion solange eine Taste gedrückt bleibt. D.h. ich möchte gerne bei gedrückter Taste von 0 bis 100 variabel Dimmen können. Hierfür habe ich mir die Tradfri Dimmer gekauft, welche die Zustände 1001 (Aus, Taste wird gehalten), 1002 (Aus, Taste gedrückt), 1003 (Aus, Taste nach 1001 losgelassen), sowie das Pendent abgebildet auf 200X.

      Geplant war eigentlich das ganze in einem Switch/If-Statement den Tastenzustand abzufragen und über eine While-Schleife das ganze so lange laufen zu lassen bis entweder 100% bzw. 0% erreicht sind oder die Taste vorher losgelassen wird. Hierfür habe ich mir eine Funktion geschrieben, die das theoretisch können sollte.

      function setLevel(SwitchState){
          if(SwitchState == 1001){
              while(Level_Value <= 100){
                  Level_Value = getState("deconz.0.Lights.1.level").val + 1;
                  console.log(Level_Value);
                  setState("deconz.0.Lights.1.level", Level_Value);
              }
          }
          else{
              return;
          }
      }
      

      Die Funktion wird auch aufgerufen, jedoch ändert sich die Lichtintensität nicht. Lege ich das was innerhalb der While-Schleife liegt außerhalb hin, so wird der Wert um 1% erhöht. Das ganze stellt hier nur ein Example dar, da ich erst die Grundfunktionalität zum laufen kriegen will. Die Abfrage ob die Taste losgelassen wurde fehlt hier. Hat hier jemand einen Tipp woran es liegt? Besten Dank!

      Viele Grüße
      Keromida

      K Offline
      K Offline
      klassisch
      Most Active
      schrieb am zuletzt editiert von klassisch
      #2

      @keromida Bei mir in etwa so:

      const s01Button1HoldId = oppleSwitch02 + '.' + 'button_'+ n +'_hold';
            const s01DimUp_buttonId = s01Button1HoldId; 
            on({id: s01Button1HoldId , change: "gt"}, function(obj){ dimUp_Button() });
      
      
       async function dimUp_Button() { 
          // dim up  
          if(debugLogOn) console.log('button dim up press ');
          // clearAllTimouts();
          bright = getState(lampBrightnessId ).val;
          lastLampBright = bright;
          let buttonHold = getState(s01DimUp_buttonId).val || getState(s02DimUp_buttonId).val;
          await delay (0.1);
          while((buttonHold) && (bright < maxBright)){
              if(debugLogOn) console.log('loop');
              bright = bright + deltaBright ;
              if (bright >= maxBright) bright = maxBright; //clipping
              if(debugLogOn) console.log ('bright ' + bright);
              setState(lampBrightnessId ,bright);
              lastLampBright = bright;
              buttonHold = getState(s01DimUp_buttonId).val || getState(s02DimUp_buttonId).val;
              await delay (0.2);
          }
      };
      

      Ikea Floalt als Panel; aqare Opple als Taster (2 Stck, s01 und s02) und ein CC2652P als Koordinator. Kein ikea GW.

      Im Übrigen gehen in dieser Konfiguration auch die ikea symfonisk Drehsteller recht gut. Bei Gruppen etwas schlechter

      1 Antwort Letzte Antwort
      0
      • KeromidaK Keromida

        Hallo zusammen!

        Ich bin hier leider nicht wirklich fündig geworden und benötige Hilfe bei der Programmierung einer kontinuierlichen Dimmfunktion solange eine Taste gedrückt bleibt. D.h. ich möchte gerne bei gedrückter Taste von 0 bis 100 variabel Dimmen können. Hierfür habe ich mir die Tradfri Dimmer gekauft, welche die Zustände 1001 (Aus, Taste wird gehalten), 1002 (Aus, Taste gedrückt), 1003 (Aus, Taste nach 1001 losgelassen), sowie das Pendent abgebildet auf 200X.

        Geplant war eigentlich das ganze in einem Switch/If-Statement den Tastenzustand abzufragen und über eine While-Schleife das ganze so lange laufen zu lassen bis entweder 100% bzw. 0% erreicht sind oder die Taste vorher losgelassen wird. Hierfür habe ich mir eine Funktion geschrieben, die das theoretisch können sollte.

        function setLevel(SwitchState){
            if(SwitchState == 1001){
                while(Level_Value <= 100){
                    Level_Value = getState("deconz.0.Lights.1.level").val + 1;
                    console.log(Level_Value);
                    setState("deconz.0.Lights.1.level", Level_Value);
                }
            }
            else{
                return;
            }
        }
        

        Die Funktion wird auch aufgerufen, jedoch ändert sich die Lichtintensität nicht. Lege ich das was innerhalb der While-Schleife liegt außerhalb hin, so wird der Wert um 1% erhöht. Das ganze stellt hier nur ein Example dar, da ich erst die Grundfunktionalität zum laufen kriegen will. Die Abfrage ob die Taste losgelassen wurde fehlt hier. Hat hier jemand einen Tipp woran es liegt? Besten Dank!

        Viele Grüße
        Keromida

        paul53P Offline
        paul53P Offline
        paul53
        schrieb am zuletzt editiert von paul53
        #3

        @keromida sagte: über eine While-Schleife das ganze so lange laufen zu lassen bis entweder 100% bzw. 0% erreicht sind oder die Taste vorher losgelassen wird.

        Verwende ein Intervall, das beim langen Drücken gestartet und beim Loslassen gestoppt wird. Beispiel:

        const idLevel = 'deconz.0.Lights.1.level';
        const idHeller = '...';
        const idDunkler = '...';
        
        var timer = null;
        
        function dimmen(delta) {
            let level = getState(idLevel).val;
            if(delta > 0 && level < 100 || delta < 0 && level > 0) {
                timer = setInterval(function() {
                    level += delta;
                    setState(idLevel, level);
                    if(level <= 0 || level >= 100) clearInterval(timer);
                }, 250);
            } 
        }
        
        on(idHeller, function(dp) {
            if(dp.state.val == 1001) dimmen(1);
            else if(dp.state.val == 1003) clearInterval(timer);
        });
        
        on(idDunkler, function(dp) {
            if(dp.state.val == 1001) dimmen(-1);
            else if(dp.state.val == 1003) clearInterval(timer);
        });
        

        Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
        Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

        OliverIOO 1 Antwort Letzte Antwort
        1
        • paul53P paul53

          @keromida sagte: über eine While-Schleife das ganze so lange laufen zu lassen bis entweder 100% bzw. 0% erreicht sind oder die Taste vorher losgelassen wird.

          Verwende ein Intervall, das beim langen Drücken gestartet und beim Loslassen gestoppt wird. Beispiel:

          const idLevel = 'deconz.0.Lights.1.level';
          const idHeller = '...';
          const idDunkler = '...';
          
          var timer = null;
          
          function dimmen(delta) {
              let level = getState(idLevel).val;
              if(delta > 0 && level < 100 || delta < 0 && level > 0) {
                  timer = setInterval(function() {
                      level += delta;
                      setState(idLevel, level);
                      if(level <= 0 || level >= 100) clearInterval(timer);
                  }, 250);
              } 
          }
          
          on(idHeller, function(dp) {
              if(dp.state.val == 1001) dimmen(1);
              else if(dp.state.val == 1003) clearInterval(timer);
          });
          
          on(idDunkler, function(dp) {
              if(dp.state.val == 1001) dimmen(-1);
              else if(dp.state.val == 1003) clearInterval(timer);
          });
          
          OliverIOO Offline
          OliverIOO Offline
          OliverIO
          schrieb am zuletzt editiert von
          #4

          @paul53 sagte in Konstantes Dimmen bei gedrückter Taste:

          @keromida sagte: über eine While-Schleife das ganze so lange laufen zu lassen bis entweder 100% bzw. 0% erreicht sind oder die Taste vorher losgelassen wird.

          Verwende ein Intervall, das beim langen Drücken gestartet und beim Loslassen gestoppt wird.

          sollte man dazwischen evtl eine pause einbauen?
          die while schleife ist blitzeschnelle bei 100, so das man in real wahrscheinlich kein dimmen wahrnimmt, sondern das licht zack bei 100% ist.

          bei @klassisch sehe ich so ein delay

          Meine Adapter und Widgets
          TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
          Links im Profil

          paul53P 1 Antwort Letzte Antwort
          1
          • OliverIOO OliverIO

            @paul53 sagte in Konstantes Dimmen bei gedrückter Taste:

            @keromida sagte: über eine While-Schleife das ganze so lange laufen zu lassen bis entweder 100% bzw. 0% erreicht sind oder die Taste vorher losgelassen wird.

            Verwende ein Intervall, das beim langen Drücken gestartet und beim Loslassen gestoppt wird.

            sollte man dazwischen evtl eine pause einbauen?
            die while schleife ist blitzeschnelle bei 100, so das man in real wahrscheinlich kein dimmen wahrnimmt, sondern das licht zack bei 100% ist.

            bei @klassisch sehe ich so ein delay

            paul53P Offline
            paul53P Offline
            paul53
            schrieb am zuletzt editiert von
            #5

            @oliverio sagte: sollte man dazwischen evtl eine pause einbauen?

            Das Intervall macht diese Pause.

            Bitte verzichtet auf Chat-Nachrichten, denn die Handhabung ist grauenhaft !
            Produktiv: RPi 2 mit S.USV, HM-MOD-RPI und SLC-USB-Stick mit root fs

            1 Antwort Letzte Antwort
            1
            • KeromidaK Offline
              KeromidaK Offline
              Keromida
              schrieb am zuletzt editiert von Keromida
              #6

              Danke für eure Antworten! Mein Fehler war tatsächlich schlicht und ergreifend, dass ich keinen Delay gesetzt habe für die Übertragung der Telegramme. Dadurch wurde der Übergang nicht gesetzt. Danke für die Hilfe! Hier der vollständige Code.

              /*
              The code makes the use of the IKEA tradfri dimmer switch to adjust a group of lights over a data point or just a single lamp.
              */
              
              const id_ButtonEvent            = 'deconz.0.Sensors.4.buttonevent';     // Input Button Event Data Point
              const id_LampBrightnessLevel    = 'deconz.0.Lights.1.level';            // Input Level Data Point
              const id_LampOnState            = 'deconz.0.Lights.1.on';               // Input OnState Data Point
              const max_Brightness            = 100;  // refers to 100%
              const min_Brightness            = 0;    // Refers to 0%
              const delta_Brightness          = 5;    // in percent
              const setBrightnessValue_Delay  = 250;  // in miliseconds, sets the periodic adjustment of the brightness level
              
              let setBrightnessValue = null;
              
              function setLampStates(delta_BrightnessValue){
                  let Level_Value = getState(id_LampBrightnessLevel).val;
                  if((delta_BrightnessValue >= min_Brightness && Level_Value <= max_Brightness) || (delta_BrightnessValue <= 0 && Level_Value >= 0)) {
                      setBrightnessValue = setInterval(function() {
                          Level_Value = Level_Value + delta_BrightnessValue;
                          setState(id_LampBrightnessLevel, Level_Value);
                          if(Level_Value <= 0 || Level_Value >= 100){
                              clearInterval(setBrightnessValue);
                          }
                      }, setBrightnessValue_Delay);
                  } 
              }
              
              on({id: id_ButtonEvent}, async function(obj){
                  switch(getState(id_ButtonEvent).val){
                      case 1001:{
                          setLampStates(delta_Brightness);
                          break;
                      }
                      case 1002:{
                          setState(id_LampOnState, true);
                          break;
                      }
                      case 1003:{
                          clearInterval(setBrightnessValue);
                          break;
                      }
                      case 2001:{
                          setLampStates(-delta_Brightness);
                          break;
                      }
                      case 2002:{
                          setState(id_LampOnState, false);
                          break;
                      }
                      case 2003:{
                          clearInterval(setBrightnessValue);
                          break;
                      }
                  }
                  
              });
              
              1 Antwort Letzte Antwort
              0
              • KeromidaK Keromida

                Hallo zusammen!

                Ich bin hier leider nicht wirklich fündig geworden und benötige Hilfe bei der Programmierung einer kontinuierlichen Dimmfunktion solange eine Taste gedrückt bleibt. D.h. ich möchte gerne bei gedrückter Taste von 0 bis 100 variabel Dimmen können. Hierfür habe ich mir die Tradfri Dimmer gekauft, welche die Zustände 1001 (Aus, Taste wird gehalten), 1002 (Aus, Taste gedrückt), 1003 (Aus, Taste nach 1001 losgelassen), sowie das Pendent abgebildet auf 200X.

                Geplant war eigentlich das ganze in einem Switch/If-Statement den Tastenzustand abzufragen und über eine While-Schleife das ganze so lange laufen zu lassen bis entweder 100% bzw. 0% erreicht sind oder die Taste vorher losgelassen wird. Hierfür habe ich mir eine Funktion geschrieben, die das theoretisch können sollte.

                function setLevel(SwitchState){
                    if(SwitchState == 1001){
                        while(Level_Value <= 100){
                            Level_Value = getState("deconz.0.Lights.1.level").val + 1;
                            console.log(Level_Value);
                            setState("deconz.0.Lights.1.level", Level_Value);
                        }
                    }
                    else{
                        return;
                    }
                }
                

                Die Funktion wird auch aufgerufen, jedoch ändert sich die Lichtintensität nicht. Lege ich das was innerhalb der While-Schleife liegt außerhalb hin, so wird der Wert um 1% erhöht. Das ganze stellt hier nur ein Example dar, da ich erst die Grundfunktionalität zum laufen kriegen will. Die Abfrage ob die Taste losgelassen wurde fehlt hier. Hat hier jemand einen Tipp woran es liegt? Besten Dank!

                Viele Grüße
                Keromida

                AsgothianA Offline
                AsgothianA Offline
                Asgothian
                Developer
                schrieb am zuletzt editiert von Asgothian
                #7

                @keromida sagte in Konstantes Dimmen bei gedrückter Taste:

                Die Funktion wird auch aufgerufen, jedoch ändert sich die Lichtintensität nicht. Lege ich das was innerhalb der While-Schleife liegt außerhalb hin, so wird der Wert um 1% erhöht. Das ganze stellt hier nur ein Example dar, da ich erst die Grundfunktionalität zum laufen kriegen will.

                Diese Art von schleifen funktionieren prinzipiell nicht.

                Grund dafür ist das der ioBroker asynchron arbeitet. Einige Funktionen (in deinem Beispiel die "setState") Funktion kehren zurück bevor die eigentliche Aktion ausgeführt ist. Das Ausführen kann dann noch wenige ms dauern (manchmal auch wenige 10 ms).

                Dadurch wird in deiner While Schleifer der Helligkeitswert wahrscheinlich nie erhöht werden. Du kannst zur Vereinfachung davon ausgehen das

                • der Befehl setState in Umgangssprache als Merke den Folgenden Wert zur Änderung auf den angegebenen Wert vor ausgedrückt werden kann
                • das diese vorgemerkte Änderung effektiv erst passiert wenn Dein Skript abgearbeitet (oder angehalten) ist (z.bsp via den "Pause" Block
                • das While/for/repeat schleifen in < 1 ms durchlaufen können.

                Wenn Du diesen Annahmen Folgst sollte klar sein das letztendlich der Wert Level_Value nie über getState("deconz.0.Lights.1.level").val + 1 hinaus kommt.

                Die "best practice" Methode für diese Art Aufgaben hat @paul53 bereits vorgestellt, da gibt es wenig zu ergänzen. Sie ist auch einem Konstrukt mit

                While (a) {
                  do something
                  pause(250);
                }
                

                vorzuziehen.

                Du wirst auf Dauer nicht darum herum kommen dich mit timeout und intervall auseinander zu setzen. Die Klassischen "while" schleifen sind für komplexe Aufgaben oft nicht flexibel genug und verleiten dazu zyklisch irgendwelche Werte abzufragen um eine Abbruchbedingung zu bekommen an Statt diese Aufgabe dem ioBroker zu überlassen und die Aktion über einen Trigger zu beenden.

                A.

                ioBroker auf RPi4 - Hardware soweit wie möglich via Zigbee.
                "Shit don't work" ist keine Fehlermeldung, sondern ein Fluch.

                KeromidaK 1 Antwort Letzte Antwort
                1
                • AsgothianA Asgothian

                  @keromida sagte in Konstantes Dimmen bei gedrückter Taste:

                  Die Funktion wird auch aufgerufen, jedoch ändert sich die Lichtintensität nicht. Lege ich das was innerhalb der While-Schleife liegt außerhalb hin, so wird der Wert um 1% erhöht. Das ganze stellt hier nur ein Example dar, da ich erst die Grundfunktionalität zum laufen kriegen will.

                  Diese Art von schleifen funktionieren prinzipiell nicht.

                  Grund dafür ist das der ioBroker asynchron arbeitet. Einige Funktionen (in deinem Beispiel die "setState") Funktion kehren zurück bevor die eigentliche Aktion ausgeführt ist. Das Ausführen kann dann noch wenige ms dauern (manchmal auch wenige 10 ms).

                  Dadurch wird in deiner While Schleifer der Helligkeitswert wahrscheinlich nie erhöht werden. Du kannst zur Vereinfachung davon ausgehen das

                  • der Befehl setState in Umgangssprache als Merke den Folgenden Wert zur Änderung auf den angegebenen Wert vor ausgedrückt werden kann
                  • das diese vorgemerkte Änderung effektiv erst passiert wenn Dein Skript abgearbeitet (oder angehalten) ist (z.bsp via den "Pause" Block
                  • das While/for/repeat schleifen in < 1 ms durchlaufen können.

                  Wenn Du diesen Annahmen Folgst sollte klar sein das letztendlich der Wert Level_Value nie über getState("deconz.0.Lights.1.level").val + 1 hinaus kommt.

                  Die "best practice" Methode für diese Art Aufgaben hat @paul53 bereits vorgestellt, da gibt es wenig zu ergänzen. Sie ist auch einem Konstrukt mit

                  While (a) {
                    do something
                    pause(250);
                  }
                  

                  vorzuziehen.

                  Du wirst auf Dauer nicht darum herum kommen dich mit timeout und intervall auseinander zu setzen. Die Klassischen "while" schleifen sind für komplexe Aufgaben oft nicht flexibel genug und verleiten dazu zyklisch irgendwelche Werte abzufragen um eine Abbruchbedingung zu bekommen an Statt diese Aufgabe dem ioBroker zu überlassen und die Aktion über einen Trigger zu beenden.

                  A.

                  KeromidaK Offline
                  KeromidaK Offline
                  Keromida
                  schrieb am zuletzt editiert von
                  #8

                  @asgothian Danke für die sehr ausführliche und verständliche Antwort! Das bringt jetzt auch eindeutig Licht ins Dunkel wieso mein Code nicht geklappt hat.

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


                  Support us

                  ioBroker
                  Community Adapters
                  Donate

                  881

                  Online

                  32.5k

                  Benutzer

                  81.7k

                  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