Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Error/Bug
    4. Maxcul ist komplett unbrauchbar (geloest mit 0.5.2)

    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

    Maxcul ist komplett unbrauchbar (geloest mit 0.5.2)

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

      Mein Vorschlag:

      CommunicationServiceLayer.prototype.writeQueue = function() {

      if (!this._queuedWrites.length) return Promise.resolve(true);

      this._queueSendInProgress = true;

      var command = this._queuedWrites.shift();

      var cmd = command.trim();

      var len = this._queuedWrites.length;

      return this._serialDeviceInstance.writeAsync(command).then(() => {

      env.logger.debug('Send Packet to CUL: ' + cmd + ', awaiting drain event');

      return this._serialDeviceInstance.drainAsync()

      }).then(() => {

      env.logger.debug('serial port buffer have been drained');

      var delay = 3000;

      if (cmd === 'X') delay = 0;

      Promise.delay(delay).then(() => {

      env.logger.debug('delayed ' + delay + 'ms, ' + len + ' in queue');

      this._queueSendInProgress = false;

      return this.writeQueue();

      });

      });

      };

      Delay = 0 bei X geht, hab ich probiert.

      Fuer mich sehen die Antworten auf die Delays deutlich weniger kritisch aus wenn sie groesser sind, da X jetzt nicht mehr drin ist verzoegert das auch nicht wirklich was. Bei vielen Kommandos bekommt man sowieso per LOVF eins auf die Muetze, da kann man gleich von Haus aus laenger warten.

      Meine Idee vom Anfang bestaetigt sich irgendwie, Kommando schicken, dann warten (zwischendrin ACK bekommen), dann naechstes Kommando schicken.

      Laut irgendeinem Artikel ist die laengste Zeit fuer ein Kommando + ACK bei ca 2,1 Sekunden. Also sollten wir wenigstens 3 Sekunden warten (als Puffer).

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

        Hi,

        dann hast Du zu früh installiert gehabt 🙂 Seit der "Version von nach 22:13 Uhr!!!" vergleiche ich einfach das erste Zeichen 🙂

        Habe jetzt Delay auf 0 gesetzt.

        Habe Queue längen-Logging an mehreren Stellen eingebaut.

        3000ms als Standard Delay übernommen.

        AN sich sollte es nicht nötig sein auf das Ack zu warten … aber ehrlich: Mir egal :-))

        Wenn andere User damit Probleme haben melden Sie sich (hoffentlich).

        Please try Github version.

        1 Reply Last reply Reply Quote 0
        • S
          skraw.iobroker last edited by

          Bin leider erst jetzt dazu gekommen.

          Wenn ich das richtig sehe ignorierst Du auch Zs Kommandos wenn sie schon in der Queue sind?

          Jetzt die Frage die kommen musste:

          Waere es kompliziert den Delay-Wert in der Konfiguration fuer den User einstellbar zu machen? Ich meine ich kann einfach die Stelle im Code editieren, aber das ist ja eigentlich nicht wirklich der Weg von ioBroker …

          Ausserdem koennte es ja verschiedene Hardware geben die auch komplett unterschiedlich reagiert. Irgendwas braucht vielleicht gar kein Delay...

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

            @skraw.iobroker:

            Bin leider erst jetzt dazu gekommen.

            Wenn ich das richtig sehe ignorierst Du auch Zs Kommandos wenn sie schon in der Queue sind? `

            Ich ignoriere alles was schon in der Queue ist - damit auch Zs Kommandos, aber nur wenn die komplette Message schon drin ist. Am Ende will ich nur sicherstellen das ggf retries oder nicht rausgehen wenn die originale Message noch nicht mal draussen ist 🙂

            @skraw.iobroker:

            Jetzt die Frage die kommen musste:

            Waere es kompliziert den Delay-Wert in der Konfiguration fuer den User einstellbar zu machen? Ich meine ich kann einfach die Stelle im Code editieren, aber das ist ja eigentlich nicht wirklich der Weg von ioBroker …

            Ausserdem koennte es ja verschiedene Hardware geben die auch komplett unterschiedlich reagiert. Irgendwas braucht vielleicht gar kein Delay... `
            Geht grundsätzlich, würde jetzt das mal so releasen und auf weiteres Feedback anderer User warten

            1 Reply Last reply Reply Quote 0
            • S
              skraw.iobroker last edited by

              Die Idee warum ich das mit der User-Config auch frage liegt auch darin, dass man in dem Dropdown Menu dann verschiedene Standard-Werte fuer verschiedene Hardware vorgeben koennte.

              Wenn ein nicht-nanoCUL beispielsweise kein Delay braeuchte koennte man:

              <delay-feld>0 (supercoole Hardware)

              5000 (nanoCUL)

              machen…

              PS: Bisher laeuft alles gut.

              Ich betreibe jetzt 15 Thermostate und 13 Fensterkontakte ziemlich problemlos.

              Was mir fehlt ist eine Statistik wo ich ueber die Zeit (sagen wir 24h) sehen kann wie hoch die Credits sind. Das wuerde es ermoeglichen konkret festzustellen wenn man wirklich keine Zeitslots mehr hat oder wann es sich etwas staut...</delay-feld>

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

                So, ich habe die Änderungen jetzt als 0.5.2 veröfentlicht. Ist morgen im "Latest".

                Für die "Konfigurieren des Delays würde ich Dich bitten noch ein Github Issue anzulegen. Danke!

                1 Reply Last reply Reply Quote 0
                • S
                  skraw.iobroker last edited by

                  Hinsichtlich der Delays gaebe es da noch eine Frage:

                  Wenn im Moment ein Kommando gesendet wird und als Antwort ein LOVF kommt bedeutet das ja, dass das Kommando effektiv weggeworfen wurde. Koennte man aus den sonstigen uebergebenen Werten beim LOVF nicht erkennen wie lange man eigentlich warten muesste bevor ueberhaupt wieder ein Kommando tatsaechlich gesendet werden kann? Jetzt wo die Delay-Funktion da ist koennte man diese ja auch nutzen um in diesem Fall zu warten bis tatsaechlich wieder ein Kommando absetzbar ist… ?

                  1 Reply Last reply Reply Quote 0
                  • S
                    skraw.iobroker last edited by

                    Wie kann ich im lib/communication-layer.js den Wert von info.quota rausfinden?

                    Ich moechte beim Warten in der Queue zumindest ausgeben wie der aktuelle Credit steht …

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

                      In Zeile 86 kommen die an und werden dann als Event "creditsReceived" zu maxcul.js gegeben und der gibt es weiter an iobroker-Adapter.

                      Also wenn dort in Zeile 86 im communication-layer.js

                      1 Reply Last reply Reply Quote 0
                      • S
                        skraw.iobroker last edited by

                        Wuerdest Du zustimmen, dass es gar keinen Sinn macht ein gequeuetes Paket zu senden wenn die Credits nicht reichen (also wahrscheinlich unter ca 220 sind)?

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

                          Also zu den "credits" was ich von FS20 und CUL weiss ist:

                          900 ist glaube die ms pro 15 Minuten die erlaubt sind (4*900=3600=36s was 1% der Stunde sind).

                          Eine FS20 nachricht dauert mindestens 220ms, also ja unter 220 macht keinen Sinn.

                          Wenn man das mal für Max! googelt dann finde ich z.B. das hier: https://groups.google.com/d/msg/CUL-fan … pJu9Uy9GEJ

                          Das würde bedeuten das eine Max!-Nachricht 109ms dauert/kostet ... denke die Wahrheit liegt irgendwie dazwischen :-)) kannst ja mal explizit einwas senden und schauen wie sich das Limit verhält.

                          1 Reply Last reply Reply Quote 0
                          • S
                            skraw.iobroker last edited by

                            Das hier verstehe ich nicht:

                            maxcul.0	2018-03-12 19:13:56.476	debug	LOVF: credits=503
                            maxcul.0	2018-03-12 19:13:56.475	debug	incoming raw data from CUL: LOVF
                            maxcul.0	2018-03-12 19:13:56.474	debug	serial port buffer have been drained
                            maxcul.0	2018-03-12 19:13:56.455	debug	Send Packet to CUL: Zs0b0100401234561b7e310067, awaiting drain event
                            maxcul.0	2018-03-12 19:13:56.448	debug	delayed next send by 5000ms (Queue length left = 7, Current Credit = 503)
                            maxcul.0	2018-03-12 19:13:56.383	debug	Ignore command because already in queue X
                            maxcul.0	2018-03-12 19:13:51.451	debug	redis pmessage io.maxcul.0.* io.maxcul.0.info.limitOverflow {"val":true,"ack":true,"ts":1520878431441,"q":0,"from":"system.adapter.maxcul.0","lc":1520878431441}
                            maxcul.0	2018-03-12 19:13:51.450	debug	serial port buffer have been drained
                            maxcul.0	2018-03-12 19:13:51.443	debug	LOVF: credits=503
                            maxcul.0	2018-03-12 19:13:51.442	debug	incoming raw data from CUL: LOVF
                            maxcul.0	2018-03-12 19:13:51.422	debug	Send Packet to CUL: Zs0b0100401234561b7edc0067, awaiting drain event
                            maxcul.0	2018-03-12 19:13:51.416	debug	delayed next send by 5000ms (Queue length left = 8, Current Credit = 503)
                            maxcul.0	2018-03-12 19:13:51.379	debug	Ignore command because already in queue X
                            maxcul.0	2018-03-12 19:13:47.498	debug	got OK-ACK Packet from 1b7d41
                            maxcul.0	2018-03-12 19:13:47.497	debug	RSSI for Message: -54
                            maxcul.0	2018-03-12 19:13:47.495	debug	decoding Message Z0E0102021B7D41123456000139643128
                            maxcul.0	2018-03-12 19:13:47.494	debug	incoming raw data from CUL: Z0E0102021B7D41123456000139643128
                            maxcul.0	2018-03-12 19:13:46.413	debug	serial port buffer have been drained
                            maxcul.0	2018-03-12 19:13:46.410	debug	Send Packet to CUL: Zs0b0100401234561b7d410071, awaiting drain event
                            

                            Warum bekommt man bei 503 credits einen LOVF zurueck?

                            geändert: Code in Code-Tags! Homoran(Mod)

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

                              Also ich sehe da vor allem ein "Ignore command because already in queue X" … also wie lange ist denn das letze "X" Kommando her und wieviel ging danach schon an Kommandos raus? Damit die Frage "wie alt ist das 503" ...

                              Meine Annahme ist das es mal 503 war dann mehreres gesendet wurde und der CUL ein "LOVF" zurückliefert ... also die 503 ist aaaalt weil zu viel nach dem letzten X kam und damit ist das Logging müll. Man müsste nach jedem Kommando immer ein "X" senden um den aktuellen Status zu bekommen. Wie wäre es damit?

                              1 Reply Last reply Reply Quote 0
                              • S
                                skraw.iobroker last edited by

                                So einfach ist das ja nicht. Das LOVF zeigt ja selbst 503 credits. Und daran haengt meine Verwunderung. wie kann das denn sein, dass ein LOVF zurueckkommt und man gleichzeitig 503 credits haette … ?

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

                                  LOVF ist exkt diese Info. Ich habe im Code nichts gesehncdas zusammen mit LOFV vom CUL ein Wert kommt. Der nimmt den "letzten" Credit-Wert den er kennt und gibt Ihn bei LOFV aus … Rest siehe oben: Wenn der letzte Wert also alt ist, ist die Ausgabe damit schrott

                                  1 Reply Last reply Reply Quote 0
                                  • S
                                    skraw.iobroker last edited by

                                    Mir scheint, dass die credits nicht hochzaehlen, wenn man keine X Kommandos schickt. Das wuerde bedeuten dass es kontraproduktiv ist die X zu ignorieren wenn schon eines in der Queue ist, denn man "verloere" dadurch anschliessend 5 credits …

                                    Die Frage ist wirklich ob es ginge die X nicht zu queuen sondern gnadenlos im 5-Sekundentakt zu schicken und nur "normale" (sprich echte Sende-) Kommandos in die Queue zu schicken...

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

                                      Die credis im CUl zählen IMMER weiter - nur der Adapter kennt diesen aktuellen Stand nicht weil er Ihn nur bekommt wenn ein "X" gesendet wurde.

                                      Daher ja meine Idee: Nach einem Kommando IMMER ein "X" zu senden um den aktuellen credit-Stand nach diesem Kommando im Programm zu haben. Dann kann man das restliche Handling so lassen

                                      1 Reply Last reply Reply Quote 0
                                      • S
                                        skraw.iobroker last edited by

                                        Ich wuerds eher anders herum machen. Alle 5 Sekunden das X senden, und wenn die Credits jeweils ueber Y gross sind (Y=220?), dann das naechste Kommando aus der Queue senden… ?

                                        1 Reply Last reply Reply Quote 0
                                        • S
                                          skraw.iobroker last edited by

                                          Mal eine Frage zur Programmierung:

                                          shift() holt das erste Element aus einer Queue. Wie schiebe ich so ein Element wieder zurueck an die erste Position in der Queue? Ich nehme an dass push() das Element an die letzte Stelle der Queue haengt, richtig?

                                          Habs gefunden …

                                          Hier ist meine neue Variante des Queue Handlings mit dem Vorteil, dass keine Nachrichten mehr dadurch verloren gehen, dass die Credits offensichtlich nicht reichen. Gleichzeitig fuege ich hinter jedem gesendeten Kommando ein X Kommando ein um die Credits auch bei gefuellter Queue aktuell zu halten. Das sieht mir im Moment als mit Abstand die beste Variante aus, die wir bisher hatten.

                                          Der Delay allein reicht ganz einfach nicht aus bei vielen CUL-Clients an einem Broker-Adapter. Da geht einfach sehr viel verloren von dem was gesendet werden soll.

                                          In dieser Version schauen wir erst obs ein X Kommando ist, das laeuft dann ohne Delay durch.

                                          Wenns kein X ist wird geschaut ob die Credits reichen, falls nein wird aus dem Kommando ein X gemacht und geschickt. Dabei ist wichtig, dass der Delay nicht auf 0 ms steht (trotz X), weil wir sonst eine Busy-Loop haben. Ich nehm an dieser Stelle mal 5000ms.

                                          Falls die Credits reichen wird das Kommando geschickt, vorher aber als naechstes Kommando ein X in die Queue geschoben um den Credit-Update gleich zu haben.

                                          Im Nicht-X Fall wird das Delay auf 2000 ms gesetzt, damit auch Zeit bleibt fuer ein ACK.

                                                  CommunicationServiceLayer.prototype.writeQueue = function() {
                                                      if (!this._queuedWrites.length) return Promise.resolve(true);
                                          
                                                      this._queueSendInProgress = true;
                                                      var command = this._queuedWrites[0];
                                                      var delay = 2000;
                                          
                                                      if (command[0] === 'X') {
                                                          command = this._queuedWrites.shift();
                                                          delay = 0;
                                                      }
                                                      else {
                                                          if (this._credits < 220) {
                                                              command = 'X\n';
                                                              delay = 5000;
                                                          }
                                                          else {
                                                              command = this._queuedWrites.shift();
                                                              this._queuedWrites.unshift('X\n');
                                                          }
                                                      }
                                          
                                                      return this._serialDeviceInstance.writeAsync(command).then(() => {
                                                          env.logger.debug('Send Packet to CUL: ' + command.trim() + ', awaiting drain event');
                                                          return this._serialDeviceInstance.drainAsync()
                                                      }).then(() => {
                                                          env.logger.debug('serial port buffer have been drained');
                                                          Promise.delay(delay).then(() => {
                                                              env.logger.debug('delayed next send by ' + delay + 'ms (Queue length left = ' + this._queuedWrites.length + ', Current Credit = ' + this._credits + ')' );
                                                              this._queueSendInProgress = false;
                                                              return this.writeQueue();
                                                          });
                                                      });
                                                  };
                                          
                                          

                                          Ich hab mir zusaetzlich die _credits besorgt:

                                                  function CommunicationServiceLayer(baudrate, serialPortName, _baseAddress) {
                                                      this._baseAddress = _baseAddress;
                                                      this.serialPortName = serialPortName;
                                                      env.logger.info('using serial device ' + this.serialPortName + '@' + baudrate);
                                                      this._messageQueue = [];
                                                      this._queueSendInProgress = false;
                                                      this._current = void 0;
                                                      this._busy = false;
                                                      this._ackResolver = null;
                                                      this._currentSentPromise = null;
                                                      this._serialDeviceInstance = new SerialPort(serialPortName, {
                                                          baudrate: baudrate,
                                                          parser: SerialPort.parsers.readline('\n'),
                                                          autoOpen: false
                                                      });
                                                      this._queuedWrites = [];
                                                      this._credits = 0;
                                                  }
                                          
                                          

                                          Und sie hier aktualisiert (ca Zeile 87):

                                                                  if (/^\d+\s+\d+$/.test(dataString)) {
                                                                      var m = dataString.match(/^(\d+)\s+(\d+)$/);
                                                                      _this._credits = parseInt(m[2],10);
                                                                      return _this.emit('creditsReceived', m[2], m[1]);
                                                                  }
                                          
                                          

                                          Und es hat sich herausgestellt, dass die folgende Sache auch noch geaendert werden muss (Zeile 188 im main.js):

                                             if (!timers[channel]) return;
                                          
                                              if (credits < 220) {
                                                  var crinfo = 'Not enough credits(' + credits + '). Wait for more...';
                                          
                                          

                                          Das ist notwendig, weil man bei 120 gerne mal LOVF kassiert.

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

                                            0.5.3 mit Deinen Änderungen (Danke dafür!!) auf GitHub und NPM.

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

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            870
                                            Online

                                            31.9k
                                            Users

                                            80.1k
                                            Topics

                                            1.3m
                                            Posts

                                            maxcul maxcul error
                                            9
                                            133
                                            13009
                                            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