Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. stdout eines ssh.exec-Aufrufs auswerten (WLAN Signalstärke)

    NEWS

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    stdout eines ssh.exec-Aufrufs auswerten (WLAN Signalstärke)

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

      @pezi said in stdout eines ssh.exec-Aufrufs auswerten (WLAN Signalstärke):

      Die Funktionsweise des folgenden Befehls ist, das der Befehl ausgeführt wird und sobald das Ergebnis vorliegt, wird die Funktion, die bei out: definiert worden ist aufgerufen (sozusagen als callback).
      Also hast du das Ergebnis hier im Block ab Zeile 3 in der Variable stdout, mit der du machen kannst was du willst.
      Im Beispielcode wird er halt auf der console ausgegeben, was du ja schon gesehen hast

      ssh.exec('iw dev wlan0 station dump', {
          out: function(stdout) {
              console.log(stdout);
          }
      }).start();
      

      gutes formatieren und einrücken hilft sehr bei der Lesbarkeit des codes

      P 1 Reply Last reply Reply Quote 0
      • P
        PeZi @OliverIO last edited by

        @oliverio
        Du hast Recht, die Formatierung war übel.
        Das hier:...

        ssh_WLAN.exec('iw dev wlan0 station dump', { 
            out: function(stdout) {
                var value = stdout
                setState('0_userdata.0.teststring', value);
                console.log(value);
            }
        }).start();
        
        

        ... funktioniert jetzt grundsätzlich.
        Allerdings gibt console.log die oben gezeigten zwei Strings aus...

        script.js.Test: Station xx:xx:xx:xx:xx:xx: (on wlan0) 
        script.js.Test: inactive time: 15610 ms rx bytes: 8170529 rx packets: 61305 tx bytes: 4542614 tx packets: 37364 tx retries: 9633 tx failed: 149 rx drop misc: 58 signal: -62 [-62] dBm signal avg: -65 [-65] dBm tx bitrate: 65.0 MBit/s MCS 6 short GI rx bitrate: 26.0 MBit/s MCS 3 expected throughput: 31.218Mbps authorized: yes authenticated: yes associated: yes preamble: short WMM/WME: yes MFP: no TDLS peer: no DTIM period: 2 beacon interval:100 short preamble: yes short slot time:yes connected time: 433687 seconds 
        

        ... Im Objekt steht aber nur der zweite String.

        Wenn mehrere Geräte an am AP angemeldet sind, kommen 3 oder mehr Strings im Log. Nur der letzte String wird ins Objekt geschrieben.

        Wie komme ich an die übrigen Teile bzw. wie können alle Teile ins Objekt geschrieben werden?

        Hier mal die Ausgabe des Befehls direkt in Putty:

        root@TP-Link-WA701ND:~# iw dev wlan0 station dump
        Station xx:xx:xx:xx:xx:xx (on wlan0)
                inactive time:  23500 ms
                rx bytes:       8695264
                rx packets:     65192
                tx bytes:       4823168
                tx packets:     39740
                tx retries:     10783
                tx failed:      182
                rx drop misc:   65
                signal:         -62 [-62] dBm
                signal avg:     -61 [-61] dBm
                tx bitrate:     52.0 MBit/s MCS 5
                rx bitrate:     26.0 MBit/s MCS 3
                expected throughput:    26.733Mbps
                authorized:     yes
                authenticated:  yes
                associated:     yes
                preamble:       short
                WMM/WME:        yes
                MFP:            no
                TDLS peer:      no
                DTIM period:    2
                beacon interval:100
                short preamble: yes
                short slot time:yes
                connected time: 461586 seconds
        Station yy:yy:yy:yy:yy: (on wlan0)
                inactive time:  1880 ms
                rx bytes:       142486
                rx packets:     1014
                tx bytes:       171118
                tx packets:     387
                tx retries:     2
                tx failed:      0
                rx drop misc:   1
                signal:         -55 [-55] dBm
                signal avg:     -55 [-55] dBm
                tx bitrate:     72.2 MBit/s MCS 7 short GI
                rx bitrate:     24.0 MBit/s
                expected throughput:    33.507Mbps
                authorized:     yes
                authenticated:  yes
                associated:     yes
                preamble:       short
                WMM/WME:        yes
                MFP:            no
                TDLS peer:      no
                DTIM period:    2
                beacon interval:100
                short preamble: yes
                short slot time:yes
                connected time: 461 seconds
        root@TP-Link-WA701ND:~#
        
        
        1 Reply Last reply Reply Quote 0
        • P
          PeZi last edited by

          Nach Abarbeitung des Befehls "iw dev wlan0 station dump" wird "function(stdout)" mehrfach aufgerufen.
          Das Gesamtergebnis kann dabei direkt zusammengesetzt werden.

          Mein Skript sieht jetzt so aus:

          'use strict'
          
          on({id: '0_userdata.0.Testpunkt', change: 'gt'}, function(obj) {
          
              var SSH = require('simple-ssh');
              var ssh_WLAN = new SSH({
                  host: '192.168.22.6',
                  user: 'user',
                  pass: 'passwort'
              });
              var Count=0;
              var Ergebnis='';
           
          
              ssh_WLAN.exec('iw dev wlan0 station dump', { 
                  out: function(stdout) {
                      var value = stdout;
                      Count=Count+1;
                      Ergebnis=Ergebnis+value;
                      setState('0_userdata.0.teststring', Ergebnis);
                  }
              }).start();
          })
          

          Funktioniert noch nicht richtig, aber der Weg geht in die richtige Richtung.

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

            Mittlerweile tut das Skript was es soll:
            Es schreibt die am Accesspunkt angemeldeten Geräte sammt der aktuellen Signalstärke in ein Objekt.

            'use strict'
            on({id: '0_userdata.0.Testpunkt', change: 'gt'}, function(obj) {
                var SSH = require('simple-ssh');
                var ssh_WLAN = new SSH({
                    host: '192.168.22.6',
                    user: 'user',
                    pass: 'passwort'
                });
                var Count=0;
                var Ergebnis = "";
                var position=0;
                var Signalliste = '';
                var erg='';
                setState('0_userdata.0.teststring', '');
                ssh_WLAN.exec('iw dev wlan0 station dump', { 
                    out: function(stdout) {
                        var value = stdout;
                        Count=Count+1;
                        erg=erg+value;
                        setState('0_userdata.0.teststring', erg);
                    }
                }).start();
                
                timeout = setTimeout(async () => {
                    timeout = null;
                    Ergebnis=(getState("0_userdata.0.teststring").val);
                    var laenge=Ergebnis.length;
                    do {
                        suche = Ergebnis.indexOf('Station', position);
                        if (suche >= 0) {
                            MAC = Ergebnis.slice(suche+8, suche + 26);
                            suche = Ergebnis.indexOf('signal:', position);
                            Signal = Ergebnis.slice(suche+7, suche + 23);
                            Signalliste = Signalliste + MAC + ' ' + Signal + '\n';
                        }
                        position = position+500;
                    } while (position < laenge);
                    setState('0_userdata.0.Signalstaerke_Garten', Signalliste);
                }, 3000);
            })
            

            Nächster Schritt:
            Zuordnung der Hostnamen zu dem MAC-Adressen...

            OliverIO 1 Reply Last reply Reply Quote 0
            • OliverIO
              OliverIO @PeZi last edited by

              @pezi sagte in stdout eines ssh.exec-Aufrufs auswerten (WLAN Signalstärke):

              Wenn es funktioniert, dann gut. Aber der Code sieht noch nicht gut aus.
              kannst du bitzte mal aus debug gründen noch die folgenden Zeilen, nach Zeile 8 einfügen

              ssh_WLAN.on("close"()=>console.log("stream close"));
              ssh_WLAN.on("data"()=>console.log("stream data"));
              ssh_WLAN.on("end"()=>console.log("stream end"));
              ssh_WLAN.on("error"()=>console.log("stream error"));
              ssh_WLAN.on("pause"()=>console.log("stream pause"));
              ssh_WLAN.on("readable"()=>console.log("stream readable"));
              ssh_WLAN.on("resume"()=>console.log("stream resume"));
              

              Zum Hintergrund. Dein aktueller Code basiert darauf, das er 3 Sekunden wartet und du dann hoffst, das alle Daten angekommen sind. Das ist keine gute Strategie.
              Ich habe gesehen, das simple-ssh, die ssh2 bibliothek verwendet und diese das node objekt stream verwendet.
              das oben sind nun alle events, die ein readable stream auslösen kann. Dein code wird nicht alle auslösen, mich interessiert aber die reihenfole. ich gehe von folgender reihenfolge aus

              • readable
              • mehrmals data
              • und einmal am ende dann end.

              so weißt du dann wenn alle daten angekommen sind.
              Ich hoffe, das ich da kein Fehler rein gemacht hab, da ich das trocken ohne ausprobieren geschrieben hab

              P 1 Reply Last reply Reply Quote 0
              • P
                PeZi @OliverIO last edited by PeZi

                @oliverio
                Danke für Deine Unterstützung.
                In Deinem Code waren noch Syntaxfehler.
                Nachdem ich die so...

                'use strict'
                on({id: '0_userdata.0.Testpunkt', change: 'gt'}, function(obj) {
                    var SSH = require('simple-ssh');
                    var ssh_WLAN = new SSH({
                        host: '192.168.22.6',
                        user: 'user',
                        pass: 'pass'
                    });
                
                ssh_WLAN.on('close', function() {console.log("stream close")});
                ssh_WLAN.on('data', function() {console.log("stream data")});
                ssh_WLAN.on('end', function() {console.log("stream end")});
                ssh_WLAN.on('error', function() {console.log("stream error")});
                ssh_WLAN.on('pause', function() {console.log("stream pause")});
                ssh_WLAN.on('readable', function() {console.log("stream readable")});
                ssh_WLAN.on('resume', function() {console.log("stream resume")});
                
                    var Count=0;
                    var Ergebnis = "";
                    var position=0;
                    var Signalliste = '';
                    var erg='';
                    setState('0_userdata.0.teststring', '');
                    ssh_WLAN.exec('iw dev wlan0 station dump', { 
                        out: function(stdout) {
                            var value = stdout;
                            Count=Count+1;
                            erg=erg+value;
                            setState('0_userdata.0.teststring', erg);
                        }
                    }).start();
                    
                    timeout = setTimeout(async () => {
                        timeout = null;
                        Ergebnis=(getState("0_userdata.0.teststring").val);
                        var laenge=Ergebnis.length;
                        do {
                            suche = Ergebnis.indexOf('Station', position);
                            if (suche >= 0) {
                                MAC = Ergebnis.slice(suche+8, suche + 26);
                                suche = Ergebnis.indexOf('signal:', position);
                                Signal = Ergebnis.slice(suche+7, suche + 23);
                                Signalliste = Signalliste + MAC + ' ' + Signal + '\n';
                            }
                            position = position+500;
                        } while (position < laenge);
                        setState('0_userdata.0.Signalstaerke_Garten', Signalliste);
                    }, 3000);
                })
                

                ... behoben habe, wird folgendes im log angezeigt:

                javascript.0	07:47:51.202	info	script.js.Test: registered 1 subscription, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
                javascript.0	07:48:06.539	info	script.js.Test: stream end
                javascript.0	07:48:06.541	info	script.js.Test: stream close
                

                Die Daten kommen aber!
                Laut Dokumentation gibt es das Event "data" nicht.
                Ich gehe mal davon aus, dass Dein Ansatz wäre, auf das Event "stream close" zu warten satt mit den 3 Sekunden Verzögerung zu arbeiten?

                OliverIO 1 Reply Last reply Reply Quote 0
                • OliverIO
                  OliverIO @PeZi last edited by OliverIO

                  @pezi sagte in stdout eines ssh.exec-Aufrufs auswerten (WLAN Signalstärke):

                  so hier etwas, was andere ebenfalls nutzen können, allerdings mit einer anderen bibliothek.
                  so kann das sehr clean angewendet werden ohne seinen hauptcode zu verunstalten.
                  ssh2 ist in den einstellungen des javascript adapters noch als zusätzliches nodemodul hinzuzufügen.

                  const { Client } = require('ssh2');
                  async function mySSH(host,username,password,command) {
                      return new Promise((resolve,reject)=>{
                          const conn = new Client();
                          conn.on('ready', () => {
                              conn.exec(command, (err, stream) => {
                                  if (err) throw err;
                                  stream.on('close', (code, signal) => {
                                  conn.end();
                                  }).on('data', (data) => {
                                  resolve(data.toString());
                                  }).stderr.on('data', (data) => {
                                  reject(data.toString());
                                  });
                              });
                          }).connect({
                          host: host,
                          port: 22,
                          username: username,
                          password: password 
                          });
                      })
                  }
                  
                  async function main() {
                      let result = await mySSH("0.0.0.0","abc","12345678","ls");
                      console.log(result);
                  }
                  main();
                  

                  wer ssh mit key authentifizierung nutzt, kann das skript sehr leicht umgebaut werden.
                  dazu einfach auf die dokuseite zu ssh2 schauen

                  P 1 Reply Last reply Reply Quote 0
                  • P
                    PeZi @OliverIO last edited by

                    @oliverio
                    Ich habe das mal versucht umzusetzen, bekomme aber folgende Fehlermeldung im Skript:

                    Cannot find module 'ssh2' or its corresponding type declarations.(2307)
                    

                    ssh2 ist im javascript-Adapter als zusätzliches Modul eingetragen und neu gestartet ist der Adapter auch 😞

                    MartinP OliverIO 2 Replies Last reply Reply Quote 0
                    • MartinP
                      MartinP @PeZi last edited by MartinP

                      @pezi Sind die Infos nicht auch über SNMP zu bekommen?
                      https://openwrt.org/docs/guide-user/services/snmp/start

                      Wenn ja wäre das doch der deutlich schulmäßigere Weg...
                      Gibt ja immerhin den SNMP-Adapter ...

                      9f667740-3041-4d62-98b3-eb60f0be8aa5-grafik.png

                      1 Reply Last reply Reply Quote 0
                      • OliverIO
                        OliverIO @PeZi last edited by

                        @pezi was heißt du erhälst eine Meldung?
                        Wenn du meinst, das ssh2 im Editor rot unterstrichen ist, dann ist das normal,
                        da iobroker die typ-definition nicht findet und daher im editor den syntax dazu nicht prüfen kann.
                        der code sollte dennoch funktionieren.
                        hast du den in der skript-console eine ausgabe erhalten?

                        P 1 Reply Last reply Reply Quote 0
                        • P
                          PeZi @OliverIO last edited by PeZi

                          @oliverio

                          Der Code funktioniert prima, ich hatte mich tatsächlich von der roten Markierung irritieren lassen.
                          Deinen Tipp bzgl. des SNMP-Adapters werde ich mal prüfen.

                          Vielen Dank für Deine Hilfe!

                          Ergänzung:
                          Der Weg über SNMP funktioniert in meinem Fall nicht, da es sich bei meinem AP um ein "4/32 Device" handelt, welches nur mit einer Minimalst-Version von OpenWRT läuft. SNMP kann darauf nicht zusätzlich installiert werden.

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

                          Support us

                          ioBroker
                          Community Adapters
                          Donate

                          1.0k
                          Online

                          31.7k
                          Users

                          79.7k
                          Topics

                          1.3m
                          Posts

                          5
                          16
                          477
                          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