コード例 #1
0
ファイル: emotiv.py プロジェクト: woodrowbarlow/biogen-music
class Emotiv(object):
    def __init__(self, displayOutput=False, headsetId=0, research_headset=True):
        self._goOn = True
        self.packets = Queue()
        self.packetsReceived = 0
        self.packetsProcessed = 0
        self.battery = 0
        self.displayOutput = displayOutput
        self.headsetId = headsetId
        self.research_headset = research_headset
        self.sensors = {
            'F3': {'value': 0, 'quality': 0},
            'FC6': {'value': 0, 'quality': 0},
            'P7': {'value': 0, 'quality': 0},
            'T8': {'value': 0, 'quality': 0},
            'F7': {'value': 0, 'quality': 0},
            'F8': {'value': 0, 'quality': 0},
            'T7': {'value': 0, 'quality': 0},
            'P8': {'value': 0, 'quality': 0},
            'AF4': {'value': 0, 'quality': 0},
            'F4': {'value': 0, 'quality': 0},
            'AF3': {'value': 0, 'quality': 0},
            'O2': {'value': 0, 'quality': 0},
            'O1': {'value': 0, 'quality': 0},
            'FC5': {'value': 0, 'quality': 0},
            'X': {'value': 0, 'quality': 0},
            'Y': {'value': 0, 'quality': 0},
            'Unknown': {'value': 0, 'quality': 0}
        }

    def setup(self, headsetId=0):
        if windows:
            self.setupWin()
        else:
            self.setupPosix()

    def updateStdout(self):
        while self._goOn:
            if self.displayOutput:
                if windows:
                    os.system('cls')
                else:
                    os.system('clear')
                print "Packets Received: %s Packets Processed: %s" % (self.packetsReceived, self.packetsProcessed)
                print('\n'.join("%s Reading: %s Strength: %s" % (k[1], self.sensors[k[1]]['value'],self.sensors[k[1]]['quality']) for k in enumerate(self.sensors)))
                print "Battery: %i" % g_battery
            gevent.sleep(1)

    def getLinuxSetup(self):
        rawinputs = []
        for filename in os.listdir("/sys/class/hidraw"):
            realInputPath = check_output(["realpath", "/sys/class/hidraw/" + filename])
            sPaths = realInputPath.split('/')
            s = len(sPaths)
            s = s - 4
            i = 0
            path = ""
            while s > i:
                path = path + sPaths[i] + "/"
                i += 1
            rawinputs.append([path, filename])
        hiddevices = []
        # TODO: Add support for multiple USB sticks? make a bit more elegant
        for input in rawinputs:
            try:
                with open(input[0] + "/manufacturer", 'r') as f:
                    manufacturer = f.readline()
                    f.close()
                if ("Emotiv Systems Inc." in manufacturer) or ("Emotiv Systems Pty Ltd" in manufacturer) :
                    with open(input[0] + "/serial", 'r') as f:
                        serial = f.readline().strip()
                        f.close()
                    print "Serial: " + serial + " Device: " + input[1]
                    # Great we found it. But we need to use the second one...
                    hidraw = input[1]
                    id_hidraw = int(hidraw[-1])
                    # The dev headset might use the first device, or maybe if more than one are connected they might.
                    id_hidraw += 1
                    hidraw = "hidraw" + id_hidraw.__str__()
                    print "Serial: " + serial + " Device: " + hidraw + " (Active)"
                    return [serial, hidraw, ]
            except IOError as e:
                print "Couldn't open file: %s" % e

    def setupWin(self):
        devices = []
        try:
            for device in hid.find_all_hid_devices():
                if device.vendor_id != 0x21A1 and device.vendor_id != 0x1234:
                    continue
                if device.product_name == 'Brain Waves':
                    devices.append(device)
                    device.open()
                    self.serialNum = device.serial_number
                    device.set_raw_data_handler(self.handler)
                elif device.product_name == 'EPOC BCI':
                    devices.append(device)
                    device.open()
                    self.serialNum = device.serial_number
                    device.set_raw_data_handler(self.handler)
                elif device.product_name == '00000000000':
                    devices.append(device)
                    device.open()
                    self.serialNum = device.serial_number
                    device.set_raw_data_handler(self.handler)
                elif device.product_name == 'Emotiv RAW DATA':
                    devices.append(device)
                    device.open()
                    self.serialNum = device.serial_number
                    device.set_raw_data_handler(self.handler)
            gevent.spawn(self.setupCrypto, self.serialNum)
            gevent.spawn(self.updateStdout)
            while self._goOn:
                try:
                    gevent.sleep(0)
                except KeyboardInterrupt:
                    self._goOn = False
                    for device in devices:
                        device.close()
        finally:
            for device in devices:
                device.close()

    def handler(self, data):
        assert data[0] == 0
        tasks.put_nowait(''.join(map(chr, data[1:])))
        self.packetsReceived += 1
        return True

    def setupPosix(self):
        _os_decryption = False
        if os.path.exists('/dev/eeg/raw'):
            # The decrpytion is handled by the Linux epoc daemon. We don't need to handle it there.
            _os_decryption = True
            self.hidraw = open("/dev/eeg/raw")
        else:
            setup = self.getLinuxSetup()
            self.serialNum = setup[0]
            if os.path.exists("/dev/" + setup[1]):
                self.hidraw = open("/dev/" + setup[1])
            else:
                self.hidraw = open("/dev/hidraw4")
            gevent.spawn(self.setupCrypto, self.serialNum)
            gevent.spawn(self.updateStdout)
        while self._goOn:
            try:
                data = self.hidraw.read(32)
                if data != "":
                    if _os_decryption:
                        self.packets.put_nowait(EmotivPacket(data))
                    else:
                        # Queue it!
                        self.packetsReceived += 1
                        tasks.put_nowait(data)
                        gevent.sleep(0)
            except KeyboardInterrupt:
                self._goOn = False
        return True

    def setupCrypto(self, sn):
        type = 0 # feature[5]
        type &= 0xF
        type = 0
        # I believe type == True is for the Dev headset, I'm not using that. That's the point of this library in the first place I thought.
        k = ['\0'] * 16
        k[0] = sn[-1]
        k[1] = '\0'
        k[2] = sn[-2]
        if type:
            k[3] = 'H'
            k[4] = sn[-1]
            k[5] = '\0'
            k[6] = sn[-2]
            k[7] = 'T'
            k[8] = sn[-3]
            k[9] = '\x10'
            k[10] = sn[-4]
            k[11] = 'B'
        else:
            k[3] = 'T'
            k[4] = sn[-3]
            k[5] = '\x10'
            k[6] = sn[-4]
            k[7] = 'B'
            k[8] = sn[-1]
            k[9] = '\0'
            k[10] = sn[-2]
            k[11] = 'H'
        k[12] = sn[-3]
        k[13] = '\0'
        k[14] = sn[-4]
        k[15] = 'P'
        # It doesn't make sense to have more than one greenlet handling this as data needs to be in order anyhow. I guess you could assign an ID or something
        # to each packet but that seems like a waste also or is it? The ID might be useful if your using multiple headsets or usb sticks.
        key = ''.join(k)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(key, AES.MODE_ECB, iv)
        for i in k: print "0x%.02x " % (ord(i))
        while self._goOn:
            while not tasks.empty():
                task = tasks.get()
                data = cipher.decrypt(task[:16]) + cipher.decrypt(task[16:])
                self.lastPacket = EmotivPacket(data, self.sensors)
                self.packets.put_nowait(self.lastPacket)
                self.packetsProcessed += 1
                gevent.sleep(0)
            gevent.sleep(0)

    def dequeue(self):
        try:
            p = self.packets.get()
            self.packets.clear()
            return p
        except Exception, e:
            print e
コード例 #2
0
class Emotiv(object):
    def __init__(self,
                 displayOutput=False,
                 headsetId=0,
                 research_headset=True):
        self._goOn = True
        self.packets = Queue()
        self.packetsReceived = 0
        self.packetsProcessed = 0
        self.battery = 0
        self.displayOutput = displayOutput
        self.headsetId = headsetId
        self.research_headset = research_headset
        self.sensors = {
            'F3': {
                'value': 0,
                'quality': 0
            },
            'FC6': {
                'value': 0,
                'quality': 0
            },
            'P7': {
                'value': 0,
                'quality': 0
            },
            'T8': {
                'value': 0,
                'quality': 0
            },
            'F7': {
                'value': 0,
                'quality': 0
            },
            'F8': {
                'value': 0,
                'quality': 0
            },
            'T7': {
                'value': 0,
                'quality': 0
            },
            'P8': {
                'value': 0,
                'quality': 0
            },
            'AF4': {
                'value': 0,
                'quality': 0
            },
            'F4': {
                'value': 0,
                'quality': 0
            },
            'AF3': {
                'value': 0,
                'quality': 0
            },
            'O2': {
                'value': 0,
                'quality': 0
            },
            'O1': {
                'value': 0,
                'quality': 0
            },
            'FC5': {
                'value': 0,
                'quality': 0
            },
            'X': {
                'value': 0,
                'quality': 0
            },
            'Y': {
                'value': 0,
                'quality': 0
            },
            'Unknown': {
                'value': 0,
                'quality': 0
            }
        }

    def setup(self, headsetId=0):
        if windows:
            self.setupWin()
        else:
            self.setupPosix()

    def updateStdout(self):
        while self._goOn:
            if self.displayOutput:
                if windows:
                    os.system('cls')
                else:
                    os.system('clear')
                print "Packets Received: %s Packets Processed: %s" % (
                    self.packetsReceived, self.packetsProcessed)
                print('\n'.join("%s Reading: %s Strength: %s" %
                                (k[1], self.sensors[k[1]]['value'],
                                 self.sensors[k[1]]['quality'])
                                for k in enumerate(self.sensors)))
                print "Battery: %i" % g_battery
            gevent.sleep(1)

    def getLinuxSetup(self):
        rawinputs = []
        for filename in os.listdir("/sys/class/hidraw"):
            realInputPath = check_output(
                ["realpath", "/sys/class/hidraw/" + filename])
            sPaths = realInputPath.split('/')
            s = len(sPaths)
            s = s - 4
            i = 0
            path = ""
            while s > i:
                path = path + sPaths[i] + "/"
                i += 1
            rawinputs.append([path, filename])
        hiddevices = []
        # TODO: Add support for multiple USB sticks? make a bit more elegant
        for input in rawinputs:
            try:
                with open(input[0] + "/manufacturer", 'r') as f:
                    manufacturer = f.readline()
                    f.close()
                if ("Emotiv Systems Inc."
                        in manufacturer) or ("Emotiv Systems Pty Ltd"
                                             in manufacturer):
                    with open(input[0] + "/serial", 'r') as f:
                        serial = f.readline().strip()
                        f.close()
                    print "Serial: " + serial + " Device: " + input[1]
                    # Great we found it. But we need to use the second one...
                    hidraw = input[1]
                    id_hidraw = int(hidraw[-1])
                    # The dev headset might use the first device, or maybe if more than one are connected they might.
                    id_hidraw += 1
                    hidraw = "hidraw" + id_hidraw.__str__()
                    print "Serial: " + serial + " Device: " + hidraw + " (Active)"
                    return [
                        serial,
                        hidraw,
                    ]
            except IOError as e:
                print "Couldn't open file: %s" % e

    def setupWin(self):
        devices = []
        try:
            for device in hid.find_all_hid_devices():
                if device.vendor_id != 0x21A1 and device.vendor_id != 0x1234:
                    continue
                if device.product_name == 'Brain Waves':
                    devices.append(device)
                    device.open()
                    self.serialNum = device.serial_number
                    device.set_raw_data_handler(self.handler)
                elif device.product_name == 'EPOC BCI':
                    devices.append(device)
                    device.open()
                    self.serialNum = device.serial_number
                    device.set_raw_data_handler(self.handler)
                elif device.product_name == '00000000000':
                    devices.append(device)
                    device.open()
                    self.serialNum = device.serial_number
                    device.set_raw_data_handler(self.handler)
                elif device.product_name == 'Emotiv RAW DATA':
                    devices.append(device)
                    device.open()
                    self.serialNum = device.serial_number
                    device.set_raw_data_handler(self.handler)
            gevent.spawn(self.setupCrypto, self.serialNum)
            gevent.spawn(self.updateStdout)
            while self._goOn:
                try:
                    gevent.sleep(0)
                except KeyboardInterrupt:
                    self._goOn = False
                    for device in devices:
                        device.close()
        finally:
            for device in devices:
                device.close()

    def handler(self, data):
        assert data[0] == 0
        tasks.put_nowait(''.join(map(chr, data[1:])))
        self.packetsReceived += 1
        return True

    def setupPosix(self):
        _os_decryption = False
        if os.path.exists('/dev/eeg/raw'):
            # The decrpytion is handled by the Linux epoc daemon. We don't need to handle it there.
            _os_decryption = True
            self.hidraw = open("/dev/eeg/raw")
        else:
            setup = self.getLinuxSetup()
            self.serialNum = setup[0]
            if os.path.exists("/dev/" + setup[1]):
                self.hidraw = open("/dev/" + setup[1])
            else:
                self.hidraw = open("/dev/hidraw4")
            gevent.spawn(self.setupCrypto, self.serialNum)
            gevent.spawn(self.updateStdout)
        while self._goOn:
            try:
                data = self.hidraw.read(32)
                if data != "":
                    if _os_decryption:
                        self.packets.put_nowait(EmotivPacket(data))
                    else:
                        # Queue it!
                        self.packetsReceived += 1
                        tasks.put_nowait(data)
                        gevent.sleep(0)
            except KeyboardInterrupt:
                self._goOn = False
        return True

    def setupCrypto(self, sn):
        type = 0  # feature[5]
        type &= 0xF
        type = 0
        # I believe type == True is for the Dev headset, I'm not using that. That's the point of this library in the first place I thought.
        k = ['\0'] * 16
        k[0] = sn[-1]
        k[1] = '\0'
        k[2] = sn[-2]
        if type:
            k[3] = 'H'
            k[4] = sn[-1]
            k[5] = '\0'
            k[6] = sn[-2]
            k[7] = 'T'
            k[8] = sn[-3]
            k[9] = '\x10'
            k[10] = sn[-4]
            k[11] = 'B'
        else:
            k[3] = 'T'
            k[4] = sn[-3]
            k[5] = '\x10'
            k[6] = sn[-4]
            k[7] = 'B'
            k[8] = sn[-1]
            k[9] = '\0'
            k[10] = sn[-2]
            k[11] = 'H'
        k[12] = sn[-3]
        k[13] = '\0'
        k[14] = sn[-4]
        k[15] = 'P'
        # It doesn't make sense to have more than one greenlet handling this as data needs to be in order anyhow. I guess you could assign an ID or something
        # to each packet but that seems like a waste also or is it? The ID might be useful if your using multiple headsets or usb sticks.
        key = ''.join(k)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(key, AES.MODE_ECB, iv)
        for i in k:
            print "0x%.02x " % (ord(i))
        while self._goOn:
            while not tasks.empty():
                task = tasks.get()
                data = cipher.decrypt(task[:16]) + cipher.decrypt(task[16:])
                self.lastPacket = EmotivPacket(data, self.sensors)
                self.packets.put_nowait(self.lastPacket)
                self.packetsProcessed += 1
                gevent.sleep(0)
            gevent.sleep(0)

    def dequeue(self):
        try:
            p = self.packets.get()
            self.packets.clear()
            return p
        except Exception, e:
            print e