Python Forum

Full Version: Parse Binary Data File and convert Epoch Time
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello All!

I am trying to extract and convert data from a binary data file. Each data entry follows this order:
  • sample time in seconds since unix epoch, 4 bytes
  • 2 byte integer
  • 2 byte integer
  • 2 byte integer
  • 2 byte integer

All values are integers

Below is the code I'm using based off a different binary data extraction project. It exports the correct number of data entries but the values do not make sense. I know I'm not parsing the binary file correctly but I;m not sure how to do the date conversion. Thanks!

import math, struct, time

field_names = ('time1', 'vol_conc', 'part_size', \
          'opt_trans', 'laser_ref')

def decode(data, offset=0):
    '''Decipher a lisst datagram from binary'''

    # Offset now tells it how far to start
    with open('li0002a', 'rb') as data:
        values = struct.unpack('i4h', data.read(12))

    # Create a dictionary for all the values
    lisst_values = dict(zip (field_names, values))

    return lisst_values

def lisst_print(lisst_values):
    'Print out all the values of a lisst dictionary'
    print 'results:'
    for key in lisst_values:
        print '    ', key, lisst_values[key]

datagram_size = 12 # 2*6 bytes per datagram

def num_datagrams(data):
    #How many packets are in data'

    # Make sure we have an even number of datagrams
    #assert (len(data) % datagram_size == 0)

    return len(data) / datagram_size

def get_offset(datagram_number):
    'Calculate the starting offset of a datagram'
    return datagram_number * datagram_size

def main():
    lisst_file = open('li0002a')
    lisst_data = lisst_file.read()

    print 'Number of datagrams:', num_datagrams(lisst_data)

    print 'Datagram Number, Time, Volume Concentration, Particle Size,\
 Optical Transmission, Laser Reference '

    for datagram_index in range( num_datagrams(lisst_data) ):
        offset = get_offset(datagram_index)
        datagram = decode(lisst_data,offset)

        print datagram_index, datagram['time1'], datagram['vol_conc'], datagram['part_size'], \
             datagram['opt_trans'], datagram['laser_ref']

if __name__=='__main__':
    main()
pure binary as in a block of memory is arranged in machine addressing order, big or little endian, so your 4 byte value.
so you may have to do some transformations, Here's a good doc for that: https://wiki.python.org/moin/BitManipulation