1818import org .epics .vtype .Alarm ;
1919import org .epics .vtype .AlarmSeverity ;
2020import org .epics .vtype .AlarmStatus ;
21+ import org .epics .vtype .Display ;
22+ import org .epics .vtype .DisplayProvider ;
2123import org .epics .vtype .Time ;
2224import org .epics .vtype .VByteArray ;
2325import org .epics .vtype .VEnum ;
3032import org .phoebus .core .vtypes .VTypeHelper ;
3133import org .phoebus .pv .PV ;
3234import org .phoebus .pv .PVPool ;
35+ import org .phoebus .pv .PVPool .TypedName ;
3336
3437import io .reactivex .rxjava3 .disposables .Disposable ;
3538
@@ -51,7 +54,7 @@ public class PVTableItem
5154 private volatile VType value ;
5255
5356 /** Value of the PV's description */
54- private volatile String desc_value = "" ;
57+ private volatile String desc_value = null ;
5558 private volatile String desc_name = "" ;
5659
5760 /** Saved (snapshot) value */
@@ -126,16 +129,24 @@ private void createPVs(final String name)
126129 updateValue (null );
127130 return ;
128131 }
132+ PV new_pv = null ;
129133 try
130134 {
131135 updateValue (VString .of ("" , Alarm .disconnected (), Time .now ()));
132- final PV new_pv = PVPool .getPV (name );
136+ new_pv = PVPool .getPV (name );
133137 value_flow = new_pv .onValueEvent ()
134138 .throttleLatest (Settings .max_update_period_ms , TimeUnit .MILLISECONDS )
135139 .subscribe (this ::updateValue );
136140 permission_flow = new_pv .onAccessRightsEvent ()
137141 .subscribe (writable -> listener .tableItemChanged (PVTableItem .this ));
138142 pv .set (new_pv );
143+ // read the value for getting description
144+ if (new_pv != null ) {
145+ VType newVal = new_pv .read ();
146+ if (newVal != null ){
147+ updateValue (newVal );
148+ }
149+ }
139150 }
140151 catch (Exception ex )
141152 {
@@ -145,28 +156,23 @@ private void createPVs(final String name)
145156 Time .now ()));
146157 }
147158
148- // For CA PVs, check the .DESC field
149- // Hardcoded knowledge to avoid non-record PVs.
150- if (Settings .show_description &&
151- ! (name .startsWith ("sim:" ) ||
152- name .startsWith ("loc:" )))
153- {
154- // Determine DESC field.
155- //Bug when a pv name contains a . caracters
156- desc_name = name + DOT + DESC_FIELD ;
157- if (!name .endsWith (DOT + DESC_FIELD ) && name .contains (DOT )) {
158- // If name already includes a field
159- // It can be a EPICS fields such as .VAL .EGU ...
160- // EPICS fields are always in Upper Case
161- // EPICS fields are 4 characters length max
159+ // First try to get description from value or pv
160+ updateDescription ();
161+ // If still no description found and channel access source
162+ final TypedName type_name = TypedName .analyze (name );
163+ String dataType = type_name != null ? type_name .type : null ;
164+ boolean channelAccess = dataType .equals ("ca" );
165+ if (Settings .show_description && desc_value == null && channelAccess ) {
166+ // For CA PVs, check the .DESC field
167+ // Hardcoded knowledge to avoid non-record PVs.
168+ // First get default datasource
169+ desc_name = name + DOT + DESC_FIELD ; // by default add .DESC
170+ if (!name .endsWith (DOT + DESC_FIELD ) && name .contains (DOT )) {
162171 final int sep = name .lastIndexOf ('.' );
163172 String fieldVal = name .substring (sep + 1 );
164- //System.out.println("fieldVal=" + fieldVal);
165- //Test if it in uppercase and max length 4
166- boolean isEpicsField = fieldVal .toUpperCase ().equals (fieldVal ) && fieldVal .length () < 5 ;
167- if (isEpicsField ) {
168- desc_name = name .replace (fieldVal , DESC_FIELD );
169- }
173+ // then replace by .DESC
174+ // Determine DESC field include dot in case of variable name such as variableEGUName
175+ desc_name = name .replace (DOT + fieldVal , DOT + DESC_FIELD );
170176 }
171177
172178 try
@@ -190,6 +196,24 @@ private void createPVs(final String name)
190196 }
191197 }
192198 }
199+
200+ private void updateDescription () {
201+ if (desc_value == null ) {
202+ //update description from value or pv
203+ VType currentValue = getValue ();
204+ if (currentValue != null ) {
205+ PV thePV = pv .get ();
206+ Display display = thePV instanceof DisplayProvider ? ((DisplayProvider ) thePV ).getDisplay () : null ;
207+ display = display == null && currentValue instanceof DisplayProvider ? ((DisplayProvider ) currentValue ).getDisplay (): display ;
208+ if (display != null ) {
209+ String description = display .getDescription ();
210+ desc_value = description != null ? description : null ;
211+ desc_name = desc_value != null ? "Description of " + name + " PV" : "no description" ;
212+ desc_flow = value_flow ;
213+ }
214+ }
215+ }
216+ }
193217
194218 /** @return <code>true</code> if item is selected to be restored */
195219 public boolean isSelected ()
@@ -255,9 +279,8 @@ public VType getValue()
255279 }
256280
257281 /** @return Description */
258- public String getDescription ()
259- {
260- return desc_value ;
282+ public String getDescription () {
283+ return desc_value == null ? "" : desc_value ;
261284 }
262285
263286 /** @return description pv name **/
@@ -305,14 +328,17 @@ public void setValue(String new_value)
305328 throw new Exception ("Not connected" );
306329
307330 final VType pv_type = the_pv .read ();
308- if (pv_type instanceof VNumber )
309- {
310- if (Settings .show_units )
311- { // Strip units so that only the number gets written
312- final String units = ((VNumber )pv_type ).getDisplay ().getUnit ();
313- if (units .length () > 0 && new_value .endsWith (units ))
331+ Display display = the_pv instanceof DisplayProvider ? ((DisplayProvider ) the_pv ).getDisplay () : null ;
332+ display = display == null && pv_type instanceof DisplayProvider ? ((DisplayProvider ) pv_type ).getDisplay ():null ;
333+
334+ if (display != null && Settings .show_units ) {
335+ // Strip units so that only the number gets written
336+ final String units = display .getUnit ();
337+ if (units .length () > 0 && new_value .endsWith (units ))
314338 new_value = new_value .substring (0 , new_value .length () - units .length ()).trim ();
315339 }
340+ if (pv_type instanceof VNumber )
341+ {
316342 the_pv .write (Double .parseDouble (new_value ));
317343 }
318344 else if (pv_type instanceof VEnum )
0 commit comments