Search in sources :

Example 1 with PlcNull

use of org.apache.plc4x.java.spi.values.PlcNull in project plc4x by apache.

the class S7ProtocolLogic method decodeReadResponse.

private PlcResponse decodeReadResponse(S7Message responseMessage, PlcReadRequest plcReadRequest) throws PlcProtocolException {
    Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
    short errorClass;
    short errorCode;
    if (responseMessage instanceof S7MessageResponseData) {
        S7MessageResponseData messageResponseData = (S7MessageResponseData) responseMessage;
        errorClass = messageResponseData.getErrorClass();
        errorCode = messageResponseData.getErrorCode();
    } else if (responseMessage instanceof S7MessageResponse) {
        S7MessageResponse messageResponse = (S7MessageResponse) responseMessage;
        errorClass = messageResponse.getErrorClass();
        errorCode = messageResponse.getErrorCode();
    } else {
        throw new PlcProtocolException("Unsupported message type " + responseMessage.getClass().getName());
    }
    // If the result contains any form of non-null error code, handle this instead.
    if ((errorClass != 0) || (errorCode != 0)) {
        // This is usually the case if PUT/GET wasn't enabled on the PLC
        if ((errorClass == 129) && (errorCode == 4)) {
            logger.warn("Got an error response from the PLC. This particular response code usually indicates " + "that PUT/GET is not enabled on the PLC.");
            for (String fieldName : plcReadRequest.getFieldNames()) {
                ResponseItem<PlcValue> result = new ResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull());
                values.put(fieldName, result);
            }
            return new DefaultPlcReadResponse(plcReadRequest, values);
        } else {
            logger.warn("Got an unknown error response from the PLC. Error Class: {}, Error Code {}. " + "We probably need to implement explicit handling for this, so please file a bug-report " + "on https://issues.apache.org/jira/projects/PLC4X and ideally attach a WireShark dump " + "containing a capture of the communication.", errorClass, errorCode);
            for (String fieldName : plcReadRequest.getFieldNames()) {
                ResponseItem<PlcValue> result = new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, new PlcNull());
                values.put(fieldName, result);
            }
            return new DefaultPlcReadResponse(plcReadRequest, values);
        }
    }
    // In all other cases all went well.
    S7PayloadReadVarResponse payload = (S7PayloadReadVarResponse) responseMessage.getPayload();
    // items from the request as this information is not returned by the PLC.
    if (plcReadRequest.getNumberOfFields() != payload.getItems().size()) {
        throw new PlcProtocolException("The number of requested items doesn't match the number of returned items");
    }
    List<S7VarPayloadDataItem> payloadItems = payload.getItems();
    int index = 0;
    for (String fieldName : plcReadRequest.getFieldNames()) {
        S7Field field = (S7Field) plcReadRequest.getField(fieldName);
        S7VarPayloadDataItem payloadItem = payloadItems.get(index);
        PlcResponseCode responseCode = decodeResponseCode(payloadItem.getReturnCode());
        PlcValue plcValue = null;
        ByteBuf data = Unpooled.wrappedBuffer(payloadItem.getData());
        if (responseCode == PlcResponseCode.OK) {
            try {
                plcValue = parsePlcValue(field, data);
            } catch (Exception e) {
                throw new PlcProtocolException("Error decoding PlcValue", e);
            }
        }
        ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
        values.put(fieldName, result);
        index++;
    }
    return new DefaultPlcReadResponse(plcReadRequest, values);
}
Also used : PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) ByteBuf(io.netty.buffer.ByteBuf) TimeoutException(java.util.concurrent.TimeoutException) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) PlcValue(org.apache.plc4x.java.api.value.PlcValue) PlcNull(org.apache.plc4x.java.spi.values.PlcNull) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) S7Field(org.apache.plc4x.java.s7.readwrite.field.S7Field)

Example 2 with PlcNull

use of org.apache.plc4x.java.spi.values.PlcNull in project plc4x by apache.

the class CANOpenProtocolLogic method publishEvent.

private void publishEvent(CANOpenService service, int nodeId, CANOpenPayload payload) {
    DefaultPlcSubscriptionHandle dispatchedHandle = null;
    for (Map.Entry<DefaultPlcConsumerRegistration, Consumer<PlcSubscriptionEvent>> entry : consumers.entrySet()) {
        DefaultPlcConsumerRegistration registration = entry.getKey();
        Consumer<PlcSubscriptionEvent> consumer = entry.getValue();
        for (PlcSubscriptionHandle handler : registration.getSubscriptionHandles()) {
            CANOpenSubscriptionHandle handle = (CANOpenSubscriptionHandle) handler;
            if (payload instanceof CANOpenPDOPayload) {
                if (handle.matches(service, nodeId)) {
                    logger.trace("Dispatching notification {} for node {} to {}", service, nodeId, handle);
                    dispatchedHandle = handle;
                    CANOpenPDOField field = (CANOpenPDOField) handle.getField();
                    byte[] data = ((CANOpenPDOPayload) payload).getPdo().getData();
                    try {
                        PlcValue value = DataItem.staticParse(new ReadBufferByteBased(data, ByteOrder.LITTLE_ENDIAN), field.getCanOpenDataType(), data.length);
                        DefaultPlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), Collections.singletonMap(handle.getName(), new ResponseItem<>(PlcResponseCode.OK, value)));
                        consumer.accept(event);
                    } catch (ParseException e) {
                        logger.warn("Could not parse data to desired type: {}", field.getCanOpenDataType(), e);
                        DefaultPlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), Collections.singletonMap(handle.getName(), new ResponseItem<>(PlcResponseCode.INVALID_DATA, new PlcNull())));
                        consumer.accept(event);
                    }
                }
            } else if (payload instanceof CANOpenHeartbeatPayload) {
                if (handle.matches(service, nodeId)) {
                    logger.trace("Dispatching notification {} for node {} to {}", service, nodeId, handle);
                    dispatchedHandle = handle;
                    final NMTState state = ((CANOpenHeartbeatPayload) payload).getState();
                    Map<String, PlcValue> fields = new HashMap<>();
                    fields.put("state", new PlcUSINT(state.getValue()));
                    fields.put("node", new PlcUSINT(nodeId));
                    PlcStruct struct = new PlcStruct(fields);
                    DefaultPlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), Collections.singletonMap(handle.getName(), new ResponseItem<>(PlcResponseCode.OK, struct)));
                    consumer.accept(event);
                }
            } else if (payload instanceof CANOpenNetworkPayload) {
                if (handle.matches(service, nodeId)) {
                    logger.trace("Dispatching notification {} for node {} to {}", service, nodeId, handle);
                    dispatchedHandle = handle;
                    final NMTStateRequest state = ((CANOpenNetworkPayload) payload).getRequest();
                    Map<String, PlcValue> fields = new HashMap<>();
                    fields.put("state", new PlcUSINT(state.getValue()));
                    fields.put("node", new PlcUSINT(nodeId));
                    PlcStruct struct = new PlcStruct(fields);
                    DefaultPlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), Collections.singletonMap(handle.getName(), new ResponseItem<>(PlcResponseCode.OK, struct)));
                    consumer.accept(event);
                }
            }
        }
    }
    if (dispatchedHandle == null) {
        logger.trace("Could not find subscription matching {} and node {}", service, nodeId);
    }
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) PlcUSINT(org.apache.plc4x.java.spi.values.PlcUSINT) DefaultPlcSubscriptionEvent(org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent) DefaultPlcSubscriptionHandle(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle) Consumer(java.util.function.Consumer) PlcStruct(org.apache.plc4x.java.spi.values.PlcStruct) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) DefaultPlcConsumerRegistration(org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration) NMTState(org.apache.plc4x.java.canopen.readwrite.NMTState) CANOpenPDOPayload(org.apache.plc4x.java.canopen.readwrite.CANOpenPDOPayload) DefaultPlcSubscriptionEvent(org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent) PlcSubscriptionEvent(org.apache.plc4x.java.api.messages.PlcSubscriptionEvent) PlcSubscriptionHandle(org.apache.plc4x.java.api.model.PlcSubscriptionHandle) DefaultPlcSubscriptionHandle(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle) NMTStateRequest(org.apache.plc4x.java.canopen.readwrite.NMTStateRequest) CANOpenNetworkPayload(org.apache.plc4x.java.canopen.readwrite.CANOpenNetworkPayload) PlcValue(org.apache.plc4x.java.api.value.PlcValue) CANOpenPDOField(org.apache.plc4x.java.canopen.field.CANOpenPDOField) CANOpenHeartbeatPayload(org.apache.plc4x.java.canopen.readwrite.CANOpenHeartbeatPayload) PlcNull(org.apache.plc4x.java.spi.values.PlcNull) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

PlcValue (org.apache.plc4x.java.api.value.PlcValue)2 ResponseItem (org.apache.plc4x.java.spi.messages.utils.ResponseItem)2 PlcNull (org.apache.plc4x.java.spi.values.PlcNull)2 ByteBuf (io.netty.buffer.ByteBuf)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 TimeoutException (java.util.concurrent.TimeoutException)1 Consumer (java.util.function.Consumer)1 PlcProtocolException (org.apache.plc4x.java.api.exceptions.PlcProtocolException)1 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)1 PlcSubscriptionEvent (org.apache.plc4x.java.api.messages.PlcSubscriptionEvent)1 PlcSubscriptionHandle (org.apache.plc4x.java.api.model.PlcSubscriptionHandle)1 PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)1 CANOpenPDOField (org.apache.plc4x.java.canopen.field.CANOpenPDOField)1 CANOpenHeartbeatPayload (org.apache.plc4x.java.canopen.readwrite.CANOpenHeartbeatPayload)1 CANOpenNetworkPayload (org.apache.plc4x.java.canopen.readwrite.CANOpenNetworkPayload)1 CANOpenPDOPayload (org.apache.plc4x.java.canopen.readwrite.CANOpenPDOPayload)1 NMTState (org.apache.plc4x.java.canopen.readwrite.NMTState)1