DreamTeam/parser.py

From Noisebridge
Jump to navigation Jump to search
import struct
from time import time
from numpy import mean
import serial
"""
work in progress - refactoring data acquisition routines - df 15 May 2013
original code from https://github.com/akloster/python-mindwave
"""

class MindWavePacketCodeVals:
	def __init__(self):
		self.standby = 0xd4
		self.connected = 0xd0
		self.raw_value = 0x80
		self.poor_signal = 0x02
		self.esense_attention = 0x04
		self.esense_meditation = 0x05
		self.sensor_data = 0x83

class MindWaveSerialPort:
	def __init__(self):
                self.port = '/dev/ttyUSB0'
		self.baudrate = 115200
		self.timeout = 0.0001
		self.dongle = serial.Serial(port=self.port, baudrate=self.baudrate, timeout=self.timeout)

class Parser:
	def __init__(self):
		self.parser = self.run()
		self.parser.next()  # wtf ?  mmmkay ...  df 15 May 2013
		self.current_vector = []
		self.raw_values = []
		self.current_meditation = 0
		self.current_attention= 0
		self.current_spectrum = []
		self.sending_data = False
		self.state ="initializing"
		self.raw_file = None
		self.esense_file = None
		self.packet_code = MindWavePacketCodeVals()
                self.serial = MindWaveSerialPort()
		self.dongle = self.serial.dongle
		
	def update(self):
		bytes = self.dongle.read(1000)
		for b in bytes:
			self.parser.send(ord(b))	# Send each byte to the generator

	def write_serial(self, string):
		self.dongle.write(string)
	
	def start_raw_recording(self, file_name):
		self.raw_file = file(file_name, "wt")
		self.raw_start_time = time()

	def start_esense_recording(self, file_name):
		self.esense_file = file(file_name, "wt")
		self.esense_start_time = time()

	def stop_raw_recording(self):
		if self.raw_file:
			self.raw_file.close()
			self.raw_file = None
		
	def stop_esense_recording(self):
		if self.esense_file:
			self.esense_file.close()
			self.esense_file = None

	def run(self):
		"""
			This generator is a convoluted mess - df May 2013
		"""
		self.buffer_len = 512*3  # hmmm ... - df May 2013
		while 1:

			# first, check packet sync
			# packet synced by 0xaa 0xaa
			byte = yield
			if byte == 0xaa:
		 		byte = yield
				if byte != 0xaa:
					continue  # sync failed
			else:
				continue  # sync failed

			# packet sync confirmed
			# read length and code
			packet_length = yield
			packet_code = yield

			if packet_code == 0xd4:
				# standing by
				self.dongle_state= "standby"
				continue
			elif packet_code == 0xd0:
				self.dongle_state = "connected"
				continue

			self.sending_data = True
			left = packet_length - 2
			while left > 0:
				if packet_code == 0x80: # raw value
					row_length = yield
					a = yield
					b = yield
					value = struct.unpack("<h",chr(a)+chr(b))[0]
					self.raw_values.append( value )
					if len(self.raw_values) > self.buffer_len:
						self.raw_values = self.raw_values[ -self.buffer_len: ]
					left -= 2
							
					if self.raw_file:
						t = time() - self.raw_start_time
						self.raw_file.write("%.4f,%i\n" %(t, value))

				elif packet_code == 0x02: # Poor signal
					a = yield
					self.poor_signal = a
					if a > 0:
						pass 
					left -= 1
				elif packet_code == 0x04: # Attention (eSense)
					a = yield
					if a > 0 :
						v = struct.unpack("b",chr(a))[0]
						if v > 0:
							self.current_attention = v
							if self.esense_file:
								self.esense_file.write("%.2f,,%i\n" % (time()-self.esense_start_time, v))
					left -= 1
				elif packet_code == 0x05: # Meditation (eSense)
					a = yield
					if a > 0:
						v = struct.unpack("b",chr(a))[0]
						if v > 0:
							self.current_meditation = v
							if self.esense_file:
								self.esense_file.write("%.2f,%i,\n" % (time()-self.esense_start_time, v))

						left -= 1
					elif packet_code == 0x83:
							vlength = yield
							self.current_vector = []
							for row in range(8):
								a = yield
								b = yield
								c = yield
								value = a*255*255+b*255+c
								self.current_vector.append(value)
							left -= vlength
					packet_code = yield