use of org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse in project plc4x by apache.
the class CANOpenProtocolLogic method writeInternally.
private void writeInternally(DefaultPlcWriteRequest writeRequest, CANOpenPDOField field, CompletableFuture<PlcWriteResponse> response) {
PlcValue writeValue = writeRequest.getPlcValues().get(0);
try {
String fieldName = writeRequest.getFieldNames().iterator().next();
WriteBufferByteBased writeBuffer = new WriteBufferByteBased(DataItem.getLengthInBytes(writeValue, field.getCanOpenDataType(), writeValue.getLength()), ByteOrder.LITTLE_ENDIAN);
DataItem.staticSerialize(writeBuffer, writeValue, field.getCanOpenDataType(), writeValue.getLength(), ByteOrder.LITTLE_ENDIAN);
final CANOpenPDOPayload payload = new CANOpenPDOPayload(new CANOpenPDO(writeBuffer.getData()));
context.sendToWire(new CANOpenFrame((short) field.getNodeId(), field.getService(), payload));
response.complete(new DefaultPlcWriteResponse(writeRequest, Collections.singletonMap(fieldName, PlcResponseCode.OK)));
} catch (Exception e) {
response.completeExceptionally(e);
}
}
use of org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse in project plc4x by apache.
the class ModbusProtocolLogic method write.
@Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
CompletableFuture<PlcWriteResponse> future = new CompletableFuture<>();
DefaultPlcWriteRequest request = (DefaultPlcWriteRequest) writeRequest;
// 2. Split up into multiple sub-requests
if (request.getFieldNames().size() == 1) {
String fieldName = request.getFieldNames().iterator().next();
PlcField field = request.getField(fieldName);
final ModbusPDU requestPdu = getWriteRequestPdu(field, writeRequest.getPlcValue(fieldName));
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).unwrap(ModbusTcpADU::getPdu).handle(responsePdu -> {
// Try to decode the response data based on the corresponding request.
PlcResponseCode responseCode;
// Check if the response was an error response.
if (responsePdu instanceof ModbusPDUError) {
ModbusPDUError errorResponse = (ModbusPDUError) responsePdu;
responseCode = getErrorCode(errorResponse);
} else {
responseCode = PlcResponseCode.OK;
// TODO: Check the correct number of elements were written.
if (responsePdu instanceof ModbusPDUWriteSingleCoilResponse) {
ModbusPDUWriteSingleCoilResponse response = (ModbusPDUWriteSingleCoilResponse) responsePdu;
ModbusPDUWriteSingleCoilRequest requestSingleCoil = (ModbusPDUWriteSingleCoilRequest) requestPdu;
if (!((response.getValue() == requestSingleCoil.getValue()) && (response.getAddress() == requestSingleCoil.getAddress()))) {
responseCode = PlcResponseCode.REMOTE_ERROR;
}
}
}
// Prepare the response.
PlcWriteResponse response = new DefaultPlcWriteResponse(request, Collections.singletonMap(fieldName, responseCode));
// 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.DefaultPlcWriteResponse in project plc4x by apache.
the class PlcEntityManagerComplexTest method getPlcEntityManager.
private PlcEntityManager getPlcEntityManager(final Map<String, PlcValue> responses) throws PlcConnectionException {
driverManager = Mockito.mock(PlcDriverManager.class);
PlcDriverManager mock = driverManager;
PlcConnection connection = Mockito.mock(PlcConnection.class);
when(mock.getConnection(ArgumentMatchers.anyString())).thenReturn(connection);
when(connection.getMetadata()).thenReturn(new PlcConnectionMetadata() {
@Override
public boolean canRead() {
return true;
}
@Override
public boolean canWrite() {
return true;
}
@Override
public boolean canSubscribe() {
return true;
}
});
PlcReader reader = readRequest -> {
Map<String, ResponseItem<PlcValue>> map = readRequest.getFieldNames().stream().collect(Collectors.toMap(Function.identity(), s -> new ResponseItem<>(PlcResponseCode.OK, Objects.requireNonNull(responses.get(s), s + " not found"))));
return CompletableFuture.completedFuture(new DefaultPlcReadResponse(readRequest, map));
};
when(connection.readRequestBuilder()).then(invocation -> new DefaultPlcReadRequest.Builder(reader, getFieldHandler()));
PlcWriter writer = writeRequest -> {
Map<String, PlcResponseCode> map = writeRequest.getFieldNames().stream().collect(Collectors.toMap(Function.identity(), s -> PlcResponseCode.OK));
return CompletableFuture.completedFuture(new DefaultPlcWriteResponse(writeRequest, map));
};
when(connection.writeRequestBuilder()).then(invocation -> new DefaultPlcWriteRequest.Builder(writer, getFieldHandler(), getValueHandler()));
return new PlcEntityManager(mock);
}
use of org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse in project plc4x by apache.
the class BaseOptimizer method processWriteResponses.
protected PlcWriteResponse processWriteResponses(PlcWriteRequest writeRequest, Map<PlcRequest, Either<PlcResponse, Exception>> writeResponses) {
Map<String, PlcResponseCode> fields = new HashMap<>();
for (Map.Entry<PlcRequest, Either<PlcResponse, Exception>> requestsEntries : writeResponses.entrySet()) {
PlcWriteRequest subWriteRequest = (PlcWriteRequest) requestsEntries.getKey();
Either<PlcResponse, Exception> writeResponse = requestsEntries.getValue();
for (String fieldName : subWriteRequest.getFieldNames()) {
if (writeResponse.isLeft()) {
PlcWriteResponse subWriteResponse = (PlcWriteResponse) writeResponse.getLeft();
fields.put(fieldName, subWriteResponse.getResponseCode(fieldName));
} else {
fields.put(fieldName, PlcResponseCode.INTERNAL_ERROR);
}
}
}
return new DefaultPlcWriteResponse(writeRequest, fields);
}
use of org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse in project plc4x by apache.
the class Plc4xProtocolLogic method write.
@Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
CompletableFuture<PlcWriteResponse> future = new CompletableFuture<>();
// Prepare the request.
List<Plc4xFieldValueRequest> fields = new ArrayList<>(writeRequest.getNumberOfFields());
for (String fieldName : writeRequest.getFieldNames()) {
final org.apache.plc4x.java.plc4x.field.Plc4xField plc4xField = (org.apache.plc4x.java.plc4x.field.Plc4xField) writeRequest.getField(fieldName);
final Plc4xValueType plc4xValueType = plc4xField.getValueType();
final PlcValue plcValue = writeRequest.getPlcValue(fieldName);
Plc4xFieldValueRequest fieldRequest = new Plc4xFieldValueRequest(new Plc4xField(fieldName, plc4xField.getAddress() + ":" + plc4xField.getPlcDataType()), plc4xValueType, plcValue);
fields.add(fieldRequest);
}
final int requestId = txIdGenerator.getAndIncrement();
Plc4xWriteRequest write = new Plc4xWriteRequest(requestId, connectionId, fields);
// Send the request and await a response.
RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
context.sendRequest(write).expectResponse(Plc4xMessage.class, requestTimeout).onTimeout(future::completeExceptionally).check(p -> p.getRequestId() == requestId).unwrap(plc4xMessage -> (Plc4xWriteResponse) plc4xMessage).check(plc4xReadResponse -> plc4xReadResponse.getConnectionId() == connectionId).handle(plc4xWriteResponse -> {
Map<String, PlcResponseCode> apiResponses = new HashMap<>();
// Create the API response from the incoming message.
for (Plc4xFieldResponse plc4xField : plc4xWriteResponse.getFields()) {
final Plc4xResponseCode plc4xResponseCode = plc4xField.getResponseCode();
final PlcResponseCode apiResponseCode = PlcResponseCode.valueOf(plc4xResponseCode.name());
apiResponses.put(plc4xField.getField().getName(), apiResponseCode);
}
// Send it back to the calling process.
future.complete(new DefaultPlcWriteResponse(writeRequest, apiResponses));
// Finish the request-transaction.
transaction.endRequest();
});
return future;
}
Aggregations