Search in sources :

Example 1 with PlcValue

use of org.apache.plc4x.java.api.value.PlcValue in project plc4x by apache.

the class CANOpenProtocolLogic method writeInternally.

private void writeInternally(DefaultPlcWriteRequest writeRequest, CANOpenPDOField field, CompletableFuture<PlcWriteResponse> response) {
    PlcValue writeValue = writeRequest.getPlcValues().get(0);
    try {
        String fieldName = writeRequest.getFieldNames().iterator().next();
        WriteBufferByteBased writeBuffer = new WriteBufferByteBased(DataItem.getLengthInBytes(writeValue, field.getCanOpenDataType(), writeValue.getLength()), ByteOrder.LITTLE_ENDIAN);
        DataItem.staticSerialize(writeBuffer, writeValue, field.getCanOpenDataType(), writeValue.getLength(), ByteOrder.LITTLE_ENDIAN);
        final CANOpenPDOPayload payload = new CANOpenPDOPayload(new CANOpenPDO(writeBuffer.getData()));
        context.sendToWire(new CANOpenFrame((short) field.getNodeId(), field.getService(), payload));
        response.complete(new DefaultPlcWriteResponse(writeRequest, Collections.singletonMap(fieldName, PlcResponseCode.OK)));
    } catch (Exception e) {
        response.completeExceptionally(e);
    }
}
Also used : PlcValue(org.apache.plc4x.java.api.value.PlcValue) CANOpenPDO(org.apache.plc4x.java.canopen.readwrite.CANOpenPDO) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse) CANOpenPDOPayload(org.apache.plc4x.java.canopen.readwrite.CANOpenPDOPayload) CANOpenAbortException(org.apache.plc4x.java.canopen.transport.CANOpenAbortException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) CANOpenFrame(org.apache.plc4x.java.canopen.readwrite.CANOpenFrame)

Example 2 with PlcValue

use of org.apache.plc4x.java.api.value.PlcValue in project plc4x by apache.

the class Plc4x2AdsProtocol method decodeReadResponse.

@SuppressWarnings("unchecked")
private InternalPlcResponse decodeReadResponse(AdsReadResponse responseMessage, PlcRequestContainer<InternalPlcRequest, InternalPlcResponse> requestContainer) {
    InternalPlcReadRequest plcReadRequest = (InternalPlcReadRequest) requestContainer.getRequest();
    // TODO: only single requests supported for now
    AdsField field = (AdsField) plcReadRequest.getFields().get(0);
    PlcResponseCode responseCode = decodeResponseCode(responseMessage.getResult());
    byte[] bytes = responseMessage.getData().getBytes();
    PlcValue value = decodeData(field.getAdsDataType(), bytes);
    // TODO: does every item has the same ads response or is this whole aggregation broken?
    Map<String, Pair<PlcResponseCode, PlcValue>> responseItems = plcReadRequest.getFieldNames().stream().collect(Collectors.toMap(fieldName -> fieldName, ignore -> Pair.of(responseCode, value)));
    return new DefaultPlcReadResponse(plcReadRequest, responseItems);
}
Also used : DirectAdsField(org.apache.plc4x.java.ads.model.DirectAdsField) PlcIoException(org.apache.plc4x.java.api.exceptions.PlcIoException) PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) PlcRequest(org.apache.plc4x.java.api.messages.PlcRequest) LoggerFactory(org.slf4j.LoggerFactory) PlcValue(org.apache.plc4x.java.api.value.PlcValue) ConcurrentMap(java.util.concurrent.ConcurrentMap) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) AdsException(org.apache.plc4x.java.ads.protocol.exception.AdsException) PlcException(org.apache.plc4x.java.api.exceptions.PlcException) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) LittleEndianEncoder.encodeData(org.apache.plc4x.java.ads.protocol.util.LittleEndianEncoder.encodeData) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) org.apache.plc4x.java.ads.api.commands(org.apache.plc4x.java.ads.api.commands) PlcList(org.apache.plc4x.java.api.value.PlcList) LinkedList(java.util.LinkedList) AdsDataType(org.apache.plc4x.java.ads.model.AdsDataType) Invoke(org.apache.plc4x.java.ads.api.generic.types.Invoke) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) AmsPacket(org.apache.plc4x.java.ads.api.generic.AmsPacket) Logger(org.slf4j.Logger) AmsNetId(org.apache.plc4x.java.ads.api.generic.types.AmsNetId) PlcProtocolPayloadTooBigException(org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException) org.apache.plc4x.java.ads.api.commands.types(org.apache.plc4x.java.ads.api.commands.types) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IOException(java.io.IOException) org.apache.plc4x.java.spi.messages(org.apache.plc4x.java.spi.messages) SymbolicAdsField(org.apache.plc4x.java.ads.model.SymbolicAdsField) Collectors(java.util.stream.Collectors) PlcField(org.apache.plc4x.java.api.model.PlcField) MessageToMessageCodec(io.netty.handler.codec.MessageToMessageCodec) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) AmsPort(org.apache.plc4x.java.ads.api.generic.types.AmsPort) AdsField(org.apache.plc4x.java.ads.model.AdsField) PlcValue(org.apache.plc4x.java.api.value.PlcValue) DirectAdsField(org.apache.plc4x.java.ads.model.DirectAdsField) SymbolicAdsField(org.apache.plc4x.java.ads.model.SymbolicAdsField) AdsField(org.apache.plc4x.java.ads.model.AdsField) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) Pair(org.apache.commons.lang3.tuple.Pair)

Example 3 with PlcValue

use of org.apache.plc4x.java.api.value.PlcValue in project plc4x by apache.

the class Plc4x2AdsProtocol method encodeWriteRequest.

private void encodeWriteRequest(PlcRequestContainer<InternalPlcRequest, InternalPlcResponse> msg, List<Object> out) throws PlcException {
    InternalPlcWriteRequest writeRequest = (InternalPlcWriteRequest) msg.getRequest();
    if (writeRequest.getFields().size() != 1) {
        throw new PlcProtocolException("Only one item supported");
    }
    PlcField field = writeRequest.getFields().get(0);
    if (field instanceof SymbolicAdsField) {
        DirectAdsField mappedField = fieldMapping.get(field);
        LOGGER.debug("Replacing {} with {}", field, mappedField);
        field = mappedField;
    }
    if (!(field instanceof DirectAdsField)) {
        throw new PlcProtocolException("PlcField not of type DirectAdsField: " + field.getClass());
    }
    DirectAdsField directAdsField = (DirectAdsField) field;
    Invoke invokeId = Invoke.of(correlationBuilder.incrementAndGet());
    IndexGroup indexGroup = IndexGroup.of(directAdsField.getIndexGroup());
    IndexOffset indexOffset = IndexOffset.of(directAdsField.getIndexOffset());
    Object[] plcValues;
    PlcValue plcValue = writeRequest.getPlcValues().get(0);
    if (plcValue instanceof PlcList) {
        plcValues = ((PlcList) plcValue).getList().toArray(new Object[0]);
    } else {
        plcValues = new Object[] { plcValue.getObject() };
    }
    byte[] bytes = encodeData(directAdsField.getAdsDataType(), plcValues);
    int bytesToBeWritten = bytes.length;
    int maxTheoreticalSize = directAdsField.getAdsDataType().getTargetByteSize() * directAdsField.getNumberOfElements();
    if (bytesToBeWritten > maxTheoreticalSize) {
        LOGGER.debug("Requested AdsDatatype {} is exceeded by number of bytes {}. Limit {}.", directAdsField.getAdsDataType(), bytesToBeWritten, maxTheoreticalSize);
        throw new PlcProtocolPayloadTooBigException("ADS", maxTheoreticalSize, bytesToBeWritten, plcValues);
    }
    Data data = Data.of(bytes);
    AmsPacket amsPacket = AdsWriteRequest.of(targetAmsNetId, targetAmsPort, sourceAmsNetId, sourceAmsPort, invokeId, indexGroup, indexOffset, data);
    LOGGER.debug("encoded write request {}", amsPacket);
    out.add(amsPacket);
    requests.put(invokeId.getAsLong(), msg);
}
Also used : PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) SymbolicAdsField(org.apache.plc4x.java.ads.model.SymbolicAdsField) PlcField(org.apache.plc4x.java.api.model.PlcField) LittleEndianEncoder.encodeData(org.apache.plc4x.java.ads.protocol.util.LittleEndianEncoder.encodeData) Invoke(org.apache.plc4x.java.ads.api.generic.types.Invoke) PlcList(org.apache.plc4x.java.api.value.PlcList) PlcValue(org.apache.plc4x.java.api.value.PlcValue) DirectAdsField(org.apache.plc4x.java.ads.model.DirectAdsField) PlcProtocolPayloadTooBigException(org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException) AmsPacket(org.apache.plc4x.java.ads.api.generic.AmsPacket)

Example 4 with PlcValue

use of org.apache.plc4x.java.api.value.PlcValue in project plc4x by apache.

the class SimulatedConnection method read.

@Override
public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
    Map<String, ResponseItem<PlcValue>> fields = new HashMap<>();
    for (String fieldName : readRequest.getFieldNames()) {
        SimulatedField field = (SimulatedField) readRequest.getField(fieldName);
        Optional<PlcValue> valueOptional = device.get(field);
        ResponseItem<PlcValue> fieldPair;
        boolean present = valueOptional.isPresent();
        fieldPair = present ? new ResponseItem<>(PlcResponseCode.OK, valueOptional.get()) : new ResponseItem<>(PlcResponseCode.NOT_FOUND, null);
        fields.put(fieldName, fieldPair);
    }
    PlcReadResponse response = new DefaultPlcReadResponse(readRequest, fields);
    return CompletableFuture.completedFuture(response);
}
Also used : PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) PlcValue(org.apache.plc4x.java.api.value.PlcValue) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) SimulatedField(org.apache.plc4x.java.simulated.field.SimulatedField)

Example 5 with PlcValue

use of org.apache.plc4x.java.api.value.PlcValue 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)

Aggregations

PlcValue (org.apache.plc4x.java.api.value.PlcValue)50 PlcList (org.apache.plc4x.java.spi.values.PlcList)19 PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)16 ResponseItem (org.apache.plc4x.java.spi.messages.utils.ResponseItem)15 CompletableFuture (java.util.concurrent.CompletableFuture)12 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)12 Logger (org.slf4j.Logger)12 LoggerFactory (org.slf4j.LoggerFactory)12 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)10 Consumer (java.util.function.Consumer)9 PlcField (org.apache.plc4x.java.api.model.PlcField)9 DefaultPlcReadResponse (org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse)9 PlcSubscriptionHandle (org.apache.plc4x.java.api.model.PlcSubscriptionHandle)8 RequestTransactionManager (org.apache.plc4x.java.spi.transaction.RequestTransactionManager)8 BigInteger (java.math.BigInteger)7 Map (java.util.Map)7 ConversationContext (org.apache.plc4x.java.spi.ConversationContext)7 Duration (java.time.Duration)6 java.util (java.util)6 Plc4xProtocolBase (org.apache.plc4x.java.spi.Plc4xProtocolBase)6