Search in sources :

Example 1 with FieldValueItem

use of org.apache.plc4x.java.spi.messages.utils.FieldValueItem 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 FieldValueItem

use of org.apache.plc4x.java.spi.messages.utils.FieldValueItem in project plc4x by apache.

the class SingleFieldOptimizer method processWriteRequest.

@Override
protected List<PlcRequest> processWriteRequest(PlcWriteRequest writeRequest, DriverContext driverContext) {
    if (writeRequest.getNumberOfFields() == 1) {
        return Collections.singletonList(writeRequest);
    }
    List<PlcRequest> subRequests = new ArrayList<>(writeRequest.getNumberOfFields());
    for (String fieldName : writeRequest.getFieldNames()) {
        PlcField field = writeRequest.getField(fieldName);
        PlcValue value = writeRequest.getPlcValue(fieldName);
        PlcWriteRequest subRequest = new DefaultPlcWriteRequest(((DefaultPlcWriteRequest) writeRequest).getWriter(), new LinkedHashMap<>(Collections.singletonMap(fieldName, new FieldValueItem(field, value))));
        subRequests.add(subRequest);
    }
    return subRequests;
}
Also used : PlcValue(org.apache.plc4x.java.api.value.PlcValue) PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) DefaultPlcWriteRequest(org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest) FieldValueItem(org.apache.plc4x.java.spi.messages.utils.FieldValueItem) PlcRequest(org.apache.plc4x.java.api.messages.PlcRequest) ArrayList(java.util.ArrayList) PlcField(org.apache.plc4x.java.api.model.PlcField) DefaultPlcWriteRequest(org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest)

Example 3 with FieldValueItem

use of org.apache.plc4x.java.spi.messages.utils.FieldValueItem in project plc4x by apache.

the class DefaultPlcWriteRequest method serialize.

@Override
public void serialize(WriteBuffer writeBuffer) throws SerializationException {
    writeBuffer.pushContext("PlcWriteRequest");
    writeBuffer.pushContext("fields");
    for (Map.Entry<String, FieldValueItem> fieldEntry : fields.entrySet()) {
        FieldValueItem fieldValueItem = fieldEntry.getValue();
        String fieldName = fieldEntry.getKey();
        writeBuffer.pushContext(fieldName);
        PlcField field = fieldValueItem.getField();
        if (!(field instanceof Serializable)) {
            throw new RuntimeException("Error serializing. Field doesn't implement XmlSerializable");
        }
        ((Serializable) field).serialize(writeBuffer);
        final PlcValue value = fieldValueItem.getValue();
        if (value instanceof PlcList) {
            PlcList list = (PlcList) value;
            for (PlcValue plcValue : list.getList()) {
                String plcValueString = plcValue.getString();
                writeBuffer.writeString("value", plcValueString.getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), plcValueString);
            }
        } else {
            String plcValueString = value.getString();
            writeBuffer.writeString("value", plcValueString.getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), plcValueString);
        }
        writeBuffer.popContext(fieldName);
    }
    writeBuffer.popContext("fields");
    writeBuffer.popContext("PlcWriteRequest");
}
Also used : PlcList(org.apache.plc4x.java.spi.values.PlcList) Serializable(org.apache.plc4x.java.spi.utils.Serializable) PlcValue(org.apache.plc4x.java.api.value.PlcValue) FieldValueItem(org.apache.plc4x.java.spi.messages.utils.FieldValueItem) PlcField(org.apache.plc4x.java.api.model.PlcField) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) TreeMap(java.util.TreeMap)

Aggregations

PlcValue (org.apache.plc4x.java.api.value.PlcValue)3 FieldValueItem (org.apache.plc4x.java.spi.messages.utils.FieldValueItem)3 PlcField (org.apache.plc4x.java.api.model.PlcField)2 DefaultPlcWriteRequest (org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest)2 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)1 PlcRequest (org.apache.plc4x.java.api.messages.PlcRequest)1 PlcWriteRequest (org.apache.plc4x.java.api.messages.PlcWriteRequest)1 S7DriverContext (org.apache.plc4x.java.s7.readwrite.context.S7DriverContext)1 S7Field (org.apache.plc4x.java.s7.readwrite.field.S7Field)1 Serializable (org.apache.plc4x.java.spi.utils.Serializable)1 PlcList (org.apache.plc4x.java.spi.values.PlcList)1