If the caller can say ‘know’ all the possible addresses ahead of time,
maybe there could be conceptually a ‘plan’ built, that would optionally be
used by the request builder
to build the best request, and cache extra data for some period of time.

So I want to read a single byte, the plan could build an optimized request
for a block of bytes or returned the cache value if that block had been
read in a configured period.

Implementations of the planner ( like a sql query optimizer maybe ) could
be specific to the driver or you could inject your own.


On December 18, 2018 at 23:04:23, Greg Trasuk (tras...@trasuk.com) wrote:


Hello all,

Years ago I went through implementing an interface to a couple of
Allen-Bradley products, and I faced the same question of how to optimize
the reading and writing operations. What I settled on, instead of trying to
micro-optimize individual operations, was to implement a “scan list”, which
could then be optimized. The idea is to define a set of PLC addresses that
need to be read or written on a regular basis. I had an xml definition that
looked a lot like this:

<plc-link ip-address=“192.168.1.5" port='2222'
plc-type='slc5' protocol=‘CSP’ optimize=‘yes'>

<scan-set period='45' optimize='false'
description='Questionable Addresses-isolated for non-optimized debug'>
<read-from-plc>
<tag name="Prod.Temp.East" address="F8:7"/>
<tag name="Prod.Temp.West" address="F8:6"/>
</read-from-plc>
</scan-set>

<scan-set period="2.1" description="Shift Enable">
<write-to-plc>
<tag name="Enable.Shift" address="B3:0/5"/>
<tag name="Enable.ProductionShift" address="B3:59/5"/>
</write-to-plc>
</scan-set>

<scan-set period='45' description='SMT Area Operating Data'>
<read-from-plc>
<tag name="L1.DowntimeMinutes.Shift" address="N100:0"/>
<tag name='L1.Uptime' address='N102:0'/>
<tag name='L1.UtilizationDowntime' address='N102:1'/>
<tag name='L1.TotalUtilizationTime' address='N102:2'/>
<tag name='L1.NonUtilizationDowntime' address='N102:3'/>
<tag name='L1.NumberOfBreakdowns' address='N102:4'/>
<tag name='L1.NumberOfBoards' address='N102:5'/>
<tag name='L1.Utilization' address='F108:1'/>
<tag name='L1.PercentDowntime' address='F108:3'/>
<tag name='L1.MaintenanceResponseAverage' address='F108:4'/>
<tag name="L1.MaintenanceResponseMinutes.Shift" address="N100:1"/>
<tag name="L1.MaterialShort.Shift" address="N113:0"/>
<tag name="L1.Setup.Shift" address="N113:2"/>
<tag name="L1.LunchBreak.Shift" address="N113:3"/>
<tag name="L1.Meetings.Shift" address="N113:4"/>
<tag name="L1.Idle.Shift" address="N113:5"/>
<tag name="L1.PM.Shift" address="N113:7"/>
<tag name="L1.Breakdown.Shift" address="N113:8"/>
<tag name="L1.Other.Shift" address="N113:10"/>
</read-from-plc>

</scan-set>
</plc-link>

The client of this scanner gets a reference to a “SharedDataStore” in which
they can look up tag values by name, and write data to the tagged value.
The data is synchronized to the PLC according to the ‘period’ that’s set on
the scan-set.

This worked out well, because it represents the intentions of the
programmer directly (e.g. read this block of tags every 45 seconds), and
then the system can optimize the read/write methods to fulfill that
intention. For instance, you can look at the block and coalesce any
sequential addresses into a block read rather than a single-address read,
if the PLC supports that. On the AB SLC, that turned out to be a quite
useful optimization. It’s also possible to flag situations where the
scanset targets are not fulfilled (e.g. it took 60 seconds to read the
block when the scanset called for 45 seconds).

Just something to think about.

Cheers,

Greg Trasuk

> On Dec 18, 2018, at 12:25 PM, Christofer Dutz <christofer.d...@c-ware.de>
wrote:
>
> Hi all,
>
> right now the S7 driver is the only driver that makes use of dynamically
rewriting a message.
>
> This is for example needed in order to allow reading of large read
requests and having the driver split that up into multiple messages.
> Ideally it would not only split up the messages, but also optimize the
requests by rearranging the order of requested elements or completely
rewriting the requests (Replace reading of 10 separate bit addresses by for
example simply reading 3 bytes)
>
> As I’m currently defining some quite generic methods in the
protocol-model, I think it would be a better Idea to solve this problem in
a more generic way as I believe most optimizations would apply to most
protocols.
> Also would I like to have this configurable: Here I would imagine that we
provide what we think is a good implementation for the individua driver but
allow overriding processors by adding alternate implementations to the
class-path and allowing to override the processor in the connection-string.
>
> I was thinking of using the same mechanism (Java Service Lookup) as we
are using for the drivers themselves.
>
> What do you think?
>
> Chris

Reply via email to