Bedeutung von ``acs`` in Node.js Projekt

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
Antworten
Benutzeravatar
Dennis89
User
Beiträge: 1349
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo zusammen,

habe mal wieder eine Frage abseits von Python und ich hoffe ihr beantwortet mir die trotzdem. Seltsamerweise konnte ich dazu im Internet nichts finden, damit hätte ich nicht gerechnet.

Ich habe eine Node.js-Projekt bekommen, welches ich auf einem Pi laufen lassen soll. Habe ja in letzter Zeit etwas an der JavaScript-Oberfläche gekratzt und um das zu vertiefen, will ich nicht nur dass das Projekt läuft, sondern ich würde den Code gerne verstehen. Es wird in einer Datei eine Klasse (siehe Codeblock) definiert und da gibt es ein Schlüsselwort `acs` und ich kann nicht rausfinden, zu was das gut ist. Ich könnte mir vorstellen, dass das irgendwie mit dem Aufruf der Klasse zusammen hängt.

Code: Alles auswählen

class Calibration
{
    constructor( parent, idx, name )
    {
        this.name = name;
        this.parent = parent;
        this.idx = idx;
    }

    acs( path, name )
    {
        if ( this.parent != undefined )
        {
            name = this.name + "." + name;
            path.unshift( this.idx );
            return this.parent.acs( path, name );
        }
    }
}
Den ersten Teil würde ich in Python so schreiben:

Code: Alles auswählen

class Calibration:
    def __init__(self, parent, name, index):
        self. name = name
        self.parent = parent
        self.index = index
Dachte bei `acs` erst an so etwas wie `@classmethod` aber das geht ja nicht, weil `this.parent` schon abgefragt wird.
Vielleicht wird es klar, wenn ich weis was `acs` ist, weil mich verwirrt auch, dass das auch eine Methode von `this.parent` ist.

Vielen Dank und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
__blackjack__
User
Beiträge: 13468
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Dennis89: `acs()` ist einfach eine Methode. Was das ist steht also genau *da* in der Klasse. Kein Schlüsselwort, nix magisches.

Ungefähr das hier wenn man mal rät, dass `path` in JavaScript ein Array ist:

Code: Alles auswählen

class Calibration:
    def __init__(self, parent, name, index):
        self.name = name
        self.parent = parent
        self.index = index

    def acs(self, path, name):
        if self.parent is not None:
            name = f"{self.name}.{name}"
            path.insert(0, self.index)
            return self.parent.acs(path, name)

        return None
Edit: Was auch immer am Ende dieser rekursiven Aufrufe ist, müsste `name` zurückgeben. Sonst macht das keinen Sinn diesen Wert aufzubauen.

Edit 2: Doku zu JavaScript-Klassen bei MDN: https://developer.mozilla.org/en-US/doc ... ce/Classes

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Benutzeravatar
Dennis89
User
Beiträge: 1349
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Morgen,

danke für die Erklärung. Oh man ist ja einfach.
Mal wieder ein gutes Beispiel, wie Abkürzungen den Leser verwirren können, sah für mich wie ein Schlüsselwort aus.

Ich bin mal gespannt wie weit ich komme 🤯

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1349
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

ich hätte noch einmal eine Frage, die sich auf das erwähnte Skript bezieht. Habe das Projekt gerade auf den Pi gepackt, Hardware angeschlossen und es läuft soweit. Es schreibt eigentlich Daten im CSV-Format in die Konsole. Jetzt kommt meine Arbeit, die Daten sollen zum einen in eine *.csv-Datei geschrieben werden, man soll einstellen können wie viele Daten in der Sekunde gelesen werden können, dann soll es noch eine Überwachung geben, ob regelmäßig Daten kommen und bei Fehler eine Mailbenachrichtigung. Und die Dateien sollen nicht unendlich groß werden, es muss aber noch definiert werden, ob eine Datei die Daten von 24 Stunden enthält oder ob vielleicht alle 4 Stunden eine neue erstellt wird. Vielleicht wird das aber auch eine Benutzerauswahl.

Ich habe in das Node.js lediglich `argv` eingebaut, damit ich beim Aufruf die gewünschte Unterbrechung in Millisekunden mit angeben kann. Mein Plan ist, das ich alles was ich aufgezählt habe in Python umsetze und das Node.js-Project mit `subprocess` aufrufe und bei Änderungen kurz stoppe. (Das spielt keine Rolle) Meine Frage bezieht sich eher auf das Schreiben in die Datei. (Bin aber für alle anderen Verbesserungen offen)

Ich könnte beim Aufruf einfach die Ausgabe in eine Datei umleiten, ich könnte aber auch die Ausgabe mit Python lesen, einen Buffer füllen und den dann wegschreiben. Sagen wir mal es kommen alle 500ms Daten, dann hört sich der Teil mit dem Buffer für mich robuster an. Um das noch zu erwähnen, das sind keine hoch sensible Daten, aber dennoch will ich keine Lösung bauen, die 3 mal am Tag abstürzt, daher wäre ich mal wieder über eure Meinung und natürlich auch über einen alternativen Vorschlag sehr dankbar!

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
__blackjack__
User
Beiträge: 13468
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Dennis89: Warum hört sich das mit dem Puffer robuster an? Ich würde da nur einen Punkt sehen wenn das Python-Programm das wegschreiben der Daten nicht-blockierend macht, also beispielsweise in einem eigenen Thread der aus einer Queue liest die potentiell unendlich wachsen kann. Was man dann vielleicht auch überwachen sollte. Andererseits kann auch das schreiben von einem anderen Prozess aus auf einem Raspi das Gesamtsystem, und damit die Datenerfassung, ausbremsen wenn es ungünstig läuft.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Benutzeravatar
Dennis89
User
Beiträge: 1349
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo und danke für die Antwort.

Das ist eher so eine Gefühlssache und technisch kann ich das nicht begründen. Ich habe mir vorgestellt dass lesen und danach gleich schreiben und bei den "kurzen" Zeitabständen gleich wieder lesen irgendwie Überschneidungen geben könnte. Ich weis natürlich nicht wie das intern so abläuft, wenn ich die Pipe auf eine Datei umleite, ist das auch eine Art Queue die eins nach dem anderen abarbeitet und der Schreibprozess stört den Leseprozess gar nicht.(?) Das waren so meine Gedanken, was das robust sein angeht.
Für mich stelle ich es mir leichter vor, wenn ich mit Python die Dateien erstelle/schreibe, das ich das erstellen von neuen Dateien in eingestellten Zeitabständen, einfacher programmieren kann. Aber die Gedanken habe ich noch nicht zu ende gedacht.
Eine Qeue wäre ja eigentlich klasse, wenn die für einen gewissen Zeitraum leer ist, dann weis ich, dass was mit dem Daten lesen nicht stimmt. Dann müsste ich mir nur noch Gedanken darüber machen, wie ich den Schreibvorgang überwache. Wenn das System 24/7 durchläuft, könnte ich die Dateien anhand ihrer Größe beurteilen, aber von 24/7 kann ich nicht ausgehen.

Letztendlich suche ich die zuverlässigste Lösung, im besten Fall verursacht die Hardware, die die Daten sendet oder das Node.js-Projekt Fehler, darauf habe ich keinen Einfluss. Habe zwar schon mit dem Gedanken gespielt, das Node.js in Python zu schreiben, ich weis aber nicht ob ich JavaScript so weit verstehe, dass ich das hinbekomme. Den Vorteil den ich dann hätte wäre zum einen ich bin über den vollständigen Programmablauf 100% im Bilde, ich könnte alles in einer Sprache machen und bei Fehler schneller reagieren. Der Nachteil, wenn es Fehler gibt, ist es meine Schuld 😃 (Damit könnte ich leben)

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
__blackjack__
User
Beiträge: 13468
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Dennis89: „Pipe in eine Datei umleiten“ meint hier wahrscheinlich einfach eine geöffnete Datei als `stdout` and `subprocess` zu übergeben. Das kann blockieren wenn der Puffer den das Betriebssystem verwendet voll ist und der Prozess weitere Daten schreiben will. Dann blockiert dessen Schreibaufruf solange bis der Puffer wieder Daten aufnehmen kann.

Wenn Du Code schreiben willst der neue Dateien nach einer gewissen Grösse oder Zeit anfangen soll, dann geht das einfache umleiten in eine Datei ja sowieso nicht.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Benutzeravatar
Dennis89
User
Beiträge: 1349
Registriert: Freitag 11. Dezember 2020, 15:13

Danke für deine Antwort.

Ja, bzw. eigentlich meinte ich das nicht, weil ich dachte folgendes würde funktionieren:

Code: Alles auswählen

#!/usr/bin/env python
from subprocess import Popen
from time import sleep


def main():
    write_to_csv = Popen(
        [
            "node",
            "test.js",
            "/dev/ttyACM0",
            "1000",
            ">",
            "/home/dennis/test.csv"
        ]
    )
    sleep(2)
    write_to_csv.kill()


if __name__ == "__main__":
    main()
Habe gemerkt dass das nicht geht und dann auch verstanden, was du gemeint hast, also ja, ich müsste dass dann so machen:

Code: Alles auswählen

#!/usr/bin/env python
from subprocess import Popen
from time import sleep


def main():
    with open("/home/dennis/test.csv", "w") as csv:
        write_to_csv = Popen(
            [
                "node",
                "test.js",
                "/dev/ttyACM0",
                "1000"
            ], stdout=csv
        )
        sleep(2)
        write_to_csv.kill()


if __name__ == "__main__":
    main()
Der Teil in der `test.js` Datei, der die Daten ausgibt sieht einfach so aus:

Code: Alles auswählen

console.log( new Date, ";", raw.name, ";", raw.type)
nur halt noch ein paar mehr Daten.

Das neu erstellen von Dateien nach der Zeit hätte ich so gemacht, das ich den Prozess gestoppt hätte, einen neuen Dateinnamen übergeben und dann wieder gestartet. Weil wenn ein Datensatz mal verloren geht, ist das nicht wild.

Aber jetzt bin ich mir irgendwie unsicherer als vorher, welchen Weg ich einschlagen soll.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
__blackjack__
User
Beiträge: 13468
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

`kill()` ist ganz schön heftig. Selbst das Kommandozeilenprogramm ``kill`` macht das nicht wenn man da nicht explizit nach fragt. Das sendet ohne Option SIGTERM und nicht SIGKILL, also `terminate()` bei `Popen`-Objekten. 🙂

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Benutzeravatar
Dennis89
User
Beiträge: 1349
Registriert: Freitag 11. Dezember 2020, 15:13

__blackjack__ hat geschrieben: Samstag 7. September 2024, 19:38 `kill()` ist ganz schön heftig.
Hatte einen doofen Tag, irgendwas musste ich jetzt mal killen :mrgreen:

Okay danke, dann werde ich `terminate()` nehmen.

Wie würdest du dass denn umsetzen? Also nur in Worte mal, ist von meinen Ansätzen einer dabei, denn du wählen würdest?

Habe noch einen anderen Gedanken, JavaScript hat `csv-stringify`, vielleicht ist es doch sinnvoller, wenn ich mich nicht zu sehr auf Python fokussiere und anstatt `console.log()` direkt in die Datei schreibe.(?)
Dabei kam eine weitere Frage auf, da der Pi headless in einem anderen Raum hängen (kopflos hängen :mrgreen: ) wird, will ich die Steuerung des Programms über eine kleine Flask-App realisieren. Man kann das Node.js-Projekt aber nicht im Browser als Umgebung ausführen, weil der Browser keinen Hardwarezugriff erlaubt, richtig? Sonst hätte ich alles in einem. Aber so wie ich es verstanden habe, gibt es Node.js damit man JavaScript außerhalb des Browsers ausführen kann.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Sirius3
User
Beiträge: 18034
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn es nur darum geht, die log-Datei zu wechseln würde ich das direkt mit nodejs in die passende Datei schreiben. Da nochmal ein Python-Script drumrum zu packen, macht das unnötig kompliziert.
node-js ist klassisch dazu da Webserver zu programmieren und qenn der dazu da ist, Parameter Deiner Messung einzustellen, wäre alles in einem Programm zu haben auch nicht unpraktisch.
Benutzeravatar
Dennis89
User
Beiträge: 1349
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Morgen,

danke für die Antwort. Ich schaue mir das mal an und versuche es in JavaScript umzusetzen und vielleicht gelingt es mir das Node.js-Projekt zu erweitern, so das ich keine Flask-App schreiben muss.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten