use of org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest in project plc4x by apache.
the class OpcuaOptimizer method processReadRequest.
@Override
protected List<PlcRequest> processReadRequest(PlcReadRequest readRequest, DriverContext driverContext) {
List<PlcRequest> processedRequests = new LinkedList<>();
// List of all items in the current request.
LinkedHashMap<String, PlcField> curFields = new LinkedHashMap<>();
for (String fieldName : readRequest.getFieldNames()) {
OpcuaField field = (OpcuaField) readRequest.getField(fieldName);
curFields.put(fieldName, field);
}
// Create a new PlcReadRequest from the remaining field items.
if (!curFields.isEmpty()) {
processedRequests.add(new DefaultPlcReadRequest(((DefaultPlcReadRequest) readRequest).getReader(), curFields));
}
return processedRequests;
}
use of org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest in project plc4x by apache.
the class SingleFieldOptimizer method processReadRequest.
@Override
protected List<PlcRequest> processReadRequest(PlcReadRequest readRequest, DriverContext driverContext) {
if (readRequest.getNumberOfFields() == 1) {
return Collections.singletonList(readRequest);
}
List<PlcRequest> subRequests = new ArrayList<>(readRequest.getNumberOfFields());
for (String fieldName : readRequest.getFieldNames()) {
PlcField field = readRequest.getField(fieldName);
PlcReadRequest subRequest = new DefaultPlcReadRequest(((DefaultPlcReadRequest) readRequest).getReader(), new LinkedHashMap<>(Collections.singletonMap(fieldName, field)));
subRequests.add(subRequest);
}
return subRequests;
}
use of org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest in project plc4x by apache.
the class ModbusProtocolLogic method read.
@Override
public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
DefaultPlcReadRequest request = (DefaultPlcReadRequest) readRequest;
// Example for sending a request ...
if (request.getFieldNames().size() == 1) {
String fieldName = request.getFieldNames().iterator().next();
ModbusField field = (ModbusField) request.getField(fieldName);
final ModbusPDU requestPdu = getReadRequestPdu(field);
int transactionIdentifier = transactionIdentifierGenerator.getAndIncrement();
// If we've reached the max value for a 16 bit transaction identifier, reset back to 1
if (transactionIdentifierGenerator.get() == 0xFFFF) {
transactionIdentifierGenerator.set(1);
}
ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitIdentifier, requestPdu, false);
RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
transaction.submit(() -> context.sendRequest(modbusTcpADU).expectResponse(ModbusTcpADU.class, requestTimeout).onTimeout(future::completeExceptionally).onError((p, e) -> future.completeExceptionally(e)).check(p -> ((p.getTransactionIdentifier() == transactionIdentifier) && (p.getUnitIdentifier() == unitIdentifier))).unwrap(ModbusTcpADU::getPdu).handle(responsePdu -> {
// Try to decode the response data based on the corresponding request.
PlcValue plcValue = null;
PlcResponseCode responseCode;
// Check if the response was an error response.
if (responsePdu instanceof ModbusPDUError) {
ModbusPDUError errorResponse = (ModbusPDUError) responsePdu;
responseCode = getErrorCode(errorResponse);
} else {
try {
plcValue = toPlcValue(requestPdu, responsePdu, field.getDataType());
responseCode = PlcResponseCode.OK;
} catch (ParseException e) {
// Add an error response code ...
responseCode = PlcResponseCode.INTERNAL_ERROR;
}
}
// Prepare the response.
PlcReadResponse response = new DefaultPlcReadResponse(request, Collections.singletonMap(fieldName, new ResponseItem<>(responseCode, plcValue)));
// Pass the response back to the application.
future.complete(response);
// Finish the request-transaction.
transaction.endRequest();
}));
} else {
future.completeExceptionally(new PlcRuntimeException("Modbus only supports single filed requests"));
}
return future;
}
use of org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest in project plc4x by apache.
the class S7ProtocolLogic method read.
@Override
public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
DefaultPlcReadRequest request = (DefaultPlcReadRequest) readRequest;
List<S7VarRequestParameterItem> requestItems = new ArrayList<>(request.getNumberOfFields());
for (PlcField field : request.getFields()) {
requestItems.add(new S7VarRequestParameterItemAddress(encodeS7Address(field)));
}
// Create a read request template.
// tpuId will be inserted before sending in #readInternal so we insert -1 as dummy here
final S7MessageRequest s7MessageRequest = new S7MessageRequest(-1, new S7ParameterReadVarRequest(requestItems), null);
// Just send a single response and chain it as Response
return toPlcReadResponse(readRequest, readInternal(s7MessageRequest));
}
use of org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest in project plc4x by apache.
the class S7Optimizer method processReadRequest.
@Override
protected List<PlcRequest> processReadRequest(PlcReadRequest readRequest, DriverContext driverContext) {
S7DriverContext s7DriverContext = (S7DriverContext) driverContext;
List<PlcRequest> processedRequests = new LinkedList<>();
// This calculates the size of the header for the request and response.
int curRequestSize = EMPTY_READ_REQUEST_SIZE;
// An empty response has the same size as an empty request.
int curResponseSize = EMPTY_READ_RESPONSE_SIZE;
// List of all items in the current request.
LinkedHashMap<String, PlcField> curFields = new LinkedHashMap<>();
for (String fieldName : readRequest.getFieldNames()) {
S7Field field = (S7Field) readRequest.getField(fieldName);
int readRequestItemSize = S7_ADDRESS_ANY_SIZE;
int readResponseItemSize = 4 + (field.getNumberOfElements() * field.getDataType().getSizeInBytes());
// If it's an odd number of bytes, add one to make it even
if (readResponseItemSize % 2 == 1) {
readResponseItemSize++;
}
// If adding the item would not exceed the sizes, add it to the current request.
if (((curRequestSize + readRequestItemSize) <= s7DriverContext.getPduSize()) && ((curResponseSize + readResponseItemSize) <= s7DriverContext.getPduSize())) {
// Increase the current request sizes.
curRequestSize += readRequestItemSize;
curResponseSize += readResponseItemSize;
// Add the item.
} else // If they would exceed, start a new request.
{
// Create a new PlcReadRequest containing the current field item.
processedRequests.add(new DefaultPlcReadRequest(((DefaultPlcReadRequest) readRequest).getReader(), curFields));
// Reset the size and item lists.
curRequestSize = EMPTY_READ_REQUEST_SIZE + readRequestItemSize;
curResponseSize = EMPTY_READ_RESPONSE_SIZE + readResponseItemSize;
curFields = new LinkedHashMap<>();
// Splitting of huge fields not yet implemented, throw an exception instead.
if (((curRequestSize + readRequestItemSize) > s7DriverContext.getPduSize()) && ((curResponseSize + readResponseItemSize) > s7DriverContext.getPduSize())) {
throw new PlcRuntimeException("Field size exceeds maximum payload for one item.");
}
}
curFields.put(fieldName, field);
}
// Create a new PlcReadRequest from the remaining field items.
if (!curFields.isEmpty()) {
processedRequests.add(new DefaultPlcReadRequest(((DefaultPlcReadRequest) readRequest).getReader(), curFields));
}
return processedRequests;
}
Aggregations