I previously have blogged about the TkbmMWBinaryParser which use special defined definition files for parsing binary data. (Check this blog)

This is a short blog about a new feature, included in kbmMW Enterprise Edition which makes it simple to visualizing the definition file and the data to be parsed.

You will find the demos in kbmMW to have been updated, to include the binary parser visualizer, and showing how to step thru data, while visualizing what fails and what succeeds during the parse.

A picture is worth many words… so here goes. This is a screenshot of the included demo:

The visualizer is in the center. It shows optionally the data being parsed (in magenta) followed by the definition (everything else).

Specific bit definitions are shown in blue, tags and subtags are in green, and constant bitmasks/values are in black.

When parsing non matching data, it is showing failed parts as red. This way its easy to see what match and what doesn’t according to the given definition.

The definition for the above visualization is shown in the end of this blog for the curious.

kbmMW also includes a couple of readers which makes reading files and streams easy. For example TkbmMWBPFileReader.

The simple setup is:

// Keep rd alive while you visualize.
rd:TkbmMWBPFileReader;
..
  // Tell file reader which definition file to use while parsing.
  rd:=TkbmMWBPFileReader.Create('toledo.yaml');
  kbmMWBinaryVisualizer1.Parser:=rd.Parser;
..
  // Tell file reader which binary file to parse.
  rd.Step('somebinaryfile.bin');

  // Step more on same file.
  rd.Step;
..

The Options property of the visualizer controls what you want to see:

TkbmMWBPVisalizerOption = (mwbpvoShowData,mwbpvoShowOnlyTouched,mwbpvoShowOnlyTouchedData);

  • mwbpvoShowData – Hexdump of the data is visualized.
  • mwbpvoShowOnlyTouched – Only show parts of the definition which was “touched”. As the parser is a short circuit parser, it will immediately give up parsing the moment something does not match the definition file. Everything matching until that point is “touched”.
  • mwbpvoShowOnlyTouchedData – Only show data which was valid or “touched”.

 

The definition for the above visualization is typically stored in YAML format, but could just as well be stored in JSON, XML or one of the binary formats supported by kbmMW’s object notation framework. YAML just makes it a cleaner read for humans imo.

# Values:
# TARE
# GROSS
# NET
# INCREMENT_SIZE
# STATUS = STATUS_OK, STATUS_DATA_ERROR, STATUS_SCALE_ERROR, STATUS_SCALE_OVERLOAD, 
#          STATUS_IN_MOTION, STATUS_TARE_ERROR, STATUS_TRANSMISSION_ERROR, STATUS_INVALID_COMMAND, STATUS_INVALID_PARAMETER
# IS_POWER_NOT_ZEROED
# IS_SETTLED
# IS_OVERLOAD
# IS_NEGATIVE
# UNIT_WEIGHT = UNIT_GRAM, UNIT_UK_POUND, UNIT_KILOGRAM, UNIT_METRIC_TON, UNIT_OUNCE, UNIT_TROY_OUNCE, UNIT_PENNY_WEIGHT, UNIT_UK_TON, UNIT_CUSTOM
# UNIT_TARE (can take same values as UNIT_WEIGHT)
# WEIGHT_FACTOR
# WEIGHT_EXPANSION
# TARE_FACTOR
# TARE_CODE = TARE_PRESET, TARE_AUTO, TARE_NONE
# TERMINAL_NO
# VALUE = current value during parsing

TOLEDO:
    VALUES: 
        # Unit constants
        # Should update to correct virtual indicator values.
        C_UNIT_GRAM:                 2000
        C_UNIT_UK_POUND:             2001
        C_UNIT_KILOGRAM:             2002
        C_UNIT_METRIC_TON:           2003
        C_UNIT_OUNCE:                2004
        C_UNIT_TROY_OUNCE:           2005
        C_UNIT_PENNY_WEIGHT:         2006
        C_UNIT_UK_TON:               2007
        C_UNIT_CUSTOM:               2008
        
        # Status constants
        # Should update to correct virtual indicator values.
        C_STATUS_OK:                 1000
        C_STATUS_DATA_ERROR:         1001
        C_STATUS_SCALE_ERROR:        1002
        C_STATUS_SCALE_OVERLOAD:     1003 
        C_STATUS_IN_MOTION:          1004
        C_STATUS_TARE_ERROR:         1005
        C_STATUS_TRANSMISSION_ERROR: 1006
        C_STATUS_INVALID_COMMAND:    1007
        C_STATUS_INVALID_PARAMETER:  1008

        # Tare constants
        # Should update to correct virtual indicator values.
        C_TARE_PRESET:               3000
        C_TARE_AUTO:                 3001
        C_TARE_NONE:                 3002
        
        # Default values
        STATUS:                    @C_STATUS_OK
        TARE:                      0
        GROSS:                     0
        NET:                       0
        INCREMENT_SIZE:            1
        IS_POWER_NOT_ZEROED:       false
        IS_SETTLED:                false
        IS_OVERLOAD:               false
        IS_NEGATIVE:               false
        IS_CHECKSUM_OK:            false
        WEIGHT_FACTOR:             1
        TARE_FACTOR:               1
        TARE_CODE:                 @C_TARE_NONE
        TERMINAL_NO:               0
        WEIGHT_UNIT:               @C_UNIT_KILOGRAM
        TARE_UNIT:                 @C_UNIT_KILOGRAM
       
    TELEGRAMS:
         bytes:
              - mask: [ 0x2, @SWA, @SWB, @SWC, 6*@W, 6*@T, 0xD, @CHK ]
                expr: - "WEIGHT_UNIT=IF(IS_UNIT_UK_POUND=1,C_UNIT_POUND,IF(IS_UNIT_KILOGRAM,C_UNIT_KILOGRAM,WEIGHT_UNIT))"
                      - "TARE_UNIT=WEIGHT_UNIT"
                      - "STATUS=IF(IS_CHECKSUM_OK=1,IF(IS_OVERLOAD,C_STATUS_OVERLOAD,C_STATUS_OK),C_STATUS_DATA_ERROR)" 
                      - "WEIGHT=WEIGHT*WEIGHT_EXPANSION*IF(WEIGHT_FACTOR<1,WEIGHT_FACTOR,1)"
                      - "TARE=TARE*TARE_EXPANSION*IF(TARE_FACTOR<1,TARE_FACTOR,1)"
                      - "GROSS=IF(IS_NETTO=0,WEIGHT,0)"
                      - "NET=IF(IS_NETTO=1,WEIGHT,0)"

    TAGS:
    
        SWA: 
         bits:
        # bit offset 0
                mask: [ 0, 0, 1, 2*@IS, 3*@DP ] 

        DP: 
         bits:
        # bit offset 0, 3 bits
              - mask: [ 0, 0, 0 ] 
                expr: [ WEIGHT_FACTOR=100, TARE_FACTOR=100 ]
              - mask: [ 0, 0, 1 ]
                expr: [ WEIGHT_FACTOR=10, TARE_FACTOR=10 ]
              - mask: [ 0, 1, 0 ]
                expr: [ WEIGHT_FACTOR=1, TARE_FACTOR=1 ]
              - mask: [ 0, 1, 1 ]
                expr: [ WEIGHT_FACTOR=0.1, TARE_FACTOR=0.1 ]
              - mask: [ 1, 0, 0 ]
                expr: [ WEIGHT_FACTOR=0.01, TARE_FACTOR=0.01 ]
              - mask: [ 1, 0, 1 ]
                expr: [ WEIGHT_FACTOR=0.001, TARE_FACTOR=0.001 ]
              - mask: [ 1, 1, 0 ]
                expr: [ WEIGHT_FACTOR=0.0001, TARE_FACTOR=0.0001 ]
              - mask: [ 1, 1, 1 ]
                expr: [ WEIGHT_FACTOR=0.00001, TARE_FACTOR=0.00001 ]

        IS:
         bits:
        # bit offset 3, 2 bits
              - mask: [ 0, 1 ]
                expr: INCREMENT_SIZE=1
              - mask: [ 1, 0 ]
                expr: INCREMENT_SIZE=2
              - mask: [ 1, 1 ]
                expr: INCREMENT_SIZE=5
               
        CHK:
         bytes:
                expr: "IS_CHECKSUM_OK=IF(CHK2COMP7(0,17)=VALUE,1,0)"


        SWB:
         bits:
                mask: [ 0, IS_POWER_NOT_ZEROED, 1, IS_UNIT_UK_POUND/IS_UNIT_KILOGRAM, !IS_SETTLED, IS_OVERLOAD, IS_NEGATIVE, IS_NETTO ]

        SWC:
         bits:
                mask: [ 0, IS_HANDTARE, 1, @EW, IS_PRINTREQUEST, 3*@WF ]
         

        WF:
         bits:
              - mask: [ 0, 0, 0 ]

              - mask: [ 0, 0, 1 ]
                expr: [WEIGHT_UNIT=C_UNIT_GRAM, TARE_UNIT=C_UNIT_GRAM ]
              - mask: [ 0, 1, 0 ]
                expr: [WEIGHT_UNIT=C_UNIT_METRIC_TON, TARE_UNIT=C_UNIT_METRIC_TON ]
              - mask: [ 0, 1, 1 ]
                expr: [WEIGHT_UNIT=C_UNIT_OUNCE, TARE_UNIT=C_UNIT_OUNCE ]
              - mask: [ 1, 0, 0 ]
                expr: [WEIGHT_UNIT=C_UNIT_TROY_OUNCE, TARE_UNIT=C_UNIT_TROY_OUNCE ]
              - mask: [ 1, 0, 1 ]
                expr: [WEIGHT_UNIT=C_UNIT_PENNY_WEIGHT, TARE_UNIT=C_UNIT_PENNY_WEIGHT ]
              - mask: [ 1, 1, 0 ]
                expr: [WEIGHT_UNIT=C_UNIT_UK_TON, TARE_UNIT=C_UNIT_UK_TON ]
              - mask: [ 1, 1, 1 ]
                expr: [WEIGHT_UNIT=C_UNIT_CUSTOM, TARE_UNIT=C_UNIT_CUSTOM ]

        EW:
         bits:
              - mask: 0
                expr: [ WEIGHT_EXPANSION=1, TARE_EXPANSION=1 ]
              - mask: 1
                expr: [ WEIGHT_EXPANSION=10, TARE_EXPANSION=10 ]

        W:
         string:
                expr: WEIGHT=VALUE
              
        T:
         string:
                expr: TARE=VALUE
              

 

 

Loading

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.