Search in sources :

Example 6 with PlcWriteRequest

use of org.apache.plc4x.java.api.messages.PlcWriteRequest in project plc4x by apache.

the class Plc4xCommunication method setValue.

public void setValue(String tag, String value, String connectionString) {
    PlcConnection connection = null;
    try {
        connection = driverManager.getConnection(connectionString);
        if (connection.isConnected() == false) {
            logger.debug("getConnection() returned a connection that isn't connected");
            connection.connect();
        }
    } catch (PlcConnectionException e) {
        logger.warn("Failed" + e);
    }
    if (!connection.getMetadata().canWrite()) {
        logger.error("This connection doesn't support writing.");
        try {
            connection.close();
        } catch (Exception e) {
            logger.warn("Closing connection failed with error " + e);
        }
        return;
    }
    // Create a new read request:
    // - Give the single item requested an alias name
    final PlcWriteRequest.Builder builder = connection.writeRequestBuilder();
    // If an array value is passed instead of a single value then convert to a String array
    if ((value.charAt(0) == '[') && (value.charAt(value.length() - 1) == ']')) {
        String[] values = value.substring(1, value.length() - 1).split(",");
        logger.info("Adding Tag " + Arrays.toString(values));
        builder.addItem(tag, tag, values);
    } else {
        builder.addItem(tag, tag, value);
    }
    PlcWriteRequest writeRequest = builder.build();
    try {
        writeRequest.execute().get();
    } catch (InterruptedException | ExecutionException e) {
        logger.warn("Failed" + e);
    }
    try {
        connection.close();
    } catch (Exception e) {
        logger.warn("Closing Connection Failed with error " + e);
    }
    return;
}
Also used : PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) PlcConnectionException(org.apache.plc4x.java.api.exceptions.PlcConnectionException) ExecutionException(java.util.concurrent.ExecutionException) PlcConnection(org.apache.plc4x.java.api.PlcConnection) TimeoutException(java.util.concurrent.TimeoutException) PlcConnectionException(org.apache.plc4x.java.api.exceptions.PlcConnectionException) ExecutionException(java.util.concurrent.ExecutionException)

Example 7 with PlcWriteRequest

use of org.apache.plc4x.java.api.messages.PlcWriteRequest in project plc4x by apache.

the class ModbusRtuProtocolLogic 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));
        ModbusRtuADU modbusRtuADU = new ModbusRtuADU(unitIdentifier, requestPdu, false);
        RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
        transaction.submit(() -> context.sendRequest(modbusRtuADU).expectResponse(ModbusRtuADU.class, requestTimeout).onTimeout(future::completeExceptionally).onError((p, e) -> future.completeExceptionally(e)).unwrap(ModbusRtuADU::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;
}
Also used : PlcWriteResponse(org.apache.plc4x.java.api.messages.PlcWriteResponse) PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) ParseException(org.apache.plc4x.java.spi.generation.ParseException) ModbusTcpConfiguration(org.apache.plc4x.java.modbus.tcp.config.ModbusTcpConfiguration) ModbusProtocolLogic(org.apache.plc4x.java.modbus.base.protocol.ModbusProtocolLogic) org.apache.plc4x.java.modbus.readwrite(org.apache.plc4x.java.modbus.readwrite) PlcValue(org.apache.plc4x.java.api.value.PlcValue) PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) CompletableFuture(java.util.concurrent.CompletableFuture) PlcField(org.apache.plc4x.java.api.model.PlcField) ModbusField(org.apache.plc4x.java.modbus.base.field.ModbusField) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) ModbusRtuConfiguration(org.apache.plc4x.java.modbus.rtu.config.ModbusRtuConfiguration) HasConfiguration(org.apache.plc4x.java.spi.configuration.HasConfiguration) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) Duration(java.time.Duration) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) DefaultPlcWriteRequest(org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest) DefaultPlcReadRequest(org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest) Collections(java.util.Collections) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcField(org.apache.plc4x.java.api.model.PlcField) PlcWriteResponse(org.apache.plc4x.java.api.messages.PlcWriteResponse) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) DefaultPlcWriteRequest(org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) CompletableFuture(java.util.concurrent.CompletableFuture) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse)

Example 8 with PlcWriteRequest

use of org.apache.plc4x.java.api.messages.PlcWriteRequest in project plc4x by apache.

the class Plc4XDf1Protocol method decode.

@Override
protected void decode(ChannelHandlerContext ctx, DF1Symbol msg, List<Object> out) throws Exception {
    logger.debug("Received DF1 Command incoming {}", msg);
    if (msg instanceof DF1SymbolMessageFrameNAK) {
        logger.warn("Received a response NAK, notify all requests");
        for (Map.Entry<Integer, PlcRequestContainer> entry : requests.entrySet()) {
            entry.getValue().getResponseFuture().complete(new DefaultPlcReadResponse((PlcReadRequest) entry.getValue().getRequest(), Collections.singletonMap("erster", new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, new PlcDINT(-1)))));
        }
        return;
    } else if (msg instanceof DF1SymbolMessageFrameACK) {
        logger.warn("Received a response ACK :D");
        return;
    }
    assert msg instanceof DF1SymbolMessageFrame;
    DF1Command command = ((DF1SymbolMessageFrame) msg).getCommand();
    int transactionId = command.getTransactionCounter();
    if (!requests.containsKey(transactionId)) {
        logger.warn("Received a response to unknown transaction id {}", transactionId);
        ctx.fireExceptionCaught(new RuntimeException("Received a response to unknown transaction id"));
        ctx.close();
        return;
    }
    // As every response has a matching request, get this request based on the tpdu.
    PlcRequestContainer requestContainer = requests.remove(transactionId);
    PlcRequest request = requestContainer.getRequest();
    // Handle the response.
    PlcResponse response = null;
    if (request instanceof PlcReadRequest) {
        /*
            Things to do
            - check response code (if there is something like that?
            - cast the bytes to right datatype
            - create Response
             */
        // We can do this as we have only one fieldName in DF1
        final String fieldName = ((PlcReadRequest) request).getFieldNames().iterator().next();
        // TODO can there be another code than ok?
        final PlcResponseCode responseCode = PlcResponseCode.OK;
        // TODO maybe check for different status bytes
        final Df1Field field = (Df1Field) ((PlcReadRequest) request).getField(fieldName);
        // Cast byte and create response item
        PlcValue responseItem = null;
        byte[] data = ((DF1UnprotectedReadResponse) command).getData();
        switch(field.getDataType()) {
            case BIT:
                break;
            case INTEGER:
                // TODO: type conversion is untested
                responseItem = new PlcDINT((int) data[0] + ((int) data[1] << 8));
                break;
            case FLOAT:
                break;
            case BIT_STRING:
                break;
            case ARRAY:
                break;
            // TODO add all other cases here...
            default:
                throw new NotImplementedException("The DataType " + field.getDataType() + " is currently not implemented!");
        }
        response = new DefaultPlcReadResponse(((PlcReadRequest) request), Collections.singletonMap(fieldName, new ResponseItem<>(responseCode, responseItem)));
    } else if (request instanceof PlcWriteRequest) {
        logger.warn("Writing is currently not implemented but received a write response?!");
        ctx.close();
        throw new NotImplementedException("This is currently not implemented!");
    }
    // Confirm the response being handled.
    if (response != null) {
        requestContainer.getResponseFuture().complete(response);
    }
}
Also used : PlcRequestContainer(org.apache.plc4x.java.spi.messages.PlcRequestContainer) PlcDINT(org.apache.plc4x.java.spi.values.PlcDINT) PlcRequest(org.apache.plc4x.java.api.messages.PlcRequest) NotImplementedException(org.apache.commons.lang3.NotImplementedException) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PlcValue(org.apache.plc4x.java.api.value.PlcValue) PlcResponse(org.apache.plc4x.java.api.messages.PlcResponse) PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map) Df1Field(org.apache.plc4x.java.df1.field.Df1Field)

Example 9 with PlcWriteRequest

use of org.apache.plc4x.java.api.messages.PlcWriteRequest in project plc4x by apache.

the class OpcuaPlcDriverTest method multipleThreads.

/*
        Test added to test the syncronized Trnasactionhandler.
        The test originally failed one out of every 5 or so.
     */
public void multipleThreads() {
    class ReadWorker extends Thread {

        private PlcConnection connection;

        public ReadWorker(PlcConnection opcuaConnection) {
            this.connection = opcuaConnection;
        }

        @Override
        public void run() {
            try {
                PlcReadRequest.Builder read_builder = connection.readRequestBuilder();
                read_builder.addItem("Bool", BOOL_IDENTIFIER_READ_WRITE);
                PlcReadRequest read_request = read_builder.build();
                for (int i = 0; i < 100; i++) {
                    PlcReadResponse read_response = read_request.execute().get();
                    assertThat(read_response.getResponseCode("Bool")).isEqualTo(PlcResponseCode.OK);
                }
            } catch (ExecutionException executionException) {
                executionException.printStackTrace();
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
        }
    }
    class WriteWorker extends Thread {

        private PlcConnection connection;

        public WriteWorker(PlcConnection opcuaConnection) {
            this.connection = opcuaConnection;
        }

        @Override
        public void run() {
            try {
                PlcWriteRequest.Builder write_builder = connection.writeRequestBuilder();
                write_builder.addItem("Bool", BOOL_IDENTIFIER_READ_WRITE, true);
                PlcWriteRequest write_request = write_builder.build();
                for (int i = 0; i < 100; i++) {
                    PlcWriteResponse write_response = write_request.execute().get();
                    assertThat(write_response.getResponseCode("Bool")).isEqualTo(PlcResponseCode.OK);
                }
            } catch (ExecutionException executionException) {
                executionException.printStackTrace();
            } catch (InterruptedException interruptedException) {
                interruptedException.printStackTrace();
            }
        }
    }
    try {
        PlcConnection opcuaConnection = new PlcDriverManager().getConnection(tcpConnectionAddress);
        Condition<PlcConnection> is_connected = new Condition<>(PlcConnection::isConnected, "is connected");
        assertThat(opcuaConnection).is(is_connected);
        ReadWorker read_worker = new ReadWorker(opcuaConnection);
        WriteWorker write_worker = new WriteWorker(opcuaConnection);
        read_worker.start();
        write_worker.start();
        read_worker.join();
        write_worker.join();
        opcuaConnection.close();
        assert !opcuaConnection.isConnected();
    } catch (Exception e) {
        fail("Exception during readVariables Test EXCEPTION: " + e.getMessage());
    }
}
Also used : Condition(org.assertj.core.api.Condition) PlcWriteResponse(org.apache.plc4x.java.api.messages.PlcWriteResponse) PlcConnection(org.apache.plc4x.java.api.PlcConnection) ExecutionException(java.util.concurrent.ExecutionException) PlcConnectionException(org.apache.plc4x.java.api.exceptions.PlcConnectionException) PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) ExecutionException(java.util.concurrent.ExecutionException) PlcDriverManager(org.apache.plc4x.java.PlcDriverManager)

Example 10 with PlcWriteRequest

use of org.apache.plc4x.java.api.messages.PlcWriteRequest 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;
}
Also used : PlcWriteResponse(org.apache.plc4x.java.api.messages.PlcWriteResponse) PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) ParseException(org.apache.plc4x.java.spi.generation.ParseException) ModbusTcpConfiguration(org.apache.plc4x.java.modbus.tcp.config.ModbusTcpConfiguration) ModbusProtocolLogic(org.apache.plc4x.java.modbus.base.protocol.ModbusProtocolLogic) org.apache.plc4x.java.modbus.readwrite(org.apache.plc4x.java.modbus.readwrite) PlcValue(org.apache.plc4x.java.api.value.PlcValue) PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) CompletableFuture(java.util.concurrent.CompletableFuture) PlcField(org.apache.plc4x.java.api.model.PlcField) ModbusField(org.apache.plc4x.java.modbus.base.field.ModbusField) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) ModbusRtuConfiguration(org.apache.plc4x.java.modbus.rtu.config.ModbusRtuConfiguration) HasConfiguration(org.apache.plc4x.java.spi.configuration.HasConfiguration) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) Duration(java.time.Duration) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) DefaultPlcWriteRequest(org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest) DefaultPlcReadRequest(org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest) Collections(java.util.Collections) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcField(org.apache.plc4x.java.api.model.PlcField) PlcWriteResponse(org.apache.plc4x.java.api.messages.PlcWriteResponse) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) DefaultPlcWriteRequest(org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) CompletableFuture(java.util.concurrent.CompletableFuture) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse)

Aggregations

PlcWriteRequest (org.apache.plc4x.java.api.messages.PlcWriteRequest)17 PlcReadRequest (org.apache.plc4x.java.api.messages.PlcReadRequest)10 PlcWriteResponse (org.apache.plc4x.java.api.messages.PlcWriteResponse)10 PlcConnection (org.apache.plc4x.java.api.PlcConnection)8 PlcValue (org.apache.plc4x.java.api.value.PlcValue)8 PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)7 PlcField (org.apache.plc4x.java.api.model.PlcField)6 PlcReadResponse (org.apache.plc4x.java.api.messages.PlcReadResponse)5 DefaultPlcReadResponse (org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse)5 DefaultPlcWriteRequest (org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest)5 Duration (java.time.Duration)4 CompletableFuture (java.util.concurrent.CompletableFuture)4 PlcDriverManager (org.apache.plc4x.java.PlcDriverManager)4 PlcProtocolException (org.apache.plc4x.java.api.exceptions.PlcProtocolException)4 PlcRequest (org.apache.plc4x.java.api.messages.PlcRequest)4 BigInteger (java.math.BigInteger)3 Collections (java.util.Collections)3 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)3 DefaultPlcReadRequest (org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest)3 DefaultPlcWriteResponse (org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse)3