DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
| Gliffy Diagram | ||||
|---|---|---|---|---|
|
General
- I ensured all of our classes have the "Plc" prefix, as I did encounter situations in which very generic type names had collisions and I had to use the fully qualified class name (including the package name). The "Plc" prefix reduces this risk.
- Introduced a PlcFieldRequest / Response classes, allowing PlcRequests and Responses that don't use field information (When calling functions, for example)
- Removed the "RequestItems". Now the data for the plc read responses is contained in the PlcReadResponse/PlcWriteRequest itself.
- Added the concept of a named-field which is in general a Field description combined with a string alias.
- All sub-types of the PlcFieldRequest/Response use these aliases to reference the field they want to access. Resulting in an API that is more similar to JDBCs RecordSet.
...
- As mentioned before, I introduced a new Level PlcFieldRequest/Response which deals with request/responses which target fields (such as read, write, subscribe).
- The requests contain a Map of Named-Fields
- The responses contain a reference to the corresponding request
- The responses contain a response code for every field in the request
- A PlcReadResponse also contains a map of byte data that contains the raw data.
- (The data should be in a general format shared by all drivers, so the drivers requiring special formats need to convert this when constructing the objects)
PlcReadResponse & PlcWriteRequest
- The getObject() is a convenience method to return values of the natural type determined by the field definition itself. This is the smallest possible type fit to contain the PLC type.
- The setObject() is a convenience method. Actually thinking about it a little bit more, we might even have just the setObject version and get rid of the rest.
- A "typeConverter" is passed in by each driver, that handles the encoding/decoding of values for that particular driver.
Example Code
Here comes some example code to demonstrate how a Programm using this API could look like.
| Code Block | ||
|---|---|---|
| ||
public static void main(String[] args) throws Exception {
PlcDriverManager manager = new PlcDriverManager();
try (PlcConnection conn = manager.getConnection("s7://192.168.167.211/0/0")) {
Optional<PlcReader> optionalReader = conn.getReader();
if (!optionalReader.isPresent()) {
return;
}
PlcReader Reader = optionalReader.get();
// Example using prepareField and prepareNamedField ...
PlcReadRequest request = new PlcReadRequest(
new PlcNamedFieldconn.prepareNamedField("parameterX", conn.prepareField("%DB8.DBX3:INT")),
new PlcNamedFieldconn.prepareNamedField("parameterY", conn.prepareField("%DB9.DBW4:DOUBLE")),
new PlcNamedField("others", conn.prepareField("%DB2.DBW2:BYTE[10]")));
CompletableFuture<PlcReadResponse> future = reader.read(request);
PlcReadResponse response = future.get();
// Access an item by it's name.
System.out.println("Parameter X: " + response.getInteger("parameterX"));
// Iterate over all items
for(String fieldName: response.getFieldNames()) {
switch(fieldName) {
case "parameterY":
System.out.println("Parameter y: " + response.getDouble(fieldName));
break;
case "others":
for(int i = 0; i < response.getNumValues(fieldName); i++) {
// Intentionally using short instead of byte
// In this case it will return Byte[i] but convert that into a Short.
System.out.println(" - " + response.getShort(fieldName, i));
}
break;
}
}
}
} |
...