datalogger.py 6.97 KB
#!/usr/bin/env python

# -*- coding: utf-8 -*-

import argparse, time, os, instruments, inspect

#==============================================================================

# Path
PATH = os.getcwd()
# Sampling time acquisition
SAMPLING_TIME = 1
# File duration
FILE_DURATION = 3600*24
# Default instrument
INSTRUMENT = None
# Default instrument adress
ADRESS = None
#Default val type
VAL_TYPE = None

#==============================================================================

def parse():
    """
    Specific parsing procedure for transfering data from any abstract instrument.
    :returns: populated namespace (parser)
    """

    parser = argparse.ArgumentParser(description = 'Acquire data from INSTRUMENT',
                                     epilog = 'Example: \'./datalogger.py -i myInstrument -st 10\' logs myInstrument every 10 seconds to output file YYYYMMDD-HHMMSS-INSTRUMENT.dat')

    parser.add_argument('-l',
                        action='store_true',
                        dest='list',
                        default=False,
                        help='List all available instruments')

    parser.add_argument('-I',
                        action='store',
                        dest='instLog',
                        default=INSTRUMENT,
                        help='Instrument to log (default '+str(INSTRUMENT)+')')

    parser.add_argument('-ip',
                        action='store',
                        dest='adress',
                        default=ADRESS,
                        help='Adress of instrument (IP, USB...) (default '+str(ADRESS)+')')

    parser.add_argument('-v',
                        action='store',
                        dest='vtype',
                        default=VAL_TYPE,
                        help='Value type to measure (default '+str(VAL_TYPE)+')')

    parser.add_argument('-st',
                        action='store',
                        dest='samplingtime',
                        default=SAMPLING_TIME,
                        help='Sampling time acquistion (default '+str(SAMPLING_TIME)+' second)')

    parser.add_argument('-fd',
                        action='store',
                        dest='fileduration',
                        default=FILE_DURATION,
                        help='File duration (infinite : \'-fd -1\') (default '+str(FILE_DURATION)+' second)')

    parser.add_argument('-p',
                        action='store',
                        dest='path',
                        default=PATH,
                        help='Absolute path (default '+PATH+')')

    args = parser.parse_args()
    return args

#==============================================================================

def acq_routine(instrument, path, samplingtime, fileduration):
    instrument.connect()
    t0 = time.time()
    filename = time.strftime("%Y%m%d-%H%M%S", time.gmtime(t0)) + '-' + instrument.model() + '.dat'
    print('Opening %s' %filename)
    try:
        year = time.strftime("%Y", time.gmtime(t0))
        month = time.strftime("%Y-%m", time.gmtime(t0))
        os.chdir(path + '/' + year + '/' + month)
    except:
        try:
            os.chdir(path + '/' + year)
            os.mkdir(month)
            os.chdir(path + '/' + year + '/' + month)
        except:
            os.chdir(path)
            os.mkdir(year)
            os.chdir(path + '/' + year)
            os.mkdir(month)
            os.chdir(path + '/' + year + '/' + month)

    data_file = open(filename, 'wr', 0)

    # Infinite loop
    while True:
        # tic
        tic = time.time()

        if time.time() - t0 >= fileduration:
            t0 = time.time()
            print('Closing %s\n' %filename)
            data_file.close()

            try:
                year = time.strftime("%Y", time.gmtime(t0))
                month = time.strftime("%Y-%m", time.gmtime(t0))
                os.chdir(path + '/' + year + '/' + month)
            except:
                try:
                    os.chdir(path + '/' + year)
                    os.mkdir(month)
                    os.chdir(path + '/' + year + '/' + month)
                except:
                    os.chdir(path)
                    os.mkdir(year)
                    os.chdir(path + '/' + year)
                    os.mkdir(month)
                    os.chdir(path + '/' + year + '/' + month)

            filename = time.strftime("%Y%m%d-%H%M%S", time.gmtime(t0)) + '-' + instrument.model() + '.dat'
            print('Opening %s\n' %filename)
            data_file = open(filename, 'wr', 0)

        try:
            try:
                #epoch time
                epoch = time.time()
                #MJD time
                mjd = epoch / 86400.0 + 40587
                # Meas values
                meas = instrument.getValue()
                meas = meas.replace(",", "\t")
                meas = meas.replace(";", "\t")
                meas = meas.replace("+", "")

                string = "%f\t%f\t%s" % (epoch, mjd, meas)
                data_file.write(string) # Write in a file
                print(string)

                # Sleep until sampletime
                time.sleep(samplingtime - (time.time() - tic))

            except Exception as ex:
                print 'Exception during controler data reading: ' + str(ex)

        except KeyboardInterrupt:
            print '\n  --> Disconnected'
            instrument.disconnect()
            data_file.close()

            # To stop the loop in a clean way
            break

#==============================================================================

def main():
    """
    Main script
    """
    # Parse command line
    args = parse()
    # path
    path = args.path
    # Sampling time
    samplingtime=float(args.samplingtime)
    # File duration
    fileduration=int(args.fileduration)
    # Instrument to log
    instLog = args.instLog
    # instrument adress
    adress = args.adress
    # val type
    vtype = args.vtype

    try:
        if args.list:
            print('\nInstruments:')
            for name, obj in inspect.getmembers(instruments):
                if inspect.ismodule(obj) and name.startswith('__') == False and name.startswith('abstract') == False:
                    print('\n' + name)
                    exec('print("\t" + instruments.%s.ALL_VAL_TYPE)'%name)

        else:
            if instLog == None:
                raise Exception('No instrument selected !')

            if adress == None and vtype == None:
                exec('myInstrument = instruments.%s.%s()'%(instLog, instLog))
            elif adress == None and vtype != None:
                exec('myInstrument = instruments.%s.%s(vtype="%s")'%(instLog, instLog, vtype))
            elif adress != None and vtype != None:
                exec('myInstrument = instruments.%s.%s(adress="%s", vtype="%s")'%(instLog, instLog, adress, vtype))
            acq_routine(myInstrument, path, samplingtime, fileduration)

    except Exception as ex:
            print 'Oops: '+str(ex)

#==============================================================================

if __name__ == "__main__":
    main()