datalogger.py 5.54 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()