Hi,
unten ist mein Code für eine Funktion, die eine UDP-Nachricht an einen Arduino versendet (versenden soll).
In verschiedenen Abwandlungen läuft das ganze jetzt schon ein Jahr, aufgrund wachsenden Bedarfes habe ich es jetzt "universell" abgeändert.
Mein Problem ist, dass ich jetzt gerne an die finishFn die 4 Werte IP. Port, Order und Answer übergeben möchte ( um diese ggf in einem Dummy abzulegen).
Sobald ich hinter das "return" der sub udpsend() eine variable notiere, return $answer;
wird die finishFn anscheinend nicht mehr aufgerufen (keine Ausgaben mehr im Telegram). Sobald ich das wieder in return;
ändere, funktioniert es einwandfrei (halt ohne den Rückgabewert)
Vielleicht liegt es daran, dass mir im Bezug auf BlockingCall() immer noch einige Sachen unklar sind.
Im Wiki steht, dass BlockingCall() einen Hash zurückliefert, in dem z.B. die Namen der Funktionen stehen.
Ebenfalls gibts einen Wert RUNNING_PID, der dafür sorgen soll, dass kein neuer BlockingCall gestartet wird, wenn noch einer läuft.
Leider bin ich irgendwie nicht in der Lage, in der abortFN oder der finishFn auf diesen Wert zurückzugreifen.
Ebenfalls vor massive Probleme hatte mich die übergabe der Parameter (IP,Port,order) an die blockingFn gestellt, die ich aber mittlerweile .. gelöst habe.
Kann mir jemand einen Tipp geben, was ich mit dem Rückgabewert von sub udpsend falsch mache, und wie ich kontrolliere, dass immer nur eine blockingFn läuft?
Danke,
Stephan
my %BChash;
sub nb_udpsend {
my $log_name = "nb_udpsend()";
my $subloglevel = 4;
my $previous_loglevel = AttrVal("global","verboseTelegram",0);
if ($previous_loglevel != $subloglevel){
fhem("attr global verboseTelegram $subloglevel");
}log_telegram("5",$log_name,"debug aktiviert","remotebot");
my $blockingFn = "udpsend";
my $finishFn = "finishFn";
my $timeout = 5;
my $abortFn = "abortFn";
my $abortArg = "nb_udpsend_errorArg: did not receive acknowledge from|$_[0]|$_[1]|$_[2]";
## $order $ip $port
my $args = $_[0] . "|" . $_[1] . "|" . $_[2];
log_telegram("4",$log_name,"_BlockingCall FN: $blockingFn ARG: $args FIN: $finishFn TO:$timeout AFN:$abortFn AARG: $abortArg _","remotebot");
if ($previous_loglevel != $subloglevel){
fhem("attr global verboseTelegram $previous_loglevel");
}
$BChash{RUNNING_PID} = BlockingCall($blockingFn,$args,$finishFn,$timeout,$abortFn,$abortArg);
return $BChash{RUNNING_PID};
}
sub udpsend {
my ($parameters) = @_;
my ($order,$ip,$port) = split("\\|",$parameters);
my $answer;
my $now = strftime "%Y-%m-%d %T",localtime();
my $sock = IO::Socket::INET->new(
Proto => 'udp',
PeerPort => $port,
PeerAddr => $ip,
) or die "could not create Socket: $!\n";
$sock->send($order) or die "Send error $!\n";
$sock->setsockopt(SOL_SOCKET, SO_RCVTIMEO, pack('l!l!', 2, 0))
or die "setsockopt: $!";
$sock->recv($answer,1024)
or die "Could not receive an answer: $!";
$sock->close();
##return $answer . "|" . $parameters; ## geht nicht
##my $return = $answer . "|" . $parameters; ## geht nicht
##return $answer; ## geht nicht
return; ## geht
}
sub abortFn {
my $log_name = "abortFn(S)";
my ($errArg,$errorder,$errip,$errport) = split("\\|",@_);
my $log_name = "nb_ardsend(S)";
my $subloglevel = 3;
my $previous_loglevel = AttrVal("global","verboseTelegram",0);
my $previous_loglevel = AttrVal("global","verboseTelegram",0);
if ($previous_loglevel != $subloglevel){
fhem("attr global verboseTelegram $subloglevel");
}
##fhem("setreading ardsend error $errorArg");
log_telegram("3",$log_name,"function aborted: $errArg " . $errip . ":" . $errport,"remotebot");
log_telegram("5",$log_name,"OUTPUT BEGIN","remotebot");
log_telegram("5",$log_name,"$errip","remotebot");
log_telegram("5",$log_name,"$errport","remotebot");
log_telegram("5",$log_name,"$errorder","remotebot");
log_telegram("5",$log_name,"OUTPUT END","remotebot");
if ($previous_loglevel != $subloglevel){
fhem("attr global verboseTelegram $previous_loglevel");
}
delete($BChash{RUNNING_PID});
}
sub finishFn {
##fhem("set remotebot message finishfn");
my $log_name = "finishFn(S)";
my ($string) = @_;
my $subloglevel = 3;
my $previous_loglevel = AttrVal("global","verboseTelegram",0);
if ($previous_loglevel != $subloglevel){
fhem("attr global verboseTelegram $subloglevel");
}
log_telegram("3",$log_name,"function finished: $string","remotebot");
if ($previous_loglevel != $subloglevel){
fhem("attr global verboseTelegram $previous_loglevel");
}
delete($BChash{RUNNING_PID});
}
Habe jetzt nur überflogen aber ich gehe davon aus das Dein Rückgabewert einen Zeilenumbruch beinhaltet. Entweder machst Du ein JSON oder Du codierst Dein Rückgabewert vorher in base64
Bin die ganze Zeit am überlegen ob das so überhaupt geht. Kenne das eigentlich nur mit einem FHEM Device Hash. Aber da es ja anscheinend ohne den response durchläuft.
Zitat von: CoolTux am 12 Oktober 2017, 17:17:36
Habe jetzt nur überflogen aber ich gehe davon aus das Dein Rückgabewert einen Zeilenumbruch beinhaltet.
Danke, das wars. Da ich von meinem Arduino einfach nur das empfangene zurücksende, kam mir gar nicht in den Sinn, dass da ein Zeilenumbruch drin sein könnte..
ZitatEntweder machst Du ein JSON oder Du codierst Dein Rückgabewert vorher in base64
Ich hab einfach mit $answer =~ s/\n/./g die Zeilenumbrüche entfernt... Die gehören für mich da eh nicht hin.
ZitatBin die ganze Zeit am überlegen ob das so überhaupt geht. Kenne das eigentlich nur mit einem FHEM Device Hash. Aber da es ja anscheinend ohne den response durchläuft.
Naja, es .. tut was ich von ihm erwarte. Aber ich schätze, die kontrolle, dass nur ein BlockingCall gleichzeitig läuft, funktioniert so nicht.
Im Moment hab ich das ein bisschen durch die aufrufenden AT's unter Kontrolle, wird alle 20 Sekunden aufgerufen, und bricht nach spätestens 5 Sekunden ab.
Aber ich vermute, es gibt noch eine bessere option.
Also, Problem gelöst, lag an der Newline. Für das andere mach ich lieber einen neuen Thread auf.
Danke,
Stephan