CUL opening CUL device /dev/ttyACM0
Attempt to reload POSIX.pm aborted.
Compilation failed in require at /usr/lib/perl5/5.10/Device/
SerialPort.pm line 6, <$fh> line 26.
BEGIN failed--compilation aborted at /usr/lib/perl5/5.10/Device/
SerialPort.pm line 6, <$fh> line 26.
Compilation failed in require at /usr/local/lib/FHEM/00_CUL.pm line
928, <$fh> line 26.
Zeile 6 in SerialPort.pm ist:
use POSIX qw(:termios_h);
Nun weiss ich nicht recht weiter. Habe termios.h nach /usr/include
geschoben, ohne Erfolg.
Vielleicht kann mir jemand helfen, ich kenne mich mit perl - bis auf
die fhz.cfg Kommandos - nicht aus. Ist vielleicht ganz einfach?
Gruesse
Felix
Das ist natuerelich ... suboptimal. termios.h & co muss man mit h2ph
installieren, perl schaut nicht nach /usr/include, und C-Header liest er auch
ungern.
Habe jetzt mit h2ph gespielt, die includes zusammengesammelt und
(tataa)
perl -e 'require "termios.ph"'; liefert keine Fehler mehr.
Aber: Er will das Objekt nicht laden:
CUL opening CUL device /dev/ttyACM0
Can't locate loadable object for module Device::SerialPort in @INC
(@INC contains: /usr/lib/perl5/5.10 .) at /usr/local/lib/FHEM/
00_CUL.pm line 928
perl /usr/lib/perl5/5.10/Device/SerialPort.pm
Can't locate loadable object for module Device::SerialPort in @INC
(@INC contains: /usr/lib/perl5/5.10 .) at /usr/lib/perl5/5.10/
DynaLoader.pm line 69
DynaLoader::croak('Can\'t locate loadable object for module
Device::SerialPort i...') called at /usr/lib/perl5/5.10/DynaLoader.pm
line 135
DynaLoader::bootstrap('Device::SerialPort', 1.002) called at /usr/lib/
perl5/5.10/XSLoader.pm line 97
XSLoader::bootstrap_inherit('Device::SerialPort', 1.002) called at /
usr/lib/perl5/5.10/Device/SerialPort.pm line 37
Zeile 37 ist XSLoader::load('Device::SerialPort', $VERSION);
Nun meine Anschlussfrage:
Ist die Abfrage (perl ...SerialPort.pm) ueberhaupt sinnvoll?
Laedt der sich in der Zeile selbst?
Die Header verweisen auf irgendwas / müssen irgendwo auch
implementiert sein. Wohl in einem KernelModul. Welches wuerde ich denn
benoetigen?
Habe das Gefuehl, ich bin auf dem Holzweg. Verstehe es einfach zu
wenig.
Angenommen, ich wuerde das CUN besorgen, dann kann ich auf dieses via
TCP/IP zugreifen. Wuerde das Modul 00_CUL.pm dann auf SerialPort.pm
verzichten?
Viele Gruesse
Felix
Vielleicht fehlt SerialPort.so? Ich habe es in
.../lib/site_perl/5.8.3/i686-linux/auto/Device/SerialPort/SerialPort.so
> Angenommen, ich wuerde das CUN besorgen, dann kann ich auf dieses via
> TCP/IP zugreifen. Wuerde das Modul 00_CUL.pm dann auf SerialPort.pm
> verzichten?
Ja, bei TCP/IP kann man darauf verzichten. Eigentlich kann man auf SerialPort
auch sonst verzichten, man muesste in 00_CUL.pm "nur" new/input/write/etc mit
open/sysread/syswrite/etc ersetzen, alle IO Funktionen sind in 4 Funktionen
zusammengefasst. Ich hatte das auch schon vor, weil mich die staendigen
SerialPort Probleme nerven, und das CUL Protokoll (genau deswegen) 7-bit ist.
Die Baudrate wird ausserdem ignoriert. Weiss jemand, ob das auch unter Windows
funktioniert?
Gruss,
Rudi
Scheint so :-)
Habe nun eine "funktionierende" Version.
CUL opened /dev/ttyACM0 for MyCUL
Use of uninitialized value $ver in pattern match (m//) at /usr/local/
lib/FHEM/00_CUL.pm line 442, <$fh> line 26.
Zeile 442 in 00_CUL.pm
while($try++ < 3 && $ver !~ m/^V/) {
CUL_SimpleWrite($hash, "V");
($err, $ver) = CUL_ReadAnswer($hash, "Version", 0);
return "$name: $err" if($err && ($err !~ m/Timeout/ || $try ==
3)); <---442
}
Was <$fh> line 26 ist, faellt mir gerade nicht ein ;-)
Habe Version 4.8 und die aktuellen Quellen versucht. Die 4.8 ging
bislang auf meinem Ubuntu-System. Deshalb nehme ich an, es ist nicht
der Fehler der Zeile 442.
Kann ich davon ausgehen, dass ich alle Abhaengigkeiten erfuellt habe?
Gruesse
Felix
ser2net (http://ser2net.sourceforge.net/)
Mit der Zeile:
27073:raw:300:/dev/ttyACM0:115200 NONE 1STOPBIT 7DATABITS
in ser2net.conf
und
define MyCUL CUL 127.0.0.1:27073 3333
in fhz.cfg
tut es prima. Supi eigentlich, leider tritt auf dem o.g. Router immer
noch der selbe Fehler auf:
CUL opened 127.0.0.1:27073 for MyCUL
Use of uninitialized value $ver in pattern match (m//) at /usr/local/
lib/FHEM/00_CUL.pm line 442, <$fh> line 27.
Use of uninitialized value $ver in pattern match (m//) at /usr/local/
lib/FHEM/00_CUL.pm line 442, <$fh> line 27.
2010.01.02 17:45:32 1: Cannot init 127.0.0.1:27073, ignoring it
Genau dieselben Einstellungen, habe nochmal dieselbe fhem 4.8
installiert.
Auf dem Router ist uebrigens Perl 5.10
Gruesse
Felix
Ich kann von meinem Rechner aus auf den ser2net port des Routers
zugreifen, und alles laeuft wie gehabt:
define MyCUL CUL 192.168.1.1:27073 3333
Es liegt also nicht am SerialPort.
Viele Gruesse
Felix
Ich bin verwirrt. Tut es oder nicht?
Koenntest Du es wieder ohne ser2net mit maximalen loglevel (attr global verbose
5) versuchen, und dabei nach der ominoese Zeile 442 (nach CUL_ReadAnswer) die
Ergebnisse protokollieren mit sowas wie:
Log 0, "ERR: $err";
Log 0, "VER: $ver";
Es tut nicht. Nicht auf dem Router (Perl 5.10, 192.168.1.1) . Es
funktioniert auf dem Ubuntu Rechner, egal wo ich das CUL reinstoepsel,
per ser2net lokal und remote und auch (lokal) per SerialPort. Nur auf
dem Router funzt der code nicht. Weder ser2net noch SerialPort.
Ich denke, es ist ein Perl-Problem. Ich habe ein bisserl debuggt (kann
nix, nur Logeintraege).
Ich habe mit ngrep herausgefunden, dass V die Version auch
tatsaechlich zurückliefert. In der Zeile
my $nfound = select($rin, undef, undef, $to);
kommot $nfound als 0 zurueck. Folgerichtig springt er nach
return ("Timeout reading answer for get $arg", undef)
gilt fuer $arg = Clear und Version
Ich weiss leider nicht, wo select definiert ist, was es tut und warum
es 0 zurueckgibt.
Der obige Test gibt:
ERR: Timeout reading answer for get Version
VER ist leer.
Das selbe gilt fuer den Vesuch mit /dev/ttyACM0.
Ich finde merkwuerdig, dass das Log exakt genauso aussieht, wie beim
TCP Versuch.
vec($rin, $hash->{FD}, 1) = 1; Hat dieselben Werte ($rin konnte ich
nicht sehen), und $to in der select Anweisung ist auch gleich.
Koenntest Du "telnet CUL-Rechner ser2net-port" starten, und mit V<return>,
X21<return>, etc versuchen, CUL direkt zum Reden zu bringen? Danach kann man
gezielt weiter suchen.
> Ich weiss leider nicht, wo select definiert ist, was es tut und warum
> es 0 zurueckgibt.
Select ist "builtin" bzw. System-Call, und liefert 0 zurueck, wenn es auf
keinem der spezifizierten Kanaele (FileDescriptoren) innerhalb der angegebenen
Zeit was angekommen ist.
Ja, das geht. Alles. ngrep zeigt, dass es auch beim fhem init geht.
> Select ist "builtin" bzw. System-Call, und liefert 0 zurueck, wenn es auf
> keinem der spezifizierten Kanaele (FileDescriptoren) innerhalb der angegebenen
> Zeit was angekommen ist.
Hier liegt wohl der Hund begraben. Es liefert nix zurück.
return "$name: $err" if($err && ($err !~ m/Timeout/ || $try == 3));
verwendet $ver gar nicht. Use of uninitialized value $ver in pattern
match (m//) ist doch Quark?
Ich wuerde das Problem nicht beim select suchen, das ist so elementar, der
"muss" funktionieren. Eher beim Verbindugsaufbau zum ser2net. Koenntest Du
ser2net auf dem FB und fhem auf einem anderen Rechner starten?
Eher ist der Zeilennummer Quark. Ich vermute die Meldung kommt aus dem
while(.., paar Zeilen hoeher.
Habe ich schon. Mehrmals wechselseitig:
fhem auf ubuntu->CUL an OpenWrt geht
fhem auf ubuntu->CUL an ubuntu geht
fhem auf OpenWRT->CUL an Ubuntu geht nicht
fhem auf OpenWRT->CUL an OpenWRT geht nicht
Habe perl noch mal deinstalliert (wegen den o.g. h2ph Vesuchen), die /
usr/lib/perl5/... weggeworfen, neu installiert, selbes Ergebnis
Hmm, dann ist wahrscheinlich perl@OpenWRT putt. Ich fuerchte da ist ernsthaftes
Perl-Debuggen notwendig.
Eine Anekdote in diesem Zusammenhang: Ich habe fuer den FB erst perl 5.8.8
uebersetzt, der hatte aber grundsaetzliche Probleme, deswegen habe ich dann
5.6.2 genommen. Kannst Du folgendes auf dem OpenWRT fhem im telnet Prompt
eingeben:
{ $x=3;; Log 0, "X is: ".$x }
Er gibt mir keinen prompt. telnet connected nicht. Das Log sagt:
Server started(...
Warum bekomme ich keinen telnet prompt?
> Warum bekomme ich keinen telnet prompt?
Perl kaputt? Was sagt denn lokal auf OpenWRT
perl -e '$x=3; print "Hello " . $x . "\n"'
> perl -e '$x=3; print "Hello " . $x . "\n"'
Hello 3
Perl geht scho, im log kommt er bis zum
: Server started (version =VERS= from =DATE= ($Id: fhem.pl,v 1.97
2010/01/01 15:18:09 rudolfkoenig Exp $), pid 6323)
Da geht mehr als Hallo Welt.
On 21 Feb., 14:39, "lord.kilmarn...@googlemail.com"
Die Antwort ist beides mal, also auf openwrt und ubuntu:
hier! >$test<simple write endfertig version: V 1.35 CUL868
fehler: Kein Fehler
Das Proggie greift auf ser2net auf port 27073 zu, wo das CUL lauscht.
Sorry fuer den schlechten Aufbau. Ich weiss jetzt auch nicht, wie ich
das in fhem einbaue. Und auch nicht, wo der Fehler eigentlich lag.
Vielleicht kann das ja hier jemand sagen, bitte.
Verstehe ich nicht...
> Kann es sein, dass das CUL einfach schneller antwortet, als
> der Read Socket aufgebaut ist?
Ja, das macht aber (theoretisch) nichts.
1) aufruf von CUL_Clear raus
sub
CUL_DoInit($)
{
my $hash = shift;
my $name = $hash->{NAME};
my $err;
my $msg = undef;
# CUL_Clear($hash);
2) sub
CUL_ReadAnswer($$$)
{
...
# return ("Timeout reading answer for get $arg", undef)
# if($nfound == 0);
...
Warum, weiss ich nicht. Die Ausgabe von $buf ist ohne clear:
buf ist T0C6000A600F7
T585800A6FF1A
T0C6000A600F8
TDV 1.35 CUL868
im zweiten Aufruf
buf ist V 1.35 CUL868
oder er haengt noch mal was sinnloses dran.
Befehle empfaengt fhem bisher auch so nicht.
in CUL_DoInit()
CUL_Clear($hash);
ausgetauscht wird und in
CUL_ReadAnswer
return ("Timeout reading answer for get $arg", undef)
if($nfound == 0);
auskommentiert wird.
Allerdings geht es dann auch noch nicht, dass fhem Befehle emfängt.
also ist nfound 0, der buffer aber voll.
wenn ich also den timeout ausschalte, faehrt der server hoch. Er
fuehr vorher sogar noch einmal CUL_ReadAnswer aus:
ReadAnswer: Command: FHTID
2010.03.06 12:13:05 1: nfound: 0 Wenn nfound = 0 -> timeout. Timeout
ist gesetzt auf 0.5
2010.03.06 12:13:05 1: buf: 3333
CUL_Clear habe ich auskommentiert.
Nach dem Hochfahren fuehrt
telnet localhost 7072 zwar dazu, dass telnet connected, er reagiert
aber nicht auf Kommandos. Genausowenig auf irgendwelche Befehle. Wenn
ich eine Taste drücke, sehe ich, dass der Befehl an fhem geschickt
wird, aber es reagiert nicht.
Warum ist nfound 0? Scheint genau das Problem zu sein: Daten kommen
an, aber fhem fängt sie nicht. Warum ist $buf gesetzt und $nfound 0?
Nix, gefunden, nur was es soll?
Kann das mit irdendwelchen Konsoleeinstellungen zu tun haben?
Mini-Zusammenfassung von "man 2 select":
select() kriegt eine Liste von Filedesriptoren (netzwerk/geraet/etc) und ein
Timeout. Es blockiert solange, bis auf einem der Descriptoren Daten anstehen
oder der Timeout abgelaufen ist. Wenn (im perl) der timeout undef ist (nicht
0!), dann ist die Timeout Funktionalitaet abgeschaltet.
Verstehe ich es richtig: select() meldet in deinem Fall nie, dass Daten
anstehen (nfound ist nie > 0), aber Daten sind da, man kann sie auslesen.
Wenn das stimmt, dann ist die select() Implementation in dem installierten
perl, libc oder linux-kernel kaputt (in dieser abnehmender Wahrscheinlichkeits-
Reihenfolge :). Falls man das debuggen moechte, dann waere interessant die
Parameter des select() Systemcalls (== libc -> kernel) zu sehen, z.Bsp. mit
strace.
Gruss,
Rudi
Ich kompiliere strace gerade und schaue dann mal, ob mir der output
etwas sagt.
Gäbe es einen Workaround um select? Immerhin liest sysread ja.
Noe. Dieser fhem ist auch nicht hochgefahren wegen:
bind(5, ..., 16) = -1 EADDRINUSE (Address already in use)
> _newselect(8, [], NULL, NULL, {0, 0})
Schaut komisch aus. Mein "Produktions-fhem" schaut aus (kann man mit strace -p
<pid> beobachten):
select(24, [5 6 15 18 19 20 22], NULL, NULL, {205, 536666}
aber auch ein fhem mit Minimalkonfig hat wenigstens den "telnet" port (attr
global port 7072) im ersten [].
Kannst Du bitte verifizieren, ob ins select Aufruf was reingesteckt wird ($rin
ist nicht undef oder 0)?
Wenn dies zum Erfolg fuehren wuerde:
Log 1, "rin ist undef" if(!defined($rin));
dann ist es irgendwas (keine Ausgabe):
Log 1, "nfound: $nfound timeleft: $timeleft Wenn nfound = 0 ->
timeout. Timeout ist gesetzt auf $to. rin ist >$rin<";
Log 1, "rin ist undef" if(!defined($rin));
ergibt
nfound: 0 timeleft: 0 Wenn nfound = 0 -> timeout. Timeout ist gesetzt
auf 0.5. rin ist ><
Habe noch mal die log.txt mit einem durchgefuehrten strace angehaengt.
Das mit dem telnet wundert mich nicht, da ich per telnet zwar
einloggen kann, er aber keinen muks auf Eingaben hin macht.
$rin ist wahrscheinlich ein kleiner Zahl und damit ein Controlcharacter, was
man nicht so recht sieht. Deswegen sollte es statt "bla...>$rin<" eher "bla..."
. unpack("H*",$rin) . "<" sein. Ansonsten tippe ich auf ein Problem in Perl
oder evtl in libc.
Mit folgendem C-Programm (selecttest.c):
=======
#include <fcntl.h>
#include <stdio.h>
#include <sys/select.h>
int
main(int ac, char *av[])
{
fd_set fdset;
int fd, ret;
fd = open(av[1], O_RDONLY);
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
printf("FD: %d, IN: %08x\n", fd, *((unsigned int *)&fdset));
ret = select(fd+1, &fdset, 0, 0, 0);
printf("RET: %d, OUT: %08x\n", ret, *((unsigned int *)&fdset));
return 0;
}
=======
Uebersetzen mit "cc -o selecttest selecttest.c", starten mit
./selecttest /dev/ttyUSB0
Habe es kompiliert
1) auf ubuntu:
./selecttest /dev/ttyACM0
FD: 3, IN: 00000008
2) auf openwrt:
./selecttest /dev/ttyACM0
FD: 3, IN: 00000008
Nehme mal an, ich schicke ein falsches Kommando? Zumindest kommt kein
OUT:....
Wenn der CUL nichts zu sagen hat, dann kommt auch kein OUT. Man koennte es mit
einem
write(fd, "V\n", 2);
vor dem select() zum reden bringen.
sagt auch nix. ubuntu & openwrt.
./selecttest /dev/ttyACM0
FD: 3, IN: 00000008
RET: 1, OUT: 00000008
Merkwuerdigerweise erst nach mehreren Wiederholungen.
Ist das jetzt ein gutes Zeichen? Ist jetzt select() ok?
Ja, was auch zu erwarten war. Und write() hat nicht funktioniert, da open mit
O_RDONLY durchgefuehrt wurde. Das Ganze also nochmal komplett:
======
#include <fcntl.h>
#include <stdio.h>
#include <sys/select.h>
int
main(int ac, char *av[])
{
fd_set fdset;
int fd, ret;
fd = open(av[1], O_RDWR);
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
write(fd, "V\n", 2);
printf("FD: %d, IN: %08x\n", fd, *((unsigned int *)&fdset));
ret = select(fd+1, &fdset, 0, 0, 0);
printf("RET: %d, OUT: %08x\n", ret, *((unsigned int *)&fdset));
return 0;
}
========
% cc -o selecttest selecttest.c
% ./selecttest /dev/ttyACM0
FD: 3, IN: 00000008
RET: 1, OUT: 00000008
(getestet mit einem angeschlossenen CUL)
Es ueberrascht mich nicht, dass hier kein Fehler vorliegt, da select eine der
zentralen Funktionen ist. Mit perl hatte ich auf dem Fritzbox vor zwei Jahren
auch schon Probleme, deswegen bin ich damals von 5.8.9 auch 5.6.2
"umgestiegen".
Offensichtlich wird perl auf ucLibc Systemen nicht so gruendlich getestet, was
ich auch nachvollziehen kann.
Gruss,
Rudi
Gruesse
Felix