Search in sources :

Example 1 with S7DriverContext

use of org.apache.plc4x.java.s7.readwrite.context.S7DriverContext in project plc4x by apache.

the class S7Optimizer method processWriteRequest.

@Override
protected List<PlcRequest> processWriteRequest(PlcWriteRequest writeRequest, 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_WRITE_REQUEST_SIZE;
    // An empty response has the same size as an empty request.
    int curResponseSize = EMPTY_WRITE_RESPONSE_SIZE;
    // List of all items in the current request.
    LinkedHashMap<String, FieldValueItem> curFields = new LinkedHashMap<>();
    for (String fieldName : writeRequest.getFieldNames()) {
        S7Field field = (S7Field) writeRequest.getField(fieldName);
        PlcValue value = writeRequest.getPlcValue(fieldName);
        int writeRequestItemSize = S7_ADDRESS_ANY_SIZE + 4;
        if (field.getDataType() == TransportSize.BOOL) {
            writeRequestItemSize += Math.ceil((double) field.getNumberOfElements() / 8);
        } else {
            writeRequestItemSize += (field.getNumberOfElements() * field.getDataType().getSizeInBytes());
        }
        // If it's an odd number of bytes, add one to make it even
        if (writeRequestItemSize % 2 == 1) {
            writeRequestItemSize++;
        }
        int writeResponseItemSize = 4;
        // If adding the item would not exceed the sizes, add it to the current request.
        if (((curRequestSize + writeRequestItemSize) <= s7DriverContext.getPduSize()) && ((curResponseSize + writeResponseItemSize) <= s7DriverContext.getPduSize())) {
            // Increase the current request sizes.
            curRequestSize += writeRequestItemSize;
            curResponseSize += writeResponseItemSize;
        // Add the item.
        } else // If adding them would exceed, start a new request.
        {
            // Create a new PlcWriteRequest containing the current field item.
            processedRequests.add(new DefaultPlcWriteRequest(((DefaultPlcWriteRequest) writeRequest).getWriter(), curFields));
            // Reset the size and item lists.
            curRequestSize = EMPTY_WRITE_REQUEST_SIZE + writeRequestItemSize;
            curResponseSize = EMPTY_WRITE_RESPONSE_SIZE + writeResponseItemSize;
            curFields = new LinkedHashMap<>();
            // Splitting of huge fields not yet implemented, throw an exception instead.
            if (((curRequestSize + writeRequestItemSize) > s7DriverContext.getPduSize()) && ((curResponseSize + writeResponseItemSize) > s7DriverContext.getPduSize())) {
                throw new PlcRuntimeException("Field size exceeds maximum payload for one item.");
            }
        }
        curFields.put(fieldName, new FieldValueItem(field, value));
    }
    // Create a new PlcWriteRequest from the remaining field items.
    if (!curFields.isEmpty()) {
        processedRequests.add(new DefaultPlcWriteRequest(((DefaultPlcWriteRequest) writeRequest).getWriter(), curFields));
    }
    return processedRequests;
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) FieldValueItem(org.apache.plc4x.java.spi.messages.utils.FieldValueItem) DefaultPlcWriteRequest(org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest) PlcValue(org.apache.plc4x.java.api.value.PlcValue) S7DriverContext(org.apache.plc4x.java.s7.readwrite.context.S7DriverContext) S7Field(org.apache.plc4x.java.s7.readwrite.field.S7Field)

Example 2 with S7DriverContext

use of org.apache.plc4x.java.s7.readwrite.context.S7DriverContext 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;
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcField(org.apache.plc4x.java.api.model.PlcField) S7DriverContext(org.apache.plc4x.java.s7.readwrite.context.S7DriverContext) DefaultPlcReadRequest(org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest) S7Field(org.apache.plc4x.java.s7.readwrite.field.S7Field)

Aggregations

PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)2 S7DriverContext (org.apache.plc4x.java.s7.readwrite.context.S7DriverContext)2 S7Field (org.apache.plc4x.java.s7.readwrite.field.S7Field)2 PlcField (org.apache.plc4x.java.api.model.PlcField)1 PlcValue (org.apache.plc4x.java.api.value.PlcValue)1 DefaultPlcReadRequest (org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest)1 DefaultPlcWriteRequest (org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest)1 FieldValueItem (org.apache.plc4x.java.spi.messages.utils.FieldValueItem)1