forked from TheFwGuy/bluetooth_Rpi3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BLTest.py
executable file
·303 lines (258 loc) · 8.22 KB
/
BLTest.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#!/usr/bin/python
# Initialize Raspberry Pi board
# If the LCD Char didplay is detected :
# - set p display - initial screen is RED to indicate no Bluetooth connectivity - LCD display IP
# - if Bluetooth paired screen become GREN and accept input to display messages on LCD
#
# If the LCD SSD1306 is detected
# -
import time
import commands
import os
import subprocess
import errno
from socket import error as socket_error
import thread
import threading
import Adafruit_CharLCD as LCD
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import bluetooth
import subprocess as sp
# Global variables
RST = None # on the PiOLED this pin isnt used
# 128x32 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)
# Configuration :
# 0 -> No Display
# 1 -> LCD Char display
# 2 -> LCD SSD1306 display
# 3 -> TFT
LCDtype = 2
server_socket=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
# Make list of button value, text, and backlight color.
buttons = ( (LCD.SELECT, 'Select', (1,1,1)),
(LCD.LEFT, 'Left' , (1,0,0)),
(LCD.UP, 'Up' , (0,0,1)),
(LCD.DOWN, 'Down' , (0,1,0)),
(LCD.RIGHT, 'Right' , (1,0,1)) )
# State machine for Bluetooth
# 0 -> Initialization program - init BT
# 1 -> waiting for connection
# 2 -> connected
# 3 -> requested SHUTDOWN from app
BTstate = 0
# Data TX/RX related variables
isDataIn = False
isDataOut = False
dataIn = " "
dataOut = " "
# Define functions
# Identify type display present
#def idDisplay():
# Bluetooth Thread
def waitBTthread():
global BTstate
global server_socket
global isDataIn
global isDataOut
global dataIn
global dataOut
while True:
time.sleep(.5) # Give some time to the main loop
if BTstate == 0:
# Init connection
server_socket=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
print "Use port_any : ", bluetooth.PORT_ANY
server_socket.bind(("", bluetooth.PORT_ANY))
server_socket.listen(1)
BTstate = 1
if BTstate == 1:
# print "Start wait ..."
# NOTE ! The line below waits for a connection blocking the loop !
try:
client_socket,address = server_socket.accept()
print "Accepted connection from ",address
BTstate = 2
except Exception as ex:
template = "1) An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
print message
if BTstate == 2:
if isDataIn == False:
# print "Wait RX"
try:
dataIn = client_socket.recv(1024, 0x40) # The function waits for characters !
print "Received: %s" % dataIn
if (dataIn == 'q\n'): # Disconnect request from app !!!
client_socket.close()
server_socket.close()
BTstate = 0
elif (dataIn == "SH\n"): # SHUTDOWN request from app !!!
client_socket.close()
server_socket.close()
BTstate = 3
else:
isDataIn = True
except Exception as ex:
template = "2) An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
if type(ex).__name__ == "BluetoothError":
if ex.args[0] == "(104, 'Connection reset by peer')":
BTstate = 0
client_socket.close()
server_socket.close()
print "Closed Bluettoth - disconnected"
elif ex.args[0] == "(11, 'Resource temporarily unavailable')":
# Ignore
a = ex.args[0]
else:
print message
else:
print message
if isDataOut:
print "Thread - attempt to send out data"
client_socket.send(dataOut)
isDataOut = False
# ----- end thread ---------
# Shutdown thread !
# The thread shutdown the Raspberry - waiting a couple of seconds
def remoteShutdownThread():
print "Shutdown thread started"
time.sleep(2)
os.system("sudo poweroff")
# ------ end thread ---------
if LCDtype == 1:
# Initialize the LCD using the pins
lcd = LCD.Adafruit_CharLCDPlate()
# create some custom characters
lcd.create_char(1, [2, 3, 2, 2, 14, 30, 12, 0])
lcd.create_char(2, [0, 1, 3, 22, 28, 8, 0, 0])
lcd.create_char(3, [0, 14, 21, 23, 17, 14, 0, 0])
lcd.create_char(4, [31, 17, 10, 4, 10, 17, 31, 0])
lcd.create_char(5, [8, 12, 10, 9, 10, 12, 8, 0])
lcd.create_char(6, [2, 6, 10, 18, 10, 6, 2, 0])
lcd.create_char(7, [31, 17, 21, 21, 21, 21, 17, 31])
# Initialization
# Start set up LCD plat RED
lcd.set_color(1.0, 0.0, 0.0)
lcd.clear()
# Display IP address
lcd.message('IP WLAN:\n')
lcd.message(commands.getoutput('hostname -I'))
elif LCDtype == 2:
# Initialize library.
disp.begin()
# Clear display.
disp.clear()
disp.display()
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
x = 0
padding = -2
top = padding
bottom = height-padding
image = Image.new('1', (width, height))
# Load default font.
font = ImageFont.load_default()
# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)
# Shell scripts for system monitoring from here : https://unix.stackexchange.com/questions/119126/command-to-display-memory-usage-disk-usage-and-cpu-load
cmd = "hostname -I | cut -d\' \' -f1"
IP = subprocess.check_output(cmd, shell = True )
draw.rectangle((0,0,width,height), outline=0, fill=0)
draw.text((x, top), "IP: " + str(IP), font=font, fill=255)
disp.image(image)
disp.display()
isDataIn = False
isDataOut = False
#t1 = threading.Thread(target= waitBTthread, args=())
#t2 = threading.Thread(target= remoteShutdownThread, args=())
while True:
if LCDtype == 1:
# Monitor push buttons
# The main loop of the program check if the Select button is pressed.
# If select is pressed, the shutdown is issued
# Check if Select is pressed
if lcd.is_pressed(LCD.SELECT):
# Button is pressed, change the message and backlight.
lcd.clear()
lcd.message('Shutdown\nin 5 sec.')
time.sleep(5)
lcd.clear()
os.system("sudo poweroff")
# Color display management
if BTstate == 0:
lcd.set_color(1.0, 0.0, 0.0)
lcd.clear()
#lcd.message('Disconnected\nBluetooth')
lcd.message('IP WLAN:\n')
lcd.message(commands.getoutput('hostname -I'))
elif BTstate == 1:
lcd.set_color(0.0, 1.0, 0.0)
elif BTstate == 2:
lcd.set_color(0.0, 0.0, 1.0)
else:
lcd.set_color(0.0, 0.0, 0.0)
elif LCDtype == 2:
draw.rectangle((0,0,width,height), outline=0, fill=0)
# Write two lines of text.
draw.text((x, top), "IP: " + str(IP), font=font, fill=255)
if BTstate == 0:
draw.text((x, top+8), "Disconnected", font=font, fill=255)
elif BTstate == 1:
draw.text((x, top+8), "Waiting connection", font=font, fill=255)
elif BTstate == 2:
draw.text((x, top+8), "Connected", font=font, fill=255)
elif BTstate == 3:
draw.text((x, top+8), "SHUTDOWN !", font=font, fill=255)
# Bluetooth management
if BTstate == 0:
# Set up Bluettoth
# Restart Bluetooth and set for slave
os.popen('sudo hciconfig hci0 reset')
os.popen('sudo hciconfig hci0 piscan')
print "Bluetooth initialization - set as slave"
t1 = threading.Thread(target= waitBTthread, args=())
if t1.is_alive() == False:
print "Start thread waiting for connection"
t1.start()
time.sleep(.2)
if BTstate == 2:
# Check if received data
if isDataIn:
print "Main : %s" % dataIn
if LCDtype == 1:
lcd.clear()
lcd.message(dataIn)
elif LCDtype == 2:
draw.text((x, top+16), dataIn, font=font, fill=255)
isDataIn = False
if LCDtype == 1:
# Check if Down is pressed
if lcd.is_pressed(LCD.DOWN):
if isDataOut == False:
# Button is pressed, send message
print "Down button pressed - send message"
dataOut = "Down\n"
isDataOut = True
if lcd.is_pressed(LCD.UP):
if isDataOut == False:
# Button is pressed, send message
print "Up button pressed - send message"
dataOut = "Up\n"
isDataOut = True
if BTstate == 3: # Shutdown requested from APP !!!!
t2 = threading.Thread(target= remoteShutdownThread, args=())
if t2.is_alive() == False:
print "Start thread for shutdown"
t2.start()
time.sleep(.2)
# At the end of the loop force show display image for LCD type 2
if LCDtype == 2:
disp.image(image)
disp.display()