in plc4j/tools/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/backend/Plc4xCommunication.java [143:248]
public DataValue getValue(AttributeFilterContext.GetAttributeContext ctx, String tag, String connectionString) {
PlcConnection connection = null;
try {
//Check if we just polled the connection, and it failed. Wait for the backoff counter to expire before we try again.
if (failedConnectionList.containsKey(connectionString)) {
if (System.currentTimeMillis() > failedConnectionList.get(connectionString) + DEFAULT_RETRY_BACKOFF) {
failedConnectionList.remove(connectionString);
} else {
logger.debug("Waiting for back off timer - " + ((failedConnectionList.get(connectionString) + DEFAULT_RETRY_BACKOFF) - System.currentTimeMillis()) + " ms left");
return BAD_RESPONSE;
}
}
//Try to connect to PLC
try {
connection = cachedPlcConnectionManager.getConnection(connectionString);
logger.debug(connectionString + " Connected");
} catch (PlcConnectionException e) {
logger.error("Failed to connect to device, error raised - " + e);
failedConnectionList.put(connectionString, System.currentTimeMillis());
return BAD_RESPONSE;
}
if (!connection.getMetadata().isReadSupported()) {
logger.error("This connection doesn't support reading.");
try {
connection.close();
} catch (Exception exception) {
logger.warn("Closing connection failed with error - " + exception);
}
return BAD_RESPONSE;
}
long timeout = DEFAULT_TIMEOUT;
if (monitoredList.containsKey(ctx.getNode().getNodeId())) {
timeout = (long) monitoredList.get(ctx.getNode().getNodeId()).getSamplingInterval() * 1000;
}
// Create a new read request:
// - Give the single item requested an alias name
PlcReadRequest.Builder builder = connection.readRequestBuilder();
builder.addTagAddress("value-1", tag);
PlcReadRequest readRequest = builder.build();
PlcReadResponse response = null;
try {
response = readRequest.execute().get(timeout, TimeUnit.MICROSECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
logger.warn(e + " Occurred while reading value, using timeout of " + timeout / 1000 + "ms");
try {
connection.close();
} catch (Exception exception) {
logger.warn("Closing connection failed with error - " + exception);
}
return BAD_RESPONSE;
}
DataValue resp = BAD_RESPONSE;
for (String tagName : response.getTagNames()) {
if (response.getResponseCode(tagName) == PlcResponseCode.OK) {
int numValues = response.getNumberOfValues(tagName);
if (numValues == 1) {
if (response.getObject(tagName) instanceof BigInteger) {
resp = new DataValue(new Variant(ulong((BigInteger) response.getObject(tagName))), StatusCode.GOOD);
} else {
resp = new DataValue(new Variant(response.getObject(tagName)), StatusCode.GOOD);
}
} else {
Object array = null;
if (response.getObject(tagName, 0) instanceof BigInteger) {
array = Array.newInstance(ULong.class, numValues);
} else {
array = Array.newInstance(response.getObject(tagName, 0).getClass(), numValues);
}
for (int i = 0; i < numValues; i++) {
if (response.getObject(tagName, i) instanceof BigInteger) {
Array.set(array, i, ulong((BigInteger) response.getObject(tagName, i)));
} else {
Array.set(array, i, response.getObject(tagName, i));
}
}
resp = new DataValue(new Variant(array), StatusCode.GOOD);
}
}
}
try {
connection.close();
} catch (Exception e) {
failedConnectionList.put(connectionString, System.currentTimeMillis());
logger.warn("Closing connection failed with error " + e);
}
return resp;
} catch (Exception e) {
logger.warn("General error reading value " + e.getStackTrace()[0].toString());
if (connection != null) {
try {
connection.close();
} catch (Exception ex) {
//Do Nothing
}
}
return BAD_RESPONSE;
}
}