Closed claudio-rosati closed 6 years ago
That's a limitation in Channel Access. Try 'caget -d CTRL_ENUM' with that channel: Channel Access only provides 16 enum strings. If you have more, you cannot read them.
Thank you Kay for the explanation.
For the record, here's the detail:
$ caget -d CTRL_ENUM TryAnyRecordYouWant.STAT
TryAnyRecordYouWant.STAT
Native data type: DBF_ENUM
Request type: DBR_CTRL_ENUM
Element count: 1
Value: NO_ALARM
Status: NO_ALARM
Severity: NO_ALARM
Enums: (16)
[ 0] NO_ALARM
[ 1] READ
[ 2] WRITE
[ 3] HIHI
[ 4] HIGH
[ 5] LOLO
[ 6] LOW
[ 7] STATE
[ 8] COS
[ 9] COMM
[10] TIMEOUT
[11] HWLIMIT
[12] CALC
[13] SCAN
[14] LINK
[15] SOFT
The underlying reason is in EPICS base/include/db_access.h:
#define MAX_ENUM_STATES 16
...
/* structure for a control enumeration field */
struct dbr_ctrl_enum{
dbr_short_t status; /* status of value */
dbr_short_t severity; /* severity of alarm */
dbr_short_t no_str; /* number of strings */
char strs[MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE];
/* state strings */
dbr_enum_t value; /* current value */
};
Channel Access cannot get more than 16 enum states.
This includes the built-in enums like the enum epicsAlarmCondition
which has more than 20 states.
No problem for code that uses the enum as a number.
Code that requests the value as a string will get the enum index as a string since we don't know the label.
Thanks Kay.
This is what I get via caget ("Value: 17; Status: UDF").
caget -d CTRL_ENUM IOC:m1.STAT IOC:m1.STAT Native data type: DBF_ENUM Request type: DBR_CTRL_ENUM Element count: 1 Value: Illegal Value (17) Status: UDF Severity: INVALID Enums: (16) [ 0] NO_ALARM [ 1] READ [ 2] WRITE [ 3] HIHI [ 4] HIGH [ 5] LOLO [ 6] LOW [ 7] STATE [ 8] COS [ 9] COMM [10] TIMEOUT [11] HWLIMIT [12] CALC [13] SCAN [14] LINK [15] SOFT
And then the IOC answers: Command: Read Notify (0x000f) Payload Size: 56 DBR Type: TIME_STRING (14) Data Count: 1 Operation ID: 1 Status: ECA_NORMAL (0x00000001) Status: 17 Severity: 3 Timestamp: Mon 01 Jan 1990 01:00:00 AM CET Value: UDF
For efficiency reasons, higher level clients like CS-Studio, EDM, ... create one connection to each PV, fetch the metadata once, and the subscribe to updates for the native type of the value.
So for an enum, we fetch the labels once (where Channel Access is limited to 16 options), and then subscribe to the native type (enum == index of the current option). No matter if that value is then used in a plot, textupdate, probe, PV tree, ... it's just one 'channel'.
Yes, you could create a separate channel each time you need access to a PV, and you could push the data type conversion to the CA server side: TextUpdate creates a channel where it asks for the TIME_STRING, Data Browser asks for the channel as a TIME_DOUBLE, Combo asks for the channel as a TIME_ENUM, ...
==> Yes, textupdate would now show "UDF" because it fetched the enum option 17 as a string. (See output of your caget that fetches data as STRING)
But Combo would still show "<17>" because it fetched the enum as an enum (See output of your caget which requests the ENUM)/ And it would create many channels, increase network traffic and CPU load on both IOC and client.
Here's what you get from EDM:
It also connects to the channel just once. For the selection widget it sees the first 16 options. For a text update, it doesn't even show "<17>" to indicate that it's the unknown option index 17, you just see "
For what it's worth, directly reading the "xxx.STAT" field is a border case that you might want to reconsider. You cannot depend on having a record with a "xxx.STAT" field at the CA server end. These days you might be talking to a pcaspy-based CA server, which will support all the DBR_* requests for channel "xxx" but there is no "xxx.STAT".
If you simply connect to the "xxx" channel, the subscription to DBRSTS
For efficiency reasons, higher level clients like CS-Studio, EDM, ... create one connection to each PV, fetch the metadata once, and the subscribe to updates for the native type of the value.
I think this is the most important statement: understanding how currently the client works.
@tboegi as I have already said in the ESS JIRA issue you opened, in you specific application probably it is better to substitute the Text Input/Text Update widget wit a Label one a a rule that, triggered by the .STAT field will display all the strings defined in the EPICS specification for the STAT field. Maybe it is not the most elegant solution but it will give you what you want quickly.
@kasemir do you know the current situation for the PV Access? Enumerations are still bound to a nibble?
The PVAccess situation is better. You get all the options:
So the implementation of edm, medm, BOY, Display Builder, .. has been correct for decades. You're welcome to work on a fix for Channel Access, but that would require an update to the protocol. With PVAccess, you're fine.
Still, consider connecting to just "xxx" instead of "xxx.STAT" because that supports any CA server, not limited to IOCs.
I understand your advice, but I think @tboegi can't do that in its very specific motor control page. I'll see what can be dome when I'll try to convert it to Display Builder.
Meanwhile, if I've understood correctly, in Display Builder I can see "UDF" in a Text Update widget if the same PV is served via pva instead of ca. I've understood correctly?
Thanks for all the digging, guys. My question was to ask if the client be improved to work like caget, especially as we run IOC's which seem to have enough CPU power to do this. Now I understand the comment "For efficiency reasons" much better. It feels not reasonable to ask for a change in CSS, when we know that using pvaccess will solve the problem.
Display Builder Text Entry and Text Update widgets displays '17' instead of 'UDF' for a .STAT field valued to 17.