Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for Enums #158

Open
dirk-zimoch opened this issue Jun 19, 2024 · 14 comments
Open

Better support for Enums #158

dirk-zimoch opened this issue Jun 19, 2024 · 14 comments
Milestone

Comments

@dirk-zimoch
Copy link
Contributor

dirk-zimoch commented Jun 19, 2024

  • An mbbi or mbbo Record connected to an enum should directly use the returned value as an index (i.e. the device support should return 2). At the moment, it is necessary to set ONVL=1, TWVL=2, etc.
  • An mbbi, mbbo, bi or bo record with no state strings defined connected to an enum should automatically set the state strings to the enum strings from the OPC-UA server.
  • A stringin or stringout (or lsi or lso) record connected to an enum should show (and for output records accept) the enum strings from the OPC-UA server instead of the string representation of the index number.
  • A waveform (or aai or aao) record with FTVL=STRING connected to an array of enums should show (and accept) the enum strings from the OPC-UA server.
@dirk-zimoch dirk-zimoch changed the title Better for Enums Better support for Enums Jun 19, 2024
@ralphlange
Copy link
Member

  • An mbbi or mbbo Record connected to an enum should directly use the returned value as an index (i.e. the device support should return 2). At the moment, it is necessary to set ONVL=1, TWVL=2, etc.

Generally, that sounds reasonable. What if the number is out of range?

  • An mbbi, mbbo, bi or bo record with no state strings defined connected to an enum should automatically set the state strings to the enum strings from the OPC-UA server.

Then for OPC UA disconnect/reconnect do what? Erase the strings on disconnect? Overwrite on reconnect? Both? Neither?
I'd rather have a link option to select that behavior explicitly. Could default to yes, but the behavior options need to be clear on what happens at disconnect/reconnect.

  • A stringin or stringout (or lsi or lso) record connected to an enum should show (and for output records accept) the enum strings from the OPC-UA server instead of the string representation of the index number.

A single string record should show all enum strings? How?

  • A waveform (or aai or aao) record with FTVL=STRING connected to an array of enums should show (and accept) the enum strings from the OPC-UA server.

Here that would work: show all strings in a single record. (Why would you do that? Well, why not.)

@dirk-zimoch
Copy link
Contributor Author

What if the number is out of range?

the record should become INVALID.

Erase the strings on disconnect?

No.

Overwrite on reconnect?

Yes.

A single string record should show all enum strings? How?

No, it should show the current state. Now it shows the current state index number like "3".
Same with STRING waveforms for arrays of Enums: Show the current states of the elements.

@ralphlange
Copy link
Member

ralphlange commented Jun 19, 2024

A single string record should show all enum strings? How?

No, it should show the current state. Now it shows the current state index number like "3".

Ah. "...should show (and for output records accept) the enum strings from the OPC-UA server..."
That sounds like changing the conversion enum <-> string ??!

@dirk-zimoch
Copy link
Contributor Author

changing the conversion enum <-> string

Exactly. Instead of converting the enum to a string showing the index number, it should show the state name. That would be much more useful.

@tboegi
Copy link

tboegi commented Jun 19, 2024

Overwrite on reconnect?

In case that an enum has less members/defintions when the PLC
progam is changed, do not keep old definitions.

Erase all before overwriting - which is now a new writing.

@ralphlange
Copy link
Member

Overwrite on reconnect?

In case that an enum has less members/defintions when the PLC progam is changed, do not keep old definitions.

Erase all before overwriting - which is now a new writing.

Yes, like that.

@dirk-zimoch
Copy link
Contributor Author

Erase all before overwriting - which is now a new writing

Of course. Keeping old strings would not make sense. The whole set of strings belongs together and should be erased / replaced atomically upon (re-)connect.

@dirk-zimoch
Copy link
Contributor Author

Progress report:

  • mbbi/mbbo records work, *ST (and *VL for your convenience) are updated (clearing old strings too) when the (open62541) client connects to the server if connected to an enum and the user has not set the strings (i.e. SDEF == 0 at startup), but not if the user has set *ST. The device support uses VAL rather than RVAL when connected to an enum.
  • stringin/stringout and lsi/lso records work. Incoming enum index is translated to choice string and output records accepts choice string or index number but fail (-> INVALID/WRITE) if the string is not known or the number is out of range.
  • ToDo: Arrays of STRING and Arrays of CHAR
  • ToDo: UaSdk support

Someone wants to write tests?

@ralphlange
Copy link
Member

@karlvestin started working on adding tests for structured data, which would leave the enum tests and the UASDK variant for me?

@dirk-zimoch
Copy link
Contributor Author

I was actually thinking of implementing the UASDK support myself.

One more point do discuss: When converting OPC-UA Enums to/from numbers, should it use the index (as now) or rather the numerical enum value? I think the latter.
Example: enum { tic = 10; tac = 20; toe = 30 }. Receiving index 1 => string = "tac", int = 20 (instead of 1)

@ralphlange
Copy link
Member

By default: Enum value, clearly.
Maybe, on demand, later... yet another option to return the index instead (??)

@dirk-zimoch
Copy link
Contributor Author

Status update: UASDK Support works. CHAR arrays work (like long strings).
I have changed the string->number conversion a bit while implementing this: A string that does not represent a number (and in case of enums not an enum choice) does not silently convert to 0 any longer but fails now. To be exact, the string has to start with a number (optionally after space), so that " 2 eggs" -> 2 but "one chicken" -> WRITE alarm.
I still have to do the index <-> enum value translations in case the enum values are not simply 0,1,2,3,... But I currently have no test setup for that. I use uaservercpp which has only one enum with non-trivial values (Priority) but no example data of that type. I also have no test setup for arrays of enums.
I still have to test enums embedded in structures.

@ralphlange
Copy link
Member

Just for the record...

Recent Tech-Talk shows the situation I think we need to avoid: a device constantly changing enum choices, based on its operational state.
https://epics.anl.gov/tech-talk/2024/msg00779.php

Obviously, that this is more an interface design question than a technical issue.
Technically: If OPC UA allows servers to change enum choices during a session, we should eventually be able to handle it. Sigh.

@dirk-zimoch
Copy link
Contributor Author

dirk-zimoch commented Jun 27, 2024

device constantly changing enum choices

That will only happen on (re-)connect (e.g. when the OPC-UA server is restarted). To be exact: during initialRead. Of course, there is some time after the ioc starts but before the connection is established, during which the records will have empty choice strings.
I call db_post_events(prec, &prec->val, DBE_PROPERTY) when the enums change so that reasonably recent GUIs will know to update the string table.
Also it is the choice of the IOC engineer: If the record has already strings defined (e.g. in the template) when the connection is established the first time, the driver will not change them.

@ralphlange ralphlange added this to the 0.11 release milestone Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants