Skip to content

Commit 8bd812a

Browse files
committed
Override getCoreName in TangoPVFactory and add examples #3602
1 parent 482e346 commit 8bd812a

File tree

13 files changed

+992
-30
lines changed

13 files changed

+992
-30
lines changed

core/pv-tango/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/.project
2+
/.classpath

core/pv-tango/src/main/java/org/phoebus/pv/tango/TangoConstHelper.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.lang.reflect.Field;
44

55
import fr.esrf.Tango.AttrDataFormat;
6+
import fr.esrf.Tango.AttrQuality;
7+
import fr.esrf.Tango.DevState;
68
import fr.esrf.TangoDs.TangoConst;
79

810
/**
@@ -41,6 +43,23 @@ public class TangoConstHelper {
4143
public static final String STATE_NAME = "STATE";
4244
public static final String STATUS_NAME = "STATUS";
4345
private final static String[] STRING_LABEL = new String[] { "STRING", STATE_NAME, STATUS_NAME};
46+
47+
private static final int NB_QUALITY = 5;
48+
public static final String[] ATTR_QUALITY_LABEL = new String[NB_QUALITY];
49+
50+
private static final int NB_STATE = 14;
51+
public static final String[] STATE_LABEL = new String[NB_STATE];
52+
53+
static {
54+
for (int i = 0; i < NB_QUALITY; i++) {
55+
ATTR_QUALITY_LABEL[i] = AttrQuality.from_int(i).toString();
56+
}
57+
58+
for (int i = 0; i < NB_STATE; i++) {
59+
STATE_LABEL[i] = DevState.from_int(i).toString();
60+
}
61+
}
62+
4463

4564
/**
4665
* Return simple type according a TangoConst_DEV_* type. *

core/pv-tango/src/main/java/org/phoebus/pv/tango/TangoPV.java

Lines changed: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.phoebus.pv.tango;
22

3+
import java.time.Instant;
34
import java.util.HashMap;
45
import java.util.Map;
56

@@ -9,6 +10,7 @@
910
import org.epics.vtype.EnumDisplay;
1011
import org.epics.vtype.Time;
1112
import org.epics.vtype.VDouble;
13+
import org.epics.vtype.VEnum;
1214
import org.epics.vtype.VString;
1315
import org.epics.vtype.VType;
1416
import org.phoebus.pv.PV;
@@ -35,7 +37,7 @@
3537
public class TangoPV extends PV {
3638

3739
private static enum MetaData {
38-
DESC, LABEL, WRITE, EGU, HOPR, HIHI, HIGH, LOPR, LOW, LOLO
40+
DESC, LABEL, WRITE, EGU, HOPR, HIHI, HIGH, LOPR, LOW, LOLO, STAT
3941
};
4042

4143
private static final String DOT = ".";
@@ -58,16 +60,23 @@ private static enum MetaData {
5860

5961
public TangoPV(String name, String baseName) {
6062
super(name);
61-
// First remove .DESC field
62-
String fullDeviceName = baseName;
63-
// Test if it is a metadata
64-
metaData = getMetadata(fullDeviceName);
65-
if (metaData != null) {
66-
fullDeviceName = fullDeviceName.replace(DOT + metaData.toString(), "");
63+
if (TangoPreferences.getInstance().isTangoDbEnable()) {
64+
// First remove .DESC field
65+
String fullDeviceName = baseName;
66+
// Test if it is a metadata
67+
metaData = getMetadata(fullDeviceName);
68+
if (metaData != null) {
69+
fullDeviceName = fullDeviceName.replace(DOT + metaData.toString(), "");
70+
}
71+
device = TangoDeviceHelper.getDeviceName(fullDeviceName);
72+
entityName = TangoDeviceHelper.getEntityName(fullDeviceName);
73+
74+
initTangoEntity();
75+
} else {
76+
// No attribute info found
77+
VType initValue = VString.of("--", Alarm.disconnected(), Time.now());
78+
notifyListenersOfValue(initValue);
6779
}
68-
device = TangoDeviceHelper.getDeviceName(fullDeviceName);
69-
entityName = TangoDeviceHelper.getEntityName(fullDeviceName);
70-
initTangoEntity();
7180
}
7281

7382
private MetaData getMetadata(String fullDeviceName) {
@@ -85,7 +94,7 @@ private MetaData getMetadata(String fullDeviceName) {
8594
}
8695

8796
private boolean isMetaData() {
88-
return metaData != null && metaData != MetaData.WRITE;
97+
return metaData != null && metaData != MetaData.WRITE && metaData != MetaData.STAT;
8998
}
9099

91100
private void initTangoEntity() {
@@ -110,9 +119,19 @@ private void initTangoEntity() {
110119
description = attributeInfo.toString();
111120
}
112121
attributeInfoEx = TangoAttributeHelper.getAttributeInfoEx(device, entityName);
113-
display = TangoPVUtil.buildDisplayFromAttributeInfo(attributeInfo, attributeInfoEx,
114-
description);
115-
enumDisplay = TangoPVUtil.buildEnumDisplayFromAttributeInfo(attributeInfoEx, display);
122+
if (metaData != null && metaData == MetaData.STAT) {
123+
enumDisplay = TangoPVUtil.getAttributeQualityEnumDisplay(attributeInfo);
124+
display = ((AdvancedEnumDisplay) enumDisplay).getDisplay();
125+
126+
} else if (entityName.equalsIgnoreCase("State")) {
127+
// Build State enumeration
128+
enumDisplay = TangoPVUtil.getDevStateEnumDisplay(device);
129+
display = ((AdvancedEnumDisplay) enumDisplay).getDisplay();
130+
} else {
131+
display = TangoPVUtil.buildDisplayFromAttributeInfo(attributeInfo, attributeInfoEx,
132+
description);
133+
enumDisplay = TangoPVUtil.buildEnumDisplayFromAttributeInfo(attributeInfoEx, display);
134+
}
116135
// It is not a description, read attribute value
117136
if (!isMetaData()) {
118137
initValue = readValue();
@@ -335,22 +354,30 @@ private VType readValue() {
335354
DeviceAttribute deviceAttribute = TangoAttributeHelper.getDeviceAttribute(deviceProxy, entityName);
336355
int type = deviceAttribute.getType();
337356
AttrDataFormat dataFormat = deviceAttribute.getDataFormat();
338-
Object result = null;
339-
if (metaData != null && metaData == MetaData.WRITE) {
340-
result = InsertExtractUtils.extractWrite(deviceAttribute, attributeInfo.writable, dataFormat);
341-
} else {
342-
result = InsertExtractUtils.extractRead(deviceAttribute, dataFormat);
343-
}
344357
Alarm alarm = TangoPVUtil.buildAlarmFromAttribute(deviceAttribute);
345358
long time = deviceAttribute.getTime();
346-
boolean isArray = dataFormat != null
347-
&& (dataFormat == AttrDataFormat.SPECTRUM || dataFormat == AttrDataFormat.IMAGE);
348-
int[] sizes = null;
349-
if (dataFormat == AttrDataFormat.IMAGE) {
350-
sizes = new int[] { deviceAttribute.getDimX(), deviceAttribute.getDimY() };
359+
if (metaData != null && metaData == MetaData.STAT) {
360+
// Read Quality of attribute
361+
int attributeQuality = TangoAttributeHelper.getAttributeQuality(deviceAttribute);
362+
Time t = Time.of(Instant.ofEpochMilli(time));
363+
rValue = VEnum.of(attributeQuality, enumDisplay, alarm, t);
364+
} else {
365+
Object result = null;
366+
if (metaData != null && metaData == MetaData.WRITE) {
367+
result = InsertExtractUtils.extractWrite(deviceAttribute, attributeInfo.writable, dataFormat);
368+
} else {
369+
result = InsertExtractUtils.extractRead(deviceAttribute, dataFormat);
370+
}
371+
372+
boolean isArray = dataFormat != null
373+
&& (dataFormat == AttrDataFormat.SPECTRUM || dataFormat == AttrDataFormat.IMAGE);
374+
int[] sizes = null;
375+
if (dataFormat == AttrDataFormat.IMAGE) {
376+
sizes = new int[] { deviceAttribute.getDimX(), deviceAttribute.getDimY() };
377+
}
378+
rValue = TangoPVUtil.convertResultToVtype(isArray, sizes, type, result, alarm, time, display,
379+
enumDisplay);
351380
}
352-
rValue = TangoPVUtil.convertResultToVtype(isArray, sizes, type, result, alarm, time, display,
353-
enumDisplay);
354381
} catch (Exception e) {
355382
String errorMessage = TangoExceptionHelper.getErrorMessage(e);
356383
rValue = VString.of(errorMessage, Alarm.disconnected(), Time.now());
@@ -405,7 +432,7 @@ public void write(Object new_value) throws Exception {
405432
@Override
406433
public boolean isReadonly() {
407434
boolean isRO = true;
408-
if (!isMetaData()) {
435+
if (!isMetaData() && metaData != MetaData.STAT) {
409436
if (attributeInfo != null) {
410437
AttrWriteType writable = attributeInfo.writable;
411438
isRO = writable == AttrWriteType.READ;
@@ -429,5 +456,6 @@ protected void close() {
429456
cb = null;
430457
}
431458
TangoPVFactory.releasePV(this);
459+
super.close();
432460
}
433461
}

core/pv-tango/src/main/java/org/phoebus/pv/tango/TangoPVFactory.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@ public String getType() {
2323
@Override
2424
public PV createPV(String name, String base_name) throws Exception {
2525

26-
String actual_name = name;
26+
String actual_name = getCoreName(name);
2727
// Actual name: tango://the_pv
2828
// Add tango://prefix if not exist
2929
if(!name.startsWith(TangoPVFactory.TYPE + "://")) {
3030
actual_name = PVPool.TypedName.format(TangoPVFactory.TYPE, name);
3131
}
3232
TangoPV tangopv = tango_pvs.get(actual_name);
33+
34+
//Check TANGO HOST
35+
3336
if (tangopv == null) {
3437
synchronized (tango_pvs) {
3538
tangopv = new TangoPV(actual_name, base_name);
@@ -39,6 +42,17 @@ public PV createPV(String name, String base_name) throws Exception {
3942

4043
return tangopv;
4144
}
45+
46+
@Override
47+
public String getCoreName(String name) {
48+
String actual_name = name;
49+
// Actual name: tango://the_pv
50+
// Add tango://prefix if not exist
51+
if(!name.startsWith(TangoPVFactory.TYPE + "://")) {
52+
actual_name = PVPool.TypedName.format(TangoPVFactory.TYPE, name);
53+
}
54+
return actual_name;
55+
}
4256

4357
protected static void releasePV(TangoPV tangopv) {
4458
if (tango_pvs.containsKey(tangopv.getName())) {

core/pv-tango/src/main/java/org/phoebus/pv/tango/TangoPVUtil.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ public static VType convertResultToVtype(boolean isArray, int[] sizes, int tango
213213
alarmState= Alarm.of(AlarmSeverity.MAJOR, AlarmStatus.UNDEFINED, state.toString());
214214
break;
215215
}
216-
resultType = VString.of(state.toString(), alarmState, time);
216+
resultType = VEnum.of(state.value(), enumDisplay, alarmState, time);
217217
} else {
218218
resultType = VString.of(result.toString(), alarm, time);
219219
}
@@ -453,5 +453,31 @@ private static boolean isUnsigned(String fieldName, String tangoType) {
453453
private static boolean isLong64(String fieldName) {
454454
return fieldName != null && fieldName.contains(TangoConstHelper.LONG_NAME + "64");
455455
}
456+
457+
protected static EnumDisplay getAttributeQualityEnumDisplay(AttributeInfo info) {
458+
EnumDisplay enumDisplay = null;
459+
if(info != null) {
460+
NumberFormat numberFormat = Display.defaultNumberFormat();
461+
Range noRange = Range.undefined();
462+
// Build Attribute Quality enumeration
463+
Range limit = Range.of(0, TangoConstHelper.ATTR_QUALITY_LABEL.length);
464+
Display display = Display.of(limit, noRange, noRange, limit, "", numberFormat, "Quality of attribute " + info.name);
465+
enumDisplay = AdvancedEnumDisplay.of(display, TangoConstHelper.ATTR_QUALITY_LABEL);
466+
}
467+
return enumDisplay;
468+
}
469+
470+
protected static EnumDisplay getDevStateEnumDisplay(String device) {
471+
EnumDisplay enumDisplay = null;
472+
if(device != null) {
473+
NumberFormat numberFormat = Display.defaultNumberFormat();
474+
Range noRange = Range.undefined();
475+
// Build Attribute Quality enumeration
476+
Range limit = Range.of(0, TangoConstHelper.STATE_LABEL.length);
477+
Display display = Display.of(limit, noRange, noRange, limit, "", numberFormat, "State of device " + device );
478+
enumDisplay = AdvancedEnumDisplay.of(display, TangoConstHelper.STATE_LABEL);
479+
}
480+
return enumDisplay;
481+
}
456482

457483
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package org.phoebus.pv.tango;
2+
3+
import static org.phoebus.pv.PV.logger;
4+
5+
import java.util.logging.Level;
6+
7+
import org.phoebus.framework.preferences.PreferencesReader;
8+
9+
import fr.esrf.TangoApi.Database;
10+
11+
public class TangoPreferences {
12+
13+
private static final String TANGO_HOST = "tango_host";
14+
private static final String DEFAULT_TANGO_HOST = "localhost:10000";
15+
private static Boolean tangoDBEnable = null;
16+
17+
private static TangoPreferences instance = null;
18+
19+
private TangoPreferences() {
20+
try {
21+
installPreferences();
22+
} catch (Exception e) {
23+
e.printStackTrace();
24+
logger.log(Level.SEVERE, "Preferences Error", e);
25+
}
26+
}
27+
28+
public static TangoPreferences getInstance() {
29+
if (instance == null) {
30+
instance = new TangoPreferences();
31+
}
32+
return instance;
33+
}
34+
35+
private void installPreferences() throws Exception {
36+
String currentTangoHost = System.getProperty(TANGO_HOST.toUpperCase());
37+
38+
final PreferencesReader prefs = new PreferencesReader(TangoPVFactory.class, "/pv_tango_preferences.properties");
39+
if (prefs != null) {
40+
String tangohost = prefs.get(TANGO_HOST);
41+
if (tangohost != null && !tangohost.trim().isEmpty()) {
42+
if(currentTangoHost == null || currentTangoHost.equalsIgnoreCase(tangohost)) {
43+
logger.log(Level.INFO, "set TANGO_HOST=" + tangohost);
44+
System.setProperty(TANGO_HOST.toUpperCase(), tangohost) ;
45+
currentTangoHost = tangohost;
46+
}
47+
}
48+
}
49+
50+
if(currentTangoHost == null) {
51+
logger.log(Level.WARNING, "env " + TANGO_HOST.toUpperCase() + " not set => force to " + DEFAULT_TANGO_HOST);
52+
System.setProperty(TANGO_HOST.toUpperCase(), DEFAULT_TANGO_HOST) ;
53+
currentTangoHost = DEFAULT_TANGO_HOST;
54+
}
55+
}
56+
57+
public boolean isTangoDbEnable() {
58+
if(tangoDBEnable == null) {
59+
//Test database
60+
try {
61+
Database db = new Database();
62+
db.ping();
63+
tangoDBEnable = true;
64+
}
65+
catch (Exception e) {
66+
tangoDBEnable = false;
67+
String currentTangoHost = System.getProperty(TANGO_HOST.toUpperCase());
68+
logger.log(Level.SEVERE, "Tango database not found on " + TANGO_HOST.toUpperCase() + "=" + currentTangoHost, e);
69+
}
70+
}
71+
return tangoDBEnable;
72+
}
73+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# ------------------------------
2+
# Package org.phoebus.pv.tango
3+
# ------------------------------
4+
5+
# Override TANGO_HOST system properties eg localhost:10000
6+
tango_host=$(TANGO_HOST)

0 commit comments

Comments
 (0)