Open meichf opened 3 weeks ago
So I've just created a ManualTest for my Logix device. I created several Controller Tags (Including UDTs) They are all called "hurz_{datatypeName}" for simplicity. the Following program works when reading:
public static void main(String[] args) throws Exception {
ManualEipLogixDriverTest test = new ManualEipLogixDriverTest("logix://192.168.23.40");
// This is the very limited number of types my controller supports.
test.addTestCase("hurz_BOOL", new PlcBOOL(true));
test.addTestCase("hurz_SINT", new PlcSINT(-42));
test.addTestCase("hurz_INT", new PlcINT(-2424));
test.addTestCase("hurz_DINT", new PlcDINT(-242442424));
test.addTestCase("hurz_REAL", new PlcREAL(3.141593F));
//test.addTestCase("hurz_UDT", new PlcStruct());
long start = System.currentTimeMillis();
test.run();
long end = System.currentTimeMillis();
System.out.printf("Finished in %d ms", end - start);
}
However I can see the UDT being correctly sent on the wire using WireShark, just it seems that decoding it is a problem for the driver. Also can't I write. As soon as I try that I get errors.
So if I look at your code, omit the "%" and the datatypes. Just "A", "B", "C", or "D" should be enough.
Ok ... I learned something more ... when reading, you can omit the datatype ... however when writing it seems to be mandatory. I think that in general we will have to implement some sort of "load the symbol table when connecting" similar to what we do for ADS and use that information throughout the session ... especially for UDTs I otherwise have no way to process them correctly.
So if I look at your code, omit the "%" and the datatypes. Just "A", "B", "C", or "D" should be enough.
I‘ve tried this, but it doesn't work
Are the tags you are trying to read controller tags or program tags? I tried with my logix device and above only worked for controller tags.
Are the tags you are trying to read controller tags or program tags? I tried with my logix device and above only worked for controller tags. It's controller tags. My device is the Allen Bradley 1756-L71, I don't know if the logix protocol is valid for this device.
The L71 is a little older than the one Chris has, it is probably running v20 and I think he should be using v35 or something. Can you confirm which version? There is probably going to be differences between v20 and the higher versions.
s Do you mean programming tools? I'm using the studio 5000, v33.
Then thats probably not the issue, Which version of PLC4X are you using?
I have tried both 0.12.0 and 0.13.0-SNAPSHOT
I have identified the problem, it works on version 0.11.0 .
I think that is just plain EIP/CIP and no Logix extensions, right? I think we completely rewrote the driver for 0.12.0
@meichf Why are you setting the bigEndian parameter to false? Specifically for the logix driver in 0.13-SNAPSHOT.
I think that is just plain EIP/CIP and no Logix extensions, right? I think we completely rewrote the driver for 0.12.0
In version 0.11.0, both EtherNet/IP and Logix were successful, while in version 0.12.0, neither was successful.
@meichf Why are you setting the bigEndian parameter to false? Specifically for the logix driver in 0.13-SNAPSHOT.
It seems that without this parameter, I am unable to connect to the device.
I found that using version 0.11.0 to read data is slow, and the duration of returning data increases with the number of points. Then, I found the problem in issue #1373, so I rewrote the method. Now, reading values is relatively normal.
private CompletableFuture<PlcReadResponse> readWithoutMessageRouter(PlcReadRequest readRequest) {
CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
List<CompletableFuture<Void>> internalFutures = new ArrayList<>();
PathSegment classSegment = new LogicalSegment(new ClassID((byte) 0, (short) 6));
PathSegment instanceSegment = new LogicalSegment(new InstanceID((byte) 0, (short) 1));
DefaultPlcReadRequest request = (DefaultPlcReadRequest) readRequest;
for (String tagName : request.getTagNames()) {
CompletableFuture<Void> internalFuture = new CompletableFuture<>();
RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
EipTag eipTag = (EipTag) request.getTag(tagName);
String tag = eipTag.getTag();
try {
CipReadRequest req = new CipReadRequest(toAnsi(tag), 1);
CipUnconnectedRequest requestItem = new CipUnconnectedRequest(classSegment, instanceSegment, req, (byte) this.configuration.getBackplane(), (byte) this.configuration.getSlot());
List<TypeId> typeIds = new ArrayList<>(2);
typeIds.add(nullAddressItem);
typeIds.add(new UnConnectedDataItem(requestItem));
CipRRData pkt = new CipRRData(sessionHandle, CIPStatus.Success.getValue(), DEFAULT_SENDER_CONTEXT, 0L, 0L, 0, typeIds);
transaction.submit(() -> context.sendRequest(pkt)
.expectResponse(EipPacket.class, REQUEST_TIMEOUT)
.onTimeout(future::completeExceptionally)
.onError((p, e) -> future.completeExceptionally(e))
.check(p -> p instanceof CipRRData)
.unwrap(p -> (CipRRData) p)
.check(p -> p.getSessionHandle() == sessionHandle)
.handle(p -> {
List<TypeId> responseTypeIds = p.getTypeIds();
UnConnectedDataItem dataItem = (UnConnectedDataItem) responseTypeIds.get(1);
Map<String, ResponseItem<PlcValue>> readResponse = decodeSingleReadResponse(dataItem.getService(), tagName, eipTag);
values.putAll(readResponse);
internalFuture.complete(null);
transaction.endRequest();
}));
internalFutures.add(internalFuture);
} catch (SerializationException e) {
future.completeExceptionally(e);
}
}
CompletableFuture.allOf(internalFutures.toArray(new CompletableFuture[0])).thenRun(() -> {
PlcReadResponse readResponse = new DefaultPlcReadResponse(readRequest, values);
future.complete(readResponse);
}).exceptionally(e -> {
future.completeExceptionally(e);
return null;
});
return future;
}
@chrisdutz The Rewritten method readWithoutMessageRouter
realy works. Hope it will be merged into the next version.
I think the new version of the driver sort of does an auto-detection of the PLC and decides which technique to use, based on that. Will see if I can have a look tomorrow afternoon.
What happened?
I wrote two programs according to the documentation on the official website of PLC4X to read Allen Bradley PLC, model Logix5571, but all the values read were null.
Here is the code. The result is that all four tag values in asPlcValue are null.
code for EtherNet/IP protocol:
code for Logix protocol:
here is the tags:
Version
v0.12.0
Programming Languages
Protocols