Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. [Gelöst] Ist es möglich die Breite dynamisch anzupassen?

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    [Gelöst] Ist es möglich die Breite dynamisch anzupassen?

    This topic has been deleted. Only users with topic management privileges can see it.
    • Peoples
      Peoples last edited by

      Hi,

      ich möchte die Breite eines Elements in Abhängigkeit eines Temperaturwertes mit Hilfe von Javascript anpassen und weis jedoch nicht ob dies möglich ist. Auf die Idee kam ich nachdem ich folgendes Script gefunden habe:

      createState('Farbe.Rollladen.PC', {
          def: '',
          type: 'string',
          name: 'Status-Farbe des Rollladen PC',
          desc: 'Status-Farbe des Rollladen PC abhängig vom Level'
      });
      var idFarbe = 'javascript.0.Farbe.Rollladen.PC'; // auf richtige Instanz achten
      on("hm-rpc.0.NEQ1362981.1.LEVEL", function (data) {
          var level = data.state.val;
          if (level == 100) {
              setState(idFarbe, 'green');
          }
          else if (level === 0){
              setState(idFarbe, 'red');
          }
          else{
              setState(idFarbe, 'orange');
          }
      });
      

      Hier wird die Farbe in Abhängigkeit des Levels angepasst.

      Da ich ein JavaScript Anfänger bin wollte ich fragen ob dann auch etwas in der Art möglich ist:

      createState('Temperatur.Kueche.Fenster', {
          def: '',
          type: 'string',
          name: 'Breite des Elements',
          desc: 'Breite des Elements in Abhängigkeit der Temp'
      });
      var idLaenge = 'javascript.0.Temperatur.Kueche.Fenster'; // auf richtige Instanz achten
      on("hm-rpc.0.MEQxxxxxxx.4.ACTUAL_TEMPERATURE", function (data) {
          var level = data.state.val;
          if (level < 10) {
              setState(idLaenge, '200px');
          }
          else if (level === 0){
              setState(idLaenge, '100px');
          }
      });
      

      Vielleicht kann hier jemand helfen bzw. Auskunft geben?

      Danke

      Peoples

      1 Reply Last reply Reply Quote 0
      • ruhr70
        ruhr70 last edited by

        Müsste eigentlich funktionieren.

        Nur Dein Skript wird die Breite immer auf 200px setzen.

         if (level < 10) {
                setState(idLaenge, '200px');
            }
            else if (level === 0){
                setState(idLaenge, '100px');
            }
        

        Wenn die Größe < 10 ist, dann 200px.

        Das else danach wird nie ausgeführt, da ein Wert von 0 auch schon im ersten Fall greift (ist auch kleiner 10).

        Werte über 10 werden gar nicht betrachtet.

        Welche Werte gibt es denn bei Dir?

        [EDIT]

        Ich würde auch erst einmal einen Datenpunkt anlegen und dort manuell den Wert ändern und schauen, ob sich die Breite Deines Widgets im laufenden VIS ändert. Wenn Das generell funktioniert, dann würde ich mich ans Skript begeben.

        1 Reply Last reply Reply Quote 0
        • Peoples
          Peoples last edited by

          Hi,

          also es geht im Detail darum dass ich eine horizontale "Temperaturlinie" erstellen möchte. Das wollte ich erst durch ein Widget realisieren jedoch ohne Erfolg.

          Näheres hier:

          http://forum.iobroker.net/viewtopic.php?f=30&t=5782

          Auf dem Weg nach einer Alternativen Lösung fand ich dann deinen Beitrag dessen Codeschnippsel ich oben ja schon gezeigt habe. Da kam mir die Idee ein Html Element mit einem Verlauf zu machen:

          .temp_horizontal{
          background: linear-gradient(to right, #1c871b 0px,#f9f927 122px,#f9f927 214px,#ff0000 336px); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
          border: black solid 1px;
          border-radius:2px;
          }
          

          Ohne eine Angabe der Breite, diese jedoch dann in Abhängigkeit der Temperatur zu setzen (bspw.: 2°C -> 10px; 4°C ->15px usw.) doch leider will das nicht wirklich funktionieren. Ich habe jetzt folgendes zusammen "geschrieben":

          createState('Temperatur.Kueche.Fenster', {
              def: '',
              type: 'string',
              name: 'Breite des Elements',
              desc: 'Breite des Elements in Abhängigkeit der Temp'
          });
          var idLaenge = 'javascript.0.Temperatur.Kueche.Fenster'; // auf richtige Instanz achten
          on("testbreite", function (data) {
              var level = data.state.val;
              if (level <= 0) {
                  setState(idLaenge, '20px');
              }
              else if ((level > 2) && (level <= 2 )){
                  setState(idLaenge, '40px');
              }
              else if ((level > 4) && (level <= 6 )){
                  setState(idLaenge, '40px');
              }
              else if ((level > 6) && (level <= 8 )){
                  setState(idLaenge, '40px');
              }
              else if ((level > 8) && (level <= 10 )){
                  setState(idLaenge, '40px');
              }
          });
          

          Das Widget schaut so aus:

          [{"tpl":"tplValueFloat","data":{"oid":"testbreite","visibility-cond":"==","visibility-val":1,"is_comma":"true","is_tdp":"false","factor":"1","signals-cond-0":"==","signals-val-0":true,"signals-icon-0":"/vis/signals/lowbattery.png","signals-icon-size-0":0,"signals-blink-0":false,"signals-horz-0":0,"signals-vert-0":0,"signals-hide-edit-0":false,"signals-cond-1":"==","signals-val-1":true,"signals-icon-1":"/vis/signals/lowbattery.png","signals-icon-size-1":0,"signals-blink-1":false,"signals-horz-1":0,"signals-vert-1":0,"signals-hide-edit-1":false,"signals-cond-2":"==","signals-val-2":true,"signals-icon-2":"/vis/signals/lowbattery.png","signals-icon-size-2":0,"signals-blink-2":false,"signals-horz-2":0,"signals-vert-2":0,"signals-hide-edit-2":false,"visibility-groups-action":"hide"},"style":{"left":"979px","top":"272px","z-index":"20","color":"white","background-color":"{javascript.0.Farbe.Rollladen.PC}","border-width":"2px","border-style":"solid","height":"30px","width":"{javascript.0.Temperatur.Kueche.Fenster}"},"widgetSet":"basic"}]
          

          Doch wie bereits erwähnt bin ich bei IoBroker blutigster Anfänger und wüsste auch nicht wo ich da den Fehler suchen sollte.

          Gruß

          Peoples

          1 Reply Last reply Reply Quote 0
          • ruhr70
            ruhr70 last edited by

            @peoples:

            Ohne eine Angabe der Breite, diese jedoch dann in Abhängigkeit der Temperatur zu setzen (bspw.: 2°C -> 10px; 4°C ->15px usw.) doch leider will das nicht wirklich funktionieren. Ich habe jetzt folgendes zusammen "geschrieben":

            createState('Temperatur.Kueche.Fenster', {
                def: '',
                type: 'string',
                name: 'Breite des Elements',
                desc: 'Breite des Elements in Abhängigkeit der Temp'
            });
            var idLaenge = 'javascript.0.Temperatur.Kueche.Fenster'; // auf richtige Instanz achten
            on("testbreite", function (data) {
                var level = data.state.val;
                if (level <= 0) {
                    setState(idLaenge, '20px');
                }
                else if ((level > 2) && (level <= 2 )){
                    setState(idLaenge, '40px');
                }
                else if ((level > 4) && (level <= 6 )){
                    setState(idLaenge, '40px');
                }
                else if ((level > 6) && (level <= 8 )){
                    setState(idLaenge, '40px');
                }
                else if ((level > 8) && (level <= 10 )){
                    setState(idLaenge, '40px');
                }
            });
            ```` `  
            

            Du bist auf einen guten Weg 😉

            coole Idee.

            Ich habe Dein Widget und das dazugehörige Binding gerade getestet. Der Farbverlauf wird dargestellt und wenn man in den Datenpunkt die Breite reinschreibt verändert sich die Widgetbreite in VIS. Das klappt also grundsätzlich.:-)

            Einzig Dein Skript verstehe ich nicht.

            Welcher Datenpunkt soll das denn sein?

            on("testbreite", function (data) {
            

            Du solltest im Admin unter Objekte im Datenpunkt javascript.0.Temperatur.Kueche.Fenster zum Testen Deine gewünschte Breite reinschreiben 100px, 300px usw. Habe ich mit Deinem Widget vorhin gemacht. Funktioniert.

            Nun musst Du Dein Skript anpassen auf den richtigen Datenpunkt der Temperatur.

            Welcher ist denn das?

            [EDIT]

            • Also CSS für den Farbverlauf: funktioniert

            • Widget: funktioniert

            • Das Binding mit der Breite aus einem Datenpunkt: funktioniert

            Jetzt ist es nur noch Dein Skript mit der richtigen Subscription.

            An Deinem on() musst Du arbeiten und an Deinem if else Baum 😉

            1 Reply Last reply Reply Quote 0
            • ruhr70
              ruhr70 last edited by

              @peoples:

              Doch wie bereits erwähnt bin ich bei IoBroker blutigster Anfänger und wüsste auch nicht wo ich da den Fehler suchen sollte. `

              Das Widget und die CSS Anpassung sieht nicht nach einem Anfänger aus.

              Probier mal (2. Zeile ID Deines Homematic Temperatur Datenpunkts eintragen):

              var idLaenge    = 'Temperatur.Kueche.Fenster';
              var idTemp      = "hm-rpc.0.MEQxxxxxxx.4.ACTUAL_TEMPERATURE";
              
              var scala       = 10; // Temperatur * scala = Pixelbreite
              var logOn       = true;
              
              createState(idLaenge,"init", {
                  name: 'Breite des Elements',
                  desc: 'Breite des Elements in Abhängigkeit der Temp',
                  type: 'string',
                  unit: '',
                  role: 'value'
              });
              
              function celsiusToPixel(temp) {
                  var pixel = Math.round(temp*scala).toString()+"px";
                  if(logOn) log("Temperatur: " + temp + " -> " + pixel);
                  return pixel;
              }
              
              function main() {
                  setState("javascript."+instance+"."+idLaenge,celsiusToPixel(getState(idTemp).val));
              }
              
              on({id: idTemp ,change:'ne'}, function(obj) {
                  if(logOn) log("neue Temperatur: " + obj.state.val);
                  setState("javascript."+instance+"."+idLaenge,celsiusToPixel(obj.state.val));
              });
              
              //Skriptstart: einmal schreiben
              setTimeout(main,    500);
              
              1 Reply Last reply Reply Quote 0
              • Peoples
                Peoples last edited by

                Hi,

                Anfänger bezieht sich auf IoBroker und Javascript, in html und CSS konnte ich schon die ein oder andere Erfahrung sammeln 😄

                Ich habe es jetzt folgender Maßen im Test und anscheinend funktioniert das:

                createState('Temperatur.Kueche.Fenster', {
                    def: '',
                    type: 'string',
                    name: 'Breite des Elements',
                    desc: 'Breite des Elements in Abhängigkeit der Temp'
                });
                var idLaenge = 'javascript.0.Temperatur.Kueche.Fenster'; // auf richtige Instanz achten
                on("hm-rpc.0.NEQ1411563.4.ACTUAL_TEMPERATURE", function (data) {
                    var level = data.state.val;
                    if (level <= 1)  setState(idLaenge, '0px');
                    if ((level > 2) && (level <= 3)) setState(idLaenge, '5px');
                    if ((level > 3) && (level <= 4)) setState(idLaenge, '10px');
                    if ((level > 4) && (level <= 5)) setState(idLaenge, '15px');
                    if ((level > 5) && (level <= 6)) setState(idLaenge, '20px');
                    if ((level > 6) && (level <= 7)) setState(idLaenge, '25px');
                    if ((level > 7) && (level <= 8)) setState(idLaenge, '30px');
                    if ((level > 8) && (level <= 9)) setState(idLaenge, '40px');
                    if ((level > 9) && (level <= 10)) setState(idLaenge, '50px');
                    if ((level > 10) && (level <= 11)) setState(idLaenge, '60px');
                    if ((level > 11) && (level <= 12)) setState(idLaenge, '70px');
                    if ((level > 12) && (level <= 13)) setState(idLaenge, '80px');
                    if ((level > 13) && (level <= 14)) setState(idLaenge, '90px');
                    if ((level > 14) && (level <= 15)) setState(idLaenge, '100px');
                    if ((level > 15) && (level <= 16)) setState(idLaenge, '110px');
                    if ((level > 16) && (level <= 17)) setState(idLaenge, '120px');
                    if ((level > 17) && (level <= 18)) setState(idLaenge, '130px');
                    if ((level > 18) && (level <= 19)) setState(idLaenge, '140px');
                    if ((level > 19) && (level <= 20)) setState(idLaenge, '150px');
                    if ((level > 20) && (level <= 21)) setState(idLaenge, '160px');
                    if ((level > 21) && (level <= 22)) setState(idLaenge, '170px');
                    if ((level > 22) && (level <= 23)) setState(idLaenge, '180px');
                    if ((level > 23) && (level <= 24)) setState(idLaenge, '190px');
                    if ((level > 24) && (level <= 25)) setState(idLaenge, '200px');
                    if ((level > 25) && (level <= 26)) setState(idLaenge, '210px');
                    if ((level > 26) && (level <= 27)) setState(idLaenge, '220px');
                    if ((level > 27) && (level <= 28)) setState(idLaenge, '230px');
                    if ((level > 28) && (level <= 29)) setState(idLaenge, '240px');
                    if ((level > 29) && (level <= 30)) setState(idLaenge, '250px');
                    if ((level > 30) && (level <= 31)) setState(idLaenge, '260px');
                    if ((level > 31) && (level <= 32)) setState(idLaenge, '270px');
                    if ((level > 32) && (level <= 33)) setState(idLaenge, '280px');
                    if ((level > 33) && (level <= 34)) setState(idLaenge, '290px');
                    if ((level > 34) && (level <= 35)) setState(idLaenge, '300px');
                    if ((level > 35) && (level <= 36)) setState(idLaenge, '310px');
                    if ((level > 36) && (level <= 37)) setState(idLaenge, '320px');
                    if ((level > 37) && (level <= 38)) setState(idLaenge, '325px');
                    if ((level > 38) && (level <= 39)) setState(idLaenge, '330px');
                    if ((level > 39) && (level <= 40)) setState(idLaenge, '335px');
                    if (level >= 40)  setState(idLaenge, '340px');
                
                });
                
                

                Das Problem ist nämlich dass ich eine max. Breite von 340px habe bedingt durch das angestrebte Design.

                Da stellt sich mir jedoch noch folgende Frage: Ist es möglich über die Auswahl der Objekt ID im Widget, diese an das Script mit weiter zu reichen?

                So bräuchte man nicht für jedes Thermostat ein sep. Script oder?.

                Deine Lösung ist natürlich viel professioneller, werde versuchen ob ich das irgendwie so anpassen kann dass es auf 340 Pixel auf geht.

                Auf jeden Fall Vielen Dank !

                Gruß

                Peoples

                1 Reply Last reply Reply Quote 0
                • ruhr70
                  ruhr70 last edited by

                  @peoples:

                  Das Problem ist nämlich dass ich eine max. Breite von 340px habe bedingt durch das angestrebte Design. `

                  Wenn Du bei 40° Maximum erreichen willst, dann kannst Du die Variable Scale oben auf 8.5 setzen (340 / 40 = 8.5).

                  Und dann in der Funktion den Maxmimalwert auf 340px begrenzen.

                  
                  var scala       = 8.5; // Temperatur * scala = Pixelbreite
                  var maxWidth    = 340;
                  
                  // ...
                  
                  function celsiusToPixel(temp) {
                      var pixelNum =  = Math.round(temp*scala);
                      if(pixelNum > maxWidth) pixelNum = maxWidth;
                      var pixelStr = pixelNum.toString()+"px";
                      if(logOn) log("Temperatur: " + temp + " -> " + pixelStr);
                      return pixelStr;
                  }
                  

                  [EDIT]
                  @peoples:

                  Da stellt sich mir jedoch noch folgende Frage: Ist es möglich über die Auswahl der Objekt ID im Widget, diese an das Script mit weiter zu reichen?

                  So bräuchte man nicht für jedes Thermostat ein sep. Script oder?. `

                  Da kenne ich leider keine Möglichkeit.

                  Du kannst aber ein Skript schreiben, welches auf mehrere Thermostate reagiert und dann mehrere Datenpunkte ändert.

                  1 Reply Last reply Reply Quote 0
                  • P
                    pix last edited by

                    Hallo,

                    warum nutzt du nicht die binding-Funktion für die Breite des Balkens als Style-Angabe?

                    Hab es gerade getestet. Dein Skript abgewandelt (andere EIngabequelle)

                    createState('TestbreiteEingabe', 0, true, {
                        def: 0,
                        type: 'number',
                        name: 'Breite des Elements',
                        desc: 'Breite des Elements in Abhängigkeit der Temp'
                    });
                    createState('Testbreite', 0, true, {
                        def: 0,
                        type: 'number',
                        name: 'Breite des Elements',
                        desc: 'Breite des Elements in Abhängigkeit der Temp'
                    });
                    var idLaenge = 'javascript.2.Testbreite'; // auf richtige Instanz achten
                    on("javascript.2.TestbreiteEingabe", function (data) {
                        var level = data.state.val;
                        var testbreite = 0;
                        if (level > 1) {
                            testbreite = 100/40 * level;
                            if (testbreite > 100) testbreite = 100;
                        }  
                        log(testbreite);
                        setState(idLaenge, testbreite);
                    });
                    
                    

                    Zum Testen gebe ich jetzt im Admin-Reiter Objekte die Zahlen einfach per Hand in TestbreiteEingabe ein. natürlich geht auch jede andere Quelle.

                    habe die Datenpunkte auf Typ Zahl geändert und nutze die Instanz javascript.2.

                    Jetzt VIS:

                    [{"tpl":"tplHtml","data":{"g_fixed":false,"g_visibility":false,"g_css_font_text":false,"g_css_background":false,"g_css_shadow_padding":false,"g_css_border":false,"g_gestures":false,"g_signals":false,"visibility-cond":"==","visibility-val":1,"visibility-groups-action":"hide","refreshInterval":"0","signals-cond-0":"==","signals-val-0":true,"signals-icon-0":"/vis/signals/lowbattery.png","signals-icon-size-0":0,"signals-blink-0":false,"signals-horz-0":0,"signals-vert-0":0,"signals-hide-edit-0":false,"signals-cond-1":"==","signals-val-1":true,"signals-icon-1":"/vis/signals/lowbattery.png","signals-icon-size-1":0,"signals-blink-1":false,"signals-horz-1":0,"signals-vert-1":0,"signals-hide-edit-1":false,"signals-cond-2":"==","signals-val-2":true,"signals-icon-2":"/vis/signals/lowbattery.png","signals-icon-size-2":0,"signals-blink-2":false,"signals-horz-2":0,"signals-vert-2":0,"signals-hide-edit-2":false,"html":"{javascript.2.Testbreite}"},"style":{"left":"83px","top":"814px","z-index":"20","width":"491px","height":"42px"},"widgetSet":"basic"}]
                    

                    Das ist ein HTML Widget, welches ein div-Container malt, dessen Breite über CSS-Anweisung festgelegt wird. Diese Anweisung wird als Binding eingefügt. Die Hintergrundfarbe ist noch als rot festgelegt, kann aber genauso als Binding dynamisch gesetzt werden.

                    {javascript.2.Testbreite}
                    

                    Das Widget hat eine feste Breite (passend zu deinem Layout), der Container im Widget passt seine Breite dynamisch an.

                    Gruß

                    Pix

                    Hier noch ein Bild: Bindings lassen sich in allen Felder in VIS verwenden: 261_bildschirmfoto_2017-03-21_um_13.23.26.jpg

                    1 Reply Last reply Reply Quote 0
                    • Peoples
                      Peoples last edited by

                      Ich versuche gerade noch die einzelnen Schritte zu erörtern bzw. zu verstehen da ich ja kein JavaScript - Profi bin.

                      Aber die Lösung ist genial, so kann ich die Breite zentral in CSS anpassen und bin trotzdem so flexiebel die Breite bei Bedarf mal schnell zu verändern.

                      TOP

                      Dank dir!

                      1 Reply Last reply Reply Quote 0
                      • coyote
                        coyote Most Active last edited by

                        Hänge mich hier auch mal mit an, da ich nach der gleichen Lösung für meine Visualisierung gesucht hatte wie peoples.

                        Gestern Abend mal noch schnell die Lösung von pix ausprobiert und funktioniert perfekt. Einfach klasse was mit iobroker und vis relativ unkompliziert machbar ist.

                        1 Reply Last reply Reply Quote 0
                        • Peoples
                          Peoples last edited by

                          Hi,

                          ergänzend zu der Javascript-Lösung hier die von mir mittlerweile genutze Umsetzung ohne Scripte direkt in Vis mit Binding.

                          Der Widgetexport (Hier muss das Thermostat noch angepasst werden):

                          ! ````
                          [{"tpl":"tplHtml","data":{"g_fixed":false,"g_visibility":false,"g_css_font_text":false,"g_css_background":true,"g_css_shadow_padding":false,"g_css_border":true,"g_gestures":false,"g_signals":false,"visibility-cond":"==","visibility-val":1,"visibility-groups-action":"hide","refreshInterval":"0","signals-cond-0":"==","signals-val-0":true,"signals-icon-0":"/vis/signals/lowbattery.png","signals-icon-size-0":0,"signals-blink-0":false,"signals-horz-0":0,"signals-vert-0":0,"signals-hide-edit-0":false,"signals-cond-1":"==","signals-val-1":true,"signals-icon-1":"/vis/signals/lowbattery.png","signals-icon-size-1":0,"signals-blink-1":false,"signals-horz-1":0,"signals-vert-1":0,"signals-hide-edit-1":false,"signals-cond-2":"==","signals-val-2":true,"signals-icon-2":"/vis/signals/lowbattery.png","signals-icon-size-2":0,"signals-blink-2":false,"signals-horz-2":0,"signals-vert-2":0,"signals-hide-edit-2":false,"html":" 1 ? 100/40value:'';value > 100? "100" : 100/40value}%">","lc-type":"last-change","lc-is-interval":true,"lc-is-moment":false,"lc-format":"","lc-position-vert":"top","lc-position-horz":"right","lc-offset-vert":0,"lc-offset-horz":0,"lc-font-size":"12px","lc-font-family":"","lc-font-style":"","lc-bkg-color":"","lc-color":"","lc-border-width":"0","lc-border-style":"","lc-border-color":"","lc-border-radius":10,"lc-zindex":0},"style":{"left":"521px","top":"255px","z-index":"3","width":"340px","height":"10px","border-width":"1px","border-style":"solid","border-color":"black","border-radius":"2px","background-color":"#404040"},"widgetSet":"basic"}]

                          
                          Und hier der CSS-Auszug:
                          

                          .temp_horizontal{
                          background: linear-gradient(to right, #0e16e4 0px,#6488a2 60px,#dfab0d 110px,#fdff00 240px,#f00000 310px); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */

                          }

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

                          Support us

                          ioBroker
                          Community Adapters
                          Donate

                          445
                          Online

                          31.9k
                          Users

                          80.2k
                          Topics

                          1.3m
                          Posts

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