use of org.apache.plc4x.java.can.generic.field.GenericCANField in project plc4x by apache.
the class GenericCANProtocolLogic method subscribe.
@Override
public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest request) {
DefaultPlcSubscriptionRequest rq = (DefaultPlcSubscriptionRequest) request;
Map<String, ResponseItem<PlcSubscriptionHandle>> answers = new LinkedHashMap<>();
DefaultPlcSubscriptionResponse response = new DefaultPlcSubscriptionResponse(rq, answers);
Map<Integer, GenericCANSubscriptionHandle> handles = new HashMap<>();
for (String key : rq.getFieldNames()) {
DefaultPlcSubscriptionField subscription = (DefaultPlcSubscriptionField) rq.getField(key);
if (subscription.getPlcSubscriptionType() != PlcSubscriptionType.EVENT) {
answers.put(key, new ResponseItem<>(PlcResponseCode.UNSUPPORTED, null));
} else if (subscription.getPlcField() instanceof GenericCANField) {
GenericCANField canField = (GenericCANField) subscription.getPlcField();
GenericCANSubscriptionHandle subscriptionHandle = handles.computeIfAbsent(canField.getNodeId(), node -> new GenericCANSubscriptionHandle(this, node));
answers.put(key, new ResponseItem<>(PlcResponseCode.OK, subscriptionHandle));
subscriptionHandle.add(key, canField);
} else {
answers.put(key, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
}
}
return CompletableFuture.completedFuture(response);
}
use of org.apache.plc4x.java.can.generic.field.GenericCANField in project plc4x by apache.
the class GenericCANProtocolLogic method decode.
@Override
public void decode(ConversationContext<GenericFrame> context, GenericFrame msg) throws Exception {
for (Map.Entry<DefaultPlcConsumerRegistration, Consumer<PlcSubscriptionEvent>> entry : consumers.entrySet()) {
DefaultPlcConsumerRegistration registration = entry.getKey();
Consumer<PlcSubscriptionEvent> consumer = entry.getValue();
for (PlcSubscriptionHandle handle : registration.getSubscriptionHandles()) {
GenericCANSubscriptionHandle subscription = (GenericCANSubscriptionHandle) handle;
Map<String, ResponseItem<PlcValue>> fields = new LinkedHashMap<>();
ReadBuffer buffer = new ReadBufferByteBased(msg.getData(), ByteOrder.LITTLE_ENDIAN);
buffer.pullContext("readFields");
if (subscription.matches(msg.getNodeId())) {
for (Entry<String, GenericCANField> field : subscription.getFields().entrySet()) {
try {
PlcValue value = read(buffer, field.getValue());
if (value == null) {
fields.put(field.getKey(), new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
} else {
fields.put(field.getKey(), new ResponseItem<>(PlcResponseCode.OK, value));
}
} catch (ParseException e) {
fields.put(field.getKey(), new ResponseItem<>(PlcResponseCode.INVALID_DATA, null));
}
}
consumer.accept(new DefaultPlcSubscriptionEvent(Instant.now(), fields));
}
buffer.closeContext("readFields");
}
}
}
use of org.apache.plc4x.java.can.generic.field.GenericCANField in project plc4x by apache.
the class GenericCANProtocolLogic method write.
@Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
final RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
CompletableFuture<PlcWriteResponse> response = new CompletableFuture<>();
transaction.submit(() -> {
Map<Integer, WriteBufferByteBased> messages = new LinkedHashMap<>();
Map<Integer, Map<String, PlcResponseCode>> responses = new HashMap<>();
for (String field : writeRequest.getFieldNames()) {
PlcField plcField = writeRequest.getField(field);
if (!(plcField instanceof GenericCANField)) {
responses.computeIfAbsent(-1, (node) -> new HashMap<>()).put(field, PlcResponseCode.UNSUPPORTED);
continue;
}
GenericCANField canField = (GenericCANField) plcField;
WriteBuffer buffer = messages.computeIfAbsent(canField.getNodeId(), (node) -> new WriteBufferByteBased(8, ByteOrder.LITTLE_ENDIAN));
Map<String, PlcResponseCode> statusMap = responses.computeIfAbsent(canField.getNodeId(), (node) -> new HashMap<>());
PlcValue value = writeRequest.getPlcValue(field);
try {
write(buffer, canField, value);
statusMap.put(field, PlcResponseCode.OK);
} catch (SerializationException e) {
statusMap.put(field, PlcResponseCode.INVALID_DATA);
}
}
Map<String, PlcResponseCode> codes = new HashMap<>();
for (Map.Entry<Integer, WriteBufferByteBased> message : messages.entrySet()) {
boolean discarded = false;
for (Map.Entry<String, PlcResponseCode> entry : responses.get(message.getKey()).entrySet()) {
codes.put(entry.getKey(), entry.getValue());
if (!discarded && entry.getValue() != PlcResponseCode.OK) {
logger.info("Discarding writing of frame with field {}. Node {} will not be communicated.", entry.getKey(), message.getKey());
discarded = true;
}
}
if (!discarded) {
byte[] data = message.getValue().getData();
logger.debug("Writing message with id {} and {} bytes of data", message.getKey(), data.length);
context.sendToWire(new GenericFrame(message.getKey(), data));
}
}
response.complete(new DefaultPlcWriteResponse(writeRequest, codes));
transaction.endRequest();
});
return response;
}
Aggregations