Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added poll option in connect(). receive() now returns None when conne…

…ction is terminated
  • Loading branch information...
commit 70ba699a85d6249151728f94d2ce20e61a64eae2 1 parent ca39989
pilliq authored
Showing with 41 additions and 24 deletions.
  1. +41 −24 scratch.py
65 scratch.py
View
@@ -17,24 +17,37 @@ class Scratch:
def __init__(self, host='localhost'):
self.host= host
self.port = 42001
- self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.connect()
+ self.connect(poll=True)
self.connected = 1
- def connect(self):
- try:
- self.connection.connect((self.host, self.port))
- except socket.error as (err, message):
- if err == errno.ECONNREFUSED:
- raise ScratchConnectionRefused('Connection refused, try enabling remote sensor connections')
- elif err == errno.EISCONN:
+
+ def connect(self, poll=False):
+ """
+ Creates a connection to the Scratch environment. If poll is True, blocks until
+ Scratch is running, and listening for connections on port 42001, else connect()
+ raises appropiate exceptions.
+ """
+ while True:
+ try:
+ # create the socket here not in __init__() to avoid errno 22 invalid argument
+ self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.connection.connect((self.host, self.port))
+ except socket.error as (err, message):
+ if err == errno.EISCONN:
raise ScratchConnectionEstablished('Already connected to Scratch')
+ elif poll == True:
+ continue
+ elif err == errno.ECONNREFUSED:
+ raise ScratchConnectionRefused('Connection refused, try enabling remote sensor connections')
else:
print(err, message)
raise ScratchConnectionError(message)
+ break
self.connected = 1
+
def disconnect(self):
self.connection.close()
self.connected = 0
+
def send(self, message):
#credit to chalkmarrow from scratch.mit.edu
n = len(message)
@@ -50,6 +63,7 @@ def send(self, message):
raise ScratchConnectionError(message)
else:
raise ScratchConnectionError('Not connected to Scratch')
+
def sensorupdate(self, data):
"""Takes a dictionary and writes a message using the keys as sensors, and the values as the update values"""
if not isinstance(data, dict):
@@ -58,6 +72,7 @@ def sensorupdate(self, data):
for key in data.keys():
message = message+' "'+key+'" '+data[key]
self.send(message)
+
def broadcast(self, data):
"""Takes a list of message strings and writes a broadcast message to scratch"""
if not isinstance(data, list):
@@ -66,8 +81,10 @@ def broadcast(self, data):
for mess in data:
message = message+' "'+mess+'"'
self.send(message)
+
def parse_message(self, message):
#TODO: parse sensorupdates with quotes in sensor names and values
+ # make more readable
if message:
sensorupdate_re = 'sensor-update[ ](((?:\").[^\"]*(?:\"))[ ](?:\"|)(.[^\"]*)(?:\"|)[ ])+'
broadcast_re = 'broadcast[ ]\".[^"]*\"'
@@ -87,7 +104,8 @@ def parse_message(self, message):
if sensorupdates[i][-1] != '\"':
j = i
multisense = ''
- #now loop through each word in list and find the word that ends with " which is the end of the variable name
+ #now loop through each word in list and find the word
+ #that ends with " which is the end of the variable name
while j < len(sensorupdates):
multisense = multisense+' '+sensorupdates[j]
if sensorupdates[j][-1] == '\"':
@@ -114,32 +132,31 @@ def parse_message(self, message):
return dict([('sensor-update', sensors), ('broadcast', broadcast)])
else:
return None
+
def receive(self, noparse=0):
""" Receives data from Scratch
Arguments:
- Optional:
- noparse -- 0 to pass message through a parser and return the message as a data structure
- 1 to not parse message, but format as a string
- 2 to not parse message and not format as a string (returns raw message)
+ noparse: 0 to pass message through a parser and return the message as a data structure
+ 1 to not parse message, but format as a string
+ 2 to not parse message and not format as a string (returns raw message)
"""
-
- try:
- mess = self.connection.recv(1024)
- except socket.error as (errno, message):
- if errno == 107 or 9:
- raise ScratchConnectionError(errno, 'A connection must first be made to Scratch with Scratch.connect()')
- else:
- raise ScratchConnectionError(errno, message)
+ try:
+ mess = self.connection.recv(1024)
+ except socket.error as (errno, message):
+ raise ScratchConnectionError(errno, message)
+ if not mess:
+ return None
if noparse == 0:
return self.parse_message(repr(mess))
- if noparse == 1:
+ if noparse == 1:
return repr(mess)
elif noparse == 2:
- return mess
+ return mess
else:
return self.parse_message(repr(mess))
if __name__ == "__main__":
+ #runs and prints out raw messages received from Scratch
try:
s = Scratch()
except ScratchConnectionError, e:
Please sign in to comment.
Something went wrong with that request. Please try again.