source: synapse/puzzlebox_synapse_interface.py @ 152

Last change on this file since 152 was 152, checked in by sc, 11 years ago

synapse/puzzlebox_synapse_client_thinkgear.py:

  • updated for PySide? QHostAddress handling

synapse/puzzlebox_synapse_protocol_thinkgear.py:

  • packet processing handed off to parent

synapse/puzzlebox_synapse_interface.py:

  • updateInterface added
  • interface updated via timer instead of child processes
  • support for ThinkGear? Connect client processing (commented out by default)

synapse/puzzlebox_synapse_server_thinkgear.py:

  • Emulation timer only called in emulation mode
  • processPacketThinkGear added
  • updateStatus cleanup
  • Property svn:executable set to *
File size: 15.9 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Puzzlebox - Synapse - Interface
5#
6# Copyright Puzzlebox Productions, LLC (2010)
7#
8# This code is released under the GNU Pulic License (GPL) version 2
9# For more information please refer to http://www.gnu.org/copyleft/gpl.html
10#
11# Last Update: 2010.08.09
12#
13#####################################################################
14# To Do:
15# - update configuration.ini file with settings entered into interface
16#####################################################################
17
18import os, sys
19
20import simplejson as json
21
22if (sys.platform != 'win32'):
23        import bluetooth
24else:
25        import serial
26
27try:
28        import PySide as PyQt4
29        from PySide import QtCore, QtGui
30except:
31        print "Using PyQt4 module"
32        from PyQt4 import QtCore, QtGui
33else:
34        print "Using PySide module"
35
36#from PyQt4 import QtCore, QtGui
37#from PySide import QtCore, QtGui
38
39#from PyQt4 import QtNetwork
40
41from puzzlebox_synapse_interface_design import Ui_Form
42
43import puzzlebox_synapse_configuration as configuration
44import puzzlebox_synapse_server_thinkgear as synapse_server
45#import puzzlebox_synapse_client_thinkgear as thinkgear_client
46#import puzzlebox_logger
47
48#####################################################################
49# Globals
50#####################################################################
51
52DEBUG = 1
53
54#THINKGEAR_POWER_THRESHOLDS = configuration.THINKGEAR_POWER_THRESHOLDS
55
56#BLUETOOTH_DEVICE = configuration.NXT_BLUETOOTH_DEVICE
57
58#NXT_BLUETOOTH_DEVICE = configuration.NXT_BLUETOOTH_DEVICE
59
60#DEFAULT_NXT_POWER_LEVEL = configuration.DEFAULT_NXT_POWER_LEVEL
61
62THINKGEAR_SERVER_HOST = configuration.THINKGEAR_SERVER_HOST
63THINKGEAR_SERVER_PORT = configuration.THINKGEAR_SERVER_PORT
64
65THINKGEAR_EEG_POWER_BAND_ORDER = configuration.THINKGEAR_EEG_POWER_BAND_ORDER
66
67THINKGEAR_EMULATION_MAX_ESENSE_VALUE = \
68        configuration.THINKGEAR_EMULATION_MAX_ESENSE_VALUE
69THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE = \
70        configuration.THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE
71
72PATH_TO_HCITOOL = '/usr/bin/hcitool'
73
74INTERFACE_UPDATE_FREQUENCY = 1000 # ms
75
76#####################################################################
77# Classes
78#####################################################################
79
80class puzzlebox_synapse_interface(QtGui.QWidget, Ui_Form):
81       
82        def __init__(self, log, server=None, DEBUG=DEBUG, parent = None):
83               
84                self.log = log
85                self.DEBUG = DEBUG
86               
87                QtGui.QWidget.__init__(self, parent)
88                self.setupUi(self)
89               
90                self.configureSettings()
91                self.connectWidgets()
92               
93                self.name = "Synapse Interface"
94               
95                self.thinkGearConnectServer = None
96                self.thinkgearConnectClient = None
97               
98                self.maxEEGPower = THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE
99               
100                self.debug_console_buffer = ''
101               
102                self.updateInterfaceTimer = QtCore.QTimer()
103                QtCore.QObject.connect(self.updateInterfaceTimer, \
104                                            QtCore.SIGNAL("timeout()"), \
105                                            self.updateInterface)
106       
107       
108        ##################################################################
109       
110        def configureSettings(self):
111               
112                # Synapse Interface
113               
114                icon = QtGui.QIcon()
115                icon.addPixmap(QtGui.QPixmap("images/puzzlebox.ico"), \
116                               QtGui.QIcon.Normal, \
117                               QtGui.QIcon.Off)
118                self.setWindowIcon(icon)
119               
120               
121                # ThinkGear Device
122               
123                self.searchForThinkGearDevices()
124               
125               
126                # ThinkGear Connect Server
127               
128                self.textLabelBluetoothStatus.setText("Status: Disconnected")
129               
130                # Display Host for ThinkGear Connect Socket Server
131                self.lineEditThinkGearHost.setText(THINKGEAR_SERVER_HOST)
132               
133                # Display Port for ThinkGear Connect Socket Server
134                self.lineEditThinkGearPort.setText('%i' % THINKGEAR_SERVER_PORT)
135               
136               
137                # ThinkgGear Progress Bars
138                self.progressBarEEGDelta.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
139                self.progressBarEEGTheta.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
140                self.progressBarEEGLowAlpha.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
141                self.progressBarEEGHighAlpha.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
142                self.progressBarEEGLowBeta.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
143                self.progressBarEEGHighBeta.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
144                self.progressBarEEGLowGamma.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
145                self.progressBarEEGMidGamma.setMaximum(THINKGEAR_EMULATION_MAX_EEG_POWER_VALUE)
146               
147                self.progressBarAttention.setMaximum(THINKGEAR_EMULATION_MAX_ESENSE_VALUE)
148                self.progressBarMeditation.setMaximum(THINKGEAR_EMULATION_MAX_ESENSE_VALUE)
149               
150                self.progressBarSignalContactQuality.setMaximum(200)
151       
152       
153        ##################################################################
154       
155        def connectWidgets(self):
156               
157                self.connect(self.pushButtonBluetoothSearch, \
158                                  QtCore.SIGNAL("clicked()"), \
159                                  self.searchForThinkGearDevices)
160               
161                self.connect(self.pushButtonBluetoothConnect, \
162                                  QtCore.SIGNAL("clicked()"), \
163                                  self.connectToThinkGearDevice)
164               
165                self.connect(self.pushButtonThinkGearConnect, \
166                                  QtCore.SIGNAL("clicked()"), \
167                                  self.startThinkGearConnectServer)
168       
169       
170        ##################################################################
171       
172        def connectToThinkGearDevice(self):
173               
174                device_selection = self.comboBoxDeviceSelect.currentText()
175               
176                success = self.startThinkGearDeviceProcessing()
177               
178                if success:
179               
180                        self.disconnect(self.pushButtonBluetoothConnect, \
181                                             QtCore.SIGNAL("clicked()"), \
182                                             self.connectToThinkGearDevice)
183                       
184                        self.connect(self.pushButtonBluetoothConnect, \
185                                          QtCore.SIGNAL("clicked()"), \
186                                          self.disconnectFromThinkGearDevice)
187                       
188                        self.textLabelBluetoothStatus.setText("Status: Connected")
189                       
190                        self.pushButtonBluetoothSearch.setEnabled(False)
191                       
192                        self.pushButtonBluetoothConnect.setText('Disconnect')
193                        self.pushButtonBluetoothConnect.setChecked(True)
194                       
195                        self.comboBoxDeviceSelect.setEnabled(False)
196               
197               
198                return(success)
199       
200       
201        ##################################################################
202       
203        def disconnectFromThinkGearDevice(self):
204               
205                self.disconnect(self.pushButtonBluetoothConnect, \
206                                     QtCore.SIGNAL("clicked()"), \
207                                     self.disconnectFromThinkGearDevice)
208               
209                self.connect(self.pushButtonBluetoothConnect, \
210                                  QtCore.SIGNAL("clicked()"), \
211                                  self.connectToThinkGearDevice)
212               
213                self.textLabelBluetoothStatus.setText("Status: Disconnected")
214               
215                self.pushButtonBluetoothSearch.setEnabled(True)
216               
217                self.pushButtonBluetoothConnect.setText('Connect')
218                self.pushButtonBluetoothConnect.setChecked(False)
219               
220                self.comboBoxDeviceSelect.setEnabled(True)
221               
222               
223                self.progressBarEEGDelta.setValue(0)
224                self.progressBarEEGTheta.setValue(0)
225                self.progressBarEEGLowAlpha.setValue(0)
226                self.progressBarEEGHighAlpha.setValue(0)
227                self.progressBarEEGLowBeta.setValue(0)
228                self.progressBarEEGHighBeta.setValue(0)
229                self.progressBarEEGLowGamma.setValue(0)
230                self.progressBarEEGMidGamma.setValue(0)
231               
232                self.progressBarAttention.setValue(0)
233                self.progressBarMeditation.setValue(0)
234               
235                self.progressBarSignalContactQuality.setValue(0)
236       
237       
238        ##################################################################
239       
240        def startThinkGearDeviceProcessing(self):
241               
242                #device_address = self.comboBoxDeviceSelect.currentText()
243               
244                #emulate_headset_data = (device_address == 'MindSet Emulator')
245               
246                #self.thinkGearConnectServer = \
247                        #puzzlebox_synapse_server(log, \
248                                                 #server_interface, \
249                                                 #server_port, \
250                                                 #device_address, \
251                                                 #DEBUG=DEBUG, \
252                                                 #parent=self)
253               
254               
255                #self.thinkGearConnectServer.start()
256               
257                return(True)
258       
259       
260        ##################################################################
261       
262        def startThinkGearConnectServer(self):
263               
264                # Ensure EEG device is connected first
265               
266                if not self.pushButtonBluetoothConnect.isChecked():
267                        success = self.connectToThinkGearDevice()
268                else:
269                        success = True
270               
271               
272                if success:
273                       
274                        self.pushButtonBluetoothSearch.setEnabled(False)
275                        self.pushButtonBluetoothConnect.setEnabled(False)
276                       
277                        server_interface = str(self.lineEditThinkGearHost.text())
278                        server_port = int(self.lineEditThinkGearPort.text())
279                        device_address = str(self.comboBoxDeviceSelect.currentText())
280                        emulate_headset_data = (device_address == 'MindSet Emulator')
281                       
282                       
283                        self.thinkGearConnectServer = \
284                                synapse_server.puzzlebox_synapse_server_thinkgear( \
285                                        log, \
286                                        server_interface=server_interface, \
287                                        server_port=server_port, \
288                                        device_address=device_address, \
289                                        emulate_headset_data=emulate_headset_data, \
290                                        DEBUG=DEBUG, \
291                                        parent=self)
292                       
293                        self.thinkGearConnectServer.start()
294                       
295                        self.updateInterfaceTimer.start(INTERFACE_UPDATE_FREQUENCY)
296                       
297                        #self.thinkgearConnectClient = \
298                                #thinkgear_client.puzzlebox_synapse_client_thinkgear( \
299                                        #self.log, \
300                                        #server_host=server_interface, \
301                                        #server_port=server_port, \
302                                        #DEBUG=0, \
303                                        #parent=self)
304                       
305                        #self.thinkgearConnectClient.start()
306                       
307                       
308                        self.disconnect(self.pushButtonThinkGearConnect, \
309                                             QtCore.SIGNAL("clicked()"), \
310                                             self.startThinkGearConnectServer)
311                       
312                        self.connect(self.pushButtonThinkGearConnect, \
313                                          QtCore.SIGNAL("clicked()"), \
314                                          self.stopThinkGearConnectServer)
315                       
316                        self.lineEditThinkGearHost.setEnabled(False)
317                        self.lineEditThinkGearPort.setEnabled(False)
318                       
319                        self.pushButtonThinkGearConnect.setText('Stop')
320       
321       
322        ##################################################################
323       
324        def stopThinkGearConnectServer(self):
325               
326                #self.thinkgearConnectClient.disconnectFromHost()
327               
328                self.updateInterfaceTimer.stop()
329               
330                self.thinkGearConnectServer.exitThread()
331               
332                self.disconnect(self.pushButtonThinkGearConnect, \
333                                     QtCore.SIGNAL("clicked()"), \
334                                     self.stopThinkGearConnectServer)
335               
336                self.connect(self.pushButtonThinkGearConnect, \
337                                  QtCore.SIGNAL("clicked()"), \
338                                  self.startThinkGearConnectServer)
339               
340                self.lineEditThinkGearHost.setEnabled(True)
341                self.lineEditThinkGearPort.setEnabled(True)
342               
343                self.pushButtonThinkGearConnect.setText('Start')
344               
345                #self.pushButtonBluetoothSearch.setEnabled(True)
346                self.pushButtonBluetoothConnect.setEnabled(True)
347       
348       
349        ##################################################################
350       
351        def updateInterface(self):
352               
353                self.processPacketThinkGear(self.thinkGearConnectServer.protocol.data_packet)
354       
355       
356        ##################################################################
357       
358        def processPacketThinkGear(self, packet):
359               
360                if self.DEBUG > 2:
361                        print packet
362               
363                #self.textEditDebugConsole.append( str(packet) )
364               
365               
366                if ('poorSignalLevel' in packet.keys()):
367                        value = 200 - packet['poorSignalLevel']
368                        self.progressBarSignalContactQuality.setValue(value)
369                        self.textEditDebugConsole.append("")
370                        self.textEditDebugConsole.append("poorSignalLevel: %i" % \
371                                                              packet['poorSignalLevel'])
372               
373               
374                if ('eSense' in packet.keys()):
375                       
376                        if ('attention' in packet['eSense'].keys()):
377                                value = packet['eSense']['attention']
378                                self.progressBarAttention.setValue(value)
379                                self.textEditDebugConsole.append("eSense attention: %i" % value)
380                       
381                        if ('meditation' in packet['eSense'].keys()):
382                                value = packet['eSense']['meditation']
383                                self.progressBarMeditation.setValue(value)
384                                self.textEditDebugConsole.append("eSense meditation: %i" % value)
385               
386               
387                if ('eegPower' in packet.keys()):
388                       
389                       
390                        for value in packet['eegPower'].keys():
391                                if packet['eegPower'][value] > self.maxEEGPower:
392                                        self.maxEEGPower = packet['eegPower'][value]
393                       
394                       
395                        if ('delta' in packet['eegPower'].keys()):
396                                value = packet['eegPower']['delta']
397                                self.progressBarEEGDelta.setMaximum(self.maxEEGPower)
398                                self.progressBarEEGDelta.setValue(value)
399                                self.textEditDebugConsole.append("delta: %i" % value)
400                       
401                        if ('theta' in packet['eegPower'].keys()):
402                                value = packet['eegPower']['theta']
403                                self.progressBarEEGTheta.setMaximum(self.maxEEGPower)
404                                self.progressBarEEGTheta.setValue(value)
405                                self.textEditDebugConsole.append("theta: %i" % value)
406                       
407                        if ('lowAlpha' in packet['eegPower'].keys()):
408                                value = packet['eegPower']['lowAlpha']
409                                self.progressBarEEGLowAlpha.setMaximum(self.maxEEGPower)
410                                self.progressBarEEGLowAlpha.setValue(value)
411                                self.textEditDebugConsole.append("lowAlpha: %i" % value)
412                       
413                        if ('highAlpha' in packet['eegPower'].keys()):
414                                value = packet['eegPower']['highAlpha']
415                                self.progressBarEEGHighAlpha.setMaximum(self.maxEEGPower)
416                                self.progressBarEEGHighAlpha.setValue(value)
417                                self.textEditDebugConsole.append("highAlpha: %i" % value)
418                       
419                        if ('lowBeta' in packet['eegPower'].keys()):
420                                value = packet['eegPower']['lowBeta']
421                                self.progressBarEEGLowBeta.setMaximum(self.maxEEGPower)
422                                self.progressBarEEGLowBeta.setValue(value)
423                                self.textEditDebugConsole.append("lowBeta: %i" % value)
424                       
425                        if ('highBeta' in packet['eegPower'].keys()):
426                                value = packet['eegPower']['highBeta']
427                                self.progressBarEEGHighBeta.setMaximum(self.maxEEGPower)
428                                self.progressBarEEGHighBeta.setValue(value)
429                                self.textEditDebugConsole.append("highBeta: %i" % value)
430                       
431                        if ('lowGamma' in packet['eegPower'].keys()):
432                                value = packet['eegPower']['lowGamma']
433                                self.progressBarEEGLowGamma.setMaximum(self.maxEEGPower)
434                                self.progressBarEEGLowGamma.setValue(value)
435                                self.textEditDebugConsole.append("lowGamma: %i" % value)
436                       
437                        if ('highGamma' in packet['eegPower'].keys()):
438                                value = packet['eegPower']['highGamma']
439                                self.progressBarEEGMidGamma.setMaximum(self.maxEEGPower)
440                                self.progressBarEEGMidGamma.setValue(value)
441                                self.textEditDebugConsole.append("highGamma: %i" % value)
442       
443       
444        ##################################################################
445       
446        def searchForThinkGearDevices(self):
447               
448                #self.pushButtonBluetoothSearch.setText('Searching')
449               
450                if (sys.platform != 'win32'):
451                       
452                        # Bluetooth module doesn't compile properly under Windows
453                       
454                        bluetooth_devices = []
455                       
456                        #bluetooth_devices = bluetooth.discover_devices( \
457                                                    #duration=5, \
458                                                    #flush_cache=True, \
459                                                    #lookup_names=True)
460                       
461                        addresses = []
462                       
463                        command = '%s con' % PATH_TO_HCITOOL
464                       
465                        output = os.popen(command, 'r')
466                       
467                        for line in output.readlines():
468                                try:
469                                        address = line.split(' ')[2]
470                                except:
471                                        pass
472                                else:
473                                        addresses.append(address)
474                       
475                        for address in addresses:
476                                device_name = bluetooth.lookup_name(address)
477                                if device_name == 'MindSet':
478                                        bluetooth_devices.append(address)
479                       
480                       
481                        if self.DEBUG:
482                                print "Bluetooth devices found:",
483                                print bluetooth_devices
484                       
485                       
486                        self.comboBoxDeviceSelect.clear()
487                       
488                        self.comboBoxDeviceSelect.addItem('MindSet Emulator')
489                       
490                       
491                        for mindset_device in bluetooth_devices:
492                                self.comboBoxDeviceSelect.addItem(mindset_device)
493               
494               
495                #self.pushButtonBluetoothSearch.setText('Search')
496       
497       
498        ##################################################################
499       
500        def closeEvent(self, event):
501               
502                quit_message = "Are you sure you want to exit the program?"
503               
504                reply = QtGui.QMessageBox.question( \
505                           self, \
506                          'Message', \
507                           quit_message, \
508                           QtGui.QMessageBox.Yes, \
509                           QtGui.QMessageBox.No)
510               
511                if reply == QtGui.QMessageBox.Yes:
512                       
513                        self.updateInterfaceTimer.stop()
514                       
515                        #if self.thinkgearConnectClient != None:
516                                #self.thinkgearConnectClient.disconnectFromHost()
517                       
518                        if self.thinkGearConnectServer != None:
519                                self.thinkGearConnectServer.exitThread()
520                       
521                        event.accept()
522               
523                else:
524                        event.ignore()
525
526
527#####################################################################
528# Functions
529#####################################################################
530
531#####################################################################
532# Main
533#####################################################################
534
535if __name__ == '__main__':
536       
537        #log = puzzlebox_logger.puzzlebox_logger(logfile='client_interface')
538        log = None
539       
540        app = QtGui.QApplication(sys.argv)
541       
542        window = puzzlebox_synapse_interface(log, DEBUG)
543        window.show()
544       
545        sys.exit(app.exec_())
546
Note: See TracBrowser for help on using the repository browser.