-
Notifications
You must be signed in to change notification settings - Fork 1
/
BeltConnection.py
117 lines (104 loc) · 4 KB
/
BeltConnection.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import threading
from bluetooth import *
# Because the application is multi-threaded, this is keep it thread-safe
_bclock = threading.Lock()
# This class Manages all connection stuff
class BeltConnection:
def __init__(self):
# Variable declaration
self.isConnected = False
self.sensors = [0,0]
self.counter = 0
self.status = ""
def connect(self):
# This is the prefix of the device name to match
target_name = "FireFly-"
target_address = None
number_of_tries = 2
# Loop a couple times in case the device/name isn't found the first time
while target_address is None and number_of_tries > 0:
number_of_tries = number_of_tries - 1
# Discover bluetooth devices in the vicinity
print "Searching for belt..."
self.status = "Searching for belt... "
nearby_devices = discover_devices()
# Loop through each device and check its name for a prefix match
for btaddr in nearby_devices:
btname = lookup_name(btaddr)
print " -Found device: %s (%s)" % (btname, btaddr)
self.status = " -Found device: %s (%s)" % (btname, btaddr)
if btname is not None and btname.startswith(target_name) == True:
# Use the first device it finds that matches name
print ' Found firefly.'
self.status = " Found FireFly"
target_address = btaddr
break
if target_address is not None:
# Begin the actual connection device using BT network socket communication
self.sock = BluetoothSocket(RFCOMM)
try: self.sock.connect((target_address, 1))
except:
print "Unable to connect to belt"
self.status = "Unable to connect to belt"
self.isConnected = False
else:
# if connection succeeded, create the multi-thread "receiver"
# which will handle receiving data in the background automatically
print "Connected to belt (%s)" % (target_address)
self.status = "Connected to belt (%s)" % (target_address)
self.isConnected = True
self.receiver = __ReceiverThread__(self)
self.receiver.start()
else:
print "Could not locate belt."
self.status = "Could not locate belt."
self.isConnected = False
# def sendHeading(self, newheading):
# # If connected, send the heading byte (0-255) to the belt
# if self.isConnected == True:
# self.sock.send(newheading)
#
# def getCurrentHeading(self):
# heading = 0
# # Acquire a thread lock (for safety) and return the last received heading
# _bclock.acquire()
# try: heading = self.lastKnownHeading
# finally: _bclock.release()
# return heading
def disconnect(self):
# If connected, do the socket cleanup stuff
if self.isConnected == True:
self.sock.close()
self.isConnected = False
print "Disconnected from belt"
self.status = "Disconnect from belt"
# This is a private class that uses threading to receive data from the belt
class __ReceiverThread__ (threading.Thread):
def __init__(self, parent):
self.parent = parent
threading.Thread.__init__(self)
def run(self):
data = ""
while self.parent.isConnected == True:
# Wait indefinitely until a byte is received. This is likely not the
# best way to do this. For production, it would be better to use the
# 'select' module to get notification when data is ready.
data = self.parent.sock.recv(1)
# Verify received
if data != "":
# Convert the byte (0-255) to a heading (0-359) and update belt
# manager with new heading within the thread lock
value = ord(data)
sensor = value/128
if value >= 128:
value -= 128
_bclock.acquire()
try:
self.parent.sensors[sensor] = value
finally: _bclock.release()
else:
# If nothing was received, this usually means the socket closed from the
# remote end, so notify that the belt is disconnected.
print "Remote client disconnected"
self.parent.status = "Remote client disconnected"
self.parent.disconnect()