paulscherrerinstitute / StreamDevice

EPICS Driver for message based I/O
GNU General Public License v3.0
28 stars 42 forks source link

Support setting local variables through info items #86

Open ralphlange opened 2 years ago

ralphlange commented 2 years ago

The % redirection parameter often breaks the layering, as record names are required within the protocol file.

Redirection targets can be set through protocol parameters, but - especially for protocols that return a whole bunch of values - this can make database links completely unreadable.

Idea: Allow setting local StreamDevice variables (scope: protocol) through info items. A record in the database could do something like

    info(stream:varLINK1, "myotherrecord.A")
    info(stream:varSTATUS, "mystatusrecord")

and the protocol could

    out "VAL?";
    in "%("$LINK1")f,%("$STATUS")i";

Advantage: all record names stay in the database; the protocol file can use redirections and still be application agnostic.

I am willing to work on this, if we can agree on the general idea and interface.

dirk-zimoch commented 2 years ago

In all my cases the redirection targets have a common prefix (the "device name"). I usually pass only this prefix as the first protocol parameter and have the "remainder" record names hard coded in the protocol. Modularity is maintained and link length stays within reasonable limits. For example with two target records $(PREFIX)LINK1 and $(PREFIX)STATUS, the link would use "@file protocol($(PREFIX)) $(PORT)" and a protocol like this: in "%(\$1LINK1)f,%(\$1STATUS)i"; Still I can see the advantage of passing protocol variables through info fields. Nice idea and probably easy to implement. I would generally extend this to any protocol variable. If variables with the same name are defined in the protocol and in info fields, which one should have higher priority? In my opiniton the info field. I would not incude the quotes in the variable defined by the info field (allowing numbers as well). Thus the syntax would look more like: in "%(\${LINK1})f,%(\${STATUS})i";

dirk-zimoch commented 2 years ago

As we are on it, how about globals through environment variables?

ralphlange commented 2 years ago

Been there, done that. But the "remainder" is still part of the record name and doesn't really belong into the protocol. If it needs to be changed because of different naming conventions between the author and the user of the stream support... see attachment. (Real life example from my desk: Evo.proto.txt)

In that case, the user still needs to change the protocol file, changing the variable setting page.

dirk-zimoch commented 2 years ago

Great :-P Next think I wanted to do anyway in the protocol files: include.

ralphlange commented 2 years ago

That would be very useful, indeed!

ralphlange commented 2 years ago

I would not include the quotes in the variable defined by the info field (allowing numbers as well). Thus the syntax would look more like: in "%(\${LINK1})f,%(\${STATUS})i";

??! (Don't understand your statement about numbers. Info items are strings.) I remember trying also that notation - I don't find it much clearer and it is 50% more overhead (three added characters compared to two "s).

dirk-zimoch commented 2 years ago

Using "%("$LINK1")f" assumes that LINK1 is a quoted string like $upref"Index" in your example (where $upref is another quoted string. This way, we could not pass for example replyTimeout. .... Minor details.

ralphlange commented 2 years ago

Oh. I see.