Devio run SimpleRead before SimpleWrite

Begonnen von Teemo, 10 Mai 2022, 12:21:09

Vorheriges Thema - Nächstes Thema

Teemo

Hello,
I'm trying to write my first module that connects and receives data hexadecimally through Devio.pm.
How to make the listener run for 1 second.
Because at this point if I run SimpleRead and after that run SimpleRead then I get exception/"DISCONNECTED" because I don't get any response back.
I would need to do a scenario like this:
- I set up a connection (it works)
- listener 1sec DevIo_SimpleRead
- immediately after the listener starts DevIo_SimpleWrite

Is this a good idea? How to do it?

rudolfkoenig

Not sure I understand the task correctly, I assume you want to wait for receiving data after establishing the connection for at most 1 second.

There is a DevIo_TimeoutRead and DevIo_Expect function, but both are deprecated, as they block FHEM.

A non-deprecated way to read with a timeout is:
- specify a ReadFn function in the module hash (in the Initialize function). If this function is called, it is guaranteed, that one(!) DevIo_SimpleRead call wont block. If the data received by one DevIo_SimpleRead is not complete, remember it, return from the function, and wait for the next call.
- call DevIo_OpenDev (e.g. in the DefineFn or SetFn), specify the 3rd parameter (initFn), and set up there an InternalTimer for 1 second.
- the function called by the timer can close the connection, or do whatever is appropriate.

Teemo

@rudolfkoenig Thanks for reply. You almost got it right :)
One main thing is diffrent. I can have the connection established all the time, but before sending the message via DevIo I would like run the listener for a second to catch the response. I would say it is something like a modbus connection. I send a message and after that immediately I get a response.

So I'd like to do sth like that:
> Define device (establilishing connection)
> Initialize device (run InternalTimer, every 60sec get data)
   > Run listener for one second for responose (asynchronous)
   > in the same time send hex message DevIo_SimpleWrite
   > Receive and convert data to state

Teemo

Eigentlich habe ich es geschafft, die Daten zu lesen, ich habe noch eine kleine Frage, wie man es schafft, dass zwischen einer Anfrage und einer anderen zum Beispiel 2 Sekunden Pause sind?

rudolfkoenig


Teemo

#5
Danke, aber wenn ich die
  InternalTimer(gettimeofday()+5,...)
  InternalTimer(gettimeofday()+10,...)
in dem ich ein DevIo_SimpleWrite mache, dann wird die *_Read Funktion von DevIo erst nach diesem letzten InternlTimer aufgerufen

EDIT. Entschuldigung, mein Fehler, funktioniert einwandfrei, danke!

Teemo

Ich habe noch eine Frage an Sie:
sub MY_MODULE_Callback($)
{
    my ($hash, $error) = @_;
    my $name = $hash->{NAME};

    # create a log emtry with the error message
    Log3 $name, 5, "MY_MODULE ($name) - error while connecting: $error";
   
    return undef;
}


$error gibt keine Informationen zurück, was könnte der Grund dafür sein? Callback nimmt ein Argument, in diesem Fall sollte ich nicht Qualität Split es, oder geben $$?

Trotz der Parametereinstellungen
$hash->{nextOpenDelay} = 60
$hash->{TIMEOUT} = 10

bei einem Verbindungsfehler sendet der Callback fast 20 Mal pro Sekunde ein Protokoll. Wie kann man sie begrenzen?

rudolfkoenig

Zitat$error gibt keine Informationen zurück, was könnte der Grund dafür sein?
Ich rate mal: MY_MODULE_Callback ist Parameter #4 in DevIo_OpenDev.
Darueber werden Fehler mitgeteilt, falls welche auftreten, sie wird aber auch mit undef als zweiten Parameter aufgerufen, falls keine Probleme aufgetreten sind, oder z.Bsp. nach einem Fehler nextOpenDelay noch nicht abgelaufen sind.

Da diese Diskussion auf deutsch gefuehrt wird, sollte aus "English Corner" verschoben werden.