Beliebige FHEM Readings Seriell senden -ERLEDIGT-

Begonnen von monkye, 05 März 2023, 09:09:07

Vorheriges Thema - Nächstes Thema

monkye

Guten Morgen,

kurz zum Ziel: Zur Anzeige diverser Informationen benötige ich eine mobile, Batterie betriebene, stromsparende Anzeige.

Bisher habe ich dazu einen Eigenbau verwendet, der im 433MHz Bereich senden und empfangen kann. Das Teil musste man per Taste ,,aus dem Schlaf reißen" und hat dann als Dummy-Temperatur-Sensor die ,,Zentrale" (damals noch nicht FHEM) angepingt und hat kurz darauf Anzeigedaten zurückgesendet bekommen. Dann ist der Sender & Empfänger schlafen gelegt worden und nach 5 Minuten Anzeige ging die Anzeige wieder in den Schlafmodus. Die AA-Batterien haben viel länger als 1 Jahr gehalten. (billigste 433MHz Sender und Empfänger + ATTiny45, I2C 2x16 LCD)

Die würde ich gerne weiter verwenden. Gelesen habe ich, dass es ECMD gibt - wüsste aber jetzt nicht wie ich damit bestimmte Datensequenzen zum Senden an einen USB-TTL-Serial Adapter rauslassen könnte...

Da, wo ich eine feste StromversOrtung habe, werde ich vermutlich alles mit ESPEeasy erledigen.

Lesehinweise und fertige, ähnliche Lösungen interessieren mich natürlich sehr :-)

Danke

Aurel_B

Hallo monkye,

das sollte - von Seiten FHEM - nicht allzu schwer sein. Ich verwende etwas sehr ähnliches um im 2 Sekunden Takt Werte an einen Arduino (via USB angeschlossen) seriell zu senden, dieser zeigt dann diese Werte auf diversen LED Anzeigen an (siehe unten). Dafür verwende ich ECMD wie folgt:


defmod Panel_unten_Arduino_ECMD ECMD serial /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.4:1.0-port0@115200
attr Panel_unten_Arduino_ECMD classdefs Panel_unten_Arduino_Classdef=/opt/fhem/ecmd_classdef/Panel_unten_Arduino.classdef
attr Panel_unten_Arduino_ECMD icon mdt-serial-port
attr Panel_unten_Arduino_ECMD room Arduino
attr Panel_unten_Arduino_ECMD verbose 3

defmod Panel_unten_Arduino_ECMDDevice ECMDDevice Panel_unten_Arduino_Classdef
attr Panel_unten_Arduino_ECMDDevice icon mdt-dev-to
attr Panel_unten_Arduino_ECMDDevice room Arduino
attr Panel_unten_Arduino_ECMDDevice verbose 3

defmod at_Send_Values_To_Panel_unten_Arduino at +*00:00:02 set Panel_unten_Arduino_ECMDDevice update
attr at_Send_Values_To_Panel_unten_Arduino icon mdt-clock-outline
attr at_Send_Values_To_Panel_unten_Arduino room Arduino

$ cat /opt/fhem/ecmd_classdef/Panel_unten_Arduino.classdef
set update cmd {sprintf("%d",ReadingsVal("Stromverbrauch_Momentan","Verbrauch_Total",0)).":".sprintf("%d",10*sprintf("%.1f",ReadingsVal("Kostal","Autarkie_heute",0))).":".sprintf("%d",10*sprintf("%.1f",ReadingsVal("Stromzaehler_Netz","Gesamtverbrauch_heute_kwh_Total",0))).":".sprintf("%d",10*sprintf("%.1f",ReadingsVal("Kostal","Ertrag_Tag_kwh_Total",0))).":".FmtTime(time())."\n"}


Die classdef zuunterst mag etwas wirr erscheinen auf den ersten Blick, ist allerdings super easy: es wird einfach ein String à la "$Wert1:$Wert2:$Wert3" etc. gesandt. Der Arduino zerlegt dann diesen String wie folgt:

int numScanned = sscanf (receivedChars, "%d:%d:%d:%d:%d:%d:%d", &origValue, &Autarkie, &Verbrauch, &Produktion, &Hour, &Minute, &Second);

Im Anhang noch die entsprechende Projektdatei, hilfreich ist dort vielleicht die Funktion recvWithEndMarker() die sich um das Einlesen des via Serial empfangenen Strings kümmert.

(https://abload.de/img/img_20230305_210714psfs6.jpg)

monkye

Danke @Ansgru, das teste ich morgen...

monkye

So, habe mal damit getestet. Es geht prinzipiell, nur - mein altes ,,Protokoll" bekomme ich damit nicht hin.

Jetzt habe ich einen zweiten Ansatz verfolgt, nämlich mit dieser Datei https://forum.fhem.de/index.php?action=dlattach;topic=14531.0;attach=4856

Aber auch hier komme ich nicht weiter, weil die Umschaltung der Baudrate nicht funktioniert. Schalte ich per
stty -F /dev/ttyUSB1 600
auf der Konsole um, dann kommt das, was ich erwarte ganz sauber raus. (Im Standard steht die Baudrate auf 9600)

Ideen oder Hinweise?


betateilchen

#4
Zitat von: monkye am 08 März 2023, 17:22:18
Ideen oder Hinweise?

Zeig doch mal, wie Du die genannte Datei verwendest.

Generell könntest Du aber auch mit dem FHEM-eigenen DevIo.pm auf die serielle Schnittstelle zugreifen, wenn Du so hardwarenah unterwegs sein möchtest.

https://wiki.fhem.de/wiki/DevIo


--
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

monkye

#5
Zitat von: betateilchen am 08 März 2023, 17:50:12
Zeig doch mal, wie Du die genannte Datei verwendest.

Generell könntest Du aber auch mit dem FHEM-eigenen DevIo.pm auf die serielle Schnittstelle zugreifen, wenn Du so hardwarenah unterwegs sein möchtest.

https://wiki.fhem.de/wiki/DevIo

In der Konsole z.B. eingeben:

{serial_comm(600,"/dev/ttyUSB1","Das ist ein Test")}



Nachtrag:
RPI mit Bullseye
FHEM ist aktuell, genau wie deCONZ

Die serielle Schnittstelle ist ein USB FTDI232 Clone

monkye

#6
Nachdem ich mal den Logicanalyzer (LA) drangemacht hatte konnte ich sehen, dass die ersten Bits herausgeschoben werden - aber dann geht quasi der Port wieder in den Ruhezustand - wie ein Timeout. Hab' dann mal ein bisschen
sleep(0.5)
eingefügt, hat schon einmal geholfen.

Damit kriege ich es aber nicht hin, dass bei mehreren nacheinander auszuführenden WRITE Commands gewartet wird, bis alle Bytes eines WRITE rausgeschoben sind. Im LA kann ich es sehen: Alle Bytes kleben aneinander....

Nun bin ich leider in Perl nicht so ,,handy", dass ich einen eigenen Thread beauftrage, die Daten laut Datagramm (mit Pausen usw.) rauszulassen. Gibt es irgendwo etwas zu lesen *oder* ein Modul, wo ich mir das anschauen kann?

Nachtrag: mit den Möglichkeiten von Device::Serial->write_done bzw. write_drain komme ich auch nicht weiter, um den Abschluss der Sendung zu bemerken...

monkye

Also ich habe es nicht hinbekommen, denn offenbar werden die Ausgaben von Device::Serial->write() an das OS übergeben (oder wem auch immer), wobei die Ausgaben gepuffert sind. Natürlich könnte ich in einzelnen Paketen senden, aber da ist das Timing Zufall. Und das zuvor genannte Thema, dass die Umschaltung der Baudrate auf niedrige 600Bps offenbar nicht sauber funktioniert - denn es wurde erst sauber übertragen, wenn ein Sleep() platziert wurde - oder an der Console die Geschwindigkeit passend eingestellt war.

Jetzt bin ich den alten Weg gegangen und verwende OPEN(), BINMODE(), SYSWRITE und CLOSE(). Das funktioniert auch zeitlich wie erwartet. Natürlich ist das ein blockierender Prozess, mal gucken ob das wirklich hinderlich ist.