Hi Julian,

I was thinking about exactly this, this morning in the train on my way to work.
An idea I had was to eventually entirely get rid of the TypesafePlc requests 
and to have 3 or 4 types of items. 
In general a:

IntegerItem
FloatingPointItem
DateItem
StringItem
...

"Integer" in the IntegerItem not relating to the Java Integer, but more the 
"Non-Floating-Point Numeric Value".
Or even merge the numeric values together and provide accessors in the desired 
type.

Something like this:
numericItem.getFloat()
numericItem.getInteger()
numericItem.getFloat()
numericItem.getDouble()
...

Or even:
numericItem.getBooleanArray() 
...

The payload would always be provided in a normalized form that is capable of 
carrying the largest value of that type.
So the dirvers would produce normalized items and the items themselves contain 
what's needed to convert that to one of the other types.

Good idea? Or not so good ... at the moment I sort of like it, but I might not 
have thought about everything.

Chris




Am 20.08.18, 09:47 schrieb "Julian Feinauer" <[email protected]>:

    Hi Chris,
    
    okay, then I had a wrong assumption. Previously, I worked a lot with 
measurement file formats from automotive industry and there you can encounter 
all and everything in one file.
    If it is as you states then I agree that a small set of static util methods 
will do the job.
    
    Only one question remains for me:
    How do we deal with the "requested" type and the "interal Java Type".
    As example, all of these statements should be valid, I think:
    
    RequestItem<Short.class>("DB4.DW4:INT")
    RequestItem<Integer.class>("DB4.DW4:INT")
    RequestItem<Long.class>("DB4.DW4:INT")
    
    But the internal LEConverter.to2ByteInt(...) would return something like a 
Short.class.
    Wouldn't we need to do the casts explicit as otherwise we could receive a 
ClassCastException or something like that?
    
    Best
    Julian
    
    Am 20.08.18, 09:16 schrieb "Christofer Dutz" <[email protected]>:
    
        Hi Julian,
        
        well I don't think this is that much of a problem. Every driver type 
(and sometimes depending on the capabilities of the remote) will map one set of 
types to - let's call them internal Java types.
        If one protocol uses LE, it will for all of its supported types. I have 
never come across a protocol, where some are LE and some are BE. So it's rather:
        
        // Inside the code of driver XYZ
        
        Switch(type) {
                case LINT: 
                        byte[] bytes = // read 4 bytes
                        return LEConverter.toIeeeFloatingPoint(bytes);
                case UINT:
                        ...
        }
        
        Or something like that ... 
        
        What do you think?
        
        Chris
        
        
        Am 17.08.18, 17:03 schrieb "Julian Feinauer" 
<[email protected]>:
        
            Hi Chris,
            
            this is exactly the idea I have in mind.
            
            For me in your step 1 I again see two steps.
            First, you have the decoding logic (e.g. your public static float 
parseIEEE754Float(byte[] in)) and then you have all this ugly branching like
            
            If (bytes.length = 4) {
                If (isDecimal()) {
                        If (isBigEndian()) {
                                // Here call the static helper method
                        }
                }
            }
            
            which I would love to avoid (and which makes it perhaps more 
comfortable for users to implement their drivers).
            
            But perhaps I am making things to complicated and we usually have 
only a small set of possibilities. 
            Then i agree that we could keep things as they are.
            
            Best
            Julian
            
            Am 17.08.18, 15:38 schrieb "Christofer Dutz" 
<[email protected]>:
            
                Hi Julian,
                
                to me it sounds like two separate things:
                1) Decoding what's coming from the outside
                2) Converting the decoded types to other types as far as that's 
possible 
                
                So the driver should know what the bytes mean that come from 
the PLC and on top of that we could convert that into something else. 
                We would need such a two phase conversion to do that anyway, 
otherwise we would sort of need the cartesian set of all combinations of 
converters.
                
                I do agree that this "interpret this integer as a Boolean", or 
"translate this float into an int" sounds universally usable.
                
                Correct?
                
                Chris
                
                
                
                Am 17.08.18, 15:03 schrieb "Julian Feinauer" 
<[email protected]>:
                
                    Hi Chris,
                    
                    you are right with what I want to do, let me explain my 
motivation.
                    Your example is right but I think there are many situations 
where this is not sufficient, especially with regards to the new Address Syntax 
for S7.
                    Basically the new syntax allows me to state something like 
this:
                    
                    "I know that the value is 2 byte unsigned integer in little 
Endian Order and I want it back as Long".
                    
                    So the first idea was that I wanted to avoid having many 
methods for all combinations of Endianness, bit-length, Signed / Unsigned and 
Decimal / Float.
                    And the second idea to also provide narrowing or widening 
or even conversion out of the box.
                    I came across this issue when thinking about the migration 
of the current conversion in the S7 driver which is like a large if 
(XXX.class.isInstance(...)) else... and thought it would be better for the 
drive to just say something like
                    
                    parse(Class<?> target, byte[] in, Representation repr)
                    
                    to avoid the m times n problem for Java Types and byte 
Representation.
                    
                    But if you (and the other driver implementors) do not see 
this concern that much I can also shift my effort to something else.
                    
                    Best
                    Julian
                    
                    
                    
                    Am 17.08.18, 14:41 schrieb "Christofer Dutz" 
<[email protected]>:
                    
                        Hi Julian,
                        
                        please let me repeat how I understood your proposal:
                        You observed that in multiple drivers the conversion 
between byte-array data to the actual Java type is pretty similar and would 
like to wrap that mapping code in some commonly shared code base?
                        
                        I agree ... if a float is transformed as IEEE 754 
Floating Point, it doesn't matter what driver this belongs to. But on the other 
side the code for doing this conversion too isn't that complex.
                        
                        I think in this case eventually even a class with 
static methods should be enough... sort of 
                        
                                public static float parseIEEE754Float(byte[] 
in);
                        
                                public static int parseLE32BitInt(byte[] in);
                        
                                ...
                        
                        Maintaining a registry component that has to be 
injected into the drivers of type conversions where drivers can register custom 
converters sounds a little overkill to me. 
                        If a driver requires other conversions, it can 
implement them itself and if it makes sense to add them to the driver-base 
version, that code is simply moved there.
                        
                        What do you think?
                        
                        Chris
                        
                        
                        
                        Am 17.08.18, 14:14 schrieb "Julian Feinauer" 
<[email protected]>:
                        
                            Hey al,
                            
                            I like to open another discussion as I am currently 
working on another refactoring of the Drivers, namely the extraction of 
"binary" encoders and decoders as common concern. After our discussion about 
the addition of the binary representation to the S7 driver I observed that 
several drivers use very similar code to transform java types to byte 
representations of specific flavor (Big Endian, ...).
                            
                            Thus my aim is to provide a “library” of common 
encoders and decoders between Java Types and byte representations that every 
driver can use but also register custom Java Types and their representation (as 
it is e.g. needed for ADS, I think).
                            
                            Do you agree with this?
                            
                            Julian
                            
                            
                        
                        
                    
                    
                
                
            
            
        
        
    
    

Reply via email to