Node.js - Shell Befehle werden teilweise nicht ausgeführt

  • Hallo liebe Pi Freunde,
    habe das Forum vor ein paar Stunden gefunden und hab auch gleich eine Frage an euch, hoffentlich kennen sich hier welche mit Node.js aus :D

    Also, erstmal die Hintergrunddaten:
    Es geht um eine Heimautomation, vom Client wird via socket.io ein Befehl gesendet, der Server bearbeitet dann diesen Befehl, dazu gibt es folgenden Code:

    Nun habe ich folgendes Problem: Ich habe ja schon die ecmd[e] exec so geschrieben, dass sie erst nach einer Sekunde ausgeführt wird, nun gibts folgendes:
    Es wird immer nur der erste exec Befehl jeweils von ecmd und von on/offcmd ausgeführt, obwohl eigentlich alles ausgeführt werden sollte.
    Die Daten sind so gespeichert: sceneECtrl: 4|2|3 etc. -> ID von einer anderen Tabelle, worin zusätzliche Befehle drin stehen.
    sceneDCtrl: 1=1|2=0|3=0|4=1 etc -> GeräteID 1 & 4 sollen an gehen, ID 2 & 3 sollen aus gehen.

    Alles andere Funktioniert bisher perfekt, nur eben das nicht richtig.
    Die Konsole spuckt mir dann folgendes aus:
    v9aS1Yb.png

    Hoffe jemand von euch versteht mein Problem und kann mir dabei helfen! Vielen Dank schonmal im Voraus! :thumbs1:

    Einmal editiert, zuletzt von xmunk (6. April 2016 um 14:48)

  • Node.js - Shell Befehle werden teilweise nicht ausgeführt? Schau mal ob du hier fündig wirst!

  • Ich würde mir erstmal die Fehlermeldungen/Rückmeldungen von exec anzeigen lassen:

    [code=php]
    exec(oncmd[devId], function(error, stdout, stderr) {
    console.log(error);
    console.log(stdout);
    console.log(stderr);
    });[/php]

    Die exec-Funktion ist nicht synchron sondern erfordert einen Callback. Brauchst du es unbedingt synchron gibt es ein npm-package, ein Tutorial dazu gibt es hier: https://davidwalsh.name/sync-exec
    Erscheint mir bei dir jedoch nicht erforderlich :)
    Testen könntest du das ganze auch einfach erstmal mit 'ls' (bzw. für Fehler: 'sl'), um zu sehen wie das ganze funktioniert.

    Sonst ist ein Blick in die Doku auch immer gut: https://www.npmjs.com/package/exec

  • Also erstmal vielen Dank für den Tipp Kleiner Mann,
    bin leider nicht viel mehr weiter gekommen, bei den Funk-Befehlen steht bei stdout "null", beim rest nichts,
    bei den irsend Befehlen steht bei error "null" und beim Rest nichts.

    Hab nur irgendwie das Gefühl dass die exec Befehle einfach zu schnell hintereinander ausgeführt werden und lirc und 433Utils einfach nicht hinterherkommen - Kann das überhaupt sein?
    Hab noch nicht sehr viel Erfahrung mit Linux, deshalb stell ich mich hier so blöd :daumendreh2:

    Ansonsten müsste es doch mit der Synchronen Version von exec funktionieren oder irre ich mich da?

  • Kannst du mal den Kompletten Code von dir schicken?
    Ich werde aus einigen Teilen nicht recht schlau und würde das anders schreiben... vielleicht wird mir dann klarer was eigentlich passieren soll und was die ganzen Variablen sind. ;)

    Gut wäre auch kurz der Inhalt eines Datenbankeintrages. Besonders wie devicectrl und extractrl aussehen.


    Ich kann dir heute Abend gerne noch was helfen :)

  • Testweise kannst du ja mal die einzelnen Befehle in einem kleinen Script zusammenfassen und dieses manuell starten. Dann sollte man schonmal sehen können, ob das zu schnelle Aufrufen das Problem ist, oder nicht. Falls nicht könnte man dann von Node aus das Script aufrufen. Sollte auch das funktionieren, muss man mal weiter suchen, aber ich würde erstmal die eben genannten Sachen testen, bevor man im npm nach was brauchbarem sucht

  • Ich tippe ebenfalls auf ein Problem mit der asynchrone Natur von exec.

    Beispiel Code:
    ...
    if(s[1] == 0){
    if(mode[devId] == 0){continue;}
    exec(offcmd[devId]);
    io.emit("turned off", devId);
    db.run("UPDATE devices SET mode=0 WHERE id=" + devId);
    mode[devId] = 0;
    }else if(s[1] == 1){
    if(mode[devId] == 1){continue;}
    exec(oncmd[devId]);
    io.emit("turned on", devId);
    db.run("UPDATE devices SET mode=1 WHERE id=" + devId);
    mode[devId] = 1;
    }
    ....

    Was hier passieren kann, ist dass "offcmd" noch läuft und dann das "oncmd" ausgeführt werden soll. Aus dem veröffentlichen Programmteil geht nicht hervor, was "offcmd" und "oncmd" machen. Wenn es etwas exklusives ist (ein lirc Kommando ?), das andere Anfragen ignoriert, erklärt das die Probleme.

  • Aaaalso, um das nochmal ein bisschen Ausführlicher zu erklären

    Wir haben hier folgendes Interface:

    Beim Klicken auf den Button einer der Buttons bei Szenen wird über eine onclick Funktion über socket.io eine Nachricht an den Server übermittelt, die so lautet: "call scene [SzenenID]", die Szenen werden aus einer SQLite Datenbank gelesen:
    MFAn7vm.png
    id: Automatisch zugewiesene ID (call scene [SzenenID])
    name: Bezeichnung der Szene
    devicectrl: Nun kommen wir der Sache etwas näher - nehmen wir als Beispiel mal die Guten Morgen Szene:
    uKYzmw9.png
    Im o.g. Script wird dies so gehandhabt: Wenn mind. ein "|" in diesem String vorhanden ist, wird der String nach diesen gesplittet, dadurch erhält man natürlich einen Array, welcher in diesem Fall folgendes beinhaltet: 1=1, 3=1, 4=1, 5=1
    Nehmen wir mal 3=1 als Grundlage für die Erklärung, 3=1 wird nun nochmal nach dem "=" gesplittet, das erste Element in diesem Array ist nun 3, das zweite 1
    Hierbei ist 3 nun die GeräteID, die Geräte werden in einer seperaten Tabelle gespeichert:
    Dno7swt.png
    Die 1 heißt in diesem Fall dass das Gerät mit der ID 3 eingeschaltet werden soll, im gegenzug würde 0 nun heißen es solle ausgeschaltet werden.
    In der devices-Tabelle gibt es nun oncmd und offcmd, diese beiden Spalten werden für jedes Gerät später im Script in einem Array mit der GeräteID gespeichert, würde bei GeräteID 3 nun heißen, dass im Serverscript folgendes steht:

    Code
    oncmd[3] = "sudo /home/pi/433Utils/RPi_utils/codesend 1361";
    
    
    offcmd[3] = "sudo /home/pi/433Utils/RPi_utils/codesend 1364";


    So, so viel erstmal zu diesem Zusammenhang.

    extractrl: extractrl bezieht sich hier auf den Menüpunkt "Erweiterte Gerätesteuerung":

    Die Dazugehörige Tabelle in der Datenbank:
    2dafg1d.png
    (Off-Topic: ID 7 und 8 sind hierbei blöd gelöst, um eine bessere Lösung werde ich mich aber erst Kümmern wenn ich erstmal dieses Problem behoben habe :P )
    Wir haben nun in der Tabelle mit den Szenen das Feld extractrl, welches wieder Trennungen mit "|" aufweist, die Prozedur ist somit die gleiche wie bei devicectrl, nur das hier einfach nur auf die ID in der extra-Tabelle (Die Tabelle in der die Daten für die Erweiterte Gerätesteuerung stehen heißt "extra") verwiesen wird, der Befehl jener ID soll dann ausgeführt werden, hierbei gilt wieder: Diese Befehle werden im Script in der Variable ecmd[extraID] gespeichert.

    Also, da ihr mein Problem ja schon kennt, hoffe ich ihr könnt nun daraus etwas mehr Interpretieren und das Konzept verstehen (Mag vielleicht ein blödes Konzept sein, ist aber relativ einfach und funktioniert).

    Wie gesagt, alles andere Funktioniert, nur die Szenen nicht richtig, es wird immer jeweils von oncmd/offcmd und ecmd nur einer der Befehle ausgeführt und nicht alle!
    Tippe wie gesagt auch auf die asynchronität der exec-Funktion, jedoch gibt es vielleicht eine andere Lösung, ich danke allen schonmal für die Hilfe! :geek:

  • Hab es jetzt mit dem oben genannten Modul (exec-sync) versucht, und - welch wunder - es funktioniert nun einwandfrei.
    Hätte es von Anfang an so ausprobieren sollen!
    Nochmals Danke an alle!

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!