use of org.apache.plc4x.java.abeth.field.AbEthField in project plc4x by apache.
the class Plc4xAbEthProtocol method decodeReadResponse.
private PlcResponse decodeReadResponse(CIPEncapsulationReadResponse plcReadResponse, PlcRequestContainer requestContainer) {
PlcReadRequest plcReadRequest = (PlcReadRequest) requestContainer.getRequest();
Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
for (String fieldName : plcReadRequest.getFieldNames()) {
AbEthField field = (AbEthField) plcReadRequest.getField(fieldName);
PlcResponseCode responseCode = decodeResponseCode(plcReadResponse.getResponse().getStatus());
PlcValue plcValue = null;
if (responseCode == PlcResponseCode.OK) {
try {
switch(field.getFileType()) {
case // output as single bytes
INTEGER:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (data.size() == 1) {
plcValue = new PlcINT(data.get(0));
} else {
plcValue = IEC61131ValueHandler.of(data);
}
}
break;
case WORD:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (((data.get(1) >> 7) & 1) == 0) {
// positive number
plcValue = IEC61131ValueHandler.of((data.get(1) << 8) + data.get(0));
} else {
// negative number
plcValue = IEC61131ValueHandler.of((((~data.get(1) & 0b01111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
}
}
break;
case DWORD:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (((data.get(3) >> 7) & 1) == 0) {
// positive number
plcValue = IEC61131ValueHandler.of((data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0));
} else {
// negative number
plcValue = IEC61131ValueHandler.of((((~data.get(3) & 0b01111111) << 24) + ((~(data.get(2) - 1) & 0b11111111) << 16) + ((~(data.get(1) - 1) & 0b11111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
}
}
break;
case SINGLEBIT:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (field.getBitNumber() < 8) {
// read from first byte
plcValue = IEC61131ValueHandler.of((data.get(0) & (1 << field.getBitNumber())) != 0);
} else {
// read from second byte
plcValue = IEC61131ValueHandler.of((data.get(1) & (1 << (field.getBitNumber() - 8))) != 0);
}
}
break;
default:
logger.warn("Problem during decoding of field {}: Decoding of file type not implemented; " + "FieldInformation: {}", fieldName, field);
}
} catch (Exception e) {
logger.warn("Some other error occurred casting field {}, FieldInformation: {}", fieldName, field, e);
}
}
ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
values.put(fieldName, result);
}
return new DefaultPlcReadResponse(plcReadRequest, values);
}
use of org.apache.plc4x.java.abeth.field.AbEthField in project plc4x by apache.
the class AbEthProtocolLogic method read.
@Override
public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
// TODO: Warning ... we are senging one request per field ... the result has to be merged back together ...
for (String fieldName : readRequest.getFieldNames()) {
PlcField field = readRequest.getField(fieldName);
if (!(field instanceof AbEthField)) {
logger.error("The field should have been of type AbEthField");
}
AbEthField abEthField = (AbEthField) field;
DF1RequestProtectedTypedLogicalRead logicalRead = new DF1RequestProtectedTypedLogicalRead(abEthField.getByteSize(), abEthField.getFileNumber(), abEthField.getFileType().getTypeCode(), abEthField.getElementNumber(), // Subelementnumber default to zero
(short) 0);
final int transactionCounter = transactionCounterGenerator.incrementAndGet();
// If we've reached the max value for a 16 bit transaction identifier, reset back to 1
if (transactionCounterGenerator.get() == 0xFFFF) {
transactionCounterGenerator.set(1);
}
// origin/sender: constant = 5
DF1RequestMessage requestMessage = new DF1CommandRequestMessage((short) configuration.getStation(), (short) 5, (short) 0, transactionCounter, logicalRead);
CIPEncapsulationReadRequest read = new CIPEncapsulationReadRequest(sessionHandle, 0, emptySenderContext, 0, requestMessage);
CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
transaction.submit(() -> context.sendRequest(read).expectResponse(CIPEncapsulationPacket.class, REQUEST_TIMEOUT).onTimeout(future::completeExceptionally).onError((p, e) -> future.completeExceptionally(e)).check(p -> p instanceof CIPEncapsulationReadResponse).unwrap(p -> (CIPEncapsulationReadResponse) p).check(p -> p.getResponse().getTransactionCounter() == transactionCounter).handle(p -> {
PlcResponse response = decodeReadResponse(p, readRequest);
// TODO: Not sure how to merge things back together ...
// future.complete(response);
// Finish the request-transaction.
transaction.endRequest();
// future.complete(((PlcReadResponse) decodeReadResponse(p, ((InternalPlcReadRequest) readRequest))));
}));
// TODO: This aborts reading other fields after sending the first fields request ... refactor.
return future;
}
// TODO: Should return an aggregated future ....
return null;
}
use of org.apache.plc4x.java.abeth.field.AbEthField in project plc4x by apache.
the class AbEthProtocolLogic method decodeReadResponse.
private PlcResponse decodeReadResponse(CIPEncapsulationReadResponse plcReadResponse, PlcReadRequest plcReadRequest) {
Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
for (String fieldName : plcReadRequest.getFieldNames()) {
AbEthField field = (AbEthField) plcReadRequest.getField(fieldName);
PlcResponseCode responseCode = decodeResponseCode(plcReadResponse.getResponse().getStatus());
PlcValue plcValue = null;
if (responseCode == PlcResponseCode.OK) {
try {
switch(field.getFileType()) {
case // output as single bytes
INTEGER:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (data.size() == 1) {
plcValue = new PlcINT(data.get(0));
} else {
plcValue = IEC61131ValueHandler.of(data);
}
}
break;
case WORD:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (((data.get(1) >> 7) & 1) == 0) {
// positive number
plcValue = IEC61131ValueHandler.of((data.get(1) << 8) + data.get(0));
} else {
// negative number
plcValue = IEC61131ValueHandler.of((((~data.get(1) & 0b01111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
}
}
break;
case DWORD:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (((data.get(3) >> 7) & 1) == 0) {
// positive number
plcValue = IEC61131ValueHandler.of((data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0));
} else {
// negative number
plcValue = IEC61131ValueHandler.of((((~data.get(3) & 0b01111111) << 24) + ((~(data.get(2) - 1) & 0b11111111) << 16) + ((~(data.get(1) - 1) & 0b11111111) << 8) + (~(data.get(0) - 1) & 0b11111111)) * -1);
}
}
break;
case SINGLEBIT:
if (plcReadResponse.getResponse() instanceof DF1CommandResponseMessageProtectedTypedLogicalRead) {
DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
List<Short> data = df1PTLR.getData();
if (field.getBitNumber() < 8) {
// read from first byte
plcValue = IEC61131ValueHandler.of((data.get(0) & (1 << field.getBitNumber())) != 0);
} else {
// read from second byte
plcValue = IEC61131ValueHandler.of((data.get(1) & (1 << (field.getBitNumber() - 8))) != 0);
}
}
break;
default:
logger.warn("Problem during decoding of field {}: Decoding of file type not implemented; " + "FieldInformation: {}", fieldName, field);
}
} catch (Exception e) {
logger.warn("Some other error occurred casting field {}, FieldInformation: {}", fieldName, field, e);
}
}
ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
values.put(fieldName, result);
}
// TODO: Double check if it's really a InternalPlcReadRequest ...
return new DefaultPlcReadResponse(plcReadRequest, values);
}
use of org.apache.plc4x.java.abeth.field.AbEthField in project plc4x by apache.
the class Plc4xAbEthProtocol method encode.
@Override
protected void encode(ChannelHandlerContext ctx, PlcRequestContainer msg, List<Object> out) throws Exception {
logger.trace("Encoding {}", msg);
PlcRequest request = msg.getRequest();
// reset counter since two byte values are possible in DF1
if (transactionCounterGenerator.get() > 65000) {
transactionCounterGenerator.set(10);
}
if (request instanceof PlcReadRequest) {
PlcReadRequest readRequest = (PlcReadRequest) msg.getRequest();
for (String fieldName : readRequest.getFieldNames()) {
PlcField field = readRequest.getField(fieldName);
if (!(field instanceof AbEthField)) {
throw new PlcProtocolException("The field should have been of type AbEthField");
}
AbEthField abEthField = (AbEthField) field;
DF1RequestProtectedTypedLogicalRead logicalRead = new DF1RequestProtectedTypedLogicalRead(abEthField.getByteSize(), abEthField.getFileNumber(), abEthField.getFileType().getTypeCode(), abEthField.getElementNumber(), // Subelementnumber default to zero
(short) 0);
// origin/sender: constant = 5
DF1RequestMessage requestMessage = new DF1CommandRequestMessage((short) station, (short) 5, (short) 0, transactionCounterGenerator.incrementAndGet(), logicalRead);
CIPEncapsulationReadRequest read = new CIPEncapsulationReadRequest(sessionHandle, 0, emptySenderContext, 0, requestMessage);
requests.put(requestMessage.getTransactionCounter(), msg);
out.add(read);
}
} else {
ctx.fireExceptionCaught(new PlcProtocolException("Unsupported request type " + request.getClass().getName()));
}
}
Aggregations