Search in sources :

Example 1 with PlcField

use of org.apache.plc4x.java.api.model.PlcField in project plc4x by apache.

the class CANOpenProtocolLogic method read.

public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
    CompletableFuture<PlcReadResponse> response = new CompletableFuture<>();
    if (readRequest.getFieldNames().size() != 1) {
        response.completeExceptionally(new IllegalArgumentException("SDO requires single field to be read"));
        return response;
    }
    PlcField field = readRequest.getFields().get(0);
    if (!(field instanceof CANOpenField)) {
        response.completeExceptionally(new IllegalArgumentException("Only CANOpenField instances are supported"));
        return response;
    }
    if (!(field instanceof CANOpenSDOField)) {
        response.completeExceptionally(new IllegalArgumentException("Only CANOpenSDOField instances are supported"));
        return response;
    }
    ;
    readInternally(readRequest, (CANOpenSDOField) field, response);
    return response;
}
Also used : PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) CompletableFuture(java.util.concurrent.CompletableFuture) CANOpenField(org.apache.plc4x.java.canopen.field.CANOpenField) CANOpenSDOField(org.apache.plc4x.java.canopen.field.CANOpenSDOField) PlcField(org.apache.plc4x.java.api.model.PlcField)

Example 2 with PlcField

use of org.apache.plc4x.java.api.model.PlcField in project plc4x by apache.

the class CANOpenProtocolLogic method write.

public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
    CompletableFuture<PlcWriteResponse> response = new CompletableFuture<>();
    if (writeRequest.getFieldNames().size() != 1) {
        response.completeExceptionally(new IllegalArgumentException("You can write only one field at the time"));
        return response;
    }
    PlcField field = writeRequest.getFields().get(0);
    if (!(field instanceof CANOpenField)) {
        response.completeExceptionally(new IllegalArgumentException("Only CANOpenField instances are supported"));
        return response;
    }
    if (field instanceof CANOpenSDOField) {
        writeInternally((DefaultPlcWriteRequest) writeRequest, (CANOpenSDOField) field, response);
        return response;
    }
    if (field instanceof CANOpenPDOField) {
        writeInternally((DefaultPlcWriteRequest) writeRequest, (CANOpenPDOField) field, response);
        return response;
    }
    response.completeExceptionally(new IllegalArgumentException("Only CANOpenSDOField instances are supported"));
    return response;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) CANOpenPDOField(org.apache.plc4x.java.canopen.field.CANOpenPDOField) CANOpenField(org.apache.plc4x.java.canopen.field.CANOpenField) CANOpenSDOField(org.apache.plc4x.java.canopen.field.CANOpenSDOField) PlcField(org.apache.plc4x.java.api.model.PlcField) PlcWriteResponse(org.apache.plc4x.java.api.messages.PlcWriteResponse) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse)

Example 3 with PlcField

use of org.apache.plc4x.java.api.model.PlcField in project plc4x by apache.

the class FirmataDriverContext method processSubscriptionRequest.

public List<FirmataMessage> processSubscriptionRequest(PlcSubscriptionRequest subscriptionRequest) {
    // Convert the request into maps of bit sets.
    Map<Integer, PinMode> requestDigitalFieldPinModes = new HashMap<>();
    Map<Integer, PinMode> requestAnalogFieldPinModes = new HashMap<>();
    for (String fieldName : subscriptionRequest.getFieldNames()) {
        final PlcField field = subscriptionRequest.getField(fieldName);
        DefaultPlcSubscriptionField subscriptionField = (DefaultPlcSubscriptionField) field;
        if (subscriptionField.getPlcField() instanceof FirmataFieldDigital) {
            FirmataFieldDigital fieldDigital = (FirmataFieldDigital) subscriptionField.getPlcField();
            PinMode fieldPinMode = (fieldDigital.getPinMode() != null) ? fieldDigital.getPinMode() : PinMode.PinModeInput;
            if (!(fieldPinMode.equals(PinMode.PinModeInput) || fieldPinMode.equals(PinMode.PinModePullup))) {
                throw new PlcInvalidFieldException("Subscription field must be of type 'INPUT' (default) or 'PULLUP'");
            }
            for (int pin = fieldDigital.getAddress(); pin < fieldDigital.getAddress() + fieldDigital.getNumberOfElements(); pin++) {
                requestDigitalFieldPinModes.put(pin, fieldPinMode);
            }
        } else if (subscriptionField.getPlcField() instanceof FirmataFieldAnalog) {
            FirmataFieldAnalog fieldAnalog = (FirmataFieldAnalog) subscriptionField.getPlcField();
            for (int pin = fieldAnalog.getAddress(); pin < fieldAnalog.getAddress() + fieldAnalog.getNumberOfElements(); pin++) {
                requestAnalogFieldPinModes.put(pin, PinMode.PinModeInput);
            }
        } else {
            throw new PlcRuntimeException("Unsupported field type " + field.getClass().getSimpleName());
        }
    }
    // If a requested digital pin is already subscribed, blank this out
    for (Map.Entry<Integer, PinMode> entry : requestDigitalFieldPinModes.entrySet()) {
        int pin = entry.getKey();
        PinMode pinMode = entry.getValue();
        if (digitalPins.containsKey(pin)) {
            if (!digitalPins.get(pin).equals(pinMode)) {
                throw new PlcInvalidFieldException(String.format("Error setting digital pin to mode %s, pin is already set to mode %s", pinMode.toString(), digitalPins.get(pin).toString()));
            } else {
                requestDigitalFieldPinModes.remove(pin);
            }
        }
    }
    // If a requested analog pin is already subscribed, blank this out
    for (Map.Entry<Integer, PinMode> entry : requestAnalogFieldPinModes.entrySet()) {
        int pin = entry.getKey();
        if (analogPins.containsKey(pin)) {
            requestAnalogFieldPinModes.remove(pin);
        }
    }
    // Remember the subscription itself.
    subscriptions.add(subscriptionRequest);
    // Create a list of messages that need to be sent to achieve the desired subscriptions.
    List<FirmataMessage> messages = new LinkedList<>();
    for (Map.Entry<Integer, PinMode> entry : requestDigitalFieldPinModes.entrySet()) {
        int pin = entry.getKey();
        PinMode pinMode = entry.getValue();
        // Digital pins can be input and output, so first we have to set it to "input"
        messages.add(new FirmataMessageCommand(new FirmataCommandSetPinMode((byte) pin, pinMode, false), false));
        // And then tell the remote to send change of state information.
        messages.add(new FirmataMessageSubscribeDigitalPinValue((byte) pin, true, false));
    }
    for (Map.Entry<Integer, PinMode> entry : requestAnalogFieldPinModes.entrySet()) {
        int pin = entry.getKey();
        // Tell the remote to send change of state information for this analog pin.
        messages.add(new FirmataMessageSubscribeAnalogPinValue((byte) pin, true, false));
    }
    return messages;
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcField(org.apache.plc4x.java.api.model.PlcField) DefaultPlcSubscriptionField(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField) PlcInvalidFieldException(org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException) FirmataFieldDigital(org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldDigital) FirmataFieldAnalog(org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldAnalog)

Example 4 with PlcField

use of org.apache.plc4x.java.api.model.PlcField in project plc4x by apache.

the class PlcConnectionAdapterTest method checkRead.

private <T> void checkRead(MockConnection connection, PlcReadRequest request, T value) throws InterruptedException, ExecutionException {
    // this is really a tests of our mock tooling but knowing it's behaving as expected
    // will help identify problems in the adapter/supplier/consumer
    PlcField plcField = request.getFields().get(0);
    // TODO: smart value conversion
    connection.setPlcValue(plcField, new PlcLong(0L));
    CompletableFuture<PlcReadResponse> cf = connection.read(request);
    assertThat(cf.isDone(), is(true));
    PlcReadResponse response = cf.get();
// TODO: fixme
// assertThat(value, equalTo(response.getResponseItems().get(0).getValues().get(0)));
}
Also used : PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) PlcField(org.apache.plc4x.java.api.model.PlcField)

Example 5 with PlcField

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

Aggregations

PlcField (org.apache.plc4x.java.api.model.PlcField)27 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)8 DefaultPlcSubscriptionField (org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField)8 CompletableFuture (java.util.concurrent.CompletableFuture)7 PlcValue (org.apache.plc4x.java.api.value.PlcValue)6 PlcReadRequest (org.apache.plc4x.java.api.messages.PlcReadRequest)5 Duration (java.time.Duration)4 org.apache.plc4x.java.api.messages (org.apache.plc4x.java.api.messages)4 PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)4 ConversationContext (org.apache.plc4x.java.spi.ConversationContext)4 ResponseItem (org.apache.plc4x.java.spi.messages.utils.ResponseItem)4 RequestTransactionManager (org.apache.plc4x.java.spi.transaction.RequestTransactionManager)4 Logger (org.slf4j.Logger)4 LoggerFactory (org.slf4j.LoggerFactory)4 BigInteger (java.math.BigInteger)3 Instant (java.time.Instant)3 java.util (java.util)3 ArrayList (java.util.ArrayList)3 Map (java.util.Map)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3