def _processDeviceEventIteration(self): for device in self.devices: try: events = device._getNativeEventBuffer() while len(events) > 0: evt = events.popleft() e = device._getIOHubEventObject(evt) if e is not None: for l in device._getEventListeners(e[DeviceEvent.EVENT_TYPE_ID_INDEX]): l._handleEvent(e) filtered_events = [] for filter in device._filters.values(): filtered_events.extend(filter._removeOutputEvents()) for i in range(len(filtered_events)): e = filtered_events[i] for l in device._getEventListeners(e[DeviceEvent.EVENT_TYPE_ID_INDEX]): l._handleEvent(e) except: printExceptionDetailsToStdErr() print2err("Error in processDeviceEvents: ", device, " : ", len(events), " : ", e) print2err("Event type ID: ",e[DeviceEvent.EVENT_TYPE_ID_INDEX], " : " , EventConstants.getName(e[DeviceEvent.EVENT_TYPE_ID_INDEX])) print2err("--------------------------------------")
def _handleEvents(self, events): try: if self.checkForExperimentAndSessionIDs(len(events)) is False: return False event = events[0] etype = event[DeviceEvent.EVENT_TYPE_ID_INDEX] eventClass = EventConstants.getClass(etype) etable = self.TABLES[eventClass.IOHUB_DATA_TABLE] np_events = [] for event in events: event[DeviceEvent.EVENT_EXPERIMENT_ID_INDEX] = self.active_experiment_id event[DeviceEvent.EVENT_SESSION_ID_INDEX] = self.active_session_id np_events.append(tuple(event)) np_array = np.array(np_events, dtype=eventClass.NUMPY_DTYPE) #ioHub.print2err('np_array:',np_array) etable.append(np_array) self.bufferedFlush(len(np_events)) except ioHubError as e: print2err(e) except Exception: printExceptionDetailsToStdErr()
def initConditionVariableTable( self, experiment_id, session_id, np_dtype): expcv_table = None expcv_node = self.emrtFile.root.data_collection.condition_variables exp_session = [('EXPERIMENT_ID','i4'),('SESSION_ID','i4')] exp_session.extend(np_dtype) np_dtype = [] for npctype in exp_session: if isinstance(npctype[0], str): nv = [str(npctype[0]),] nv.extend(npctype[1:]) np_dtype.append(tuple(nv)) else: np_dtype.append(npctype) self._EXP_COND_DTYPE = np.dtype(np_dtype) try: expCondTableName = "EXP_CV_%d"%(experiment_id) experimentConditionVariableTable = getattr(self.emrtFile.root.data_collection.condition_variables, _f_get_child)(expCondTableName) self.TABLES['EXP_CV'] = experimentConditionVariableTable except NoSuchNodeError as nsne: try: experimentConditionVariableTable = getattr(self.emrtFile, create_table)(self.emrtFile.root.data_collection.condition_variables, expCondTableName, self._EXP_COND_DTYPE, title='Condition Variable Values for Experiment ID %d' % (experiment_id)) self.TABLES['EXP_CV'] = experimentConditionVariableTable self.emrtFile.flush() except Exception: printExceptionDetailsToStdErr() return False except Exception: print2err( 'Error getting expcv_table for experiment %d, table name: %s' % (experiment_id, expCondTableName)) printExceptionDetailsToStdErr() return False self._activeRunTimeConditionVariableTable = expcv_table return True
def checkIfSessionCodeExists(self,sessionCode): try: if self.iohub.emrt_file: return self.iohub.emrt_file.checkIfSessionCodeExists(sessionCode) return False except: printExceptionDetailsToStdErr()
def shutdown(self): try: self._running=False if Computer.system=='linux2': if self._hookManager: self._hookManager.cancel() while len(self.deviceMonitors) > 0: m=self.deviceMonitors.pop(0) m.running=False if self.eventBuffer: self.clearEventBuffer() try: self.closeDataStoreFile() except: pass while len(self.devices) > 0: d=self.devices.pop(0) try: if d is not None: d._close() except: pass gevent.sleep() except: print2err("Error in ioSever.shutdown():") printExceptionDetailsToStdErr()
def run(rootScriptPathDir,configFilePath): import tempfile tdir=tempfile.gettempdir() cdir,cfile=os.path.split(configFilePath) if tdir==cdir: tf=open(configFilePath) ioHubConfig=json.loads(tf.read()) tf.close() os.remove(configFilePath) else: ioHubConfig=load(file(configFilePath,'r'), Loader=Loader) hub_defaults_config=load(file(os.path.join(iohub.IO_HUB_DIRECTORY,'default_config.yaml'),'r'), Loader=Loader) updateDict(ioHubConfig,hub_defaults_config) try: s = ioServer(rootScriptPathDir, ioHubConfig) except Exception,e: printExceptionDetailsToStdErr() sys.stdout.flush() try: s.shutdown() except: pass return -1
def __init__(self, rootScriptPathDir, config=None): self._session_id=None self._experiment_id=None self.log("Server Time Offset: {0}".format(Computer.globalClock.getLastResetTime())) self._hookManager=None self.emrt_file=None self.config=config self.devices=[] self.deviceMonitors=[] self.sessionInfoDict=None self.experimentInfoList=None self.filterLookupByInput={} self.filterLookupByOutput={} self.filterLookupByName={} self._hookDevice=None ioServer.eventBuffer=deque(maxlen=config.get('global_event_buffer',2048)) self._running=True # start UDP service self.udpService=udpServer(self,':%d'%config.get('udp_port',9000)) try: # initial dataStore setup if 'data_store' in config and psychopy.iohub._DATA_STORE_AVAILABLE: experiment_datastore_config=config.get('data_store') default_datastore_config_path=os.path.join(IO_HUB_DIRECTORY,'datastore','default_datastore.yaml') #print2err('default_datastore_config_path: ',default_datastore_config_path) _dslabel,default_datastore_config=load(file(default_datastore_config_path,'r'), Loader=Loader).popitem() for default_key,default_value in default_datastore_config.iteritems(): if default_key not in experiment_datastore_config: experiment_datastore_config[default_key]=default_value if experiment_datastore_config.get('enable', True): #print2err("Creating ioDataStore....") resultsFilePath=rootScriptPathDir self.createDataStoreFile(experiment_datastore_config.get('filename','events')+'.hdf5',resultsFilePath,'a',experiment_datastore_config) #print2err("Created ioDataStore.") except: print2err("Error during ioDataStore creation....") printExceptionDetailsToStdErr() #built device list and config from initial yaml config settings try: for iodevice in config.get('monitor_devices',()): for device_class_name,deviceConfig in iodevice.iteritems(): #print2err("======================================================") #print2err("Started load process for: {0}".format(device_class_name)) self.createNewMonitoredDevice(device_class_name,deviceConfig) except: print2err("Error during device creation ....") printExceptionDetailsToStdErr() raise ioHubError("Error during device creation ....")
def flush(self): try: if self.emrtFile: self.emrtFile.flush() except ClosedFileError: pass except: printExceptionDetailsToStdErr()
def updateDataStoreStructure(self, device_instance, event_class_dict): dfilter = tables.Filters( complevel=0, complib='zlib', shuffle=False, fletcher32=False) for event_cls_name, event_cls in event_class_dict.items(): if event_cls.IOHUB_DATA_TABLE: event_table_label = event_cls.IOHUB_DATA_TABLE if event_table_label not in self.TABLES: try: self.TABLES[event_table_label] = self.emrtFile.createTable( self.groupNodeForEvent(event_cls), self.eventTableLabel2ClassName(event_table_label), event_cls.NUMPY_DTYPE, title='%s Data' % (device_instance.__class__.__name__, ), filters=dfilter.copy()) self.flush() except tables.NodeError: self.TABLES[event_table_label] = self.groupNodeForEvent(event_cls)._f_get_child(self.eventTableLabel2ClassName(event_table_label)) except Exception as e: print2err('---------------ERROR------------------') print2err( 'Exception %s in iohub.datastore.updateDataStoreStructure:' % (e.__class__.__name__)) print2err('\tevent_cls: {0}'.format(event_cls)) print2err( '\tevent_cls_name: {0}'.format(event_cls_name)) print2err( '\tevent_table_label: {0}'.format(event_table_label)) print2err( '\teventTableLabel2ClassName: {0}'.format( self.eventTableLabel2ClassName(event_table_label))) print2err( '\tgroupNodeForEvent(event_cls): {0}'.format( self.groupNodeForEvent(event_cls))) print2err('\nException:') printExceptionDetailsToStdErr() print2err('--------------------------------------') if event_table_label in self.TABLES: self.addClassMapping(event_cls, self.TABLES[event_table_label]) else: print2err( '---- IOHUB.DATASTORE CANNOT ADD CLASS MAPPING ----') print2err( '\t** TABLES missing key: {0}'.format(event_table_label)) print2err('\tevent_cls: {0}'.format(event_cls)) print2err('\tevent_cls_name: {0}'.format(event_cls_name)) print2err( '\teventTableLabel2ClassName: {0}'.format( self.eventTableLabel2ClassName(event_table_label))) print2err('----------------------------------------------')
def shutDown(self): try: self.disableHighPriority() self.iohub.shutdown() self._running=False self.stop() except: print2err("Error in ioSever.shutdown():") printExceptionDetailsToStdErr() sys.exit(1)
def log(self,text,level=None): try: log_time=currentSec() exp=self.deviceDict.get('Experiment',None) if exp and self._session_id and self._experiment_id: while len(self._logMessageBuffer): lm=self._logMessageBuffer.popleft() exp.log(*lm) exp.log(text,level,log_time) else: self._logMessageBuffer.append((text,level,log_time)) except: printExceptionDetailsToStdErr()
def __init__(self,remote_address,sync_state_target): try: Greenlet.__init__(self) self._sync_socket=None self.initial_sync_interval=0.2 self._remote_address=remote_address while self._sync_socket is None: self._sync_socket=ioHubTimeSyncConnection(remote_address) sleep(1) self.sync_state_target=proxy(sync_state_target) except Exception as e: print2err("** Exception during ioHubTimeGreenSyncManager.__init__: ",self._remote_address) printExceptionDetailsToStdErr()
def _initializeConditionVariableTable(self,experiment_id,np_dtype): experimentConditionVariableTable=None self._EXP_COND_DTYPE=N.dtype(np_dtype) try: expCondTableName="EXP_CV_%d"%(experiment_id) experimentConditionVariableTable=self.emrtFile.root.data_collection.condition_variables._f_getChild(expCondTableName) self.TABLES['EXP_CV']=experimentConditionVariableTable except NoSuchNodeError, nsne: try: experimentConditionVariableTable=self.emrtFile.createTable(self.emrtFile.root.data_collection.condition_variables,expCondTableName,self._EXP_COND_DTYPE,title='Condition Variable Values for Experiment ID %d'%(experiment_id)) self.TABLES['EXP_CV']=experimentConditionVariableTable self.emrtFile.flush() except: printExceptionDetailsToStdErr() return False
def log(self,text,level=None): try: log_time=currentSec() exp=self.deviceDict.get('Experiment',None) if exp and self._session_id and self._experiment_id: while len(self._logMessageBuffer): lm=self._logMessageBuffer.popleft() #print2err('>>>!!! Logging BACKLOGGED LogEvent: ',lm,", ",(exp, self._session_id, self._experiment_id)) exp.log(*lm) #print2err('>>>!!! Logging LogEvent: ',(text,level,log_time),", ",(exp, self._session_id, self._experiment_id)) exp.log(text,level,log_time) else: #print2err('>>>!!! Adding LogEvent to _logMessageBuffer: ',(text,level,log_time),", ",(exp, self._session_id, self._experiment_id)) self._logMessageBuffer.append((text,level,log_time)) except: printExceptionDetailsToStdErr()
def _handleEvent(self, event): try: if self.checkForExperimentAndSessionIDs(event) is False: return False etype = event[DeviceEvent.EVENT_TYPE_ID_INDEX] eventClass = EventConstants.getClass(etype) etable = self.TABLES[eventClass.IOHUB_DATA_TABLE] event[DeviceEvent.EVENT_EXPERIMENT_ID_INDEX] = self.active_experiment_id event[DeviceEvent.EVENT_SESSION_ID_INDEX] = self.active_session_id np_array = np.array([tuple(event), ], dtype=eventClass.NUMPY_DTYPE) etable.append(np_array) self.bufferedFlush() except Exception: print2err("Error saving event: ", event) printExceptionDetailsToStdErr()
def handleGetEvents(self,replyTo): try: currentEvents=list(self.iohub.eventBuffer) self.iohub.eventBuffer.clear() if len(currentEvents)>0: currentEvents=sorted(currentEvents, key=itemgetter(DeviceEvent.EVENT_HUB_TIME_INDEX)) self.sendResponse(('GET_EVENTS_RESULT',currentEvents),replyTo) else: self.sendResponse(('GET_EVENTS_RESULT', None),replyTo) return True except Exception, e: print2err("IOHUB_GET_EVENTS_ERROR") printExceptionDetailsToStdErr() self.sendResponse('IOHUB_GET_EVENTS_ERROR', replyTo) return False
def _processDeviceEventIteration(self): for device in self.devices: try: events=device._getNativeEventBuffer() #if events and len(events)>0: # ioHub.print2err("_processDeviceEventIteration.....", device._event_listeners) while len(events)>0: evt=events.popleft() e=device._getIOHubEventObject(evt) if e is not None: for l in device._getEventListeners(e[DeviceEvent.EVENT_TYPE_ID_INDEX]): l._handleEvent(e) except: printExceptionDetailsToStdErr() print2err("Error in processDeviceEvents: ", device, " : ", len(events), " : ", e) print2err("Event type ID: ",e[DeviceEvent.EVENT_TYPE_ID_INDEX], " : " , EventConstants.getName(e[DeviceEvent.EVENT_TYPE_ID_INDEX])) print2err("--------------------------------------")
def _addRowToConditionVariableTable(self,session_id,data): if self.emrtFile and 'EXP_CV' in self.TABLES and self._EXP_COND_DTYPE is not None: try: etable=self.TABLES['EXP_CV'] for i,d in enumerate(data): if isinstance(d,(list,tuple)): data[i]=tuple(d) np_array= N.array([tuple(data),],dtype=self._EXP_COND_DTYPE) etable.append(np_array) self.bufferedFlush() return True except: printExceptionDetailsToStdErr() return False
def sendResponse(self,data,address): packet_data=None try: num_packets = -1 packet_data_length = -1 # TODO: Max packet size on OS X seems to be 8192 !! max_size = int(MAX_PACKET_SIZE/2-20) packet_data = self.pack(data) packet_data_length = len(packet_data) if packet_data_length >= max_size: num_packets = int(packet_data_length//max_size)+1 self.sendResponse(('IOHUB_MULTIPACKET_RESPONSE',num_packets),address) for p in xrange(num_packets-1): self.socket.sendto(packet_data[p*max_size:(p+1)*max_size],address) self.socket.sendto(packet_data[(p+1)*max_size:packet_data_length],address) else: self.socket.sendto(packet_data,address) except: print2err('Error trying to send data to experiment process:') print2err('max_size: ',max_size) print2err('data length: ',packet_data_length) print2err('num_packets: ',num_packets) print2err("=============================") printExceptionDetailsToStdErr() print2err("=============================") first_data_element="NO_DATA_AVAILABLE" if data: print2err('Data was [{0}]'.format(data)) try: first_data_element=data[0] except: pass packet_data_length=0 if packet_data: packet_data_length=len(packet_data) print2err('packet Data length: ',len(packet_data)) print2err("IOHUB_SERVER_RESPONSE_ERROR") printExceptionDetailsToStdErr() packet_data=self.pack('IOHUB_SERVER_RESPONSE_ERROR') self.socket.sendto(packet_data,address)
def _initializeConditionVariableTable(self,experiment_id,session_id,np_dtype): experimentConditionVariableTable=None exp_session=[('EXPERIMENT_ID','i4'),('SESSION_ID','i4')] exp_session.extend(np_dtype) np_dtype=exp_session #print2err('np_dtype: ',np_dtype,' ',type(np_dtype)) self._EXP_COND_DTYPE=N.dtype(np_dtype) try: expCondTableName="EXP_CV_%d"%(experiment_id) experimentConditionVariableTable=self.emrtFile.root.data_collection.condition_variables._f_getChild(expCondTableName) self.TABLES['EXP_CV']=experimentConditionVariableTable except NoSuchNodeError, nsne: try: experimentConditionVariableTable=self.emrtFile.createTable(self.emrtFile.root.data_collection.condition_variables,expCondTableName,self._EXP_COND_DTYPE,title='Condition Variable Values for Experiment ID %d'%(experiment_id)) self.TABLES['EXP_CV']=experimentConditionVariableTable self.emrtFile.flush() except: printExceptionDetailsToStdErr() return False
def receive(self): try: data, address = self.sock.recvfrom(self._rcvBufferLength) self.lastAddress=address self.feed(data) result=self.unpack() if result[0] == 'IOHUB_MULTIPACKET_RESPONSE': num_packets=result[1] for p in range(num_packets-1): data, address = self.sock.recvfrom(self._rcvBufferLength) self.feed(data) data, address = self.sock.recvfrom(self._rcvBufferLength) self.feed(data) result=self.unpack() return result,address except Exception as e: printExceptionDetailsToStdErr()
def sendResponse(self,data,address): packet_data=None try: max_size=MAX_PACKET_SIZE/2-20 packet_data=self.pack(data) packet_data_length=len(packet_data) if packet_data_length>= max_size: num_packets=len(packet_data)/max_size+1 self.sendResponse(('IOHUB_MULTIPACKET_RESPONSE',num_packets),address) for p in xrange(num_packets-1): self.socket.sendto(packet_data[p*max_size:(p+1)*max_size],address) self.socket.sendto(packet_data[(p+1)*max_size:packet_data_length],address) else: self.socket.sendto(packet_data,address) except: print2err('Error trying to send data to experiment process:') print2err('data length:',len(data)) print2err("=============================") printExceptionDetailsToStdErr() print2err("=============================") first_data_element="NO_DATA_AVAILABLE" if data: print2err('Data was [{0}]'.format(data)) try: first_data_element=data[0] except: pass packet_data_length=0 if packet_data: packet_data_length=len(packet_data) print2err('packet Data length: ',len(packet_data)) data=createErrorResult('IOHUB_SERVER_RESPONSE_ERROR', msg="The ioHub Server Failed to send the intended response.", first_data_element=str(first_data_element), packet_data_length=packet_data_length, max_packet_size=max_size) packet_data=self.pack(data) packet_data_length=len(packet_data) self.socket.sendto(packet_data,address)
def extendConditionVariableTable(self, experiment_id, session_id, data): if self._EXP_COND_DTYPE is None: return False if self.emrtFile and 'EXP_CV' in self.TABLES: temp = [experiment_id,session_id] temp.extend(data) data = temp try: etable = self.TABLES['EXP_CV'] #print2err('data: ',data,' ',type(data)) for i, d in enumerate(data): if isinstance(d, (list, tuple)): data[i] = tuple(d) np_array = np.array([tuple(data), ], dtype=self._EXP_COND_DTYPE) etable.append(np_array) self.bufferedFlush() return True except Exception: printExceptionDetailsToStdErr() return False
def extendConditionVariableTable(self, experiment_id, session_id, data): if self._EXP_COND_DTYPE is None: return False if self.emrtFile and 'EXP_CV' in self.TABLES: temp = [experiment_id, session_id] temp.extend(data) data = temp try: etable = self.TABLES['EXP_CV'] #print2err('data: ',data,' ',type(data)) for i, d in enumerate(data): if isinstance(d, (list, tuple)): data[i] = tuple(d) np_array = np.array([ tuple(data), ], dtype=self._EXP_COND_DTYPE) etable.append(np_array) self.bufferedFlush() return True except Exception: printExceptionDetailsToStdErr() return False
def _handleEvent(self, event): try: eventClass = None if self.checkForExperimentAndSessionIDs(event) is False: return False etype = event[DeviceEvent.EVENT_TYPE_ID_INDEX] # print2err("*** ",DeviceEvent.EVENT_TYPE_ID_INDEX, '_handleEvent: ',etype,' : event list: ',event) eventClass = EventConstants.getClass(etype) etable = self.TABLES[eventClass.IOHUB_DATA_TABLE] event[DeviceEvent.EVENT_EXPERIMENT_ID_INDEX] = self.active_experiment_id event[DeviceEvent.EVENT_SESSION_ID_INDEX] = self.active_session_id np_array = np.array([tuple(event), ], dtype=eventClass.NUMPY_DTYPE) etable.append(np_array) self.bufferedFlush() except Exception: print2err("Error saving event: ", event) printExceptionDetailsToStdErr()
def shutdown(self): try: self._running = False if Computer.system == 'linux2': if self._hookManager: self._hookManager.cancel() elif Computer.system == 'win32': if self._hookDevice and self._hookDevice._hookManager: #self._hookDevice._hookManager = None #.UnhookMouse() #self._hookDevice._hookManager.UnhookKeyboard() self._hookDevice._hookManager = None self._hookDevice = None while len(self.deviceMonitors) > 0: m = self.deviceMonitors.pop(0) m.running = False if self.eventBuffer: self.clearEventBuffer() try: self.closeDataStoreFile() except: pass while len(self.devices) > 0: d = self.devices.pop(0) try: if d is not None: d._close() except: pass except: print2err("Error in ioSever.shutdown():") printExceptionDetailsToStdErr()
def shutdown(self): try: self._running=False if Computer.system=='linux2': if self._hookManager: self._hookManager.cancel() elif Computer.system=='win32': if self._hookDevice and self._hookDevice._hookManager: #self._hookDevice._hookManager = None #.UnhookMouse() #self._hookDevice._hookManager.UnhookKeyboard() self._hookDevice._hookManager = None self._hookDevice = None while len(self.deviceMonitors) > 0: m=self.deviceMonitors.pop(0) m.running=False if self.eventBuffer: self.clearEventBuffer() try: self.closeDataStoreFile() except: pass while len(self.devices) > 0: d=self.devices.pop(0) try: if d is not None: d._close() except: pass except: print2err("Error in ioSever.shutdown():") printExceptionDetailsToStdErr()
def run(rootScriptPathDir,configFilePath): psychopy.iohub.EXP_SCRIPT_DIRECTORY = rootScriptPathDir import tempfile tdir=tempfile.gettempdir() cdir,cfile=os.path.split(configFilePath) if tdir==cdir: tf=open(configFilePath) ioHubConfig=json.loads(tf.read()) tf.close() os.remove(configFilePath) else: ioHubConfig=load(open(configFilePath,'r'), Loader=Loader) hub_defaults_config=load(open(os.path.join(psychopy.iohub.IO_HUB_DIRECTORY,'default_config.yaml'),'r'), Loader=Loader) updateDict(ioHubConfig,hub_defaults_config) try: s = ioServer(rootScriptPathDir, ioHubConfig) except Exception as e: printExceptionDetailsToStdErr() sys.stdout.flush() try: s.shutdown() except Exception: pass return -1 try: s.log('Receiving datagrams on :9000') s.udpService.start() if Computer.system == 'win32': gevent.spawn(s.pumpMsgTasklet, s.config.get('windows_msgpump_interval', 0.00375)) if hasattr(gevent,'run'): for m in s.deviceMonitors: m.start() gevent.spawn(s.processEventsTasklet, 0.01) sys.stdout.write("IOHUB_READY\n\r\n\r") #print2err("Computer.psychopy_process: ", Computer.psychopy_process) if Computer.psychopy_process: gevent.spawn(s.checkForPsychopyProcess, 0.5) sys.stdout.flush() gevent.run() else: glets=[] if Computer.system == 'win32': glets.append(gevent.spawn(s.pumpMsgTasklet, s.config.get('windows_msgpump_interval', 0.00375))) for m in s.deviceMonitors: m.start() glets.append(m) glets.append(gevent.spawn(s.processEventsTasklet,0.01)) sys.stdout.write("IOHUB_READY\n\r\n\r") sys.stdout.flush() #print2err("Computer.psychopy_process: ", Computer.psychopy_process) if Computer.psychopy_process: glets.append(gevent.spawn(s.checkForPsychopyProcess, 0.5)) gevent.joinall(glets) s.log("Server END Time Offset: {0}".format(Computer.global_clock.getLastResetTime()),'DEBUG') except Exception as e: print2err("Error occurred during ioServer.start(): ",str(e)) printExceptionDetailsToStdErr() print2err("------------------------------") sys.stdout.write("IOHUB_FAILED\n\r\n\r") sys.stdout.flush() try: s.shutdown() except Exception: pass return -1
def handleExperimentDeviceRequest(self,request,replyTo): request_type= request.pop(0) if request_type == 'EVENT_TX': exp_events=request.pop(0) for eventAsTuple in exp_events: ioServer.deviceDict['Experiment']._nativeEventCallback(eventAsTuple) self.sendResponse(('EVENT_TX_RESULT',len(exp_events)),replyTo) return True elif request_type == 'DEV_RPC': dclass=request.pop(0) dmethod=request.pop(0) args=None kwargs=None if len(request)==1: args=request[0] elif len(request)==2: args=request[0] kwargs=request[1] if len(kwargs)==0: kwargs=None dev=None if dclass.find('.') > 0: for dname, dev in ioServer.deviceDict.items(): if dname.endswith(dclass): dev=ioServer.deviceDict.get(dname,None) break else: dev=ioServer.deviceDict.get(dclass,None) if dev is None: print2err("IOHUB_DEVICE_ERROR") printExceptionDetailsToStdErr() self.sendResponse('IOHUB_DEVICE_ERROR', replyTo) return False try: method=getattr(dev,dmethod) except Exception: print2err("IOHUB_DEVICE_METHOD_ERROR") printExceptionDetailsToStdErr() self.sendResponse('IOHUB_DEVICE_METHOD_ERROR', replyTo) return False result=[] try: if args and kwargs: result=method(*args, **kwargs) elif args: result=method(*args) elif kwargs: result=method(**kwargs) else: result=method() self.sendResponse(('DEV_RPC_RESULT',result),replyTo) return True except Exception as e: print2err("RPC_DEVICE_RUNTIME_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_DEVICE_RUNTIME_ERROR', replyTo) return False elif request_type == 'GET_DEVICE_LIST': try: dev_list=[] for d in self.iohub.devices: dev_list.append((d.name,d.__class__.__name__)) self.sendResponse(('GET_DEV_LIST_RESULT',len(dev_list),dev_list),replyTo) return True except Exception as e: print2err("RPC_DEVICE_RUNTIME_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_DEVICE_RUNTIME_ERROR', replyTo) return False elif request_type == 'GET_DEV_INTERFACE': dclass=request.pop(0) data=None if dclass in ['EyeTracker','DAQ']: for dname, hdevice in ioServer.deviceDict.items(): if dname.endswith(dclass): data=hdevice._getRPCInterface() break else: dev=ioServer.deviceDict.get(dclass,None) if dev: data=dev._getRPCInterface() if data: self.sendResponse(('GET_DEV_INTERFACE',data),replyTo) return True else: print2err("GET_DEV_INTERFACE_ERROR") printExceptionDetailsToStdErr() self.sendResponse('GET_DEV_INTERFACE_ERROR', replyTo) return False elif request_type == 'ADD_DEVICE': dclass_name=request.pop(0) dconfig_dict=request.pop(1) # add device to ioSever here data=self.iohub.createNewMonitoredDevice(dclass_name,dconfig_dict) # end adding device to server if data: self.sendResponse(('ADD_DEVICE',data),replyTo) return True else: print2err("ADD_DEVICE_ERROR") printExceptionDetailsToStdErr() self.sendResponse('ADD_DEVICE_ERROR', replyTo) return False else: print2err("DEVICE_RPC_TYPE_NOT_SUPPORTED_ERROR") printExceptionDetailsToStdErr() self.sendResponse('DEVICE_RPC_TYPE_NOT_SUPPORTED_ERROR', replyTo) return False
def createNewMonitoredDevice(self,device_class_name,deviceConfig): #print2err("#### createNewMonitoredDevice: ",device_class_name) self._all_device_config_errors=dict() try: device_instance=None device_config=None device_event_ids=None event_classes=None device_instance_and_config=self.addDeviceToMonitor(device_class_name,deviceConfig) if device_instance_and_config: device_instance,device_config,device_event_ids,event_classes=device_instance_and_config DeviceConstants.addClassMapping(device_instance.__class__) EventConstants.addClassMappings(device_instance.__class__,device_event_ids,event_classes) else: print2err('## Device was not started by the ioHub Server: ',device_class_name) raise ioHubError("Device config validation failed") except: print2err("Error during device creation ....") printExceptionDetailsToStdErr() raise ioHubError("Error during device creation ....") # Update DataStore Structure if required. if psychopy.iohub._DATA_STORE_AVAILABLE: try: if self.emrt_file is not None: self.emrt_file.updateDataStoreStructure(device_instance,event_classes) except: print2err("Error while updating datastore for device addition:",device_instance,device_event_ids) printExceptionDetailsToStdErr() self.log("Adding ioServer and DataStore event listeners......") # add event listeners for saving events if psychopy.iohub._DATA_STORE_AVAILABLE and self.emrt_file is not None: if device_config['save_events']: device_instance._addEventListener(self.emrt_file,device_event_ids) self.log("DataStore listener for device added: device: %s eventIDs: %s"%(device_instance.__class__.__name__,device_event_ids)) #print2err("DataStore listener for device added: device: %s eventIDs: %s"%(device_instance.__class__.__name__,device_event_ids)) else: #print2err("DataStore saving disabled for device: %s"%(device_instance.__class__.__name__,)) self.log("DataStore saving disabled for device: %s"%(device_instance.__class__.__name__,)) else: #print2err("DataStore Not Evabled. No events will be saved.") self.log("DataStore Not Enabled. No events will be saved.") # Add Device Monitor for Keyboard or Mouse device type deviceDict=ioServer.deviceDict iohub=self if device_class_name in ('Mouse','Keyboard'): if Computer.system == 'win32': if self._hookDevice is None: iohub.log("Creating pyHook Monitors....") #print2err("Creating pyHook Monitor....") class pyHookDevice(object): def __init__(self): import pyHook self._hookManager=pyHook.HookManager() self._mouseHooked=False self._keyboardHooked=False if device_class_name == 'Mouse': #print2err("Hooking Mouse.....") self._hookManager.MouseAll = deviceDict['Mouse']._nativeEventCallback self._hookManager.HookMouse() self._mouseHooked=True elif device_class_name == 'Keyboard': #print2err("Hooking Keyboard.....") self._hookManager.KeyAll = deviceDict['Keyboard']._nativeEventCallback self._hookManager.HookKeyboard() self._keyboardHooked=True #iohub.log("WindowsHook PumpEvents Periodic Timer Created.") def _poll(self): import pythoncom # PumpWaitingMessages returns 1 if a WM_QUIT message was received, else 0 if pythoncom.PumpWaitingMessages() == 1: raise KeyboardInterrupt() #print2err("Creating pyHook Monitor......") self._hookDevice=pyHookDevice() hookMonitor=DeviceMonitor(self._hookDevice,0.00375) self.deviceMonitors.append(hookMonitor) #print2err("Created pyHook Monitor.") else: #print2err("UPDATING pyHook Monitor....") if device_class_name == 'Mouse' and self._hookDevice._mouseHooked is False: #print2err("Hooking Mouse.....") self._hookDevice._hookManager.MouseAll = deviceDict['Mouse']._nativeEventCallback self._hookDevice._hookManager.HookMouse() self._hookDevice._mouseHooked=True elif device_class_name == 'Keyboard' and self._hookDevice._keyboardHooked is False: #print2err("Hooking Keyboard.....") self._hookDevice._hookManager.KeyAll = deviceDict['Keyboard']._nativeEventCallback self._hookDevice._hookManager.HookKeyboard() self._hookDevice._keyboardHooked=True #print2err("Finished Updating pyHook Monitor.") elif Computer.system == 'linux2': # TODO: consider switching to xlib-ctypes implementation of xlib # https://github.com/garrybodsworth/pyxlib-ctypes from .devices import pyXHook if self._hookManager is None: #iohub.log("Creating pyXHook Monitors....") self._hookManager = pyXHook.HookManager() self._hookManager._mouseHooked=False self._hookManager._keyboardHooked=False if device_class_name == 'Keyboard': #print2err("Hooking Keyboard.....") self._hookManager.HookKeyboard() self._hookManager.KeyDown = deviceDict['Keyboard']._nativeEventCallback self._hookManager.KeyUp = deviceDict['Keyboard']._nativeEventCallback self._hookManager._keyboardHooked=True elif device_class_name == 'Mouse': #print2err("Hooking Mouse.....") self._hookManager.HookMouse() self._hookManager.MouseAllButtonsDown = deviceDict['Mouse']._nativeEventCallback self._hookManager.MouseAllButtonsUp = deviceDict['Mouse']._nativeEventCallback self._hookManager.MouseAllMotion = deviceDict['Mouse']._nativeEventCallback self._hookManager._mouseHooked=True #print2err("Starting pyXHook.HookManager.....") self._hookManager.start() #iohub.log("pyXHook Thread Created.") #print2err("pyXHook.HookManager thread created.") else: #iohub.log("Updating pyXHook Monitor....") if device_class_name == 'Keyboard' and self._hookManager._keyboardHooked is False: #print2err("Hooking Keyboard.....") self._hookManager.HookKeyboard() self._hookManager.KeyDown = deviceDict['Keyboard']._nativeEventCallback self._hookManager.KeyUp = deviceDict['Keyboard']._nativeEventCallback self._hookManager._keyboardHooked=True if device_class_name == 'Mouse' and self._hookManager._mouseHooked is False: #print2err("Hooking Mouse.....") self._hookManager.HookMouse() self._hookManager.MouseAllButtonsDown = deviceDict['Mouse']._nativeEventCallback self._hookManager.MouseAllButtonsUp = deviceDict['Mouse']._nativeEventCallback self._hookManager.MouseAllMotion = deviceDict['Mouse']._nativeEventCallback self._hookManager._mouseHooked=True #iohub.log("Finished Updating pyXHook Monitor....") else: # OSX if self._hookDevice is None: self._hookDevice=[] if device_class_name == 'Mouse' and 'Mouse' not in self._hookDevice: #print2err("Hooking OSX Mouse.....") mouseHookMonitor=DeviceMonitor(deviceDict['Mouse'],0.004) self.deviceMonitors.append(mouseHookMonitor) deviceDict['Mouse']._CGEventTapEnable(deviceDict['Mouse']._tap, True) self._hookDevice.append('Mouse') #print2err("Done Hooking OSX Mouse.....") if device_class_name == 'Keyboard' and 'Keyboard' not in self._hookDevice: #print2err("Hooking OSX Keyboard.....") kbHookMonitor=DeviceMonitor(deviceDict['Keyboard'],0.004) self.deviceMonitors.append(kbHookMonitor) deviceDict['Keyboard']._CGEventTapEnable(deviceDict['Keyboard']._tap, True) self._hookDevice.append('Keyboard') #print2err("DONE Hooking OSX Keyboard.....") return [device_class_name, device_config['name'], device_instance._getRPCInterface()]
sys.stdout.write("IOHUB_READY\n\r\n\r") sys.stdout.flush() #print2err("Computer.psychopy_process: ", Computer.psychopy_process) if Computer.psychopy_process: glets.append(gevent.spawn(s.checkForPsychopyProcess, 0.5)) gevent.joinall(glets) s.log("Server END Time Offset: {0}".format(Computer.globalClock.getLastResetTime()),'DEBUG') except Exception as e: print2err("Error occurred during ioServer.start(): ",str(e)) printExceptionDetailsToStdErr() print2err("------------------------------") sys.stdout.write("IOHUB_FAILED\n\r\n\r") sys.stdout.flush() try: s.shutdown() except: pass return -1 if __name__ == '__main__': prog=sys.argv[0] if len(sys.argv)>=2:
def handle(self, request, replyTo): if self._running is False: return False self.feed(request) request = self.unpack() request_type= request.pop(0) if request_type == 'SYNC_REQ': self.sendResponse(['SYNC_REPLY',currentSec()],replyTo) return True elif request_type == 'PING': clienttime=request.pop(0) msg_id=request.pop(0) payload=request.pop(0) ctime=currentSec() self.sendResponse(["PING_BACK",ctime,msg_id,payload,replyTo],replyTo) return True elif request_type == 'GET_EVENTS': return self.handleGetEvents(replyTo) elif request_type == 'EXP_DEVICE': return self.handleExperimentDeviceRequest(request,replyTo) elif request_type == 'RPC': callable_name=request.pop(0) args=None kwargs=None if len(request)==1: args=request.pop(0) if len(request)==1: kwargs=request.pop(0) result=None try: result=getattr(self,callable_name) except: print2err("RPC_ATTRIBUTE_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_ATTRIBUTE_ERROR',replyTo) return False if result and callable(result): funcPtr=result try: if args is None and kwargs is None: result = funcPtr() elif args and kwargs: result = funcPtr(*args,**kwargs) elif args and not kwargs: result = funcPtr(*args) elif not args and kwargs: result = funcPtr(**kwargs) edata=('RPC_RESULT',callable_name,result) self.sendResponse(edata,replyTo) return True except Exception,e: print2err("RPC_RUNTIME_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_RUNTIME_ERROR', replyTo) return False else: print2err("RPC_NOT_CALLABLE_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_NOT_CALLABLE_ERROR', replyTo) return False
def __init__(self, *args, **kwargs): Device.__init__(self, *args, **kwargs['dconfig']) self._serial = None self.port = self.getConfiguration().get('port') if self.port.lower() == 'auto': pports = self.findPorts() if pports: self.port = pports[0] if len(pports) > 1: print2err( "Warning: Serial device port configuration set " "to 'auto'.\nMultiple serial ports found:\n", pports, "\n** Using port ", self.port) self.baud = self.getConfiguration().get('baud') self.bytesize = self._bytesizes[self.getConfiguration().get( 'bytesize')] self.parity = self._parities[self.getConfiguration().get('parity')] self.stopbits = self._stopbits[self.getConfiguration().get('stopbits')] self._parser_config = self.getConfiguration().get('event_parser') self._byte_diff_mode = None self._custom_parser = None self._custom_parser_kwargs = {} custom_parser_func_str = self._parser_config.get('parser_function') if custom_parser_func_str: # print2err("CUSTOM SERIAL PARSER FUNC STR: ", custom_parser_func_str) # Function referenced by string must have the following signature: # # evt_list = someCustomParserName(read_time, rx_data, parser_state, **kwargs) # # where: # read_time: The time when the serial device read() returned # with the new rx_data. # rx_data: The new serial data received. Any buffering of data # across function calls must be done by the function # logic itself. parser_state could be used to hold # such a buffer if needed. # parser_state: A dict which can be used by the function to # store any values that need to be accessed # across multiple calls to the function. The dict # is initially empty. # kwargs: The parser_kwargs preference dict read from # the event_parser preferences; or an empty dict if # parser_kwargs was not found. # # The function must return a list like object, used to provide ioHub # with any new serial events that have been found. # Each element of the list must be a dict like object, representing # a single serial device event found by the parsing function. # A dict can contain the following key, value pairs: # data: The string containing the parsed event data. (REQUIRED) # time: The timestamp for the event (Optional). If not provided, # the return time of the latest serial.read() is used. # Each event returned by the function generates a SerialInputEvent # with the data field = the dict data value. import importlib, sys try: #print2err("EXP_SCRIPT_DIRECTORY: ",EXP_SCRIPT_DIRECTORY) if EXP_SCRIPT_DIRECTORY not in sys.path: sys.path.append(EXP_SCRIPT_DIRECTORY) mod_name, func_name = custom_parser_func_str.rsplit('.', 1) mod = importlib.import_module(mod_name) self._custom_parser = getattr(mod, func_name) except: print2err( "ioHub Serial Device Error: could not load " "custom_parser function: ", custom_parser_func_str) printExceptionDetailsToStdErr() if self._custom_parser: self._custom_parser_kwargs = self._parser_config.get( 'parser_kwargs', {}) else: self._byte_diff_mode = self._parser_config.get('byte_diff') if self._byte_diff_mode: self._rx_buffer = None else: self._resetParserState() self._rx_buffer = '' self._event_count = 0 self._timeout = None self._serial = None self.setConnectionState(True)
def _poll(self): try: logged_time = getTime() if self.isConnected(): self._mcu.getSerialRx() if logged_time - self._last_sync_time >= self.time_sync_interval: self._mcu._runTimeSync() self._last_sync_time = logged_time if not self.isReportingEvents(): return False confidence_interval = logged_time - self._last_callback_time events = self._mcu.getRxEvents() for event in events: current_MCU_time = event.device_time #self.getSecTime() device_time = event.device_time if event.local_time is None: event.local_time = logged_time delay = logged_time - event.local_time #current_MCU_time-device_time # local_time is in iohub time space already, so delay does not # need to be used to adjust iohub time iohub_time = event.local_time elist = None if event.getTypeInt() == T3Event.ANALOG_INPUT_EVENT: elist = [ EventConstants.UNDEFINED, ] * 19 elist[4] = AnalogInputEvent.EVENT_TYPE_ID for i, v in enumerate(event.ain_channels): elist[(i + 11)] = v elif event.getTypeInt() == T3Event.DIGITAL_INPUT_EVENT: elist = [ EventConstants.UNDEFINED, ] * 12 elist[4] = DigitalInputEvent.EVENT_TYPE_ID elist[-1] = event.getDigitalInputByte() elif event.getTypeInt() == T3Event.THRESHOLD_EVENT: elist = [ EventConstants.UNDEFINED, ] * 19 elist[4] = ThresholdEvent.EVENT_TYPE_ID for i, v in enumerate(event.threshold_state_changed): elist[(i + 11)] = v if elist: elist[0] = 0 elist[1] = 0 elist[2] = 0 elist[3] = Computer._getNextEventID() elist[5] = device_time elist[6] = logged_time elist[7] = iohub_time elist[8] = confidence_interval elist[9] = delay elist[10] = 0 self._addNativeEventToBuffer(elist) replies = self._mcu.getRequestReplies(True) for reply in replies: rid = reply.getID() if rid in self._request_dict: self._response_dict[rid] = reply del self._request_dict[rid] self._last_callback_time = logged_time return True except Exception as e: print2err("--------------------------------") print2err("ERROR in MCU._poll: ", e) printExceptionDetailsToStdErr() print2err("---------------------")
def handleExperimentDeviceRequest(self, request, replyTo): request_type = request.pop(0) if request_type == 'EVENT_TX': exp_events = request.pop(0) for eventAsTuple in exp_events: ioServer.deviceDict['Experiment']._nativeEventCallback( eventAsTuple) self.sendResponse(('EVENT_TX_RESULT', len(exp_events)), replyTo) return True elif request_type == 'DEV_RPC': dclass = request.pop(0) dmethod = request.pop(0) args = None kwargs = None if len(request) == 1: args = request[0] elif len(request) == 2: args = request[0] kwargs = request[1] if len(kwargs) == 0: kwargs = None dev = None if dclass.find('.') > 0: for dname, dev in ioServer.deviceDict.iteritems(): if dname.endswith(dclass): dev = ioServer.deviceDict.get(dname, None) break else: dev = ioServer.deviceDict.get(dclass, None) if dev is None: print2err("IOHUB_DEVICE_ERROR") printExceptionDetailsToStdErr() self.sendResponse('IOHUB_DEVICE_ERROR', replyTo) return False try: method = getattr(dev, dmethod) except Exception: print2err("IOHUB_DEVICE_METHOD_ERROR") printExceptionDetailsToStdErr() self.sendResponse('IOHUB_DEVICE_METHOD_ERROR', replyTo) return False result = [] try: if args and kwargs: result = method(*args, **kwargs) elif args: result = method(*args) elif kwargs: result = method(**kwargs) else: result = method() self.sendResponse(('DEV_RPC_RESULT', result), replyTo) return True except Exception, e: print2err("RPC_DEVICE_RUNTIME_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_DEVICE_RUNTIME_ERROR', replyTo) return False
class ioHubpyTablesFile(): def __init__(self, fileName, folderPath, fmode='a', ioHubsettings=None): self.fileName = fileName self.folderPath = folderPath self.filePath = os.path.join(folderPath, fileName) self.settings = ioHubsettings self.active_experiment_id = None self.active_session_id = None self.flushCounter = self.settings.get('flush_interval', 32) self._eventCounter = 0 self.TABLES = dict() self._eventGroupMappings = dict() self.emrtFile = openFile(self.filePath, mode=fmode) atexit.register(close_open_data_files, False) if len(self.emrtFile.title) == 0: self.buildOutTemplate() self.flush() else: self.loadTableMappings() def updateDataStoreStructure(self, device_instance, event_class_dict): dfilter = Filters(complevel=0, complib='zlib', shuffle=False, fletcher32=False) def eventTableLabel2ClassName(event_table_label): tokens = str(event_table_label[0] + event_table_label[1:].lower() + 'Event').split('_') return ''.join([t[0].upper() + t[1:] for t in tokens]) for event_cls_name, event_cls in event_class_dict.iteritems(): if event_cls.IOHUB_DATA_TABLE: event_table_label = event_cls.IOHUB_DATA_TABLE if event_table_label not in self.TABLES: self.TABLES[event_table_label] = self.emrtFile.createTable( self._eventGroupMappings[event_table_label], eventTableLabel2ClassName(event_table_label), event_cls.NUMPY_DTYPE, title="%s Data" % (device_instance.__class__.__name__, ), filters=dfilter.copy()) self.flush() self.addClassMapping(event_cls, self.TABLES[event_table_label]) def loadTableMappings(self): # create meta-data tables self._buildEventGroupMappingDict() self.TABLES[ 'EXPERIMENT_METADETA'] = self.emrtFile.root.data_collection.experiment_meta_data self.TABLES[ 'SESSION_METADETA'] = self.emrtFile.root.data_collection.session_meta_data self.TABLES[ 'CLASS_TABLE_MAPPINGS'] = self.emrtFile.root.class_table_mapping # create tables dict of hdf5 path mappings try: self.TABLES[ 'KEYBOARD_KEY'] = self.emrtFile.root.data_collection.events.keyboard.KeyboardKeyEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'KEYBOARD_CHAR'] = self.emrtFile.root.data_collection.events.keyboard.KeyboardCharEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'MOUSE_INPUT'] = self.emrtFile.root.data_collection.events.mouse.MouseInputEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'TOUCH'] = self.emrtFile.root.data_collection.events.touch.TouchEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'GAMEPAD_STATE_CHANGE'] = self.emrtFile.root.data_collection.events.gamepad.GamepadStateChangeEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'MESSAGE'] = self.emrtFile.root.data_collection.events.experiment.MessageEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'LOG'] = self.emrtFile.root.data_collection.events.experiment.LogEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'MULTI_CHANNEL_ANALOG_INPUT'] = self.emrtFile.root.data_collection.events.analog_input.MultiChannelAnalogInputEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'MONOCULAR_EYE_SAMPLE'] = self.emrtFile.root.data_collection.events.eyetracker.MonocularEyeSampleEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'BINOCULAR_EYE_SAMPLE'] = self.emrtFile.root.data_collection.events.eyetracker.BinocularEyeSampleEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'FIXATION_START'] = self.emrtFile.root.data_collection.events.eyetracker.FixationStartEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'FIXATION_END'] = self.emrtFile.root.data_collection.events.eyetracker.FixationEndEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'SACCADE_START'] = self.emrtFile.root.data_collection.events.eyetracker.SaccadeStartEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'SACCADE_END'] = self.emrtFile.root.data_collection.events.eyetracker.SaccadeEndEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'BLINK_START'] = self.emrtFile.root.data_collection.events.eyetracker.BlinkStartEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass try: self.TABLES[ 'BLINK_END'] = self.emrtFile.root.data_collection.events.eyetracker.BlinkEndEvent except: # Just means the table for this event type has not been created as the event type is not being recorded pass def buildOutTemplate(self): self.emrtFile.title = DATA_FILE_TITLE self.emrtFile.FILE_VERSION = FILE_VERSION self.emrtFile.SCHEMA_DESIGNER = SCHEMA_AUTHORS self.emrtFile.SCHEMA_MODIFIED = SCHEMA_MODIFIED_DATE #CREATE GROUPS #self.emrtFile.createGroup(self.emrtFile.root, 'analysis', title='Data Analysis Files, notebooks, scripts and saved results tables.') self.TABLES['CLASS_TABLE_MAPPINGS'] = self.emrtFile.createTable( self.emrtFile.root, 'class_table_mapping', ClassTableMappings, title= 'Mapping of ioHub DeviceEvent Classes to ioHub DataStore Tables.') self.emrtFile.createGroup( self.emrtFile.root, 'data_collection', title='Data Collected using the ioHub Event Framework.') self.flush() self.emrtFile.createGroup( self.emrtFile.root.data_collection, 'events', title='All Events that were Saved During Experiment Sessions.') self.emrtFile.createGroup( self.emrtFile.root.data_collection, 'condition_variables', title= "Tables created to Hold Experiment DV and IV's Values Saved During an Experiment Session." ) self.flush() self.TABLES['EXPERIMENT_METADETA'] = self.emrtFile.createTable( self.emrtFile.root.data_collection, 'experiment_meta_data', ExperimentMetaData, title= 'Information About Experiments Saved to This ioHub DataStore File.' ) self.TABLES['SESSION_METADETA'] = self.emrtFile.createTable( self.emrtFile.root.data_collection, 'session_meta_data', SessionMetaData, title= 'Information About Sessions Saved to This ioHub DataStore File.') self.flush() self.emrtFile.createGroup(self.emrtFile.root.data_collection.events, 'experiment', title='Experiment Device Events.') self.emrtFile.createGroup(self.emrtFile.root.data_collection.events, 'keyboard', title='Keyboard Device Events.') self.emrtFile.createGroup(self.emrtFile.root.data_collection.events, 'mouse', title='Mouse Device Events.') self.emrtFile.createGroup(self.emrtFile.root.data_collection.events, 'touch', title='Touch Device Events.') self.emrtFile.createGroup(self.emrtFile.root.data_collection.events, 'gamepad', title='GamePad Device Events.') self.emrtFile.createGroup(self.emrtFile.root.data_collection.events, 'analog_input', title='AnalogInput Device Events.') self.emrtFile.createGroup(self.emrtFile.root.data_collection.events, 'eyetracker', title='EyeTracker Device Events.') self.flush() self._buildEventGroupMappingDict() def _buildEventGroupMappingDict(self): self._eventGroupMappings[ 'KEYBOARD_KEY'] = self.emrtFile.root.data_collection.events.keyboard self._eventGroupMappings[ 'KEYBOARD_CHAR'] = self.emrtFile.root.data_collection.events.keyboard self._eventGroupMappings[ 'MOUSE_INPUT'] = self.emrtFile.root.data_collection.events.mouse self._eventGroupMappings[ 'TOUCH'] = self.emrtFile.root.data_collection.events.touch self._eventGroupMappings[ 'GAMEPAD_STATE_CHANGE'] = self.emrtFile.root.data_collection.events.gamepad self._eventGroupMappings[ 'MULTI_CHANNEL_ANALOG_INPUT'] = self.emrtFile.root.data_collection.events.analog_input self._eventGroupMappings[ 'MESSAGE'] = self.emrtFile.root.data_collection.events.experiment self._eventGroupMappings[ 'LOG'] = self.emrtFile.root.data_collection.events.experiment self._eventGroupMappings[ 'MONOCULAR_EYE_SAMPLE'] = self.emrtFile.root.data_collection.events.eyetracker self._eventGroupMappings[ 'BINOCULAR_EYE_SAMPLE'] = self.emrtFile.root.data_collection.events.eyetracker self._eventGroupMappings[ 'FIXATION_START'] = self.emrtFile.root.data_collection.events.eyetracker self._eventGroupMappings[ 'FIXATION_END'] = self.emrtFile.root.data_collection.events.eyetracker self._eventGroupMappings[ 'SACCADE_START'] = self.emrtFile.root.data_collection.events.eyetracker self._eventGroupMappings[ 'SACCADE_END'] = self.emrtFile.root.data_collection.events.eyetracker self._eventGroupMappings[ 'BLINK_START'] = self.emrtFile.root.data_collection.events.eyetracker self._eventGroupMappings[ 'BLINK_END'] = self.emrtFile.root.data_collection.events.eyetracker def addClassMapping(self, ioClass, ctable): names = [ x['class_id'] for x in self.TABLES['CLASS_TABLE_MAPPINGS'].where( "(class_id == %d)" % (ioClass.EVENT_TYPE_ID)) ] if len(names) == 0: trow = self.TABLES['CLASS_TABLE_MAPPINGS'].row trow['class_id'] = ioClass.EVENT_TYPE_ID trow['class_type_id'] = 1 # Device or Event etc. trow['class_name'] = ioClass.__name__ trow['table_path'] = ctable._v_pathname trow.append() self.flush() def createOrUpdateExperimentEntry(self, experimentInfoList): #ioHub.print2err("createOrUpdateExperimentEntry called with: ",experimentInfoList) experiment_metadata = self.TABLES['EXPERIMENT_METADETA'] result = [ row for row in experiment_metadata.iterrows() if row['code'] == experimentInfoList[1] ] if len(result) > 0: result = result[0] self.active_experiment_id = result['experiment_id'] return self.active_experiment_id max_id = 0 id_col = experiment_metadata.col('experiment_id') if len(id_col) > 0: max_id = N.amax(id_col) self.active_experiment_id = max_id + 1 experimentInfoList[0] = self.active_experiment_id experiment_metadata.append([ experimentInfoList, ]) self.flush() #ioHub.print2err("Experiment ID set to: ",self.active_experiment_id) return self.active_experiment_id def createExperimentSessionEntry(self, sessionInfoDict): #ioHub.print2err("createExperimentSessionEntry called with: ",sessionInfoDict) session_metadata = self.TABLES['SESSION_METADETA'] max_id = 0 id_col = session_metadata.col('session_id') if len(id_col) > 0: max_id = N.amax(id_col) self.active_session_id = int(max_id + 1) values = (self.active_session_id, self.active_experiment_id, sessionInfoDict['code'], sessionInfoDict['name'], sessionInfoDict['comments'], sessionInfoDict['user_variables']) session_metadata.append([ values, ]) self.flush() #ioHub.print2err("Session ID set to: ",self.active_session_id) return self.active_session_id def _initializeConditionVariableTable(self, experiment_id, session_id, np_dtype): experimentConditionVariableTable = None exp_session = [('EXPERIMENT_ID', 'i4'), ('SESSION_ID', 'i4')] exp_session.extend(np_dtype) np_dtype = exp_session #print2err('np_dtype: ',np_dtype,' ',type(np_dtype)) self._EXP_COND_DTYPE = N.dtype(np_dtype) try: expCondTableName = "EXP_CV_%d" % (experiment_id) experimentConditionVariableTable = self.emrtFile.root.data_collection.condition_variables._f_getChild( expCondTableName) self.TABLES['EXP_CV'] = experimentConditionVariableTable except NoSuchNodeError, nsne: try: experimentConditionVariableTable = self.emrtFile.createTable( self.emrtFile.root.data_collection.condition_variables, expCondTableName, self._EXP_COND_DTYPE, title='Condition Variable Values for Experiment ID %d' % (experiment_id)) self.TABLES['EXP_CV'] = experimentConditionVariableTable self.emrtFile.flush() except: printExceptionDetailsToStdErr() return False except Exception: print2err( 'Error getting experimentConditionVariableTable for experiment %d, table name: %s' % (experiment_id, expCondTableName)) printExceptionDetailsToStdErr() return False
def handle(self, request, replyTo): if self._running is False: return False self.feed(request) request = self.unpack() request_type = request.pop(0) if request_type == 'SYNC_REQ': self.sendResponse(['SYNC_REPLY', currentSec()], replyTo) return True elif request_type == 'PING': clienttime = request.pop(0) msg_id = request.pop(0) payload = request.pop(0) ctime = currentSec() self.sendResponse(["PING_BACK", ctime, msg_id, payload, replyTo], replyTo) return True elif request_type == 'GET_EVENTS': return self.handleGetEvents(replyTo) elif request_type == 'EXP_DEVICE': return self.handleExperimentDeviceRequest(request, replyTo) elif request_type == 'RPC': callable_name = request.pop(0) args = None kwargs = None if len(request) == 1: args = request.pop(0) if len(request) == 1: kwargs = request.pop(0) result = None try: result = getattr(self, callable_name) except Exception: print2err("RPC_ATTRIBUTE_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_ATTRIBUTE_ERROR', replyTo) return False if result and callable(result): funcPtr = result try: if args is None and kwargs is None: result = funcPtr() elif args and kwargs: result = funcPtr(*args, **kwargs) elif args and not kwargs: result = funcPtr(*args) elif not args and kwargs: result = funcPtr(**kwargs) edata = ('RPC_RESULT', callable_name, result) self.sendResponse(edata, replyTo) return True except Exception, e: print2err("RPC_RUNTIME_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_RUNTIME_ERROR', replyTo) return False else: print2err("RPC_NOT_CALLABLE_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_NOT_CALLABLE_ERROR', replyTo) return False
device=dclass, dmethod=dmethod, args=args, kwargs=kwargs, exception=str(e)), replyTo) return False elif request_type == 'GET_DEVICE_LIST': try: dev_list = [] for d in self.iohub.devices: dev_list.append((d.name, d.__class__.__name__)) self.sendResponse( ('GET_DEV_LIST_RESULT', len(dev_list), dev_list), replyTo) return True except Exception, e: printExceptionDetailsToStdErr() self.sendResponse( createErrorResult( 'RPC_DEVICE_RUNTIME_ERROR', msg= "An error occurred on the ioHub Server while getting the Device list for the Experiment Process", devices=str(self.iohub.devices), dev_list=str(dev_list), exception=str(e)), replyTo) return False elif request_type == 'GET_DEV_INTERFACE': dclass = request.pop(0) data = None if dclass in ['EyeTracker', 'DAQ']: for dname, hdevice in ioServer.deviceDict.iteritems():
def __init__(self, rootScriptPathDir, config=None): self._session_id = None self._experiment_id = None self.log("Server Time Offset: {0}".format( Computer.globalClock.getLastResetTime())) self._hookManager = None self.emrt_file = None self.config = config self.devices = [] self.deviceMonitors = [] self.sessionInfoDict = None self.experimentInfoList = None self.filterLookupByInput = {} self.filterLookupByOutput = {} self.filterLookupByName = {} self._hookDevice = None ioServer.eventBuffer = deque( maxlen=config.get('global_event_buffer', 2048)) self._running = True # start UDP service self.udpService = udpServer(self, ':%d' % config.get('udp_port', 9000)) try: # initial dataStore setup if 'data_store' in config and psychopy.iohub._DATA_STORE_AVAILABLE: experiment_datastore_config = config.get('data_store') default_datastore_config_path = os.path.join( IO_HUB_DIRECTORY, 'datastore', 'default_datastore.yaml') #print2err('default_datastore_config_path: ',default_datastore_config_path) _dslabel, default_datastore_config = load( file(default_datastore_config_path, 'r'), Loader=Loader).popitem() for default_key, default_value in default_datastore_config.iteritems( ): if default_key not in experiment_datastore_config: experiment_datastore_config[ default_key] = default_value if experiment_datastore_config.get('enable', True): #print2err("Creating ioDataStore....") resultsFilePath = rootScriptPathDir self.createDataStoreFile( experiment_datastore_config.get('filename', 'events') + '.hdf5', resultsFilePath, 'a', experiment_datastore_config) #print2err("Created ioDataStore.") except: print2err("Error during ioDataStore creation....") printExceptionDetailsToStdErr() #built device list and config from initial yaml config settings try: for iodevice in config.get('monitor_devices', ()): for device_class_name, deviceConfig in iodevice.iteritems(): #print2err("======================================================") #print2err("Started load process for: {0}".format(device_class_name)) self.createNewMonitoredDevice(device_class_name, deviceConfig) except: print2err("Error during device creation ....") printExceptionDetailsToStdErr() raise ioHubError("Error during device creation ....") # Add PubSub device listeners to other event types try: for d in self.devices: if d.__class__.__name__ == "EventPublisher": monitored_event_ids = d._event_listeners.keys() for eid in monitored_event_ids: event_device_class = EventConstants.getClass( eid).PARENT_DEVICE for ed in self.devices: if ed.__class__ == event_device_class: ed._addEventListener(d, [ eid, ]) break except Exception, e: print2err("Error PubSub Device listener association ....") printExceptionDetailsToStdErr() raise e
def _poll(self): try: logged_time = getTime() if not self.isReportingEvents(): self._last_poll_time = logged_time return False if self.isConnected(): if self._custom_parser: parser_state = self._parser_state newrx = self.read() read_time = getTime() if newrx: try: serial_events = self._custom_parser(read_time, newrx, parser_state, **self._custom_parser_kwargs) for evt in serial_events: if type(evt) == dict: evt_time = evt.get('time', read_time) evt_data = evt.get('data', "NO DATA FIELD IN EVENT DICT.") self._createSerialEvent(logged_time, evt_time, evt_data) else: print2err("ioHub Serial Device Error: Events returned from custom parser must be dict's. Skipping: ",str(evt)) except: print2err("ioHub Serial Device Error: Exception during parsing function call.") import traceback, sys traceback.print_exc(file=sys.stderr) print2err("---") elif self._byte_diff_mode: rx = self.read() read_time = getTime() for c in rx: if self._rx_buffer is not None and c != self._rx_buffer: self._createByteChangeSerialEvent(logged_time, read_time, self._rx_buffer, c) self._rx_buffer = c else: parser_state = self._parser_state rx_buffer = self._rx_buffer + self.read() read_time = getTime() prefix = self._parser_config['prefix'] delimiter = self._parser_config['delimiter'] if parser_state['prefix_found'] is False: if prefix and rx_buffer and len(rx_buffer) >= len(prefix): pindex = rx_buffer.find(prefix) if pindex >= 0: rx_buffer = rx_buffer[pindex+len(prefix):] parser_state['prefix_found'] = True if parser_state['delimiter_found'] is False: if delimiter and self._rx_buffer and len(rx_buffer) >= len(delimiter): dindex = rx_buffer.find(delimiter) if dindex >= 0: parser_state['delimiter_found'] = True sindex = dindex eindex = dindex+len(delimiter) parser_state['parsed_event'] += rx_buffer[:sindex] if len(rx_buffer) > eindex: rx_buffer = rx_buffer[eindex:] else: rx_buffer = '' self._rx_buffer = rx_buffer self._createMultiByteSerialEvent(logged_time, read_time) return True if parser_state['bytes_needed'] > 0 and rx_buffer: rxlen = len(rx_buffer) #takebytes = rxlen - parser_state['bytes_needed'] if rxlen > parser_state['bytes_needed']: parser_state['parsed_event'] += rx_buffer[:parser_state['bytes_needed']] parser_state['bytes_needed'] = 0 rx_buffer = rx_buffer[parser_state['bytes_needed']:] else: parser_state['parsed_event'] += rx_buffer parser_state['bytes_needed'] -= rxlen rx_buffer = '' if parser_state['bytes_needed'] == 0: self._rx_buffer = rx_buffer self._createMultiByteSerialEvent(logged_time, read_time) return True self._rx_buffer = rx_buffer else: read_time = logged_time self._last_poll_time = read_time return True except Exception, e: print2err("--------------------------------") print2err("ERROR in Serial._poll: ",e) printExceptionDetailsToStdErr() print2err("---------------------")
def handleExperimentDeviceRequest(self,request,replyTo): request_type= request.pop(0) if request_type == 'EVENT_TX': exp_events=request.pop(0) for eventAsTuple in exp_events: ioServer.deviceDict['Experiment']._nativeEventCallback(eventAsTuple) self.sendResponse(('EVENT_TX_RESULT',len(exp_events)),replyTo) return True elif request_type == 'DEV_RPC': dclass=request.pop(0) dmethod=request.pop(0) args=None kwargs=None if len(request)==1: args=request[0] elif len(request)==2: args=request[0] kwargs=request[1] if len(kwargs)==0: kwargs=None dev=None if dclass.find('.') > 0: for dname, dev in ioServer.deviceDict.iteritems(): if dname.endswith(dclass): dev=ioServer.deviceDict.get(dname,None) break else: dev=ioServer.deviceDict.get(dclass,None) if dev is None: print2err("IOHUB_DEVICE_ERROR") printExceptionDetailsToStdErr() self.sendResponse('IOHUB_DEVICE_ERROR', replyTo) return False try: method=getattr(dev,dmethod) except: print2err("IOHUB_DEVICE_METHOD_ERROR") printExceptionDetailsToStdErr() self.sendResponse('IOHUB_DEVICE_METHOD_ERROR', replyTo) return False result=[] try: if args and kwargs: result=method(*args, **kwargs) elif args: result=method(*args) elif kwargs: result=method(**kwargs) else: result=method() self.sendResponse(('DEV_RPC_RESULT',result),replyTo) return True except Exception, e: print2err("RPC_DEVICE_RUNTIME_ERROR") printExceptionDetailsToStdErr() self.sendResponse('RPC_DEVICE_RUNTIME_ERROR', replyTo) return False
def __init__(self, *args, **kwargs): Device.__init__(self, *args, **kwargs['dconfig']) self._serial = None self.port = self.getConfiguration().get('port') if self.port.lower() == 'auto': pports = self.findPorts() if pports: self.port = pports[0] if len(pports) > 1: print2err( "Warning: Serial device port configuration set " "to 'auto'.\nMultiple serial ports found:\n", pports, "\n** Using port ", self.port ) self.baud = self.getConfiguration().get('baud') self.bytesize = self._bytesizes[self.getConfiguration().get('bytesize')] self.parity = self._parities[self.getConfiguration().get('parity')] self.stopbits = self._stopbits[self.getConfiguration().get('stopbits')] self._parser_config = self.getConfiguration().get('event_parser') self._byte_diff_mode = None self._custom_parser = None self._custom_parser_kwargs = {} custom_parser_func_str = self._parser_config.get('parser_function') if custom_parser_func_str: # print2err("CUSTOM SERIAL PARSER FUNC STR: ", custom_parser_func_str) # Function referenced by string must have the following signature: # # evt_list = someCustomParserName(read_time, rx_data, parser_state, **kwargs) # # where: # read_time: The time when the serial device read() returned # with the new rx_data. # rx_data: The new serial data received. Any buffering of data # across function calls must be done by the function # logic itself. parser_state could be used to hold # such a buffer if needed. # parser_state: A dict which can be used by the function to # store any values that need to be accessed # across multiple calls to the function. The dict # is initially empty. # kwargs: The parser_kwargs preference dict read from # the event_parser preferences; or an empty dict if # parser_kwargs was not found. # # The function must return a list like object, used to provide ioHub # with any new serial events that have been found. # Each element of the list must be a dict like object, representing # a single serial device event found by the parsing function. # A dict can contain the following key, value pairs: # data: The string containing the parsed event data. (REQUIRED) # time: The timestamp for the event (Optional). If not provided, # the return time of the latest serial.read() is used. # Each event returned by the function generates a SerialInputEvent # with the data field = the dict data value. import importlib, sys try: #print2err("EXP_SCRIPT_DIRECTORY: ",EXP_SCRIPT_DIRECTORY) if EXP_SCRIPT_DIRECTORY not in sys.path: sys.path.append(EXP_SCRIPT_DIRECTORY) mod_name, func_name = custom_parser_func_str.rsplit('.', 1) mod = importlib.import_module(mod_name) self._custom_parser = getattr(mod, func_name) except: print2err( "ioHub Serial Device Error: could not load " "custom_parser function: ", custom_parser_func_str) printExceptionDetailsToStdErr() if self._custom_parser: self._custom_parser_kwargs = self._parser_config.get('parser_kwargs',{}) else: self._byte_diff_mode = self._parser_config.get('byte_diff') if self._byte_diff_mode: self._rx_buffer = None else: self._resetParserState() self._rx_buffer = '' self._event_count = 0 self._timeout = None self._serial = None self.setConnectionState(True)
def _poll(self): try: logged_time = getTime() if not self.isReportingEvents(): self._last_poll_time = logged_time return False if self.isConnected(): if self._byte_diff_mode: rx = self.read() read_time = getTime() for c in rx: if self._rx_buffer is not None and c != self._rx_buffer: self._createByteChangeSerialEvent( logged_time, read_time, self._rx_buffer, c) self._rx_buffer = c else: parser_state = self._parser_state rx_buffer = self._rx_buffer + self.read() read_time = getTime() prefix = self._parser_config['prefix'] delimiter = self._parser_config['delimiter'] if parser_state['prefix_found'] is False: if prefix and rx_buffer and len(rx_buffer) >= len( prefix): pindex = rx_buffer.find(prefix) if pindex >= 0: rx_buffer = rx_buffer[pindex + len(prefix):] parser_state['prefix_found'] = True if parser_state['delimiter_found'] is False: if delimiter and self._rx_buffer and len( rx_buffer) >= len(delimiter): dindex = rx_buffer.find(delimiter) if dindex >= 0: parser_state['delimiter_found'] = True sindex = dindex eindex = dindex + len(delimiter) parser_state[ 'parsed_event'] += rx_buffer[:sindex] if len(rx_buffer) > eindex: rx_buffer = rx_buffer[eindex:] else: rx_buffer = '' self._rx_buffer = rx_buffer self._createMultiByteSerialEvent( logged_time, read_time) return True if parser_state['bytes_needed'] > 0 and rx_buffer: rxlen = len(rx_buffer) #takebytes = rxlen - parser_state['bytes_needed'] if rxlen > parser_state['bytes_needed']: parser_state[ 'parsed_event'] += rx_buffer[:parser_state[ 'bytes_needed']] parser_state['bytes_needed'] = 0 rx_buffer = rx_buffer[ parser_state['bytes_needed']:] else: parser_state['parsed_event'] += rx_buffer parser_state['bytes_needed'] -= rxlen rx_buffer = '' if parser_state['bytes_needed'] == 0: self._rx_buffer = rx_buffer self._createMultiByteSerialEvent( logged_time, read_time) return True self._rx_buffer = rx_buffer else: read_time = logged_time self._last_poll_time = read_time return True except Exception, e: print2err("--------------------------------") print2err("ERROR in Serial._poll: ", e) printExceptionDetailsToStdErr() print2err("---------------------")
def _poll(self): try: logged_time = getTime() if not self.isReportingEvents(): self._last_poll_time = logged_time return False if self.isConnected(): if self._custom_parser: parser_state = self._parser_state newrx = self.read() read_time = getTime() if newrx: try: serial_events = self._custom_parser( read_time, newrx, parser_state, **self._custom_parser_kwargs) for evt in serial_events: if type(evt) == dict: evt_time = evt.get('time', read_time) evt_data = evt.get( 'data', "NO DATA FIELD IN EVENT DICT.") self._createSerialEvent( logged_time, evt_time, evt_data) else: print2err( "ioHub Serial Device Error: Events returned from custom parser must be dict's. Skipping: ", str(evt)) except: print2err( "ioHub Serial Device Error: Exception during parsing function call." ) import traceback, sys traceback.print_exc(file=sys.stderr) print2err("---") elif self._byte_diff_mode: rx = self.read() read_time = getTime() for c in rx: if self._rx_buffer is not None and c != self._rx_buffer: self._createByteChangeSerialEvent( logged_time, read_time, self._rx_buffer, c) self._rx_buffer = c else: parser_state = self._parser_state rx_buffer = self._rx_buffer + self.read() read_time = getTime() prefix = self._parser_config['prefix'] delimiter = self._parser_config['delimiter'] if parser_state['prefix_found'] is False: if prefix and rx_buffer and len(rx_buffer) >= len( prefix): pindex = rx_buffer.find(prefix) if pindex >= 0: rx_buffer = rx_buffer[pindex + len(prefix):] parser_state['prefix_found'] = True if parser_state['delimiter_found'] is False: if delimiter and self._rx_buffer and len( rx_buffer) >= len(delimiter): dindex = rx_buffer.find(delimiter) if dindex >= 0: parser_state['delimiter_found'] = True sindex = dindex eindex = dindex + len(delimiter) parser_state[ 'parsed_event'] += rx_buffer[:sindex] if len(rx_buffer) > eindex: rx_buffer = rx_buffer[eindex:] else: rx_buffer = '' self._rx_buffer = rx_buffer self._createMultiByteSerialEvent( logged_time, read_time) return True if parser_state['bytes_needed'] > 0 and rx_buffer: rxlen = len(rx_buffer) #takebytes = rxlen - parser_state['bytes_needed'] if rxlen > parser_state['bytes_needed']: parser_state[ 'parsed_event'] += rx_buffer[:parser_state[ 'bytes_needed']] parser_state['bytes_needed'] = 0 rx_buffer = rx_buffer[ parser_state['bytes_needed']:] else: parser_state['parsed_event'] += rx_buffer parser_state['bytes_needed'] -= rxlen rx_buffer = '' if parser_state['bytes_needed'] == 0: self._rx_buffer = rx_buffer self._createMultiByteSerialEvent( logged_time, read_time) return True self._rx_buffer = rx_buffer else: read_time = logged_time self._last_poll_time = read_time return True except Exception, e: print2err("--------------------------------") print2err("ERROR in Serial._poll: ", e) printExceptionDetailsToStdErr() print2err("---------------------")
def createNewMonitoredDevice(self, device_class_name, deviceConfig): #print2err("#### createNewMonitoredDevice: ",device_class_name) self._all_device_config_errors = dict() try: device_instance = None device_config = None device_event_ids = None event_classes = None device_instance_and_config = self.addDeviceToMonitor( device_class_name, deviceConfig) if device_instance_and_config: device_instance, device_config, device_event_ids, event_classes = device_instance_and_config DeviceConstants.addClassMapping(device_instance.__class__) EventConstants.addClassMappings(device_instance.__class__, device_event_ids, event_classes) else: print2err('## Device was not started by the ioHub Server: ', device_class_name) raise ioHubError("Device config validation failed") except: print2err("Error during device creation ....") printExceptionDetailsToStdErr() raise ioHubError("Error during device creation ....") # Update DataStore Structure if required. if psychopy.iohub._DATA_STORE_AVAILABLE: try: if self.emrt_file is not None: self.emrt_file.updateDataStoreStructure( device_instance, event_classes) except: print2err( "Error while updating datastore for device addition:", device_instance, device_event_ids) printExceptionDetailsToStdErr() self.log("Adding ioServer and DataStore event listeners......") # add event listeners for saving events if psychopy.iohub._DATA_STORE_AVAILABLE and self.emrt_file is not None: if device_config['save_events']: device_instance._addEventListener(self.emrt_file, device_event_ids) self.log( "DataStore listener for device added: device: %s eventIDs: %s" % (device_instance.__class__.__name__, device_event_ids)) #print2err("DataStore listener for device added: device: %s eventIDs: %s"%(device_instance.__class__.__name__,device_event_ids)) else: #print2err("DataStore saving disabled for device: %s"%(device_instance.__class__.__name__,)) self.log("DataStore saving disabled for device: %s" % (device_instance.__class__.__name__, )) else: #print2err("DataStore Not Evabled. No events will be saved.") self.log("DataStore Not Enabled. No events will be saved.") # Add Device Monitor for Keyboard or Mouse device type deviceDict = ioServer.deviceDict iohub = self if device_class_name in ('Mouse', 'Keyboard'): if Computer.system == 'win32': if self._hookDevice is None: iohub.log("Creating pyHook Monitors....") #print2err("Creating pyHook Monitor....") class pyHookDevice(object): def __init__(self): import pyHook self._hookManager = pyHook.HookManager() self._mouseHooked = False self._keyboardHooked = False if device_class_name == 'Mouse': #print2err("Hooking Mouse.....") self._hookManager.MouseAll = deviceDict[ 'Mouse']._nativeEventCallback self._hookManager.HookMouse() self._mouseHooked = True elif device_class_name == 'Keyboard': #print2err("Hooking Keyboard.....") self._hookManager.KeyAll = deviceDict[ 'Keyboard']._nativeEventCallback self._hookManager.HookKeyboard() self._keyboardHooked = True #iohub.log("WindowsHook PumpEvents Periodic Timer Created.") def _poll(self): import pythoncom # PumpWaitingMessages returns 1 if a WM_QUIT message was received, else 0 if pythoncom.PumpWaitingMessages() == 1: raise KeyboardInterrupt() #print2err("Creating pyHook Monitor......") self._hookDevice = pyHookDevice() hookMonitor = DeviceMonitor( self._hookDevice, self.config.get('windows_msgpump_interval', 0.00375)) self.deviceMonitors.append(hookMonitor) #print2err("Created pyHook Monitor.") else: #print2err("UPDATING pyHook Monitor....") if device_class_name == 'Mouse' and self._hookDevice._mouseHooked is False: #print2err("Hooking Mouse.....") self._hookDevice._hookManager.MouseAll = deviceDict[ 'Mouse']._nativeEventCallback self._hookDevice._hookManager.HookMouse() self._hookDevice._mouseHooked = True elif device_class_name == 'Keyboard' and self._hookDevice._keyboardHooked is False: #print2err("Hooking Keyboard.....") self._hookDevice._hookManager.KeyAll = deviceDict[ 'Keyboard']._nativeEventCallback self._hookDevice._hookManager.HookKeyboard() self._hookDevice._keyboardHooked = True #print2err("Finished Updating pyHook Monitor.") elif Computer.system == 'linux2': # TODO: consider switching to xlib-ctypes implementation of xlib # https://github.com/garrybodsworth/pyxlib-ctypes from .devices import pyXHook if self._hookManager is None: #iohub.log("Creating pyXHook Monitors....") self._hookManager = pyXHook.HookManager() self._hookManager._mouseHooked = False self._hookManager._keyboardHooked = False if device_class_name == 'Keyboard': #print2err("Hooking Keyboard.....") self._hookManager.HookKeyboard() self._hookManager.KeyDown = deviceDict[ 'Keyboard']._nativeEventCallback self._hookManager.KeyUp = deviceDict[ 'Keyboard']._nativeEventCallback self._hookManager._keyboardHooked = True elif device_class_name == 'Mouse': #print2err("Hooking Mouse.....") self._hookManager.HookMouse() self._hookManager.MouseAllButtonsDown = deviceDict[ 'Mouse']._nativeEventCallback self._hookManager.MouseAllButtonsUp = deviceDict[ 'Mouse']._nativeEventCallback self._hookManager.MouseAllMotion = deviceDict[ 'Mouse']._nativeEventCallback self._hookManager._mouseHooked = True #print2err("Starting pyXHook.HookManager.....") self._hookManager.start() #iohub.log("pyXHook Thread Created.") #print2err("pyXHook.HookManager thread created.") else: #iohub.log("Updating pyXHook Monitor....") if device_class_name == 'Keyboard' and self._hookManager._keyboardHooked is False: #print2err("Hooking Keyboard.....") self._hookManager.HookKeyboard() self._hookManager.KeyDown = deviceDict[ 'Keyboard']._nativeEventCallback self._hookManager.KeyUp = deviceDict[ 'Keyboard']._nativeEventCallback self._hookManager._keyboardHooked = True if device_class_name == 'Mouse' and self._hookManager._mouseHooked is False: #print2err("Hooking Mouse.....") self._hookManager.HookMouse() self._hookManager.MouseAllButtonsDown = deviceDict[ 'Mouse']._nativeEventCallback self._hookManager.MouseAllButtonsUp = deviceDict[ 'Mouse']._nativeEventCallback self._hookManager.MouseAllMotion = deviceDict[ 'Mouse']._nativeEventCallback self._hookManager._mouseHooked = True #iohub.log("Finished Updating pyXHook Monitor....") else: # OSX if self._hookDevice is None: self._hookDevice = [] if device_class_name == 'Mouse' and 'Mouse' not in self._hookDevice: #print2err("Hooking OSX Mouse.....") mouseHookMonitor = DeviceMonitor(deviceDict['Mouse'], 0.004) self.deviceMonitors.append(mouseHookMonitor) deviceDict['Mouse']._CGEventTapEnable( deviceDict['Mouse']._tap, True) self._hookDevice.append('Mouse') #print2err("Done Hooking OSX Mouse.....") if device_class_name == 'Keyboard' and 'Keyboard' not in self._hookDevice: #print2err("Hooking OSX Keyboard.....") kbHookMonitor = DeviceMonitor(deviceDict['Keyboard'], 0.004) self.deviceMonitors.append(kbHookMonitor) deviceDict['Keyboard']._CGEventTapEnable( deviceDict['Keyboard']._tap, True) self._hookDevice.append('Keyboard') #print2err("DONE Hooking OSX Keyboard.....") return [ device_class_name, device_config['name'], device_instance._getRPCInterface() ]