Beispiel #1
0
    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("--------------------------------------")
Beispiel #2
0
    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()
Beispiel #3
0
 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
Beispiel #4
0
 def checkIfSessionCodeExists(self,sessionCode):
     try:
         if self.iohub.emrt_file:
             return self.iohub.emrt_file.checkIfSessionCodeExists(sessionCode)
         return False
     except:
         printExceptionDetailsToStdErr()
Beispiel #5
0
 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()
Beispiel #6
0
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
Beispiel #7
0
    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 ....")
Beispiel #8
0
 def flush(self):
     try:
         if self.emrtFile:
             self.emrtFile.flush()
     except ClosedFileError:
         pass
     except:
         printExceptionDetailsToStdErr()
Beispiel #9
0
    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('----------------------------------------------')
Beispiel #10
0
 def shutDown(self):
     try:
         self.disableHighPriority()
         self.iohub.shutdown()
         self._running=False
         self.stop()
     except:
         print2err("Error in ioSever.shutdown():")
         printExceptionDetailsToStdErr()
         sys.exit(1)
Beispiel #11
0
 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()
Beispiel #12
0
 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()
Beispiel #13
0
 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
Beispiel #14
0
 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()
Beispiel #15
0
    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()
Beispiel #16
0
    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
Beispiel #17
0
 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("--------------------------------------")
Beispiel #18
0
    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
Beispiel #19
0
    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)
Beispiel #20
0
 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
Beispiel #21
0
    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()
Beispiel #22
0
    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)
Beispiel #23
0
    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
Beispiel #24
0
    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
Beispiel #25
0
    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()
Beispiel #26
0
    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()
Beispiel #27
0
    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()
Beispiel #28
0
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
Beispiel #29
0
    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
Beispiel #30
0
    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()]
Beispiel #31
0
    
            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:
Beispiel #32
0
 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
Beispiel #33
0
    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)
Beispiel #34
0
    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("---------------------")
Beispiel #35
0
    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
Beispiel #36
0
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
Beispiel #37
0
    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
Beispiel #38
0
                        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():
Beispiel #39
0
    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
Beispiel #40
0
    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("---------------------")
Beispiel #41
0
    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
Beispiel #42
0
    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)
Beispiel #43
0
    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("---------------------")
Beispiel #44
0
    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("---------------------")
Beispiel #45
0
    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()
            ]