Search in sources :

Example 1 with S7SubscriptionField

use of org.apache.plc4x.java.s7.readwrite.field.S7SubscriptionField in project plc4x by apache.

the class S7ProtocolLogic method encodeEventSubcriptionRequest.

private void encodeEventSubcriptionRequest(DefaultPlcSubscriptionRequest request, List<S7ParameterUserDataItem> parameterItems, List<S7PayloadUserDataItem> payloadItems) {
    byte subsevent = 0;
    for (String fieldName : request.getFieldNames()) {
        if (request.getField(fieldName) instanceof DefaultPlcSubscriptionField) {
            PlcField event = ((DefaultPlcSubscriptionField) request.getField(fieldName)).getPlcField();
            if (event instanceof S7SubscriptionField) {
                subsevent = (byte) (subsevent | ((S7SubscriptionField) event).getEventType().getValue());
            }
        }
    }
    S7ParameterUserDataItemCPUFunctions parameter = new S7ParameterUserDataItemCPUFunctions(// Method
    (short) 0x11, // FunctionType
    (byte) 0x04, // FunctionGroup
    (byte) 0x04, // SubFunction
    (short) 0x02, // SequenceNumber
    (short) 0x00, // DataUnitReferenceNumber
    null, // LastDataUnit
    null, // errorCode
    null);
    parameterItems.clear();
    parameterItems.add(parameter);
    S7PayloadUserDataItemCpuFunctionMsgSubscription payload = null;
    if (subsevent > 0) {
        payload = new S7PayloadUserDataItemCpuFunctionMsgSubscription(DataTransportErrorCode.OK, DataTransportSize.OCTET_STRING, subsevent, "HmiRtm  ", null, null);
    } else {
        // TODO: Check for ALARM_S (S7300) and ALARM_8 (S7400), maybe we need verify the CPU
        AlarmStateType alarmtype;
        if (s7DriverContext.getControllerType() == S7ControllerType.S7_400) {
            alarmtype = AlarmStateType.ALARM_INITIATE;
        } else {
            alarmtype = AlarmStateType.ALARM_S_INITIATE;
        }
        payload = new S7PayloadUserDataItemCpuFunctionMsgSubscription(DataTransportErrorCode.OK, DataTransportSize.OCTET_STRING, subsevent, "HmiRtm  ", alarmtype, (short) 0x00);
    }
    payloadItems.clear();
    payloadItems.add(payload);
}
Also used : DefaultPlcSubscriptionField(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField) S7SubscriptionField(org.apache.plc4x.java.s7.readwrite.field.S7SubscriptionField) PlcField(org.apache.plc4x.java.api.model.PlcField)

Example 2 with S7SubscriptionField

use of org.apache.plc4x.java.s7.readwrite.field.S7SubscriptionField in project plc4x by apache.

the class S7ProtocolLogic method subscribe.

@Override
public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest subscriptionRequest) {
    CompletableFuture<PlcSubscriptionResponse> future = new CompletableFuture<>();
    DefaultPlcSubscriptionRequest request = (DefaultPlcSubscriptionRequest) subscriptionRequest;
    List<S7ParameterUserDataItem> parameterItems = new ArrayList<>(request.getNumberOfFields());
    List<S7PayloadUserDataItem> payloadItems = new ArrayList<>(request.getNumberOfFields());
    for (String fieldName : request.getFieldNames()) {
        final DefaultPlcSubscriptionField sf = (DefaultPlcSubscriptionField) request.getField(fieldName);
        final S7SubscriptionField field = (S7SubscriptionField) sf.getPlcField();
        switch(field.getFieldType()) {
            case EVENT_SUBSCRIPTION:
                ;
                encodeEventSubcriptionRequest(request, parameterItems, payloadItems);
                break;
            case EVENT_UNSUBSCRIPTION:
                ;
                // encodeEventUnSubcriptionRequest(msg, out);
                break;
            case ALARM_ACK:
                ;
                // encodeAlarmAckRequest(msg, out);
                break;
            case ALARM_QUERY:
                ;
                // encodeAlarmQueryRequest(msg, out);
                break;
            case CYCLIC_SUBSCRIPTION:
                ;
                // encodeCycledSubscriptionRequest(msg, out);
                break;
            case CYCLIC_UNSUBSCRIPTION:
                ;
                // encodeCycledUnSubscriptionRequest(msg, out);
                break;
            default:
                ;
        }
        ;
    // final PlcValue plcValue = request.getPlcValue(fieldName);
    // parameterItems.add(new S7VarRequestParameterItemAddress(encodeS7Address(field)));
    // payloadItems.add(serializePlcValue(field, plcValue));
    }
    final int tpduId = tpduGenerator.getAndIncrement();
    // If we've reached the max value for a 16 bit transaction identifier, reset back to 1
    if (tpduGenerator.get() == 0xFFFF) {
        tpduGenerator.set(1);
    }
    TPKTPacket tpktPacket = new TPKTPacket(new COTPPacketData(null, new S7MessageUserData(tpduId, new S7ParameterUserData(parameterItems), new S7PayloadUserData(payloadItems, null)), true, (short) tpduId, null));
    // Start a new request-transaction (Is ended in the response-handler)
    RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
    transaction.submit(() -> context.sendRequest(tpktPacket).onTimeout(new TransactionErrorCallback<>(future, transaction)).onError(new TransactionErrorCallback<>(future, transaction)).expectResponse(TPKTPacket.class, REQUEST_TIMEOUT).check(p -> p.getPayload() instanceof COTPPacketData).unwrap(p -> ((COTPPacketData) p.getPayload())).unwrap(COTPPacket::getPayload).check(p -> p.getTpduReference() == tpduId).handle(p -> {
        try {
            future.complete(((PlcSubscriptionResponse) decodeEventSubcriptionRequest(p, subscriptionRequest)));
        } catch (PlcProtocolException e) {
            logger.warn("Error sending 'write' message: '{}'", e.getMessage(), e);
        }
        // Finish the request-transaction.
        transaction.endRequest();
    }));
    return future;
}
Also used : PlcWriteResponse(org.apache.plc4x.java.api.messages.PlcWriteResponse) PlcWriteRequest(org.apache.plc4x.java.api.messages.PlcWriteRequest) DriverContext(org.apache.plc4x.java.spi.context.DriverContext) LoggerFactory(org.slf4j.LoggerFactory) PlcValue(org.apache.plc4x.java.api.value.PlcValue) TimeoutException(java.util.concurrent.TimeoutException) ByteBuffer(java.nio.ByteBuffer) PlcSubscriptionRequest(org.apache.plc4x.java.api.messages.PlcSubscriptionRequest) Unpooled(io.netty.buffer.Unpooled) DefaultPlcWriteResponse(org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse) PlcReadRequest(org.apache.plc4x.java.api.messages.PlcReadRequest) PlcSubscriptionResponse(org.apache.plc4x.java.api.messages.PlcSubscriptionResponse) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConversationContext(org.apache.plc4x.java.spi.ConversationContext) Duration(java.time.Duration) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) Plc4xProtocolBase(org.apache.plc4x.java.spi.Plc4xProtocolBase) PlcUnsubscriptionRequest(org.apache.plc4x.java.api.messages.PlcUnsubscriptionRequest) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) PlcSubscriptionHandle(org.apache.plc4x.java.api.model.PlcSubscriptionHandle) BlockingQueue(java.util.concurrent.BlockingQueue) S7PlcSubscriptionHandle(org.apache.plc4x.java.s7.readwrite.utils.S7PlcSubscriptionHandle) org.apache.plc4x.java.spi.generation(org.apache.plc4x.java.spi.generation) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) org.apache.plc4x.java.s7.readwrite(org.apache.plc4x.java.s7.readwrite) PlcNull(org.apache.plc4x.java.spi.values.PlcNull) DefaultPlcWriteRequest(org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) org.apache.plc4x.java.s7.readwrite.types(org.apache.plc4x.java.s7.readwrite.types) IntStream(java.util.stream.IntStream) S7StringField(org.apache.plc4x.java.s7.readwrite.field.S7StringField) java.util(java.util) PlcReadResponse(org.apache.plc4x.java.api.messages.PlcReadResponse) CompletableFuture(java.util.concurrent.CompletableFuture) PlcUnsubscriptionResponse(org.apache.plc4x.java.api.messages.PlcUnsubscriptionResponse) DefaultPlcReadResponse(org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse) PlcResponse(org.apache.plc4x.java.api.messages.PlcResponse) S7DriverContext(org.apache.plc4x.java.s7.readwrite.context.S7DriverContext) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) ByteBuf(io.netty.buffer.ByteBuf) DefaultPlcSubscriptionResponse(org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse) DefaultPlcSubscriptionField(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField) BiConsumer(java.util.function.BiConsumer) Logger(org.slf4j.Logger) DefaultPlcUnsubscriptionRequest(org.apache.plc4x.java.spi.messages.DefaultPlcUnsubscriptionRequest) PlcField(org.apache.plc4x.java.api.model.PlcField) IEC61131ValueHandler(org.apache.plc4x.java.spi.values.IEC61131ValueHandler) Consumer(java.util.function.Consumer) DefaultPlcSubscriptionRequest(org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionRequest) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) S7SubscriptionField(org.apache.plc4x.java.s7.readwrite.field.S7SubscriptionField) S7Field(org.apache.plc4x.java.s7.readwrite.field.S7Field) DefaultPlcReadRequest(org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest) S7SubscriptionField(org.apache.plc4x.java.s7.readwrite.field.S7SubscriptionField) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) CompletableFuture(java.util.concurrent.CompletableFuture) DefaultPlcSubscriptionField(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField) PlcSubscriptionResponse(org.apache.plc4x.java.api.messages.PlcSubscriptionResponse) DefaultPlcSubscriptionResponse(org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse) DefaultPlcSubscriptionRequest(org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionRequest)

Example 3 with S7SubscriptionField

use of org.apache.plc4x.java.s7.readwrite.field.S7SubscriptionField in project plc4x by apache.

the class S7ProtocolLogic method decodeEventSubcriptionRequest.

private PlcSubscriptionResponse decodeEventSubcriptionRequest(S7Message responseMessage, PlcSubscriptionRequest plcSubscriptionRequest) throws PlcProtocolException {
    Map<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
    short errorClass = 0;
    short errorCode = 0;
    if (responseMessage instanceof S7MessageUserData) {
        S7MessageUserData messageUserData = (S7MessageUserData) responseMessage;
        S7PayloadUserData payload = (S7PayloadUserData) messageUserData.getPayload();
    // errorClass = payload.getItems()[0].
    // errorCode = messageUserData.getParameter().
    } 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 : plcSubscriptionRequest.getFieldNames()) {
                values.put(fieldName, null);
            }
            return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, 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 : plcSubscriptionRequest.getFieldNames()) {
                values.put(fieldName, null);
            }
            return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
        }
    }
    // In all other cases all went well.
    S7PayloadUserData payload = (S7PayloadUserData) responseMessage.getPayload();
    List<S7PayloadUserDataItem> payloadItems = payload.getItems();
    // Only one item for any number of subscription (4)
    if (payloadItems.size() == 0) {
        throw new PlcProtocolException("The number of requested items doesn't match the number of returned items");
    }
    boolean responseOk = false;
    if (payloadItems.get(0) instanceof S7PayloadUserDataItemCpuFunctionMsgSubscriptionResponse) {
        S7PayloadUserDataItemCpuFunctionMsgSubscriptionResponse item = (S7PayloadUserDataItemCpuFunctionMsgSubscriptionResponse) payloadItems.get(0);
        if ((item.getReturnCode() == DataTransportErrorCode.OK) && (item.getTransportSize() == DataTransportSize.OCTET_STRING)) {
            responseOk = true;
        }
    } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCpuFunctionMsgSubscriptionSysResponse) {
        S7PayloadUserDataItemCpuFunctionMsgSubscriptionSysResponse item = (S7PayloadUserDataItemCpuFunctionMsgSubscriptionSysResponse) payloadItems.get(0);
        if ((item.getReturnCode() == DataTransportErrorCode.OK) && (item.getTransportSize() == DataTransportSize.OCTET_STRING)) {
            responseOk = true;
        }
    } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCpuFunctionMsgSubscriptionAlarmResponse) {
        S7PayloadUserDataItemCpuFunctionMsgSubscriptionAlarmResponse item = (S7PayloadUserDataItemCpuFunctionMsgSubscriptionAlarmResponse) payloadItems.get(0);
        if ((item.getReturnCode() == DataTransportErrorCode.OK) && (item.getTransportSize() == DataTransportSize.OCTET_STRING)) {
            responseOk = true;
        }
    }
    if (responseOk) {
        for (String fieldName : plcSubscriptionRequest.getFieldNames()) {
            DefaultPlcSubscriptionField dfield = (DefaultPlcSubscriptionField) plcSubscriptionRequest.getField(fieldName);
            S7SubscriptionField field = (S7SubscriptionField) dfield.getPlcField();
            switch(field.getEventType()) {
                case MODE:
                    values.put(fieldName, new ResponseItem<>(PlcResponseCode.OK, modeHandle));
                    break;
                case SYS:
                    values.put(fieldName, new ResponseItem<>(PlcResponseCode.OK, sysHandle));
                    break;
                case USR:
                    values.put(fieldName, new ResponseItem<>(PlcResponseCode.OK, usrHandle));
                    break;
                case ALM:
                    values.put(fieldName, new ResponseItem<>(PlcResponseCode.OK, almHandle));
                    break;
            }
        }
        return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
    }
    return null;
}
Also used : S7SubscriptionField(org.apache.plc4x.java.s7.readwrite.field.S7SubscriptionField) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) DefaultPlcSubscriptionResponse(org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse) DefaultPlcSubscriptionField(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem)

Aggregations

S7SubscriptionField (org.apache.plc4x.java.s7.readwrite.field.S7SubscriptionField)3 DefaultPlcSubscriptionField (org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField)3 PlcProtocolException (org.apache.plc4x.java.api.exceptions.PlcProtocolException)2 PlcField (org.apache.plc4x.java.api.model.PlcField)2 DefaultPlcSubscriptionResponse (org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse)2 ResponseItem (org.apache.plc4x.java.spi.messages.utils.ResponseItem)2 ByteBuf (io.netty.buffer.ByteBuf)1 Unpooled (io.netty.buffer.Unpooled)1 ByteBuffer (java.nio.ByteBuffer)1 Duration (java.time.Duration)1 java.util (java.util)1 ArrayBlockingQueue (java.util.concurrent.ArrayBlockingQueue)1 BlockingQueue (java.util.concurrent.BlockingQueue)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 TimeoutException (java.util.concurrent.TimeoutException)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 BiConsumer (java.util.function.BiConsumer)1 Consumer (java.util.function.Consumer)1 IntStream (java.util.stream.IntStream)1 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)1