use of org.apache.plc4x.java.modbus.field.ModbusField 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.modbus.field.ModbusField in project plc4x by apache.
the class ModbusProtocolLogic method fromPlcValue.
private byte[] fromPlcValue(PlcField field, PlcValue plcValue) {
ModbusDataType fieldDataType = ((ModbusField) field).getDataType();
try {
if (plcValue instanceof PlcList) {
WriteBufferByteBased writeBuffer = new WriteBufferByteBased(DataItem.getLengthInBytes(plcValue, fieldDataType, plcValue.getLength()));
DataItem.staticSerialize(writeBuffer, plcValue, fieldDataType, plcValue.getLength(), ByteOrder.BIG_ENDIAN);
byte[] data = writeBuffer.getData();
if (((ModbusField) field).getDataType() == ModbusDataType.BOOL) {
// Reverse Bits in each byte as
// they should be ordered like this: 8 7 6 5 4 3 2 1 | 0 0 0 0 0 0 0 9
byte[] bytes = new byte[data.length];
for (int i = 0; i < data.length; i++) {
bytes[i] = reverseBitsOfByte(data[i]);
}
return bytes;
}
return data;
} else {
WriteBufferByteBased writeBuffer = new WriteBufferByteBased(DataItem.getLengthInBytes(plcValue, fieldDataType, plcValue.getLength()));
DataItem.staticSerialize(writeBuffer, plcValue, fieldDataType, plcValue.getLength(), ByteOrder.BIG_ENDIAN);
return writeBuffer.getData();
}
} catch (SerializationException e) {
throw new PlcRuntimeException("Unable to parse PlcValue :- " + e);
}
}
Aggregations