You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@plc4x.apache.org by Christofer Dutz <ch...@c-ware.de> on 2018/03/05 20:35:04 UTC

Re: Batch reads with JPA like annotation magic?

Hi Niclas,

after recovering from that nasty Flu, that is plaguing Germany at the moment, I am working on catching up on what I missed. 
I tried to follow, but some things I felt to worn out to work my head around. 

Could you elaborate a little on Ploygene? How would this allow extending our requests with additional magic? Does this work in a simple way: No need to configure plugins, code generation or learn some complex API? I would like to keep PLC4X as simple as possible, but as extendable as possible. 

So I'm always open for new ideas (

Chris



Am 20.02.18, 03:32 schrieb "hedhman@gmail.com im Auftrag von Niclas Hedhman" <hedhman@gmail.com im Auftrag von niclas@hedhman.org>:

    Being the Overlord of Magic that can be done in Java, I have some comments
    to make on this idea.
    
    1. In principle what you suggest can already be done quite easily in Apache
    Polygene, by creating a "generic mixin" that overrides the generic
    PropertyMixin. Polygene is probably way more powerful than anything you
    could dream up here. Although Polygene has a strong JSON serialization and
    persistence "story", both fully pluggable, it does not use the Glasgow
    spec, a.k.a JavaBeans, a.k.a "getter/setter naming convention", which has
    been plaguing the Java community for 2 decades now.
    If I created a Plc4xBackingPropertyMixin, which I think would only take a
    few hours, maybe a couple of days, depending on how advance we want it, you
    would end up with;
    
    
    
    
    *public interface Boiler{*
    
    *    @Plc4x( url="s7://......", period=5000, priority=low )*
    
    
    *    Property<Boolean> running();*
    
    *    @Plc4x( url="s7://......", direction=out )*
    
    
    *    Property<Boolean> onoff();*
    
    *    @Plc4x( url="s7://......", period=500, priority=high )*
    
    
    
    *    Property<Boolean> alarm();    @Plc4x( url="s7://......", period=5000,
    priority=normal )*
    
    *    Property<Double> temperature();*
    *}*
    
    and in the "assembly", we would need to override the default PropertyMixin,
    by doing;
    
        *module.transients( Boiler.class ).withMixins(
    Plc4xBackingPropertyMixin.class );*
    
    That said, Apache Polygene is quite overwhelming for new users, so although
    the idea is very persuasive for myself, I am under no illusion that others
    are as easily convinced. And it is quite likely that I will create this,
    since you brought it up, and the effort is rather small.
    
    
    2. I have been doing PLC Master apps in Java since 1997 (and other
    languages since 1984), and experience tells me that the biggest challenge
    for really large applications is how to handle "permanent" vs "temporary"
    values. What do I mean? In really large systems, it is not feasible to scan
    all variables at all times. The latency will not be acceptable. Instead, we
    acknowledge that many values are only of interest when someone is looking
    at them, be it a person or a datalogger. Not saying it is unsolvable, but
    it adds a fair bit of complexity in a Java world with GC, and relying on
    finalize() is not really a solution and the outside "javabeans-friendly"
    frameworks are clueless about resource management.
    
    GutFeeling(tm) says that this can and should probably be postponed until we
    have more experience and made all compatibility-breaking changes that comes
    along the way.
    
    
    
    Cheers
    Niclas
    
    
    On Tue, Feb 20, 2018 at 5:32 AM, Christofer Dutz <ch...@c-ware.de>
    wrote:
    
    > Hi Dale,
    >
    > The direction thing was inspired by the way the Beckhoff ADS protocol was
    > designed.
    >
    > There they sometimes Send Data alongside read requests and sometimes have
    > strange "return what's in there and then overwrite with this" type of
    > requests.
    > The Beckhoff support guy mentioned that they are used quite a lot.
    >
    > That was the main reasoning for me mentioning the direction thing. In
    > general this could be set to a default of being bedirectional.
    >
    > Chris
    >
    >
    > Am 19.02.18, 18:25 schrieb "Dale LaBossiere" <dm...@gmail.com>:
    >
    >     Doesn’t the user need access to the response code for each annotated
    > item?
    >
    >     I’m unclear on why a Direction is needed/desired.  Is it just for
    > “documentation" of what is possible for an item at that address?  Maybe it
    > would be checked when the annotated class is used in a Read vs Write
    > request to verify the request makes sense for that item?  Or… ?
    >
    >     Could you provide some small pseudo-code of how the app would use the
    > API with such an annotated class.
    >
    >     class MyAnnotatedClass { … };
    >     PlcConnection connection = PlcDriver(…);
    >
    >     // make a read requests
    >     …?
    >
    >     // access data in the responses
    >     …?
    >
    >     — Dale
    >
    >
    >     > On Feb 19, 2018, at 6:16 AM, Christofer Dutz <
    > christofer.dutz@c-ware.de> wrote:
    >     >
    >     > Hi,
    >     >
    >     > in the past I have been thinking how we can make the batch reads as
    > simple as possible.
    >     >
    >     > I would like to introduce an idea I had:
    >     >
    >     > What if we started supporting annotated POJO classes? (The following
    > names are just ideas …)
    >     >
    >     > A POJO class could be annotated with some “@PlcEntity” annotation.
    >     > A property inside one of these classes could then be annotated with
    > “@PlcProperty”
    >     > This PlcProperty could have the following attributes:
    >     >
    >     >  *   Direction (Read/Write/Read&Write)
    >     >  *   Property (Name of a property that provides the address in the
    > PLC)
    >     >  *   Address (Alternative to provide the address directly and give
    > up on the flexibility to change the PLC-type / Protocol)
    >     >
    >     > Providing would definitely be the less preferred option, but I guess
    > we would have to provide a way that is extremely simple for new developers
    > to get started. I wouldn’t want to overwhelm them with too much magic in
    > the start.
    >     >
    >     > The connection could be extended to look a (configurable) property
    > file. A property property (😉) would then use this property map in the
    > connection to get the real address string for the given property - hereby
    > keeping the full portability.
    >     >
    >     > Maybe it would be better to have two separate property annotations:
    > one for property-based and one for hard-coded address strings.
    >     >
    >     > The benefit would be that we then could simplify the integrations to
    > frameworks like Edgent as we could create sources and sinks based on the
    > POJO type.
    >     >
    >     > What do you think?
    >     >
    >     > Chris
    >
    >
    >
    >
    
    
    -- 
    Niclas Hedhman, Software Developer
    http://polygene.apache.org - New Energy for Java
    


Re: Batch reads with JPA like annotation magic?

Posted by Niclas Hedhman <ni...@hedhman.org>.
Chris,
that is exactly my line of thought as well.

On Tue, Mar 6, 2018 at 4:43 PM, Christofer Dutz <ch...@c-ware.de>
wrote:

> Hi Niclas,
>
> as far as I understood Polygene especially after your examples. I would be
> hesitant to use this per default in PLC4Xs core. It does seem to add quite
> a lot of complexity which I personally would like to avoid. I don't want to
> confuse potential users. Especially the ones peeking into our world from
> the Automation side of the industry. If we present them with something they
> can't immediately wrap their heads around, I doubt we will have much
> adoption from their side.
>
> However if it was possible to use Polygene to implement some "JPA for
> PLCs" like functionality, I think a dedicated integration module for this
> alongside examples would be a good way to go.
>
> What do you (all) think?
>
> Chris
>
>
>
>
> Am 06.03.18, 07:24 schrieb "hedhman@gmail.com im Auftrag von Niclas
> Hedhman" <hedhman@gmail.com im Auftrag von niclas@hedhman.org>:
>
>     Polygene is highly opinionated, for better and worse. Minimally,
> Polygene
>     requires to start a runtime, and that everything needed is declared
>     explicitly upfront at boot time. The minimal start code is something
> like;
>
>
>     public static void main( String[] args )
>         throws Exception
>     {
>         app = new SingletonAssembler( module -> {
>             module.transients( Boiler.class, Ahu.class, Fan.class )
>                   .withMixins( Plc4xBackingPropertyMixin.class );
>
>             module.services( Plc4xPollService.class )
>                   .withMixins( Plc4xModbusDriver.class );
>             :
>             :
>         } );
>     }
>
>
>     If one wants to implement additional behavior in the Boiler class,
> then you
>     create Mixin classes. Let's say we want to capture the temperature
> once an
>     hour.
>
>     @Mixins(HistoryMixin.class)
>     interface Boiler
>     {
>         @Plc4x( url="s7://......", period=60000 )
>         Property<Double> temperature();
>
>         List<Double> temperatureHistory();
>     }
>
>     public abstract class HistoryMixin
>         implements Boiler, Scheduled
>     {
>         int maxHours = 24;
>
>         LinkedBlockingDeque<Double> history = new LinkedBlockingDeque<>();
>
>         @Override
>         public void tick()
>         {
>             Double value = temperature().get();
>             history.addLast(value);
>             while( history.size() > maxHours )
>             {
>                 history.removeFirst();
>             }
>         }
>
>         @Override
>         public List<Double> temperatureHistory()
>         {
>             return new ArrayList<>( history );
>         }
>     }
>
>
>     Above, let's say that "Scheduled" is a service to allow something to
> get a
>     tick() upon some period/interval. What I want to draw attention to is
> that
>     the HistoryMixin is implementing only the method(s) it need to, and
> that
>     the Boiler interface can declare such permanent functionality as an
>     annotation, instead of as a start-up declaration in the assembly. The
> fact
>     that the Mixin is abstract is handled by the runtime and it will
> compose
>     all these individual (so called) fragments into a single object (we
> call it
>     a Composite) when you instantiate it from the builder.
>
>     It is a whole new different way of writing software. Some people love
> it,
>     and others have a hard time understanding how it can possibly work.
> Just
>     scratching the surface, and please read
>     https://hedhman.wordpress.com/2017/05/10/introducing-apache-polygene/
> for a
>     larger introduction to the subject.
>
>
>     If you don't want to write the entire project in Polygene "style", you
> need
>     to either use the Spring library bridge (possibly need upgrade that
> one a
>     bit), where each Service in Polygene will show up as a Spring bean, or
>     leverage various points of external hooks for Polygene, such
>     importedServices.
>
>
>     Don't want to bore you too much.
>
>
>     My actual main point was that your suggestion/idea can quickly become
> quite
>     a large undertaking and detract from the primary focus that (I think)
> PLC4X
>     should have. And bringing up Polygene was more to show that what you
>     suggest can be done very easily already in Polygene, and all that work
>     wouldn't be needed.
>
>
>     Cheers
>     Niclas
>
>
>     On Tue, Mar 6, 2018 at 4:35 AM, Christofer Dutz <
> christofer.dutz@c-ware.de>
>     wrote:
>
>     > Hi Niclas,
>     >
>     > after recovering from that nasty Flu, that is plaguing Germany at the
>     > moment, I am working on catching up on what I missed.
>     > I tried to follow, but some things I felt to worn out to work my head
>     > around.
>     >
>     > Could you elaborate a little on Ploygene? How would this allow
> extending
>     > our requests with additional magic? Does this work in a simple way:
> No need
>     > to configure plugins, code generation or learn some complex API? I
> would
>     > like to keep PLC4X as simple as possible, but as extendable as
> possible.
>     >
>     > So I'm always open for new ideas (
>     >
>     > Chris
>     >
>     >
>     >
>     > Am 20.02.18, 03:32 schrieb "hedhman@gmail.com im Auftrag von Niclas
>     > Hedhman" <hedhman@gmail.com im Auftrag von niclas@hedhman.org>:
>     >
>     >     Being the Overlord of Magic that can be done in Java, I have some
>     > comments
>     >     to make on this idea.
>     >
>     >     1. In principle what you suggest can already be done quite
> easily in
>     > Apache
>     >     Polygene, by creating a "generic mixin" that overrides the
> generic
>     >     PropertyMixin. Polygene is probably way more powerful than
> anything you
>     >     could dream up here. Although Polygene has a strong JSON
> serialization
>     > and
>     >     persistence "story", both fully pluggable, it does not use the
> Glasgow
>     >     spec, a.k.a JavaBeans, a.k.a "getter/setter naming convention",
> which
>     > has
>     >     been plaguing the Java community for 2 decades now.
>     >     If I created a Plc4xBackingPropertyMixin, which I think would
> only
>     > take a
>     >     few hours, maybe a couple of days, depending on how advance we
> want
>     > it, you
>     >     would end up with;
>     >
>     >
>     >
>     >
>     >     *public interface Boiler{*
>     >
>     >     *    @Plc4x( url="s7://......", period=5000, priority=low )*
>     >
>     >
>     >     *    Property<Boolean> running();*
>     >
>     >     *    @Plc4x( url="s7://......", direction=out )*
>     >
>     >
>     >     *    Property<Boolean> onoff();*
>     >
>     >     *    @Plc4x( url="s7://......", period=500, priority=high )*
>     >
>     >
>     >
>     >     *    Property<Boolean> alarm();    @Plc4x( url="s7://......",
>     > period=5000,
>     >     priority=normal )*
>     >
>     >     *    Property<Double> temperature();*
>     >     *}*
>     >
>     >     and in the "assembly", we would need to override the default
>     > PropertyMixin,
>     >     by doing;
>     >
>     >         *module.transients( Boiler.class ).withMixins(
>     >     Plc4xBackingPropertyMixin.class );*
>     >
>     >     That said, Apache Polygene is quite overwhelming for new users,
> so
>     > although
>     >     the idea is very persuasive for myself, I am under no illusion
> that
>     > others
>     >     are as easily convinced. And it is quite likely that I will
> create
>     > this,
>     >     since you brought it up, and the effort is rather small.
>     >
>     >
>     >     2. I have been doing PLC Master apps in Java since 1997 (and
> other
>     >     languages since 1984), and experience tells me that the biggest
>     > challenge
>     >     for really large applications is how to handle "permanent" vs
>     > "temporary"
>     >     values. What do I mean? In really large systems, it is not
> feasible to
>     > scan
>     >     all variables at all times. The latency will not be acceptable.
>     > Instead, we
>     >     acknowledge that many values are only of interest when someone is
>     > looking
>     >     at them, be it a person or a datalogger. Not saying it is
> unsolvable,
>     > but
>     >     it adds a fair bit of complexity in a Java world with GC, and
> relying
>     > on
>     >     finalize() is not really a solution and the outside
>     > "javabeans-friendly"
>     >     frameworks are clueless about resource management.
>     >
>     >     GutFeeling(tm) says that this can and should probably be
> postponed
>     > until we
>     >     have more experience and made all compatibility-breaking changes
> that
>     > comes
>     >     along the way.
>     >
>     >
>     >
>     >     Cheers
>     >     Niclas
>     >
>     >
>     >     On Tue, Feb 20, 2018 at 5:32 AM, Christofer Dutz <
>     > christofer.dutz@c-ware.de>
>     >     wrote:
>     >
>     >     > Hi Dale,
>     >     >
>     >     > The direction thing was inspired by the way the Beckhoff ADS
>     > protocol was
>     >     > designed.
>     >     >
>     >     > There they sometimes Send Data alongside read requests and
> sometimes
>     > have
>     >     > strange "return what's in there and then overwrite with this"
> type of
>     >     > requests.
>     >     > The Beckhoff support guy mentioned that they are used quite a
> lot.
>     >     >
>     >     > That was the main reasoning for me mentioning the direction
> thing. In
>     >     > general this could be set to a default of being bedirectional.
>     >     >
>     >     > Chris
>     >     >
>     >     >
>     >     > Am 19.02.18, 18:25 schrieb "Dale LaBossiere" <
> dml.apache@gmail.com>:
>     >     >
>     >     >     Doesn’t the user need access to the response code for each
>     > annotated
>     >     > item?
>     >     >
>     >     >     I’m unclear on why a Direction is needed/desired.  Is it
> just for
>     >     > “documentation" of what is possible for an item at that
> address?
>     > Maybe it
>     >     > would be checked when the annotated class is used in a Read vs
> Write
>     >     > request to verify the request makes sense for that item?  Or… ?
>     >     >
>     >     >     Could you provide some small pseudo-code of how the app
> would
>     > use the
>     >     > API with such an annotated class.
>     >     >
>     >     >     class MyAnnotatedClass { … };
>     >     >     PlcConnection connection = PlcDriver(…);
>     >     >
>     >     >     // make a read requests
>     >     >     …?
>     >     >
>     >     >     // access data in the responses
>     >     >     …?
>     >     >
>     >     >     — Dale
>     >     >
>     >     >
>     >     >     > On Feb 19, 2018, at 6:16 AM, Christofer Dutz <
>     >     > christofer.dutz@c-ware.de> wrote:
>     >     >     >
>     >     >     > Hi,
>     >     >     >
>     >     >     > in the past I have been thinking how we can make the
> batch
>     > reads as
>     >     > simple as possible.
>     >     >     >
>     >     >     > I would like to introduce an idea I had:
>     >     >     >
>     >     >     > What if we started supporting annotated POJO classes?
> (The
>     > following
>     >     > names are just ideas …)
>     >     >     >
>     >     >     > A POJO class could be annotated with some “@PlcEntity”
>     > annotation.
>     >     >     > A property inside one of these classes could then be
> annotated
>     > with
>     >     > “@PlcProperty”
>     >     >     > This PlcProperty could have the following attributes:
>     >     >     >
>     >     >     >  *   Direction (Read/Write/Read&Write)
>     >     >     >  *   Property (Name of a property that provides the
> address in
>     > the
>     >     > PLC)
>     >     >     >  *   Address (Alternative to provide the address
> directly and
>     > give
>     >     > up on the flexibility to change the PLC-type / Protocol)
>     >     >     >
>     >     >     > Providing would definitely be the less preferred option,
> but I
>     > guess
>     >     > we would have to provide a way that is extremely simple for new
>     > developers
>     >     > to get started. I wouldn’t want to overwhelm them with too much
>     > magic in
>     >     > the start.
>     >     >     >
>     >     >     > The connection could be extended to look a (configurable)
>     > property
>     >     > file. A property property (😉) would then use this property
> map in
>     > the
>     >     > connection to get the real address string for the given
> property -
>     > hereby
>     >     > keeping the full portability.
>     >     >     >
>     >     >     > Maybe it would be better to have two separate property
>     > annotations:
>     >     > one for property-based and one for hard-coded address strings.
>     >     >     >
>     >     >     > The benefit would be that we then could simplify the
>     > integrations to
>     >     > frameworks like Edgent as we could create sources and sinks
> based on
>     > the
>     >     > POJO type.
>     >     >     >
>     >     >     > What do you think?
>     >     >     >
>     >     >     > Chris
>     >     >
>     >     >
>     >     >
>     >     >
>     >
>     >
>     >     --
>     >     Niclas Hedhman, Software Developer
>     >     http://polygene.apache.org - New Energy for Java
>     >
>     >
>     >
>
>
>     --
>     Niclas Hedhman, Software Developer
>     http://polygene.apache.org - New Energy for Java
>
>
>


-- 
Niclas Hedhman, Software Developer
http://polygene.apache.org - New Energy for Java

Re: Batch reads with JPA like annotation magic?

Posted by Christofer Dutz <ch...@c-ware.de>.
Hi Niclas,

as far as I understood Polygene especially after your examples. I would be hesitant to use this per default in PLC4Xs core. It does seem to add quite a lot of complexity which I personally would like to avoid. I don't want to confuse potential users. Especially the ones peeking into our world from the Automation side of the industry. If we present them with something they can't immediately wrap their heads around, I doubt we will have much adoption from their side.

However if it was possible to use Polygene to implement some "JPA for PLCs" like functionality, I think a dedicated integration module for this alongside examples would be a good way to go. 

What do you (all) think?

Chris




Am 06.03.18, 07:24 schrieb "hedhman@gmail.com im Auftrag von Niclas Hedhman" <hedhman@gmail.com im Auftrag von niclas@hedhman.org>:

    Polygene is highly opinionated, for better and worse. Minimally, Polygene
    requires to start a runtime, and that everything needed is declared
    explicitly upfront at boot time. The minimal start code is something like;
    
    
    public static void main( String[] args )
        throws Exception
    {
        app = new SingletonAssembler( module -> {
            module.transients( Boiler.class, Ahu.class, Fan.class )
                  .withMixins( Plc4xBackingPropertyMixin.class );
    
            module.services( Plc4xPollService.class )
                  .withMixins( Plc4xModbusDriver.class );
            :
            :
        } );
    }
    
    
    If one wants to implement additional behavior in the Boiler class, then you
    create Mixin classes. Let's say we want to capture the temperature once an
    hour.
    
    @Mixins(HistoryMixin.class)
    interface Boiler
    {
        @Plc4x( url="s7://......", period=60000 )
        Property<Double> temperature();
    
        List<Double> temperatureHistory();
    }
    
    public abstract class HistoryMixin
        implements Boiler, Scheduled
    {
        int maxHours = 24;
    
        LinkedBlockingDeque<Double> history = new LinkedBlockingDeque<>();
    
        @Override
        public void tick()
        {
            Double value = temperature().get();
            history.addLast(value);
            while( history.size() > maxHours )
            {
                history.removeFirst();
            }
        }
    
        @Override
        public List<Double> temperatureHistory()
        {
            return new ArrayList<>( history );
        }
    }
    
    
    Above, let's say that "Scheduled" is a service to allow something to get a
    tick() upon some period/interval. What I want to draw attention to is that
    the HistoryMixin is implementing only the method(s) it need to, and that
    the Boiler interface can declare such permanent functionality as an
    annotation, instead of as a start-up declaration in the assembly. The fact
    that the Mixin is abstract is handled by the runtime and it will compose
    all these individual (so called) fragments into a single object (we call it
    a Composite) when you instantiate it from the builder.
    
    It is a whole new different way of writing software. Some people love it,
    and others have a hard time understanding how it can possibly work. Just
    scratching the surface, and please read
    https://hedhman.wordpress.com/2017/05/10/introducing-apache-polygene/ for a
    larger introduction to the subject.
    
    
    If you don't want to write the entire project in Polygene "style", you need
    to either use the Spring library bridge (possibly need upgrade that one a
    bit), where each Service in Polygene will show up as a Spring bean, or
    leverage various points of external hooks for Polygene, such
    importedServices.
    
    
    Don't want to bore you too much.
    
    
    My actual main point was that your suggestion/idea can quickly become quite
    a large undertaking and detract from the primary focus that (I think) PLC4X
    should have. And bringing up Polygene was more to show that what you
    suggest can be done very easily already in Polygene, and all that work
    wouldn't be needed.
    
    
    Cheers
    Niclas
    
    
    On Tue, Mar 6, 2018 at 4:35 AM, Christofer Dutz <ch...@c-ware.de>
    wrote:
    
    > Hi Niclas,
    >
    > after recovering from that nasty Flu, that is plaguing Germany at the
    > moment, I am working on catching up on what I missed.
    > I tried to follow, but some things I felt to worn out to work my head
    > around.
    >
    > Could you elaborate a little on Ploygene? How would this allow extending
    > our requests with additional magic? Does this work in a simple way: No need
    > to configure plugins, code generation or learn some complex API? I would
    > like to keep PLC4X as simple as possible, but as extendable as possible.
    >
    > So I'm always open for new ideas (
    >
    > Chris
    >
    >
    >
    > Am 20.02.18, 03:32 schrieb "hedhman@gmail.com im Auftrag von Niclas
    > Hedhman" <hedhman@gmail.com im Auftrag von niclas@hedhman.org>:
    >
    >     Being the Overlord of Magic that can be done in Java, I have some
    > comments
    >     to make on this idea.
    >
    >     1. In principle what you suggest can already be done quite easily in
    > Apache
    >     Polygene, by creating a "generic mixin" that overrides the generic
    >     PropertyMixin. Polygene is probably way more powerful than anything you
    >     could dream up here. Although Polygene has a strong JSON serialization
    > and
    >     persistence "story", both fully pluggable, it does not use the Glasgow
    >     spec, a.k.a JavaBeans, a.k.a "getter/setter naming convention", which
    > has
    >     been plaguing the Java community for 2 decades now.
    >     If I created a Plc4xBackingPropertyMixin, which I think would only
    > take a
    >     few hours, maybe a couple of days, depending on how advance we want
    > it, you
    >     would end up with;
    >
    >
    >
    >
    >     *public interface Boiler{*
    >
    >     *    @Plc4x( url="s7://......", period=5000, priority=low )*
    >
    >
    >     *    Property<Boolean> running();*
    >
    >     *    @Plc4x( url="s7://......", direction=out )*
    >
    >
    >     *    Property<Boolean> onoff();*
    >
    >     *    @Plc4x( url="s7://......", period=500, priority=high )*
    >
    >
    >
    >     *    Property<Boolean> alarm();    @Plc4x( url="s7://......",
    > period=5000,
    >     priority=normal )*
    >
    >     *    Property<Double> temperature();*
    >     *}*
    >
    >     and in the "assembly", we would need to override the default
    > PropertyMixin,
    >     by doing;
    >
    >         *module.transients( Boiler.class ).withMixins(
    >     Plc4xBackingPropertyMixin.class );*
    >
    >     That said, Apache Polygene is quite overwhelming for new users, so
    > although
    >     the idea is very persuasive for myself, I am under no illusion that
    > others
    >     are as easily convinced. And it is quite likely that I will create
    > this,
    >     since you brought it up, and the effort is rather small.
    >
    >
    >     2. I have been doing PLC Master apps in Java since 1997 (and other
    >     languages since 1984), and experience tells me that the biggest
    > challenge
    >     for really large applications is how to handle "permanent" vs
    > "temporary"
    >     values. What do I mean? In really large systems, it is not feasible to
    > scan
    >     all variables at all times. The latency will not be acceptable.
    > Instead, we
    >     acknowledge that many values are only of interest when someone is
    > looking
    >     at them, be it a person or a datalogger. Not saying it is unsolvable,
    > but
    >     it adds a fair bit of complexity in a Java world with GC, and relying
    > on
    >     finalize() is not really a solution and the outside
    > "javabeans-friendly"
    >     frameworks are clueless about resource management.
    >
    >     GutFeeling(tm) says that this can and should probably be postponed
    > until we
    >     have more experience and made all compatibility-breaking changes that
    > comes
    >     along the way.
    >
    >
    >
    >     Cheers
    >     Niclas
    >
    >
    >     On Tue, Feb 20, 2018 at 5:32 AM, Christofer Dutz <
    > christofer.dutz@c-ware.de>
    >     wrote:
    >
    >     > Hi Dale,
    >     >
    >     > The direction thing was inspired by the way the Beckhoff ADS
    > protocol was
    >     > designed.
    >     >
    >     > There they sometimes Send Data alongside read requests and sometimes
    > have
    >     > strange "return what's in there and then overwrite with this" type of
    >     > requests.
    >     > The Beckhoff support guy mentioned that they are used quite a lot.
    >     >
    >     > That was the main reasoning for me mentioning the direction thing. In
    >     > general this could be set to a default of being bedirectional.
    >     >
    >     > Chris
    >     >
    >     >
    >     > Am 19.02.18, 18:25 schrieb "Dale LaBossiere" <dm...@gmail.com>:
    >     >
    >     >     Doesn’t the user need access to the response code for each
    > annotated
    >     > item?
    >     >
    >     >     I’m unclear on why a Direction is needed/desired.  Is it just for
    >     > “documentation" of what is possible for an item at that address?
    > Maybe it
    >     > would be checked when the annotated class is used in a Read vs Write
    >     > request to verify the request makes sense for that item?  Or… ?
    >     >
    >     >     Could you provide some small pseudo-code of how the app would
    > use the
    >     > API with such an annotated class.
    >     >
    >     >     class MyAnnotatedClass { … };
    >     >     PlcConnection connection = PlcDriver(…);
    >     >
    >     >     // make a read requests
    >     >     …?
    >     >
    >     >     // access data in the responses
    >     >     …?
    >     >
    >     >     — Dale
    >     >
    >     >
    >     >     > On Feb 19, 2018, at 6:16 AM, Christofer Dutz <
    >     > christofer.dutz@c-ware.de> wrote:
    >     >     >
    >     >     > Hi,
    >     >     >
    >     >     > in the past I have been thinking how we can make the batch
    > reads as
    >     > simple as possible.
    >     >     >
    >     >     > I would like to introduce an idea I had:
    >     >     >
    >     >     > What if we started supporting annotated POJO classes? (The
    > following
    >     > names are just ideas …)
    >     >     >
    >     >     > A POJO class could be annotated with some “@PlcEntity”
    > annotation.
    >     >     > A property inside one of these classes could then be annotated
    > with
    >     > “@PlcProperty”
    >     >     > This PlcProperty could have the following attributes:
    >     >     >
    >     >     >  *   Direction (Read/Write/Read&Write)
    >     >     >  *   Property (Name of a property that provides the address in
    > the
    >     > PLC)
    >     >     >  *   Address (Alternative to provide the address directly and
    > give
    >     > up on the flexibility to change the PLC-type / Protocol)
    >     >     >
    >     >     > Providing would definitely be the less preferred option, but I
    > guess
    >     > we would have to provide a way that is extremely simple for new
    > developers
    >     > to get started. I wouldn’t want to overwhelm them with too much
    > magic in
    >     > the start.
    >     >     >
    >     >     > The connection could be extended to look a (configurable)
    > property
    >     > file. A property property (😉) would then use this property map in
    > the
    >     > connection to get the real address string for the given property -
    > hereby
    >     > keeping the full portability.
    >     >     >
    >     >     > Maybe it would be better to have two separate property
    > annotations:
    >     > one for property-based and one for hard-coded address strings.
    >     >     >
    >     >     > The benefit would be that we then could simplify the
    > integrations to
    >     > frameworks like Edgent as we could create sources and sinks based on
    > the
    >     > POJO type.
    >     >     >
    >     >     > What do you think?
    >     >     >
    >     >     > Chris
    >     >
    >     >
    >     >
    >     >
    >
    >
    >     --
    >     Niclas Hedhman, Software Developer
    >     http://polygene.apache.org - New Energy for Java
    >
    >
    >
    
    
    -- 
    Niclas Hedhman, Software Developer
    http://polygene.apache.org - New Energy for Java
    


Re: Batch reads with JPA like annotation magic?

Posted by Niclas Hedhman <ni...@hedhman.org>.
Polygene is highly opinionated, for better and worse. Minimally, Polygene
requires to start a runtime, and that everything needed is declared
explicitly upfront at boot time. The minimal start code is something like;


public static void main( String[] args )
    throws Exception
{
    app = new SingletonAssembler( module -> {
        module.transients( Boiler.class, Ahu.class, Fan.class )
              .withMixins( Plc4xBackingPropertyMixin.class );

        module.services( Plc4xPollService.class )
              .withMixins( Plc4xModbusDriver.class );
        :
        :
    } );
}


If one wants to implement additional behavior in the Boiler class, then you
create Mixin classes. Let's say we want to capture the temperature once an
hour.

@Mixins(HistoryMixin.class)
interface Boiler
{
    @Plc4x( url="s7://......", period=60000 )
    Property<Double> temperature();

    List<Double> temperatureHistory();
}

public abstract class HistoryMixin
    implements Boiler, Scheduled
{
    int maxHours = 24;

    LinkedBlockingDeque<Double> history = new LinkedBlockingDeque<>();

    @Override
    public void tick()
    {
        Double value = temperature().get();
        history.addLast(value);
        while( history.size() > maxHours )
        {
            history.removeFirst();
        }
    }

    @Override
    public List<Double> temperatureHistory()
    {
        return new ArrayList<>( history );
    }
}


Above, let's say that "Scheduled" is a service to allow something to get a
tick() upon some period/interval. What I want to draw attention to is that
the HistoryMixin is implementing only the method(s) it need to, and that
the Boiler interface can declare such permanent functionality as an
annotation, instead of as a start-up declaration in the assembly. The fact
that the Mixin is abstract is handled by the runtime and it will compose
all these individual (so called) fragments into a single object (we call it
a Composite) when you instantiate it from the builder.

It is a whole new different way of writing software. Some people love it,
and others have a hard time understanding how it can possibly work. Just
scratching the surface, and please read
https://hedhman.wordpress.com/2017/05/10/introducing-apache-polygene/ for a
larger introduction to the subject.


If you don't want to write the entire project in Polygene "style", you need
to either use the Spring library bridge (possibly need upgrade that one a
bit), where each Service in Polygene will show up as a Spring bean, or
leverage various points of external hooks for Polygene, such
importedServices.


Don't want to bore you too much.


My actual main point was that your suggestion/idea can quickly become quite
a large undertaking and detract from the primary focus that (I think) PLC4X
should have. And bringing up Polygene was more to show that what you
suggest can be done very easily already in Polygene, and all that work
wouldn't be needed.


Cheers
Niclas


On Tue, Mar 6, 2018 at 4:35 AM, Christofer Dutz <ch...@c-ware.de>
wrote:

> Hi Niclas,
>
> after recovering from that nasty Flu, that is plaguing Germany at the
> moment, I am working on catching up on what I missed.
> I tried to follow, but some things I felt to worn out to work my head
> around.
>
> Could you elaborate a little on Ploygene? How would this allow extending
> our requests with additional magic? Does this work in a simple way: No need
> to configure plugins, code generation or learn some complex API? I would
> like to keep PLC4X as simple as possible, but as extendable as possible.
>
> So I'm always open for new ideas (
>
> Chris
>
>
>
> Am 20.02.18, 03:32 schrieb "hedhman@gmail.com im Auftrag von Niclas
> Hedhman" <hedhman@gmail.com im Auftrag von niclas@hedhman.org>:
>
>     Being the Overlord of Magic that can be done in Java, I have some
> comments
>     to make on this idea.
>
>     1. In principle what you suggest can already be done quite easily in
> Apache
>     Polygene, by creating a "generic mixin" that overrides the generic
>     PropertyMixin. Polygene is probably way more powerful than anything you
>     could dream up here. Although Polygene has a strong JSON serialization
> and
>     persistence "story", both fully pluggable, it does not use the Glasgow
>     spec, a.k.a JavaBeans, a.k.a "getter/setter naming convention", which
> has
>     been plaguing the Java community for 2 decades now.
>     If I created a Plc4xBackingPropertyMixin, which I think would only
> take a
>     few hours, maybe a couple of days, depending on how advance we want
> it, you
>     would end up with;
>
>
>
>
>     *public interface Boiler{*
>
>     *    @Plc4x( url="s7://......", period=5000, priority=low )*
>
>
>     *    Property<Boolean> running();*
>
>     *    @Plc4x( url="s7://......", direction=out )*
>
>
>     *    Property<Boolean> onoff();*
>
>     *    @Plc4x( url="s7://......", period=500, priority=high )*
>
>
>
>     *    Property<Boolean> alarm();    @Plc4x( url="s7://......",
> period=5000,
>     priority=normal )*
>
>     *    Property<Double> temperature();*
>     *}*
>
>     and in the "assembly", we would need to override the default
> PropertyMixin,
>     by doing;
>
>         *module.transients( Boiler.class ).withMixins(
>     Plc4xBackingPropertyMixin.class );*
>
>     That said, Apache Polygene is quite overwhelming for new users, so
> although
>     the idea is very persuasive for myself, I am under no illusion that
> others
>     are as easily convinced. And it is quite likely that I will create
> this,
>     since you brought it up, and the effort is rather small.
>
>
>     2. I have been doing PLC Master apps in Java since 1997 (and other
>     languages since 1984), and experience tells me that the biggest
> challenge
>     for really large applications is how to handle "permanent" vs
> "temporary"
>     values. What do I mean? In really large systems, it is not feasible to
> scan
>     all variables at all times. The latency will not be acceptable.
> Instead, we
>     acknowledge that many values are only of interest when someone is
> looking
>     at them, be it a person or a datalogger. Not saying it is unsolvable,
> but
>     it adds a fair bit of complexity in a Java world with GC, and relying
> on
>     finalize() is not really a solution and the outside
> "javabeans-friendly"
>     frameworks are clueless about resource management.
>
>     GutFeeling(tm) says that this can and should probably be postponed
> until we
>     have more experience and made all compatibility-breaking changes that
> comes
>     along the way.
>
>
>
>     Cheers
>     Niclas
>
>
>     On Tue, Feb 20, 2018 at 5:32 AM, Christofer Dutz <
> christofer.dutz@c-ware.de>
>     wrote:
>
>     > Hi Dale,
>     >
>     > The direction thing was inspired by the way the Beckhoff ADS
> protocol was
>     > designed.
>     >
>     > There they sometimes Send Data alongside read requests and sometimes
> have
>     > strange "return what's in there and then overwrite with this" type of
>     > requests.
>     > The Beckhoff support guy mentioned that they are used quite a lot.
>     >
>     > That was the main reasoning for me mentioning the direction thing. In
>     > general this could be set to a default of being bedirectional.
>     >
>     > Chris
>     >
>     >
>     > Am 19.02.18, 18:25 schrieb "Dale LaBossiere" <dm...@gmail.com>:
>     >
>     >     Doesn’t the user need access to the response code for each
> annotated
>     > item?
>     >
>     >     I’m unclear on why a Direction is needed/desired.  Is it just for
>     > “documentation" of what is possible for an item at that address?
> Maybe it
>     > would be checked when the annotated class is used in a Read vs Write
>     > request to verify the request makes sense for that item?  Or… ?
>     >
>     >     Could you provide some small pseudo-code of how the app would
> use the
>     > API with such an annotated class.
>     >
>     >     class MyAnnotatedClass { … };
>     >     PlcConnection connection = PlcDriver(…);
>     >
>     >     // make a read requests
>     >     …?
>     >
>     >     // access data in the responses
>     >     …?
>     >
>     >     — Dale
>     >
>     >
>     >     > On Feb 19, 2018, at 6:16 AM, Christofer Dutz <
>     > christofer.dutz@c-ware.de> wrote:
>     >     >
>     >     > Hi,
>     >     >
>     >     > in the past I have been thinking how we can make the batch
> reads as
>     > simple as possible.
>     >     >
>     >     > I would like to introduce an idea I had:
>     >     >
>     >     > What if we started supporting annotated POJO classes? (The
> following
>     > names are just ideas …)
>     >     >
>     >     > A POJO class could be annotated with some “@PlcEntity”
> annotation.
>     >     > A property inside one of these classes could then be annotated
> with
>     > “@PlcProperty”
>     >     > This PlcProperty could have the following attributes:
>     >     >
>     >     >  *   Direction (Read/Write/Read&Write)
>     >     >  *   Property (Name of a property that provides the address in
> the
>     > PLC)
>     >     >  *   Address (Alternative to provide the address directly and
> give
>     > up on the flexibility to change the PLC-type / Protocol)
>     >     >
>     >     > Providing would definitely be the less preferred option, but I
> guess
>     > we would have to provide a way that is extremely simple for new
> developers
>     > to get started. I wouldn’t want to overwhelm them with too much
> magic in
>     > the start.
>     >     >
>     >     > The connection could be extended to look a (configurable)
> property
>     > file. A property property (😉) would then use this property map in
> the
>     > connection to get the real address string for the given property -
> hereby
>     > keeping the full portability.
>     >     >
>     >     > Maybe it would be better to have two separate property
> annotations:
>     > one for property-based and one for hard-coded address strings.
>     >     >
>     >     > The benefit would be that we then could simplify the
> integrations to
>     > frameworks like Edgent as we could create sources and sinks based on
> the
>     > POJO type.
>     >     >
>     >     > What do you think?
>     >     >
>     >     > Chris
>     >
>     >
>     >
>     >
>
>
>     --
>     Niclas Hedhman, Software Developer
>     http://polygene.apache.org - New Energy for Java
>
>
>


-- 
Niclas Hedhman, Software Developer
http://polygene.apache.org - New Energy for Java