Ich überwache derzeit mittels telnet Modul einen Socket auf einem PC im Netzwerk. Dabei geht es mir zunächst nur darum im Floorplan anzuzeigen, wenn der Socket nicht offen ist. Folgendes define:
define W_SERVANT telnet 192.168.178.25:4711
attr W_SERVANT connectInterval 5
attr W_SERVANT connectTimeout 1
attr W_SERVANT devStateIcon Disconnected:servant.offline Connected:empty
Das funktioniert soweit, hat aber das Problem, dass telnet offenbar blockierend arbeitet. Das Webinterface wartet daher idR auf den Ablauf des Timeouts (daher ist er auch so klein gewählt). Davon abgesehen, war das telnet-Modul laut commandref und Wiki eigentlich für einen ganz anderen Zweck gedacht und es muss sich unglaublich missbraucht fühlen.
Gibt es ein geeigneteres Modul um einen TCP Socket zu überwachen? Falls nicht: Kann ich telnet dazu überreden zu forken?
Sollte jemand vor dem selben Problem stehen: PRESENCE ist das richtige Modul, wenn man eine einfache Funktion einbindet:
fhem.cfg:
define REVO_SERVANT PRESENCE function { presence_port('192.168.178.123', 4711) }
99_myUtils.pm:
sub presence_port($$) {
my $ip = shift;
my $port = shift;
return IO::Socket::INET->new(
PeerPort => $port,
PeerAddr => $ip,
Proto => 'tcp',
Timeout => 5
)?1:0;
}
Statt IP und Port zu übergeben, habe ich noch die Möglichkeit Namen von PRESENCE oder XBMC Objekten zu benutzen eingebaut. Dann sehen define und sub folgendermassen aus:
fhem.cfg:
define REVO_SERVANT PRESENCE function { presence_port('REVO', 4711) }
99_myUtils.pm:
sub presence_port($;$) {
my $host = shift;
my $port = shift;
my $ip;
if(!$port && $host =~ /((?:\d{1,3}\.){3}\d{1,3}):(\d{1,5})/) {
# $host = 192.168.178.47:11
$ip = $1;
$port = $2;
} elsif($port && $host =~ /(?:\d{1,3}\.){3}\d{1,3}/) {
# $host = 192.168.178.47
# $port = 11
$ip = $host;
} else {
my $type = InternalVal($host, 'TYPE', undef);
if($type eq 'PRESENCE') {
$ip = InternalVal($host, 'ADDRESS', undef);
} elsif($type eq 'XBMC') {
$ip = InternalVal($host, 'Host', undef);
}
}
if($ip && $port) {
return IO::Socket::INET->new(
PeerPort => $port,
PeerAddr => $ip,
Proto => 'tcp',
Timeout => 5
)?1:0;
}
return 0;
}
Hat den Vorteil, dass man eine Stelle weniger hat, an der eine IP notiert wird.