source: remote_control/puzzlebox_brainstorms_network_server.py @ 111

Last change on this file since 111 was 111, checked in by sc, 11 years ago
  • PySide? import attempted before PyQt4 where available
  • problem specifying port when calling socket.listen on QTcpServer
  • Property svn:executable set to *
File size: 7.0 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Puzzlebox - Brainstorms - Network - Server
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.07.10
12#
13#####################################################################
14
15import os, sys
16import signal
17
18import simplejson as json
19
20try:
21        import PySide as PyQt4
22        from PySide import QtCore, QtNetwork
23except:
24        print "Using PyQt4 module"
25        from PyQt4 import QtCore, QtNetwork
26else:
27        print "Using PySide module"
28
29#from PyQt4 import QtCore, QtNetwork
30
31import puzzlebox_brainstorms_configuration as configuration
32import puzzlebox_brainstorms_remote_control as remote_control
33#import puzzlebox_logger
34
35#####################################################################
36# Globals
37#####################################################################
38
39DEBUG = 1
40
41SERVER_INTERFACE = configuration.BRAINSTORMS_SERVER_INTERFACE
42SERVER_PORT = configuration.BRAINSTORMS_SERVER_PORT
43
44CLIENT_NO_REPLY_WAIT = configuration.CLIENT_NO_REPLY_WAIT * 1000
45
46DELIMITER = configuration.BRAINSTORMS_DELIMITER
47
48BLUETOOTH_DEVICE = configuration.NXT_BLUETOOTH_DEVICE
49
50VARIABLE_CONTROL_DURATION = configuration.BRAINSTORMS_VARIABLE_CONTROL_DURATION
51
52#####################################################################
53# Classes
54#####################################################################
55
56class puzzlebox_brainstorms_network_server:
57       
58        def __init__(self, log, \
59                          server_interface=SERVER_INTERFACE, \
60                          server_port=SERVER_PORT, \
61                          embedded_mode=False, \
62                          DEBUG=DEBUG, \
63                          parent=None):
64               
65                self.log = log
66                self.DEBUG = DEBUG
67               
68                self.server_interface = server_interface
69                self.server_port = server_port
70               
71                self.embedded_mode=embedded_mode
72               
73                self.configureNetwork()
74               
75                self.rc = None
76               
77                #self.rc = remote_control.puzzlebox_brainstorms_remote_control( \
78                            #device=BLUETOOTH_DEVICE, \
79                            #DEBUG=DEBUG)
80       
81       
82        ##################################################################
83       
84        def configureNetwork(self):
85       
86                #self.blockSize = 0
87                self.socket = QtNetwork.QTcpServer()
88                self.socket.name = 'Brainstorms Server'
89               
90                if self.DEBUG:
91                        print "<---- [%s] Initializing server on %s:%i" % \
92                                (self.socket.name, self.server_interface, self.server_port)
93       
94                if (self.server_interface == ''):
95                        result = self.socket.listen(port=self.server_port)
96                else:
97                        result = self.socket.listen(address=self.server_interface, \
98                                           port=self.server_port)
99               
100                if not result:
101                        if self.DEBUG:
102                                print "ERROR [%s] Unable to start the server:" % self.socket.name,
103                                print self.socket.errorString()
104                               
105                        self.socket.close()
106                        return
107               
108               
109                self.socket.newConnection.connect(self.processConnection)
110       
111       
112        ##################################################################
113       
114        def processConnection(self):
115               
116                if self.DEBUG:
117                        print "--> [%s]: Client connected" % self.socket.name
118               
119                clientConnection = self.socket.nextPendingConnection()
120                clientConnection.disconnected.connect(clientConnection.deleteLater)
121               
122                if (self.embedded_mode):
123                       
124                        # Only one client connection to server will work in embedded mode
125                        self.clientConnection = clientConnection
126                        clientConnection.readyRead.connect(self.processData)
127               
128               
129                else:
130                       
131                        if not clientConnection.waitForReadyRead(CLIENT_NO_REPLY_WAIT):
132                                if self.DEBUG:
133                                        print "WARNING [%s] Timeout waiting for client to transmit data" % \
134                                                self.socket.name
135                                        #print "State:",
136                                        #print clientConnection.state()
137                                clientConnection.disconnectFromHost()
138                                return
139                       
140                       
141                        self.processData(clientConnection)
142                       
143                        #clientConnection.disconnectFromHost()
144       
145       
146        ##################################################################
147       
148        def processData(self, clientConnection=None):
149               
150                if (clientConnection == None):
151                        clientConnection = self.clientConnection
152               
153                socket_buffer = clientConnection.readAll()
154               
155                for packet in socket_buffer.split(DELIMITER):
156                       
157                        if packet != '':
158                               
159                                try:
160                                        data = json.loads(packet.data())
161                                except:
162                                        data = packet
163                               
164                                if self.DEBUG:
165                                        print "--> [%s] Received:" % self.socket.name,
166                                        print data
167                               
168                                response = self.processCommand(data)
169                               
170                                if response != None:
171                                       
172                                        data = json.dumps(response)
173                                       
174                                       
175                                        if clientConnection.waitForConnected(CLIENT_NO_REPLY_WAIT):
176                                               
177                                                if self.DEBUG:
178                                                        print "<-- [%s] Sending:" % self.socket.name,
179                                                        print data
180                                               
181                                                clientConnection.write(data)
182       
183       
184        ##################################################################
185       
186        def processCommand(self, data):
187               
188                response = {}
189               
190                if not VARIABLE_CONTROL_DURATION:
191                       
192                        response['status'] = self.executeCommand(data['command'], data['power'])
193               
194               
195                else:
196                       
197                        if ((self.rc == None) or \
198                                 (self.rc.connection == None)):
199                               
200                                if ('bluetooth_device' in data.keys()):
201                                        bluetooth_device = data['bluetooth_device']
202                                else:
203                                        bluetooth_device = BLUETOOTH_DEVICE
204                               
205                                self.rc = remote_control.puzzlebox_brainstorms_remote_control( \
206                                             device=bluetooth_device, \
207                                             DEBUG=DEBUG)
208                       
209                       
210                        if self.rc.connection != None:
211                               
212                                self.rc.run(data['command'], data['power'])
213                                response['status'] = self.rc.get_battery_voltage(self.rc.connection)
214                       
215                        else:
216                               
217                                self.rc = None
218                                response = {}
219                                response['status'] = 'LEGO NXT N/A'
220               
221               
222                return(response)
223       
224       
225        ##################################################################
226       
227        def executeCommand(self, command, bluetooth_device=BLUETOOTH_DEVICE):
228               
229                #command_line = 'python puzzlebox_brainstorms_remote_control.py --command=%s' % command
230               
231                #os.system(command_line)
232               
233                status = 'N/A'
234               
235                rc = remote_control.puzzlebox_brainstorms_remote_control( \
236                        device=bluetooth_device, \
237                        command=command, \
238                        DEBUG=DEBUG)
239               
240                if rc.connection != None:
241                        rc.run(rc.command)
242                        rc.stop()
243                        status = rc.get_battery_voltage(rc.connection)
244               
245               
246                return(status)
247
248
249#####################################################################
250# Main
251#####################################################################
252
253if __name__ == '__main__':
254       
255        # Perform correct KeyboardInterrupt handling
256        signal.signal(signal.SIGINT, signal.SIG_DFL)
257       
258        #log = puzzlebox_logger.puzzlebox_logger(logfile='server_brainstorms')
259        log = None
260       
261        # Collect default settings and command line parameters
262        server_interface = SERVER_INTERFACE
263        server_port = SERVER_PORT
264       
265        for each in sys.argv:
266               
267                if each.startswith("--interface="):
268                        server_interface = each[ len("--interface="): ]
269                if each.startswith("--port="):
270                        server_port = each[ len("--port="): ]
271       
272       
273        app = QtCore.QCoreApplication(sys.argv)
274       
275        server = puzzlebox_brainstorms_network_server(log, \
276                                                      server_interface, \
277                                                      server_port, \
278                                                      embedded_mode=False, \
279                                                      DEBUG=DEBUG)
280       
281        sys.exit(app.exec_())
282
Note: See TracBrowser for help on using the repository browser.