use of org.apache.plc4x.java.api.model.PlcField in project plc4x by apache.
the class Plc4XDf1Protocol method encode.
@Override
protected void encode(ChannelHandlerContext ctx, PlcRequestContainer msg, List<Object> out) throws Exception {
logger.trace("Received Request {} to send out", msg);
if (msg.getRequest() instanceof PlcReadRequest) {
for (PlcField field : ((PlcReadRequest) msg.getRequest()).getFields()) {
if (!(field instanceof Df1Field)) {
throw new IllegalArgumentException("Invalid field type found inside Df1 Request");
}
int address = ((Df1Field) field).getAddress();
short size = ((Df1Field) field).getDataType().getLength();
int transactionId = this.transactionId.getAndIncrement();
while (((transactionId & 0xFF) == 0x10) || (((transactionId >>> 8) & 0xFF) == 0x10)) {
// prevent that one of the transactionID bytes is 0x10, which has to be escaped by double 0x10 and makes life a lot harder
transactionId = this.transactionId.getAndIncrement();
}
logger.debug("Creating request for offset {}, with length {} and transaction id {}", address, size, transactionId);
requests.put(transactionId, msg);
switch(((Df1Field) field).getAddress_type()) {
case OFFSET:
out.add(new DF1UnprotectedReadRequest((short) 0x00, (short) transactionId, address, size));
break;
case LOGICAL:
// TODO: add 'protected typed logical read' to mspec
throw new NotImplementedException("not yet implemented in mspec");
}
}
} else {
throw new IllegalStateException("This should not happen!");
}
}
use of org.apache.plc4x.java.api.model.PlcField in project plc4x by apache.
the class ManualPLC4XOpcua method main.
public static void main(String[] args) {
try {
// When switching JDK versions from a newer to an older version,
// this can cause the server to not start correctly.
// Deleting the directory makes sure the key-store is initialized correctly.
Path securityBaseDir = Paths.get(System.getProperty("java.io.tmpdir"), "server", "security");
try {
Files.delete(securityBaseDir);
} catch (Exception e) {
// Ignore this ...
}
ExampleServer testServer = new ExampleServer();
testServer.startup().get();
} catch (Exception e) {
throw new PlcRuntimeException(e);
}
PlcConnection opcuaConnection = null;
OpcuaPlcFieldHandler fieldH = new OpcuaPlcFieldHandler();
PlcField field = fieldH.createField(BOOL_IDENTIFIER);
try {
opcuaConnection = new PlcDriverManager().getConnection("opcua:tcp://127.0.0.1:12686/milo?discovery=false");
} catch (PlcConnectionException e) {
throw new PlcRuntimeException(e);
}
try {
PlcReadRequest.Builder builder = opcuaConnection.readRequestBuilder();
builder.addItem("Bool", BOOL_IDENTIFIER);
builder.addItem("ByteString", BYTE_STRING_IDENTIFIER);
builder.addItem("Byte", BYTE_IDENTIFIER);
builder.addItem("Double", DOUBLE_IDENTIFIER);
builder.addItem("Float", FLOAT_IDENTIFIER);
builder.addItem("Int16", INT16_IDENTIFIER);
builder.addItem("Int32", INT32_IDENTIFIER);
builder.addItem("Int64", INT64_IDENTIFIER);
builder.addItem("Integer", INTEGER_IDENTIFIER);
builder.addItem("SByte", SBYTE_IDENTIFIER);
builder.addItem("String", STRING_IDENTIFIER);
builder.addItem("UInt16", UINT16_IDENTIFIER);
builder.addItem("UInt32", UINT32_IDENTIFIER);
builder.addItem("UInt64", UINT64_IDENTIFIER);
builder.addItem("UInteger", UINTEGER_IDENTIFIER);
builder.addItem("BoolArray", BOOL_ARRAY_IDENTIFIER);
builder.addItem("ByteStringArray", BYTE_STRING_ARRAY_IDENTIFIER);
builder.addItem("ByteArray", BYTE_ARRAY_IDENTIFIER);
builder.addItem("DoubleArray", DOUBLE_ARRAY_IDENTIFIER);
builder.addItem("FloatArray", FLOAT_ARRAY_IDENTIFIER);
builder.addItem("Int16Array", INT16_ARRAY_IDENTIFIER);
builder.addItem("Int32Array", INT32_ARRAY_IDENTIFIER);
builder.addItem("Int64Array", INT64_ARRAY_IDENTIFIER);
builder.addItem("IntegerArray", INTEGER_ARRAY_IDENTIFIER);
builder.addItem("SByteArray", SBYTE_ARRAY_IDENTIFIER);
builder.addItem("StringArray", STRING_ARRAY_IDENTIFIER);
builder.addItem("UInt16Array", UINT16_ARRAY_IDENTIFIER);
builder.addItem("UInt32Array", UINT32_ARRAY_IDENTIFIER);
builder.addItem("UInt64Array", UINT64_ARRAY_IDENTIFIER);
builder.addItem("UIntegerArray", UINTEGER_ARRAY_IDENTIFIER);
builder.addItem("DoesNotExists", DOES_NOT_EXIST_IDENTIFIER);
PlcReadRequest request = builder.build();
PlcReadResponse response = request.execute().get();
// Collection coll = response.getAllStrings("String");
PlcWriteRequest.Builder wBuilder = opcuaConnection.writeRequestBuilder();
wBuilder.addItem("w-Bool", BOOL_IDENTIFIER, true);
// wBuilder.addItem("w-ByteString", BYTE_STRING_IDENTIFIER, "TEST".getBytes());
wBuilder.addItem("w-Byte", BYTE_IDENTIFIER, (byte) 1);
wBuilder.addItem("w-Double", DOUBLE_IDENTIFIER, (double) 0.25);
wBuilder.addItem("w-Float", FLOAT_IDENTIFIER, (float) 0.25);
wBuilder.addItem("w-INT16", INT16_IDENTIFIER, 12);
wBuilder.addItem("w-Int32", INT32_IDENTIFIER, (int) 314);
wBuilder.addItem("w-Int64", INT64_IDENTIFIER, (long) 123125);
wBuilder.addItem("w-Integer", INTEGER_IDENTIFIER, (int) 314);
wBuilder.addItem("w-SByte", SBYTE_IDENTIFIER, (byte) 1);
wBuilder.addItem("w-String", STRING_IDENTIFIER, "TEST");
wBuilder.addItem("w-UInt16", UINT16_IDENTIFIER, new BigInteger("12"));
wBuilder.addItem("w-UInt32", UINT32_IDENTIFIER, new BigInteger("123"));
wBuilder.addItem("w-UInt64", UINT64_IDENTIFIER, new BigInteger("1245152"));
wBuilder.addItem("w-UInteger", UINTEGER_IDENTIFIER, new BigInteger("1245152"));
PlcWriteRequest writeRequest = wBuilder.build();
PlcWriteResponse wResponse = writeRequest.execute().get();
// Create Subscription
PlcSubscriptionRequest.Builder sBuilder = opcuaConnection.subscriptionRequestBuilder();
sBuilder.addChangeOfStateField("Bool", BOOL_IDENTIFIER);
sBuilder.addChangeOfStateField("ByteString", BYTE_STRING_IDENTIFIER);
sBuilder.addChangeOfStateField("Byte", BYTE_IDENTIFIER);
sBuilder.addChangeOfStateField("Double", DOUBLE_IDENTIFIER);
sBuilder.addChangeOfStateField("Float", FLOAT_IDENTIFIER);
sBuilder.addChangeOfStateField("Int16", INT16_IDENTIFIER);
sBuilder.addChangeOfStateField("Int32", INT32_IDENTIFIER);
sBuilder.addChangeOfStateField("Int64", INT64_IDENTIFIER);
sBuilder.addChangeOfStateField("Integer", INTEGER_IDENTIFIER);
sBuilder.addChangeOfStateField("SByte", SBYTE_IDENTIFIER);
sBuilder.addChangeOfStateField("String", STRING_IDENTIFIER);
sBuilder.addChangeOfStateField("UInt16", UINT16_IDENTIFIER);
sBuilder.addChangeOfStateField("UInt32", UINT32_IDENTIFIER);
sBuilder.addChangeOfStateField("UInt64", UINT64_IDENTIFIER);
sBuilder.addChangeOfStateField("UInteger", UINTEGER_IDENTIFIER);
sBuilder.addChangeOfStateField("BoolArray", BOOL_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("ByteStringArray", BYTE_STRING_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("ByteArray", BYTE_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("DoubleArray", DOUBLE_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("FloatArray", FLOAT_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("Int16Array", INT16_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("Int32Array", INT32_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("Int64Array", INT64_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("IntegerArray", INTEGER_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("SByteArray", SBYTE_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("StringArray", STRING_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("UInt16Array", UINT16_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("UInt32Array", UINT32_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("UInt64Array", UINT64_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("UIntegerArray", UINTEGER_ARRAY_IDENTIFIER);
sBuilder.addChangeOfStateField("DoesNotExists", DOES_NOT_EXIST_IDENTIFIER);
PlcSubscriptionRequest subscriptionRequest = sBuilder.build();
// Get result of creating subscription
PlcSubscriptionResponse sResponse = subscriptionRequest.execute().get();
final OpcuaSubscriptionHandle subscriptionHandle = (OpcuaSubscriptionHandle) sResponse.getSubscriptionHandle("Bool");
// Create handler for returned value
subscriptionHandle.register(plcSubscriptionEvent -> {
assert plcSubscriptionEvent.getResponseCode("Bool").equals(PlcResponseCode.OK);
});
// Wait for value to be returned from server
Thread.sleep(1200);
subscriptionHandle.stopSubscriber();
Thread.sleep(20000);
opcuaConnection.close();
} catch (Exception e) {
throw new PlcRuntimeException(e);
}
}
use of org.apache.plc4x.java.api.model.PlcField in project plc4x by apache.
the class ModbusTcpProtocolLogic 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.api.model.PlcField in project plc4x by apache.
the class ModbusAsciiProtocolLogic 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));
ModbusAsciiADU modbusAsciiADU = new ModbusAsciiADU(unitIdentifier, requestPdu, false);
RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
transaction.submit(() -> context.sendRequest(modbusAsciiADU).expectResponse(ModbusAsciiADU.class, requestTimeout).onTimeout(future::completeExceptionally).onError((p, e) -> future.completeExceptionally(e)).unwrap(ModbusAsciiADU::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.api.model.PlcField in project plc4x by apache.
the class AdsProtocolLogic method singleWrite.
protected CompletableFuture<PlcWriteResponse> singleWrite(PlcWriteRequest writeRequest, DirectAdsField directAdsField) {
CompletableFuture<PlcWriteResponse> future = new CompletableFuture<>();
final String fieldName = writeRequest.getFieldNames().iterator().next();
final AdsField plcField = (AdsField) writeRequest.getField(fieldName);
final PlcValue plcValue = writeRequest.getPlcValue(fieldName);
final int stringLength;
if (directAdsField.getAdsDataType() == AdsDataType.STRING) {
stringLength = plcValue.getString().length() + 1;
} else {
if (directAdsField.getAdsDataType() == AdsDataType.WSTRING) {
stringLength = (plcValue.getString().length() + 1) * 2;
} else {
stringLength = 0;
}
}
try {
WriteBufferByteBased writeBuffer = new WriteBufferByteBased(DataItem.getLengthInBytes(plcValue, plcField.getAdsDataType().getDataFormatName(), stringLength));
DataItem.staticSerialize(writeBuffer, plcValue, plcField.getAdsDataType().getDataFormatName(), stringLength, ByteOrder.LITTLE_ENDIAN);
AdsData adsData = new AdsWriteRequest(directAdsField.getIndexGroup(), directAdsField.getIndexOffset(), writeBuffer.getData());
AmsPacket amsPacket = new AmsPacket(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(), configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(), CommandId.ADS_WRITE, DEFAULT_COMMAND_STATE, 0, getInvokeId(), adsData);
AmsTCPPacket amsTCPPacket = new AmsTCPPacket(amsPacket);
// Start a new request-transaction (Is ended in the response-handler)
RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
transaction.submit(() -> context.sendRequest(amsTCPPacket).expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())).onTimeout(future::completeExceptionally).onError((p, e) -> future.completeExceptionally(e)).check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == amsPacket.getInvokeId()).unwrap(response -> (AdsWriteResponse) response.getUserdata().getData()).handle(responseAdsData -> {
if (responseAdsData.getResult() == ReturnCode.OK) {
final PlcWriteResponse plcWriteResponse = convertToPlc4xWriteResponse(writeRequest, responseAdsData);
// Convert the response from the PLC into a PLC4X Response ...
future.complete(plcWriteResponse);
} else {
// TODO: Implement this correctly.
future.completeExceptionally(new PlcException("Unexpected return code " + responseAdsData.getResult()));
}
// Finish the request-transaction.
transaction.endRequest();
}));
} catch (Exception e) {
future.completeExceptionally(new PlcException("Error"));
}
return future;
}
Aggregations