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