> On Feb 5, 2018, at 5:43 AM, Christofer Dutz <[email protected]> wrote:
> ...
> I was also thinking about how we could make this easier. I think this is also
> a general problem we probably have solve in the "normal API" too.
>
> While working on some Jackson Yaml parsing code, I thought that it might be
> an option to create Pojo classes with properties, that are annotated with
> PlcAnnotations that provide the Addresses in the PLC. The downside of this
> approach would be that this way the address string is hard-coded inside the
> program.
>
> An Alternative would be to have an additional annotation with a property
> name. Then we could provide the type as well as a "Propteries" object that is
> passed to the API.
>
> @PlcAnnotation("INPUTS/1.0")
> private byte myProperty;
>
> or
>
> @PlcAnnotation("some.property.id")
> private byte myProperty;
>
> Then the adapters could extract the name and the addresses from the pojo
> class itself and hereby greatly reduce the code needed to create a request.
>
> What do you think?
I don’t have experience with defining annotations/processors or java code
generators so bear with me :-)
Maybe you could flesh out a simple batch usage example involving a couple of
types to clarify the overall story, including response code access, etc.
I would *guess* that “hardcoding” a data-item’s address in the application
wouldn't be an issue. It would be a problem if one was trying to build an
interactive application that probed/read items as described by user commands
(e.g., “read byte INPUTS/1.0”) :-)
Based on a couple of hours perusing the latest API, I think a user would really
like the ability to easily use a more type specific batch-of-hetero-data-items
class. Here’s a thought exercise — that doesn’t involve annotations. You may
have already gone through this sort of exercise. Sorry if that’s the case.
Does the user really want/need separate request vs response item types? Can’t
an item just be an: Address, Value, ResponseCode?
Not clear to me there’s a need for separate read vs write items.
class PlcDataItem<T> { // not an existing plc class.
...
public String getAddress() { … }
public T getValue() { …} // throw if code != OK?, or return null?
public void setValue(T value) { …}
public ResponseCode getCode() {…}
public void setCode(ResponseCode) {…}
}
// Define a my batch of data items
class MyBatch {
private final PlcDataItem<Byte> fooItem = new
PlcDataItem<>(“INPUTS/1.0”);
private final PlcDataItem<Float[]> barItem = new
PlcDataItem<>(“INPUTS/2.0”, 3/*count*/);
PlcDataItem<Byte> getFooItem() { return fooItem; } // comple time
typesafe
PlcDataItem<Float[]> getBarItem() { return barItem; }
}
PlcConnector connector = …
// only need to do this once. introspects MyBatch to get data item info
PlcBatchReadRequest<MyBatch> readRequest =
PlcReadRequestFactory.newBatchReadRequest(connector, MyBatch.class);
while (true) {
PlcBatchReadResponse<MyBatch> readResponse =
connector.getReader().readBatch(readRequest).get();
MyBatch myBatch = PlcReadResponseFactory.fillDataObject(readResponse,
new MyBatch()); // compile time typesafe
// or if you prefer: MyBatch myBatch = readResponse.getBatch();
System.out.println("batch: " + myBatch);
// do typesafe access of the data items with named accessors
if (myBatch.getFooItem().getCode() == ResponseCode.OK) {
Byte value = myBatch.getFooItem().getValue(); // comple time
typesafe
System.out.println("foo: " + value);
} else {
...
}
JsonObject jo = gson.toJson(myBatch);
System.out.println("json: " + jo);
sleep(1000);
}