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;
}
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;
}
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");
}
Aggregations