COM Port Abfrage in der Bash

brenner

Commander
Registriert
Apr. 2002
Beiträge
3.037
Unte Windows nutze ich Putty, stelle dieses auf Seriell um, gebe COM-Port und Baudrate ein und bekomme dann eine Konsole geöffnet. In dieser kann ich dann z.B. "$TXT" absetzen und bekomme dann meine gewünschten Werte, z.B.
TA: 13,5°C Kesselstatus: 0
TK: 53,4°C Kesselstarts: 530
PK: 0% Kessellaufzeit: 1041

Nun möchte ich das ganze in meiner Debian VM laufen lassen, den USB-Seriell Converter habe uch erfolgreich durchgeschleift, ein dmesg gibt mir folgendes aus:
[78776.449195] usb 2-1: new full speed USB device using uhci_hcd and address 4
[78777.039596] usb 2-1: New USB device found, idVendor=0403, idProduct=6001
[78777.039603] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[78777.039608] usb 2-1: Product: FT232R USB UART
[78777.039612] usb 2-1: Manufacturer: FTDI
[78777.039614] usb 2-1: SerialNumber: A400fERE
[78777.045734] usb 2-1: configuration #1 chosen from 1 choice
[78777.057681] ftdi_sio 2-1:1.0: FTDI USB Serial Device converter detected
[78777.057726] usb 2-1: Detected FT232RL
[78777.057729] usb 2-1: Number of endpoints 2
[78777.057733] usb 2-1: Endpoint 1 MaxPacketSize 64
[78777.057736] usb 2-1: Endpoint 2 MaxPacketSize 64
[78777.057739] usb 2-1: Setting MaxPacketSize 64
[78777.059816] usb 2-1: FTDI USB Serial Device converter now attached to ttyUSB0
root@cacti01:/


Ich möchte jetzt das Ganze via Bash abfragen um mir anschließend einzelne Werte rauscutten kann und die in eine Textdatei legen.

Leider scheitert das Ganze momentan daran das ich nicht weiß wie ich den COMPort (wie auch schon beim Putty) öffne zum abfragen :(
 
cat /dev/ttyUSB0

edit: in deinem Fall vielleicht in einer Konsole echo "$TXT" > /dev/ttyUSB0 und in einer anderen cat /dev/ttyUSB0. Probier das doch mal aus, ob dann was zurückkommt wie du es erwartest.
 
Danke,

aber leider bekomme ich von dem Device alle 10 Sekunden neue Werte, sprich es stoppt nicht nach der ersten Ausgabe :-(
 
Ich dachte die Werte kommen nur, nachdem du $TXT abschickst? Wofür ist das dann gut?
Ich würde sowieso das Ausgabeformat von was auch immer das ist ändern, dass es besser Maschinenlesbar ist.
Du kannst es auch statt mit cat mit tail -f in eine Textdatei pipen (wenn ich mich nicht täusche).
Das wäre dann sowas wie
tail -f /dev/ttyUSB0 > /pfad/zur/textdatei.txt

Keine Garantie, habe gerade kein Unix da, aber du kannst es ja leicht mit man tail herausfinden.
Vielleicht kannst du auch noch mal genau erklären, was du machen willst. Willst du etwas "loggen" oder auf Abruf genau einen Wert erhalten?
 
Stimmt, aber mit deinem Befehl kommen sie zyklisch alle 10s refreshed.

Der Tail funktioniert leider nicht, die Textdatei wird nicht gefüllt.

Ich schreib gleich nochmal ausführlich was ich machen will.

Danke! :-)
Ergänzung ()

Ich habe seit gestern ein Interface mit dem ich die Daten meiner Heizungsanlage auslesen kann. Das funktioniert an sich soweit, aber ich möchte die Werte nehmen und in meiner Haussteuerung verwenden. Diese Werte bekomme ich mittels einer wget Abfrage in die Haussteuerung.

Auslesen kann ich die Werte z.B. so:
Code:
root@cacti01:~# cat /dev/ttyUSB0 115200
[05.05.2012 19:16]

TA:  14,6°C   Kesselstatus:   0
TK:   0,0°C   Kesselstarts:   2141
PK:     0%    Kessellaufzeit: 872

Puffer         Heizkreis 1      Heizkreis 2
======         ===========      ===========
TWO:  56,6°C   TI1:   31,0°C    TI2:     0,0°C
TPO:  34,6°C   TV1:   33,3°C    TV2:   -29,6°C
TPU:  34,4°C   TR1:   33,5°C    TR2:   -29,1°C
TWU:  33,5°C   TV1S:  34,4°C    TV1S:    0,0°C
TWOS: 56,0°C   RT1S:  23,0°C    RT2Sl:   0,0°C
TPOS: 44,4°C   PHK1:    50%     PHK2:     0%

Solar                           Störung
=====                           =======
TSA:        38,6°C              Kessel: -
TSE:        30,6°C              Fühler: -
PSO:         0%                 Solar:  -
Status:      Aus
Leistung:    0,0kW
Tagesgewinn: 16kWh
Ertrag:      85kWh


Diese Anzeige aktualisiert sich selbstständig alle 10 Sekunden.


Mittels solch eines wget Aufrufes kommen die Werte in die Haussteuerung:
Code:
[url]http://192.168.0.11/addons/db/state.cgi?item=TA&dp=STATE&value=10[/url]

Würde hier also heißen das TA (Temperatur Aussen) auf 10°C gesetzt wird.




Teilziel ist jetzt also z.B. den TA Werte aus de seriellen Schnittstelle auszulesen und mittels wget zu übertragen.
Komplettziel natürlich alle Werte übertragen im maximal 5 Minutentakt.
 
Kannst du denn Einfluss nehmen auf das Format, wie es von der Heizungsanlage kommt?
So wird das noch ein bisschen Arbeit, das mit awk, sed und so weiter auseinander zu nehmen.

Du müsstest mal schauen, was da für ein Abschlusszeichen nach der letzten Zeile kommt, also nach "Ertrag ..." und dann die Schnittstelle auslesen mit einem Programm, was sich nach diesem Zeichen terminiert. Bin mir da nicht sicher wie man das am geschicktesten macht.

Wofür ist denn nun dieses $TXT? Kannst du nicht vielleicht mit einem zweiten Befehl die Ausgabe der Heizungsanlage wieder schlafen schicken?

Dann das ganze in eine Textdatei pipen und Zeilenweise die Variablen mit awk, sed, ... heraussuchen und per wget Befehl weiterleiten.

Über einen Cronjob alle 15 Minuten oder so ausführen lassen.
 
Hallo Lamer,

wenn ich per Putty oder unter Linux mit "screen" raufgehe, kann ich die Befehle wie #TXT absetzen. Es geht z.B. auch #CSV, dann bekomme ich die reinen Zahlenwerte direkt hintereinander ausgegeben, was das rausgrabben erheblich vereinfachen würde.

Genaues hier:
http://www.emsystech.de/download/systainterface/SystaInterface_Handbuch.pdf


Ich weiß nur nicht wie ich das dann automatisiere, also den z.B. screen Aufruf mit anschließenden #CSV Aufruf um dann einen bestimmten Wert davon mit wget abzusetzen.
 
Ok, ich weiß nicht wie gut deine Linuxkenntnisse überhaupt sind.

Generell kannst du, wenn du nach einem Befehl eine Textausgabe auf dem Bildschirm hast, das ganze stattdessen auch in eine Datei schreiben (pipen).
Wenn "befehl" eine Bildschirmausgabe macht, dann schreibt "befehl > text.txt" die Ausgabe in eine Textdatei statt sie anzuzeigen.
Screen benutze ich selbst nur um mehrere Terminals über ssh zu nutzen. Schau doch mal ob du die Ausgabe von Screen wegpipen kannst.

Wenn du dann eine Textdatei hast, kannst du mit grep oder awk eine Zeile isolieren. Die awk Syntax hab ich nicht im Kopf, aber bei google findest du sicher schnell das richtige. Danach solltest du dann die einzelne gewünschte Zahl vor dir haben.
 
Hallo,

ich lese meinen Stromzähler über ein serieller Interface aus und schreibe die Werte in eine Datenbank. Ich hab es auch erst über die "bash" versucht.
Bei der "bash" hatte Probleme die "Com-Werte" richtig zu setzen - außerdem sollten die Werte sowieso in eine Datenbank.

Deshalb habe ich ein kleines C-Prg (ab)geschrieben und angepasst.

Falls Du Interesse hast kann ich Dir den Code schicken.
 
@lamer:
Geht zu mit Linuxkenntnissen, bisher habe ich mit etwas Hilfe das notwwendigste immer hinbekommen.

@warti:
Danke, aber in eine Datenbank will ich genau nicht schreiben da es bei mir keinen Sinn macht und unnötig Performance raubt.
Ich komme ja an die Werte, weiß nur nicht sie (wie beschrieben) für mich zu nutzen. Ich denke technisch 0 Problem wenn man weiß wie es geht.
 
Ich hab mal den Datenbankanteil rausgeschmissen und durch eine einfache Ausgabe ersetzt.

Code:
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <sys/stat.h>
#include <fcntl.h>


#define BAUDRATE B9600
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1 /* POSIX compliant source */

void readline (int fd, char *buffer, int max)
{
        char c;
        int i=0, res;
        max --;
        do {
                res = read(fd, &c, 1);
                buffer[i] = c;
                i ++;
                if (i > max) break;
                if (res == 0) break;
        } while (c != '\n');
        buffer[i] = 0;
}



void main()
{
        int fd;
        int SocketFD ;
        struct termios oldtio,newtio;
        char buf[255];
        // Serielles device oeffnen
        fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
        if (fd <0) {perror(MODEMDEVICE); exit(-1); }
        tcgetattr(fd,&oldtio); /* save current port settings */

        // Serielles device einstellen
        memset(&newtio,0 , sizeof(newtio));
        newtio.c_cflag = BAUDRATE | CS7 | CLOCAL | PARENB | CREAD;  // 9600 7E1
        newtio.c_iflag = IGNPAR;
        newtio.c_oflag = 0;
        newtio.c_lflag = 0;             /* set input mode (non-canonical, no echo,...) */
        newtio.c_cc[VTIME]    = 0;      /* inter-character timer unused */
        newtio.c_cc[VMIN]     = 1;      /* blocking read until 1 chars received */
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd,TCSANOW,&newtio);


        while (1)
        {
                readline(fd,buf,255);
                printf("%s\n", buf);
        }


        tcsetattr(fd,TCSANOW,&oldtio);
}

einfach mit gcc übersetzen:

gcc <source.c> -o <executable>

wichtig! Dieses Prg. stellt aktuell auf 9600 7E1. Für andere Parameter einfach suchen ...
 
Danke das du trotzdem noch weiter versuchst zu helfen.
Das kommt dabei raus, eine zyklische (10s) Ausgabe von etwas was ich nicht lesen kann ;-)

Code:
root@cacti01:~# gcc wartisource.c -o wartiexe
root@cacti01:~# ls
hmc.cache  hmcompanion.jar  test001.log  test01.txt  wartiexe  wartisource.c
root@cacti01:~# ./wartiexe
[O      ª¹e0L&R
               ÒÅe]C¡HD

é L&ICHH©ÖÍe¶.WÕsSHDUé HL       CPH©ÖÍe¶.WKÑs
                                             Ué &ICHHÒA &)CPH$%ÒA K¦bÅaCC!ÕUé &©C@Hé &báaCHH$é PH&      CC!ÕõM:PL       CPH*Ué I&       C@H$±:PH&       CC!õM:ZN        CH*Ù*Ò M¦              ¡H) IHÔT½lX®(DÑö¹]ë5

Oêõu    B¡Qêõu=Oj)SP'   A ¦)CB¡YÖÍe¶MH©¤¤ME£~Z«É:KHµ=:PH$       ÁU      B¡ê
r¤´Ñaº].A HP×5

¦Y*W¹g  Z]
ZXVk
Ergänzung ()

Ich glaub e die kryptischen Zeichen kommen durch die falschen Porteinstellungen. Habe deine Einstelungen in 115200 Baud und CS8 geändert. Scheint aber nicht gereicht zu haben.

Unter Debian erreiche ich hiermit die korrekte Funktion:
Code:
stty -F /dev/ttyUSB0 115200 cs8 raw -parity
 
.. hallo,

Du musst die entsprechende Einstellung im Sourcecode ändern!!

Zeile 10 und Zeile 45.

Das Prg. überschreibt die aktuellen Einstellungen ...

*Edit* Hier ein gefundenes Bsp:
Code:
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

// set to 8N1
newtio.c_cflag &= ~PARENB;
newtio.c_cflag &= ~CSTOPB;
newtio.c_cflag &= ~CSIZE;
newtio.c_cflag |= CS8;

newtio.c_iflag = IGNPAR;
 
Danke,

so sieht es besser aus :D

Code:
root@cacti01:~# rm wartiexe
root@cacti01:~# gcc wartisource.c -o wartiexe
root@cacti01:~# ./wartiexe
[06.05.2012 13:47]



TA:  11,8°C   Kesselstatus:   0

TK:   0,0°C   Kesselstarts:   2145

PK:     0%    Kessellaufzeit: 875



Puffer         Heizkreis 1      Heizkreis 2

======         ===========      ===========

TWO:  48,2°C   TI1:   28,8°C    TI2:     0,0°C

TPO:  47,8°C   TV1:   42,6°C    TV2:   -29,6°C

TPU:  41,5°C   TR1:   28,5°C    TR2:   -29,1°C

TWU:  30,1°C   TV1S:  37,2°C    TV1S:    0,0°C

TWOS:  0,0°C   RT1S:  23,0°C    RT2Sl:   0,0°C

TPOS: 47,2°C   PHK1:    50%     PHK2:     0%



Solar                           Störung

=====                           =======

TSA:        35,8°C              Kessel: -

TSE:        34,6°C              Fühler: -

PSO:         0%                 Solar:  -

Status:      Aus

Leistung:    0,0kW

Tagesgewinn: 2kWh

Ertrag:      87kWh

^C
root@cacti01:~#



Leider, wie beim "CAT" zyklische 10s Ausgabe und dieses Mal ist noch eine zusätzliche Leerzeile zwischen jeder Zeile, aber das ist ja egal.

Wie mache ich jetzt weiter? Habe ja quasi die gleiche Ausgangssituation wie bisher.
 
Bzgl. Leerzeile:

Lösche in Zeile 58 das "\n"

Code:
./wartiexe  | grep <zeile> | cut --delimiter=' ' -f2 | cut -b2- | cut -b-2 > dateiausgabe.txt

und wenn es zu viele Leerzeichen sind folgenden Befehl dazwischen:

Code:
tr -s ' ' ' '
 
Zuletzt bearbeitet:
warti schrieb:
Bzgl. Leerzeile:

Lösche in Zeile 58 das "\n"

Code:
./wartiexe  | grep <zeile> | cut --delimiter=' ' -f2 | cut -b2- | cut -b-2 > dateiausgabe.txt

und wenn es zu viele Leerzeichen sind folgenden Befehl dazwischen:

Code:
tr -s ' ' ' '


Danke,

Leerzeilen sind jetzt weg, bin gespannt auf die nächste Zeile, aber ich muss mir kurz mal zu Essen holen :)
 
... machen wir es doch umgekehrt. Welchen Wert möchtest Du denn haben? Dann schauen "wir" weiter ;)
 
Hmmm,

das klappt noch nicht so und ich habs mit diversen Zeilen ausprobiert

Code:
root@cacti01:~# ./wartiexe  | grep 11 | cut --delimiter=' ' -f2 | cut -b2- | cut -b-2 > dateiausgabe2.txt
^C
root@cacti01:~# cat dateiausgabe2.txt
root@cacti01:~#


Das hier bringt auch nicht viel, nach einer halben Minute Wartezeit kommen solche Ausgaben raus, im viererpack und die falsche Zeile.

Code:
root@cacti01:~# ./wartiexe  | grep 11
TA:  11,7°C   Kesselstatus:   0
TA:  11,8°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,8°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
^C
root@cacti01:~#
Ergänzung ()

warti schrieb:
... machen wir es doch umgekehrt. Welchen Wert möchtest Du denn haben? Dann schauen "wir" weiter ;)


Oh, zu spät gesehen.

Anfangen würd ich einfach gerne mal mit dem TA (TemperaturAussen) Wert.
 
Code:
wartiexe |  grep TA:

ergibt:

Code:
TA:   14,6°C    Kesselstatus:    0

dann mehrfache Leerzeichen weg:

Code:
 wartiexe | grep TA: | tr -s ' ' ' '

ergibt:
Code:
TA: 14,6°C Kesselstatus: 0

jetzt noch aufteilen mit cut (Trennzeichen ist hier das Leerzeichen) - 2tes Feld soll es sein:

Code:
wartiexe | grep TA: | tr -s ' ' ' ' | cut --delimiter=' ' -f2

ergibt:
Code:
14,6°C


Und jetzt die ersten 4 Zeichen:

Code:
wartiexe | grep TA: | tr -s ' ' ' ' | cut --delimiter=' ' -f2 | cut -b-4

ergibt:
Code:
14,6

und das ganze in eine Datei:

Code:
wartiexe | grep TA: | tr -s ' ' ' ' | cut --delimiter=' ' -f2 | cut -b-4 > Aussentemperatur.txt
 
Zuletzt bearbeitet: (fehler im script)
Ich scheitere leider schon am Anfang.

Nach 1Minute kommt eine Ausgabe mit 6 Zeilen und wird dann regeläßig um weitere 6 Zeilen erweitert wenn ich nicht abreche.

So weit so schlecht ;-) Was mich aber noch mehr wundert ist, woher die 11,8 kommt und warum das ganze 1 Minute bis zur ersten Ausgabe dauert.


Code:
root@cacti01:~# ./wartiexe
[06.05.2012 15:14]

TA:  11,7°C   Kesselstatus:   0
TK:   0,0°C   Kesselstarts:   2146
PK:    50%    Kessellaufzeit: 875

Puffer         Heizkreis 1      Heizkreis 2
======         ===========      ===========
TWO:  46,7°C   TI1:   29,0°C    TI2:     0,0°C
TPO:  45,0°C   TV1:   41,2°C    TV2:   -29,6°C
TPU:  36,9°C   TR1:   36,2°C    TR2:   -29,1°C
TWU:  29,5°C   TV1S:  37,3°C    TV1S:    0,0°C
TWOS:  0,0°C   RT1S:  23,0°C    RT2Sl:   0,0°C
TPOS: 47,3°C   PHK1:    50%     PHK2:     0%

Solar                           Störung
=====                           =======
TSA:        38,0°C              Kessel: -
TSE:        32,0°C              Fühler: -
PSO:         0%                 Solar:  -
Status:      Aus
Leistung:    0,0kW
Tagesgewinn: 2kWh
Ertrag:      87kWh
^C
root@cacti01:~# ./wartiexe |  grep TA:
TA:  11,8°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
TA:  11,7°C   Kesselstatus:   0
^C
root@cacti01:~#
 
Zurück
Oben