• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Programm im Hintergrund ausführen

.., weiß ich jetzt was der Code macht.
OK

Bin mal gespannt wie es weiter geht... :)
Nun braucht es eine gescheite Planung der Topologie.
Du willst die Heizungssteuerung überwachen, Steuerbefehle absetzen, Status anzeigen, Konfigurationen senden, etc. ?
Welche dieser Aufgaben soll der Raspberry leisten?
Wird ein Browser dabei eine Rolle spielen, z.B. als Anwenderinterface für Eingaben, als Zustandsanzeige, als mathematische Instanz zum Berechnen von Heizkurven, als primäre Instanz zur Systemkonfiguration, etc?
Ist eine Datenbank geplant für Statistiken, Einsparungsmaßnahmen, Verbrauch, graphische Darstellungen, Vergleichsberechnungen, etc?
Wo befindet sich die koordinierende Intelligenz? Im Raspberry, in einem PC oder irgendwo im Netz?

Zwar haben wir nun die Möglichkeit, über unsere pipes in alle Richtungen zu kommunizieren.
Damit ist aber erst das Wie geklärt. Es fehlt uns noch das Wer mit Wem und Was darüber gesendet wird,
Deshalb sind die Informationen zu meinen Fragen jetzt notwendig, um den Aufbau planen zu können.

Im Grunde ist das alles eine simple Angelegenheit, sofern die Konzeption des Systems der Realität stimmig angepasst wurde.
Was technisch möglich ist und wie man das realisiert, das weiß ich.
Was das fertige System können soll, mußt du nun darstellen.
 
OP
O

Onkel-Tom

Newbie
Im Grunde ist das alles eine simple Angelegenheit

Wie so oft wenn man sich auskennt :ROFLMAO:

Teile von dem was jetzt kommt habe ich zwar oben schon beschrieben, aber ich denke alles an einem ist einfacher zu lesen als in den alten Posts noch mal suchen zu müssen.

Also, dann fange ich mal etwas mit dem Überblick an.
Die Heizung läuft wie jede andere Heizung autark. Sie verwendet zur Steuerung intern das ebus Protokoll. Dazu habe ich eine Platine gelötet ( Bauplan aus dem Netz ) welche per USB an einen RasPi angeschlossen ist und auf der anderen Seite am 2-Draht-Bus der Heizung hängt. Auf dem RasPi läuft das Programm ebusd ( Ebus-Dämon ) welches Daten vom Bus der Heizungssteuerung empfangen und senden kann. Den ebusd habe ich so konfiguriert, dass er alle empfangenen Daten auch per MQTT an meinen MQTT-Server sendet. Der MQTT-Server läuft auf der Synology-NAS in einer eigenen VM. Nur als Randnotiz, der MQTT-Server ist nicht nur für die Daten der Heizungssteuerung, sondern auch für die Daten zur Ladereglung meiner PV-Anlage, E-Auto, Druckersteuerung usw. zuständig.
Die Visualisierung und bei Bedarf steuerung des Ganzen übernimmt der IoBroker in einer eigenen VM auf der NAS.
Noch eine Randnotiz, Paralell zu dem ebusd der Heizungssteuerung läuft das ganze noch einmal für die Solarsteuerung und Lüftungsanlage. Es sind also insgesammt 3 Platinen und 3 ebusd-Instanzen, aber das nur nebenbei ;-)
Ich denke das ist ein ganz guter Überblick über den Aufbau. Wenn noch was fehlt oder unklar ist einfach fragen.

Jetzt mal so zur Grundidee.
Da Energiesparen ja nichts schlechtes ist, wollte ich das Ganze mal visualisieren was ich für andere Projekte schon in IoBroker gemacht habe.
Wie immer braucht man dazu natürlich Daten ;-)
Da die Heizungssteuerung nur die Daten über den Bus schickt welch sie gerade benötigt, sind manche Daten veraltet. Manche Daten werden scheinbar auch nicht ohne weiteres über den Bus gesendet sonder irgendwie nur intern verarbeitet. Das schönste Beispiel ist die Zirkulationspumpe, welche man über einen potentialfreien Eingang ansteuern kann und dann 5min. läuft, das Signal aber nicht auf dem Bus übertragen wird. Man kann nur überwachen ob die Pumpe läuft oder nicht.
Um nicht mit alten Daten zu arbeiten bin ich auf die Idee gekommen, alle Daten nach einer gewissen Zeit abzufragen. Je nach Daten mit unterschiedlichem Intervall. Meine erste Lösung dazu war einfach stumpf alles abzufragen was ich mit dem Skript Abruf-heat.sh realisiert habe ( im Anhang )
Damit war ich zuerst mal zufrieden und das funktioniert auch so weit. Dann habe ich im Log vom ebusd entdeckt dass alle paar Sekunden die Fehlermeldung ERR: arbitration lost, retry kommt, was man im Betrieb nicht merkt aber meinen inneren Monk getriggert hat.
Dann bin ich auf die Idee gekommen den Bus dadurch zu entlasten, dass ich nur noch die Daten abfrage die nach einer gewissen Zeit nicht aktualisiert sind.
Dazu habe ich mir eine Konfigurationsdatei erstellt die im Prinzip für jeden Datenpunkt eine Zeilen und drei Spalten hat. Erste Spalte ist das Topic welches von MQTT kommt ohne die Daten dahinter also das was auch per mosquitto_sub -h 192.168.1.41 -t ebusd-heat/# -v -u admin -P admin -F "%t" empfangen wird. Die zweite Spalt ist der Zeitintervall nach dem ein Wert spätestens aktualisiert sein soll. In der dritten Spalte ist der Befehl um die Daten per ebusd abzurufen. ( Abrufdaten.txt )
Jetzt zum eigentlichen Skript.
Um es für mich leichter zu machen habe ich ein Array erstellt, dass die Felder nummeriert. Mit der ersten Zahl wird die Zeile und mit der zweiten Zahl die Spalte bezeichnet, also ist 123 die dritte Spalte in der zwölften Zeile.. Beim einlesen der Abrufdaten.txt habe ich eine vierte Spalte generiert in der ich die aktuelle Zeit+Abrufzeit im epoch-Format gespeichert habe. Bis dahin hat alles funktioniert.
Da der mosquitto-Client ja den Programmablauf blockiert, wollte ich den auslagern und eine Datei als "Puffer" verwende in die mosquitto alle empfangenen Nachrichten reinschreibt. Im Programmablauf sollte die erste Zeile aus dem Puffer ausgelesen werden, die Zeile im Array gefunden werden und dann die aktuelle Zeit + Abrufzeit aus Spalte 2 in Spalte 4 geschrieben werden. Ist der Puffer leer läuft das Programm durch Spalte 4 und schaut welche zeit abgelaufen ist, also der Wert kleiner der aktuellen Zeit ist. Wenn ein Wert in Spalte 4 gefunden wurde, wird der Befehl aus Spalte 3 mit ebusd ausgeführt.
Was daraus geworden ist kennt ihr ja :lol:

Ich hoffe das war halbwegs verständlich.
=> Gräfin Klara: Auf jeden Vall möchte ich mich schon mal für deine Arbeit die Du dir hier machst bedanken!!!

LG

Thomas
 

Anhänge

  • Abruf-heat.txt
    17,5 KB · Aufrufe: 7
  • Abrufdaten.txt
    30,5 KB · Aufrufe: 3

abgdf

Guru
Schonmal nicht schlecht. Zu Heizung, Löten, usw. kann ich nichts sagen, da kenne ich mich nicht aus.

Die Struktur von "Abruf-heat.txt" ist ja im Prinzip nicht so schwierig, es gibt da halt viele Wiederholungen. Ich würde empfehlen, Einrückungen zu machen, 4 Leerzeichen pro Code-Block sind üblich. Dann sieht das Ganze so aus:
Code:
#!/bin/bash
# alle 20 Sekunden den ersten Satz Befehle ausführen
i=0
for (( ; ; ))
do
    ebusctl -p 8888 r -m 20 -c cc Mode
    ....
    i=$((i+1))
    sleep 20
    # nach 100 Sekunden den zweiten Satz Befehle ausführen
    if [ $((i % 5)) -eq 0 ]
    then
        ebusctl -p 8888 r -m 300 -c cc currenterror
        ....
    fi
    # nach 1000 Sekunden den dritten Satz Befehle ausführen
    if [ $((i % 50)) -eq 0 ]
    then
        ebusctl -p 8888 r -m 300 -c cc Timer.Friday
        ....
    fi
    # nach 10000 Sekunden den vierten Satz Befehle ausführen
    if [ $((i % 500)) -eq 0 ]
    then
        i=0
        ebusctl -p 8888 r -m 300 -c ehp ApplianceCode
        ....
    fi
done
Eine Endlos-Schleife würde ich lieber mit
Code:
while test 1 -eq 1; do ... done
machen als mit "for".
Größere Projekte gehe ich meistens in Python an. Das ist eine sehr angenehme, leistungsfähige und leicht zu lernende Sprache. Lohnt sich unbedingt, sich damit vertraut zu machen. In Python würde ich die Sache so schreiben:
Code:
#!/usr/bin/python3
# coding: utf-8

import os
import time

# SLEEPTIME = 20

# For testing:
SLEEPTIME = 1

a = (1, 5, 50, 500)

def runEbusctl(n):
    commands = (("ebusctl -p 8888 r -m 20 -c cc Mode", "..."),
                ("ebusctl -p 8888 r -m 300 -c cc currenterror", "..."),
                ("ebusctl -p 8888 r -m 300 -c cc Timer.Friday", "..."),
                ("ebusctl -p 8888 r -m 300 -c ehp ApplianceCode", "..."))
    print(a.index(n))
    for e in commands[a.index(n)]:
        print(e)
        # os.system(e)
    print()

i = 1

while True:
    for n in range(len(a)):
        if i % a[n] == 0:
            runEbusctl(a[n])
            if n == len(a) - 1:
                i = 1
    i += 1
    time.sleep(SLEEPTIME)
Mir fällt auf: "i" sollte wohl lieber immer bei "1" anfangen, denn z.B. "0 % 50" wäre ja 0, dann würden die Befehle sofort getriggert, was wohl nicht gewünscht ist.
 
Zuletzt bearbeitet:
OP
O

Onkel-Tom

Newbie
es gibt da halt viele Wiederholungen
Das mit den Wiederholungen kommt daher, dass der ebusd die Signale der Heizung über eine csv-Datei decodiert. Vom Bus kommt etwa so was in Hex 1050b5040101 / 09150300000081000100 und wird dann mit Hilfe der csv-Datei übersetzt. Ich habe dann alle Befehle in Excel zu einem kompletten ebusd-Befehl verknüpft. Von dort habe ich dann einfach alles kopiert und musste es nicht im Programm zusammen bauen.
Mit Python habe ich mich auch schon mal etwas beschäftigt aber nur um mal Programme etwas anzupassen. Das Problem für mich ist halt dass ich nur ab und zu mal etwas programmiere und bis dort hin habe ich die Hälfte wieder vergessen. Man wird halt nicht jünger ;-)
Mit der Shell mache ich halt ziemlich viel und deshalb ist mir das lieber. Wenn ich natürlich sehe wie Gräfin Klara da in die Tasten haut dann bin ich natürlich auch raus. Für das kleine Pipe-Skript habe ich 3 Tage Google gequält bis ich da alles verstanden habe was da wo passiert. Von den Kenntnissen bin ich Lichtjahre entfernt. Zu meiner Entschuldigung kann ich vielleicht sagen dass ich vor ca. 30 Jahren mal einen DOS-Kurs besucht habe und den Rest habe ich mir selbst erarbeitet. Da ich beruflich überhaupt nichts damit zu tun habe ist das halt alles nur so nebenbei. Das Problem ist halt, wenn man es nicht nutzt ist alles schneller vergessen als gelernt.
LG
Thomas
 
  • Like
Reaktionen: H1A
Wie so oft wenn man sich auskennt :ROFLMAO:

Teile von dem was jetzt kommt habe ich zwar oben schon beschrieben, aber ich denke alles an einem ist einfacher zu lesen als in den alten Posts noch mal suchen zu müssen.

Also, dann fange ich mal etwas mit dem Überblick an.
Die Heizung läuft wie jede andere Heizung autark. Sie verwendet zur Steuerung intern das ebus Protokoll. Dazu habe ich eine Platine gelötet ( Bauplan aus dem Netz ) welche per USB an einen RasPi angeschlossen ist und auf der anderen Seite am 2-Draht-Bus der Heizung hängt. Auf dem RasPi läuft das Programm ebusd ( Ebus-Dämon ) welches Daten vom Bus der Heizungssteuerung empfangen und senden kann. Den ebusd habe ich so konfiguriert, dass er alle empfangenen Daten auch per MQTT an meinen MQTT-Server sendet. Der MQTT-Server läuft auf der Synology-NAS in einer eigenen VM. Nur als Randnotiz, der MQTT-Server ist nicht nur für die Daten der Heizungssteuerung, sondern auch für die Daten zur Ladereglung meiner PV-Anlage, E-Auto, Druckersteuerung usw. zuständig.
Die Visualisierung und bei Bedarf steuerung des Ganzen übernimmt der IoBroker in einer eigenen VM auf der NAS.
Noch eine Randnotiz, Paralell zu dem ebusd der Heizungssteuerung läuft das ganze noch einmal für die Solarsteuerung und Lüftungsanlage. Es sind also insgesammt 3 Platinen und 3 ebusd-Instanzen, aber das nur nebenbei ;-)
Ich denke das ist ein ganz guter Überblick über den Aufbau. Wenn noch was fehlt oder unklar ist einfach fragen.
Fragen:
IoBroker Visualisierung und Steuerung. Soll es dabei bleiben?
Die Steuerung bzw. Kontrolle der Heizungsanlage sollte nicht weiter entfernt sein als jene Instanz, auf der der ebusd läuft.
Das würde auch die Quelle der Visualisierungsdaten bzw. mindestens die Visualisierung der Kontrolleingaben am Raspberry vorgeben.
Je dezentralisierter die Aufgaben, umso mehr Fehlerquellen und Administration fallen an.
Wenn Heizungsanlage und Raspberry funktionieren, darf NAS,VM und sonstiges ausfallen ohne nennenswerte Einschränkungen.
So meine Meinung.
Jetzt mal so zur Grundidee.
Da Energiesparen ja nichts schlechtes ist, wollte ich das Ganze mal visualisieren was ich für andere Projekte schon in IoBroker gemacht habe.
Wie immer braucht man dazu natürlich Daten ;-)
Da die Heizungssteuerung nur die Daten über den Bus schickt welch sie gerade benötigt, sind manche Daten veraltet.
Das verstehe ich nicht.
Du setzt am Raspberry mit ebusctl ein Query (Abfrage) an den ebusd ab.
ebusd kommuniziert dann über USB <--> dein Interface <--> 2-draht <--> Heizungsanlage
Wie soll es da zu alten Datenbeständen kommen?
Du beschreibst das so, als ob du alte Bestände erst abschöpfen mußt um an aktuelle Daten zu kommen.
Sollte die Heizungsanlage einen Datenstack füllen, der durch queries geleert werden muß, dann MUSS es auch ein Kommando
geben, das da sagt: Lösche deinen Stack, ich will das neueste Material. Alles andere ist mir nicht erklärlich

Manche Daten werden scheinbar auch nicht ohne weiteres über den Bus gesendet sonder irgendwie nur intern verarbeitet. Das schönste Beispiel ist die Zirkulationspumpe, welche man über einen potentialfreien Eingang ansteuern kann und dann 5min. läuft, das Signal aber nicht auf dem Bus übertragen wird. Man kann nur überwachen ob die Pumpe läuft oder nicht.
Das wird wohl spezifisch je Heizungsanlage sein. Manche Hersteller können, andere nicht.
Um nicht mit alten Daten zu arbeiten bin ich auf die Idee gekommen, alle Daten nach einer gewissen Zeit abzufragen. Je nach Daten mit unterschiedlichem Intervall. Meine erste Lösung dazu war einfach stumpf alles abzufragen was ich mit dem Skript Abruf-heat.sh realisiert habe ( im Anhang )
Damit war ich zuerst mal zufrieden und das funktioniert auch so weit. Dann habe ich im Log vom ebusd entdeckt dass alle paar Sekunden die Fehlermeldung ERR: arbitration lost, retry kommt, was man im Betrieb nicht merkt aber meinen inneren Monk getriggert hat.
Würde ich mir im derzeitigen Zustand keine Gedanken machen.
Du setzt in deinem script die queries ohne zeitlicher Verzögerung ab.
ebusd muß deine Textangaben erst umständlich aus einem file in binäre Kommandos übersetzen,
der 2-draht Bus ist langsam, die Reaktionszeiten der Heizungsanlage sind unbekannt.
Probleme mit Latency bzw. Reaktionszeit sind unter diesen Umständen verständlich.
Dann bin ich auf die Idee gekommen den Bus dadurch zu entlasten, dass ich nur noch die Daten abfrage die nach einer gewissen Zeit nicht aktualisiert sind.
Dazu habe ich mir eine Konfigurationsdatei erstellt die im Prinzip für jeden Datenpunkt eine Zeilen und drei Spalten hat. Erste Spalte ist das Topic welches von MQTT kommt ohne die Daten dahinter also das was auch per mosquitto_sub -h 192.168.1.41 -t ebusd-heat/# -v -u admin -P admin -F "%t" empfangen wird. Die zweite Spalt ist der Zeitintervall nach dem ein Wert spätestens aktualisiert sein soll. In der dritten Spalte ist der Befehl um die Daten per ebusd abzurufen. ( Abrufdaten.txt )
Jetzt zum eigentlichen Skript.
Um es für mich leichter zu machen habe ich ein Array erstellt, dass die Felder nummeriert. Mit der ersten Zahl wird die Zeile und mit der zweiten Zahl die Spalte bezeichnet, also ist 123 die dritte Spalte in der zwölften Zeile.. Beim einlesen der Abrufdaten.txt habe ich eine vierte Spalte generiert in der ich die aktuelle Zeit+Abrufzeit im epoch-Format gespeichert habe. Bis dahin hat alles funktioniert.
Da der mosquitto-Client ja den Programmablauf blockiert, wollte ich den auslagern und eine Datei als "Puffer" verwende in die mosquitto alle empfangenen Nachrichten reinschreibt. Im Programmablauf sollte die erste Zeile aus dem Puffer ausgelesen werden, die Zeile im Array gefunden werden und dann die aktuelle Zeit + Abrufzeit aus Spalte 2 in Spalte 4 geschrieben werden. Ist der Puffer leer läuft das Programm durch Spalte 4 und schaut welche zeit abgelaufen ist, also der Wert kleiner der aktuellen Zeit ist. Wenn ein Wert in Spalte 4 gefunden wurde, wird der Befehl aus Spalte 3 mit ebusd ausgeführt.
Was daraus geworden ist kennt ihr ja :lol:
Dafür muß eine andere Lösung gefunden werden.
Ich melde mich
Ich hoffe das war halbwegs verständlich.
=> Gräfin Klara: Auf jeden Vall möchte ich mich schon mal für deine Arbeit die Du dir hier machst bedanken!!!

LG

Thomas
Ja, alles verständlich.

Gruß
 
OP
O

Onkel-Tom

Newbie
Fragen:
IoBroker Visualisierung und Steuerung. Soll es dabei bleiben?
Ja, das soll so bleiben.
Wenn Heizungsanlage und Raspberry funktionieren, darf NAS,VM und sonstiges ausfallen ohne nennenswerte Einschränkungen.
So meine Meinung.
Da bin ich bei dir. Die Steuerung der Heizung läuft ja auch komplett autark. Wenn ich etwas über den ebusd in die Heizungssteuerung schreibe, dann weiß die Steuerung nicht dass das vom iobroker kommt. Die Daten könnten genau so gut vom Eingabemodul an der Heizung oder im Wohnzimmer kommen.
ebusd kommuniziert dann über USB <--> dein Interface <--> 2-draht <--> Heizungsanlage
Wie soll es da zu alten Datenbeständen kommen?
Die Steuerung der Heizung ist eine Platine an der über den ebus verschiedene Geräte angeschlossen sind. Das ist mindesten das Kontrollpanel direkt an der Heizung, in meinem Fall noch ein zweites im Wohnzimmer im Erdgeschoss und ein zweites im OG. Des weiteren hängt noch ein Erweiterungsmodul für den zweiten und dritten Heizkreis. Wenn ich jetzt nicht am Bedienmodul von der Steuerung einen Wert abrufe bleiben die in der Hauptplatine. Gewisse Daten kommen immer mal über den Bus da sie als Broadcast gesendet werden aber nicht alle. Wenn ich jetzt z.B die Brauchwassertemperatur von vor 5 Stunden habe bringt mich das viel weiter ;-)
Dafür muß eine andere Lösung gefunden werden.
Ich melde mich
Vielleicht kommst Du ja auf eine gute / bessere Idee.
Wenn noch irgendwelche Fragen offen sind einfach kurz Bescheid sagen.
LG
Thomas
 
OP
O

Onkel-Tom

Newbie
Das weiß ich selbst noch nicht genau da ich ja noch keine Daten habe ;-)
Ich bringe dir mal ein Beispiel.
Unsere Heizung ist eine Wärmepumpe und die läuft am effizientesten wenn die Vorlauftemperatur so gering ist wie möglich.
Die Vorlauftemperatur wird über die Heizkurve eingestellt und die sollte so niedrig wie möglich sein. Ist die Vorlauftemperatur zu hoch regelt das in unserem Fall die Steuerung der Fußbodenheizung durch schließen der Ventile damit es im Zimmer nicht zu warm wird. Da ich jetzt nicht Tagelang neben den elektrisch angesteuerten Ventilen sitzen möchte und denen beim Regeln zusehen will, habe ich eine kleine Platine gebaut die mit einem ESP8266 über MQTT die Daten an den IoBroker sendet. Aus den Daten habe ich dann eine Grafik gebastelt und ich konnte sehen wie oft die Ventile auf und zu sind. Mit den Daten konnte ich dann die Heizkurve über ZDF anpassen.
So gehe ich so was normalerweise an.
LG
Thomas
 
Was mir dazu einfällt und ich dir anbieten könnte ist ein tcp/ip client damon
So etwas gibt es noch gar nicht, meint google.

Console:
# tomd -d -s localhost:8888 -p /tmp/ebusd_pts
oder start mit systemd

-d run as daemon
-s server:port (z.B localhost:8888 oder name:8888 zu deinem Raspberry irgendwo mit dem ebusd)
-p bidirektionale Kommunikationsschnittstelle zwischen tomd und deinem script

tomd verbindet sich mit ebusd über tcp/ip und bleibt verbunden.
Alles was du im script nach /tmp/ebusd_pts screibst, wird 1:1 nach ebusd übertragen.
z.B.: printf "r -m 20 -c ehp HwcHcValve\n" >&$PTS_FILEHANDLE
Alles was ebusd sendet, kannst du aus /tmp/ebusd_pts lesen.
z.B.: read -t $tmo -u $PTS_FILEHANDLE
Ist bereits aus den pipes oben bekannt, jedoch würde ich tty pseudeterminal verwenden, also nur eine pipe für read/write
Die pipe wird von tomd erstellt.

Du mußt also kein Programm im script starten, bist aber für das ebus protokoll zur Gänze selbst verantwortlich.
Ich kontrolliere weder was ich nach ebusd schreibe, noch was ich von diesem empfange.
Zum Testen kannst du einen anderen server verwenden, z.B.
# ncat -v -l -k localhost 2222
mit tomd verbinden und mit deinem script kommunizieren.

Lauffähig auf ARM Raspberry und/oder Intel x86_64, programmiert in C für max.performance
Programmierzeit ca. 2 Std.

ABER
Kein sourcecode, das wäre zuviel verlangt.
Es kann sein, dass du am Raspberry ein library instaliieren mußt.

Fehlt was an Funktionalität?

PS
unter der Erklärung für option -s erscheint immer ein smily.
Das stammt nicht von mir sondern wird erzeugt von dieser schwachsinnigen Forensoftware.
Ich kann es nicht löschen.
 
Zuletzt bearbeitet von einem Moderator:
OP
O

Onkel-Tom

Newbie
Hallo Gräfin Klara,

vielen Dank für deine Bemühungen und das Angebot. aber das kann ich nicht annehmen. Ich möchte nicht dass Du dich 2 Stunden hinsetzt um meine Probleme zu löse. Des weiteren lerne ich ja nichts wenn Du meine Probleme löst ;-)
Heißt das Angebot ein extra Programm zu schreiben eigentlich dass es mit einer Pipe doch nicht funktioniert?
Da ich ja grundsätzlich nicht so schnell aufgebe, habe ich mir die ebusd-Doku in der neuesten Version angeschaut und dabei noch eine Funktion gefunden welche ich jetzt mal aktiviert habe und die schmeißt die Daten nicht nur per MQTT raus, sondern auch noch auf eine Webseite als Json. Ich denke das könnte ein guter Ansatz sein ohne das MQTT-gedöns das alles blockiert. Ich habe ja hier wieder einiges gelernt das ich dabei sicher einsetzen kann. Mal sehen ob ich das so hin bekomme.
Wenn dabei wieder für mich unlösbare Probleme aufkommen, würde ich mir hier gerne noch mal einen Schubser in die richtige Richtung abholen :)

LG
Thomas
 
vielen Dank für deine Bemühungen und das Angebot. aber das kann ich nicht annehmen.
ok
Heißt das Angebot ein extra Programm zu schreiben eigentlich dass es mit einer Pipe doch nicht funktioniert?
Die pipes funktionieren, nur deine Programmierarbeiten hätten sich vereinfacht
.. ohne das MQTT-gedöns das alles blockiert.
Sehr gute Entscheidung
 

Christina

Moderator
Teammitglied
PS
unter der Erklärung für option -s erscheint immer ein smily.
Das stammt nicht von mir sondern wird erzeugt von dieser schwachsinnigen Forensoftware.
Ich kann es nicht löschen.
Hi Gräfin Klara,

das Smiley :p "Doppelpunkt p" kannst du verhindern, wenn du den Ausdruck so [PLAIN]:p[/PLAIN] setzt.
Siehe auch: Hilfe und Impressum > BBCodes

Im Forenbeitrag #29 (7. Zeile) habe ich es schon eingefügt als [PLAIN]-s server:port[/PLAIN]
LG, Christina
 
OP
O

Onkel-Tom

Newbie
Die pipes funktionieren, nur deine Programmierarbeiten hätten sich vereinfacht
Wenn du Lust und Zeit hast kannst kannst du mir es ja trotzdem erklären. Bestimmt kann ich das Wissen irgendwann mal anwenden.
Ich hatte es ja mit der Pipe versucht und sie wurde auch schön angelegt, nur mit dem Datenaustausch hatte es nicht geklappt.
Ob das mit dem Json so einfach wird weiß ich noch nicht. Ich bin mich da noch am einlesen.

LG
Thomas
 
Wenn du Lust und Zeit hast kannst kannst du mir es ja trotzdem erklären. Bestimmt kann ich das Wissen irgendwann mal anwenden.
Ich hatte es ja mit der Pipe versucht und sie wurde auch schön angelegt, nur mit dem Datenaustausch hatte es nicht geklappt.
Was du brauchst ist ein TCP/IP client daemon
Passen würde der: tcpsvd - TCP/IP service daemon

Ob das mit dem Json so einfach wird weiß ich noch nicht. Ich bin mich da noch am einlesen.
Mit einem tcp/ip client, wie z.B. ebusctl, telnet oder ncat, bekommst du die echten Rohdaten vom ebusd server.
Das sind die Daten, die du willst.
Wenn du ebusd so konfigurierst, dass ebusd json sendet, dann bekommst du die selben Daten aber eingebettet in JSON.
Verwendet wird das typischerweise in clients mit einer Java oder Javascript engine.
Wenn du dich mit Javascript auskennst, dann kannst du dich mit dem Browser zum ebusd verbinden mit servername:8888
ebusd wird dann dem browser mit den Daten im Format JSON antworten.
Willst du das? Eher nein.
Schau dir tcpsvd an. Damit kommst du weiter und die Verwendung der pipes wird dann auch verständlich.
 
Zuletzt bearbeitet:
Passen würde der: tcpsvd - TCP/IP service daemon
Falsch, vergiss das! Ich habe die man page erst jetzt gelesen. Meine Erinnerung war fehlerhaft.

Beispiel einer Kommunikation mit einem tcp server in bash:

Code:
#!/bin/bash

# code für Kommunikation über sockets (c) Gräfin Klara
SOCK_SERVER="localhost"
SOCK_PORT="2222"
SOCK_FD=0
MSG_RD=""
#-----------------------------------------------------------
sig_exit()
{
    [ $SOCK_FD -eq 0 ] && exit 0
    exec {SOCK_FD}<&-
    SOCK_FD=0
    printf "** socket closed\n"
    exit 0
}
sig_pipe()
{
    printf "** broken socket\n"
    exit 0
}
open_socket()
{
    local pl="/dev/tcp/$SOCK_SERVER/$SOCK_PORT"
    [ $SOCK_FD -ne 0 ] && exec {SOCK_FD}<&-
    { exec {SOCK_FD}<>"$pl"; }> /dev/null 2>&1 || return 1
    trap "sig_exit" EXIT
    trap "sig_pipe" SIGPIPE
    return 0
}
# in: Lese mit Zeitablauf in Sekunden
# Resultat in MSG_RD
read_socket()
{
    local tmo="$1"
    [ $SOCK_FD -eq 0 ] && return 1
    read -t $tmo -u $SOCK_FD || return 1
    MSG_RD="$REPLY"
    return 0
}
write_socket()
{
    local str="$1"
    [ $SOCK_FD -eq 0 ] && return 1
    printf "$str" >&$SOCK_FD 2> /dev/null
}
#-----------------------------------------------------------

if ! open_socket; then
    printf "** Verbindung nicht möglich\n"
    exit 1
fi

while true; do
    if read_socket 2; then
        printf "** Message: %s\n" "$MSG_RD"
    else
        printf "** Read timeout\n"
    fi
    write_socket "Hallo server\n"
done
exit 0

Anwendung:
Starte in einer console einen tcp server mit:
# ncat -v -l -k localhost 2222
Starte dieses script am selben Rechner und schau was passiert.
Die Kommunikation ist bidirektional

Wenn du das verstehst, ändere den servername und die portnummer im script und verbinde dich mit ebusd.

Gruß
 
OP
O

Onkel-Tom

Newbie
Hallo Gräfin Klara,

wieder einmal vielen Dank für deine Mühe und die viele Arbeit die Du dir damit machst.

Wenn du das verstehst, ändere den servername und die portnummer im script und verbinde dich mit ebusd.
Da ich nicht nur verstehen will was bei deinem Programm hinten raus kommt sonder auch was jeder Befehl macht habe ich jetzt wohl ein paar Tage zu tun, aber ich habe es ja so gewollt :lol:

Bin mal gespannt was ich da wieder alles lerne.....

LG
Thomas
 
wieder einmal vielen Dank für deine Mühe und die viele Arbeit die Du dir damit machst.
Die Arbeitszeit für dieses script waren wenige Minuten.
Das ist überhaupt kein Problem.


Ein paar Hinweise zu den Funktionen:

sig_exit()
Wann immer du das script mit einem exit verlässt, landest du in sig_exit()
Sollte dieses script ein daemon sein (nennen wir es tomd) und jemand setzt auf die console ein:
# systemctl stop tomd.service
landest du in sig_exit()
Räum dort auf, schließe die Verbindungen, schreib in den log, usw. und beende mit exit 0

sig_pipe()
Wie jeder ordentlich tcp_client bemerkt auch dieses script, wenn der server (z.B. ebusd) sich beendet oder seine Verbindung schließt
Ist das der Fall, landest du in sig_pipe.
Hier könnte ein timer gestartet werden, der in Intervallen mit open_socket() versucht, wieder eine Verbindung zu schaffen.
Was auch immer in diesem Fall passieren soll, sig_pipe ist dafür da.

open_socket()
Nimm es wie es ist. Darüber wirst du im Netz nichts gescheites finden.

read_socket()
Die Wartezeit darf auch sein z.B. 0.5 für 500mS oder auch 0.
Da die Verbindung zum Server immer aufgebaut bleibt, kommst du hier nie in eine Blockade.
Ist die Wartezeit z.B. auf 10 Sekunden gesetzt aber es wird ein Telegramm empfangen oder ein Telegramm steht schon in
der Warteschlange, dann liefert read_socket sofort. Sollte dieses script ein daemon sein, dann ist read_socket() der
richtige Platz um zu schlafen ohne etwas zu versäumen.

write_socket()
Selbsterklärend.

Gemeinsam mit den pipes kann dieser tomd ein proxy sein, der Telegramme .z.B.
aus der pipe 1:1 an ebusd weiterreicht, empfangene Telegramme von ebusd irgendwohin versendet,
sie übersetzt, verwirft oder selbständig mit ebusd irgendwelche Aufgaben erledigt.
Da du Software aus dem Netz beziehst, die nur starr beschriebene Aufgaben erfüllen, braucht es eine Instanz,
die dir die Möglichkeit gibt, Individualität in das System zu bringen.
 
Zuletzt bearbeitet:
Oben