Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. On event/trigger in JavaScript Klasse verwenden

    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

    On event/trigger in JavaScript Klasse verwenden

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

      Hallo,
      ich bin Momentan dabei die JavaSkripte für die Beleuchtung in meinem Heim zu verbessern/überarbeiten.

      Ich würde gerne eine Klasse für die Beleuchtung anlegen.
      Das Skript sieht folgendermaßen aus:

      //room and light names
      var roomName = "livingRoom"
      var lightName = "light1"
      
      //physical light
      var stateID = 'zigbee.0.00158d000484f150.state'/*Switch state*///'zigbee.0.group_1.state'/*Switch state*/
      var brighnessID = 'zigbee.0.00158d000484f150.brightness'/*Brightness*///'zigbee.0.group_1.brightness'/*Brightness*/
      var colortempID = 'zigbee.0.00158d0001aa6b65.colortemp'/*Color temperature*///'zigbee.0.group_1.colortemp'/*Color temperature*/
      var rgbcolorID = ""
      
      //physical button
      var buttonClickID = 'shelly.0.SHSW-1#500291F0A6E5#1.Relay0.Input'/*Input / Detach*/
      var buttonDoubleClickID = ""
      var buttonHoldID = ""
      
      
      class light {
          constructor(roomName, lightName, stateID, brightnessID, colorTempID, RGBcolorID, buttonClickID, buttonDoubleClickID, buttonHoldID) {
              this.roomName = roomName
              this.lightName = lightName
              this.stateID = stateID
              this.brighnessID = brightnessID
              this.colorTempID = colorTempID
              this.RGBcolorID = RGBcolorID
              this.buttonClickID = buttonClickID
              this.buttonDoubleClickID = buttonDoubleClickID
              this.buttonHoldID = buttonHoldID
      
              log(this.stateID)   //debug
      
              //set new folder for the light and objects for state, brightness etc. but only if parameter was given to constructor
              if(this.stateID != ""){
                  //create userdata object for virtual light 
                  createState(("0_userdata.0." + roomName + "." + this.lightName + ".state"), false, function() {
                      //Init physical light
                      log(this.stateID)   //debug
                      log(stateID)    //debug
                      log("0_userdata.0." + this.roomName + "." + this.lightName + ".state")  //debug
                      log(getState("0_userdata.0.livingRoom.light1.state").val)   //debug
                      log(getState("0_userdata.0." + roomName + "." + this.lightName + ".state").val) //debug
                      setState(this.stateID, getState("0_userdata.0." + roomName + "." + this.lightName + ".state").val)
                  });
              }
              if(this.brighnessID != ""){
                  createState(("0_userdata.0." + this.roomName + "." + this.lightName + ".brightness"), 255, function() {
                      setState(this.brighnessID, getState("0_userdata.0." + roomName + this.lightName + ".brightness").val)
                  });
              } 
              if(this.colorTempID != ""){
                  createState(("0_userdata.0." + this.roomName + "." + this.lightName + ".colorTemp"), 100, function() {
                      setState(this.colorTempID, getState("0_userdata.0." + roomName + "." + this.lightName + ".colorTemp").val)
                  });
              } 
              if(this.RGBcolorID != ""){
                  createState(("0_userdata.0." + this.roomName + "." + this.lightName + ".RGBcolor"), false, function() {
                      setState(this.RGBcolorID, getState("0_userdata.0." + roomName + "." + this.lightName + ".RGBcolor").val)
                  });
              } 
          }
      
          //turn on/off light
          setLight(trigger){
              if(getState(this.stateID).val){
                  setState(this.stateID, false);
                  setState("0_userdata.0." + this.roomName + "." + this.lightName + ".state", false, true)
                  log("Light turned off by " + trigger)
              }
              else{
                  setState(this.stateID, true);
                  setState("0_userdata.0." + this.roomName + "." + this.lightName + ".state", true, true)
                  log("Light turned on by " + trigger)
              }
          }
          //Methods for changing brightness, colortemp and rgb
      
      
          //Trigger shelly button click (momentary switch) 
          //on({id: this.buttonClickID, val: true}, function (obj) {    //not working
              //this.setLight("button") //Not working
          //})  //not working
      
          //Trigger button double tap and hold
      
          //Trigger from siri over "0_userdata.0.livingRoom.light1.state"
      
      }
      
      const livingRoomLight = new light(roomName, lightName, stateID, brighnessID, colortempID, rgbcolorID, buttonClickID, buttonDoubleClickID, buttonHoldID);
      
      
      
      

      Es wird ein virtuelles Licht durch createState im Konstruktor angelegt. Je nach Übergabe-Parameter werden neben dem Objekt State auch die Objekte Brightness, ColorTemp und RGB angelegt. Zudem wird das “physische Licht” (in dem Fall Zigbee) initialisiert - state false, brightness 255 etc.

      Es wurde testhalber eine Methode angelegt um das Licht erstmal ein/auszuschalten. Die Methode funktioniert, wenn der Trigger ausserhalb der Klasse angelegt wird.

      Ich würde gerne nun mehrer Trigger in der Klasse anlegen (ab Zeile 71). Im Regelfall gibt es pro Raum einen Lichtschalter (Shelly/Zigbee) und einen virtuellen Schalter mittels Siri (yahka) welcher die durch createState angelegten Objekte in userdata ändert.
      Wie kann ich am besten einen Trigger in der Klasse realisieren? Das obere Beispiel funktioniert jedenfalls nicht und der Output sieht folgendermaßen aus:

      00:25:50.872	info	javascript.0 (2155) Start javascript script.js.living_room.living_room_light_oop
      00:25:50.885	info	javascript.0 (2155) script.js.living_room.living_room_light_oop: zigbee.0.00158d000484f150.state
      00:25:50.886	info	javascript.0 (2155) script.js.living_room.living_room_light_oop: registered 0 subscriptions and 0 schedules
      00:25:50.962	info	javascript.0 (2155) script.js.living_room.living_room_light_oop: undefined
      00:25:50.962	info	javascript.0 (2155) script.js.living_room.living_room_light_oop: zigbee.0.00158d000484f150.state
      00:25:50.963	info	javascript.0 (2155) script.js.living_room.living_room_light_oop: 0_userdata.0.undefined.undefined.state
      00:25:50.963	info	javascript.0 (2155) script.js.living_room.living_room_light_oop: false
      00:25:50.964	warn	javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:40:21)
      00:25:50.964	info	javascript.0 (2155) script.js.living_room.living_room_light_oop: null
      00:25:50.965	warn	javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:41:40)
      00:25:50.967	warn	javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:41:17)
      00:25:50.971	warn	javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:46:44)
      00:25:50.973	warn	javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:46:17)
      00:25:50.977	warn	javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:51:44)
      00:25:50.979	warn	javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:51:17)
      

      Die Objekte in Userdata werden aber angelegt:
      cf00899b-00d8-4f8b-92c3-cfedce5977d3-image.png

      Warum wird this.stateID in Zeile 27 ausgegeben aber in Zeile 33 nicht?

      Sollte die Klasse funktionieren, wie kann ich Objekte in neuen (leeren) Skripten anlegen ohne jedes Mal die Klasse kopieren zu müssen?
      Mir ist bekannt das man mittels TypeSkript Funktionen auslagern kann.
      Muss ich mit der Klasse später auch diesen Weg gehen?

      Für heute genug IOBroker - ich geh jetzt ins Bett.

      Grüße
      Christoph

      Der IOBroker wurde vor ein paar Tagen von 3.x.x auf 4.0.24 geupdatet.
      Node.js v12.22.6
      NPM 6.14.15

      Raspberry ist Model 4 mit 4gb RAM

      OliverIO W 2 Replies Last reply Reply Quote 0
      • OliverIO
        OliverIO @csuser last edited by OliverIO

        @csuser sagte in On event/trigger in JavaScript Klasse verwenden:

        Warum wird this.stateID in Zeile 27 ausgegeben aber in Zeile 33 nicht?

        irgendwas stimmt mit den zeilennnummern nicht.
        weder in 27 noch in 33 gibt es was mit this.stateID
        aber ich vermute mal das es sich einmal im callback der createstate funktion befindet und einmal ausserhalb.

        createstate ist eine async funktion, daher ist this im callback nicht deine klasse, sondern etwas anderes (musst schauen was der callback bereitstellt), daher steht stateID unter this dort nicht zur Verfügung.
        um das zu lösen könntest du vor createState den Wert aus this.stateID einer Variable mit let zuweisen oder die createstate funktion an den aktuellen scope binden
        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind?retiredLocale=de
        allerdings finde ich das persönlich sehr hässlich (obwohl ich es auch schon häufig so eingesetzt habe)

        hier noch dazu was zum lesen
        https://www.pluralsight.com/guides/javascript-callbacks-variable-scope-problem
        meine 2. Lösung hat er unter ES6 verzeichnet.
        Die bind Lösung steht gar nicht da. Aber bind macht ungefähr sowas wie die Funktion zusammen mit der Variable in eine closure einpacken und die funktion dann verwenden

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

          @oliverio sagte in On event/trigger in JavaScript Klasse verwenden:

          createstate ist eine async funktion, daher ist this im callback nicht deine klasse, sondern etwas anderes (musst schauen was der callback bereitstellt), daher steht stateID unter this dort nicht zur Verfügung.

          Genau. Grund ist der Context von this. Daher am besten mit Arrow-Functions in den Callbacks arbeiten.

          1 Reply Last reply Reply Quote 0
          • W
            WolfgangFB @csuser last edited by

            @csuser
            Das Thema ist zwar schon ziemlich alt, weil ich aber selbst vor diesem Problem stand hier die Lösung wie man Trigger in einer Klasse realisiert: Man muss das in eine Methode auslagern (die man aber im constructor ausführen kann)

            class MyClass{
                constructor(){
                    this.SetUpTrigger();
                }
                SetUpTrigger(){
                    on("javascript.0.Bla.Blub", function(obj){
                        console.log(obj.id)});
                }
            }
            
            let Class = new MyClass();
            
            
            1 Reply Last reply Reply Quote 0
            • First post
              Last post

            Support us

            ioBroker
            Community Adapters
            Donate

            983
            Online

            31.8k
            Users

            80.0k
            Topics

            1.3m
            Posts

            4
            4
            506
            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