Reputation: 699
I connect a bluetooth device in a python (3.10) program like this:
import socket
serverMACAddress = '00:07:80:e0:a4:fc'
port = 1
size = 1024
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.connect((serverMACAddress,port))
In the main loop I have this:
try:
while 1: #main loop
data = s.recv(size)
if data:
data_received( data )
else:
try:
s.????
except:
print("no data")
except:
print("Closing socket")
s.close()
Everything works fine unless the bluetooth device is switched off and then switched on again. I am trying to solve how to have the bluetooth device re-connect with the logic in the try-statement (s.????) within the loop, but I am unable to come up with a solution.
I am a beginner in BT and Python, but this should be pretty straightforward, right? I must be missing something very obvious. Any suggestions out there?
Modified version based on the suggestion by ukBaz:
try:
while 1: #main loop
try:
data = s.recv(size)
except socket.error():
connected = False
s = socket.socket
while not connected:
#attempt to re-connect
try:
s.connect((serverMACAddress,port))
connected = True
except:
time.sleep(5)
if data:
data_received( data )
except:
print("Closing socket")
s.close()
After adding clientSocket.send:
while True: #main loop
# attempt to reconnect, otherwise sleep for 2 seconds
if not connected:
try:
# configure socket and connect to server
clientSocket = socket.socket(
socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM
)
clientSocket.connect((serverMACAddress, port))
connected = True
print("Connection successful")
except socket.error:
print("No connection, retrying")
# time.sleep(2)
# attempt to send and receive, otherwise reset connection status
else:
data = clientSocket.recv(size)
if data:
data_received( data )
# Use send to check if scale is connected
try:
clientSocket.send(b"x")
except socket.error:
print("connection lost... reconnecting")
# set connection status
connected = False
Upvotes: 0
Views: 1265
Reputation: 7994
I ran the following connecting to a remote HC-06 module on an Arduino. I tested the code below with Python 3.10 (Windows) and Python 3.8 (Linux) and it worked as expected on both.
It has a continuous while loop that if it is connected sends & receives data. If it is not connected, then it tries to connect. It uses except socket.error
to detect there is an issue with the connection.
import socket
from time import sleep
host = "00:00:12:34:56:78"
port = 1
chunks = 1024
# keep track of connection status
connected = False
while True:
# attempt to reconnect, otherwise sleep for 2 seconds
if not connected:
try:
# configure socket and connect to server
clientSocket = socket.socket(
socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM
)
clientSocket.connect((host, port))
connected = True
print("Connection successful")
except socket.error:
print("No connection, retrying")
sleep(2)
# attempt to send and receive, otherwise reset connection status
else:
try:
print("sending data...")
clientSocket.send(b"Test")
print("Reading data..")
message = clientSocket.recv(chunks).decode("UTF-8")
print("Recv'd", message)
except socket.error:
# set connection status
connected = False
print("connection lost... reconnecting")
If the socket is only doing read, then a timeout needs to be set so that it raises an exception. The value of the timeout might need to be tuned for your particular situation. As an example:
import socket
import time
import select
serverMACAddress = "00:00:12:34:56:78"
port = 1
size = 1024
# keep track of connection status
connected = False
def data_received(info):
print(info)
while True: #main loop
# attempt to reconnect, otherwise sleep for 2 seconds
if not connected:
try:
# configure socket and connect to server
clientSocket = socket.socket(
socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM
)
clientSocket.connect((serverMACAddress, port))
clientSocket.settimeout(5.5)
connected = True
print("Connection successful")
except socket.error:
print("No connection, retrying")
time.sleep(2)
# attempt to send and receive, otherwise reset connection status
else:
try:
data = clientSocket.recv(size)
print("Reading data..")
if data:
data_received(data)
# Assume connection lost if read timeout raised
except socket.timeout:
# set connection status
connected = False
print("connection lost... reconnecting")
Upvotes: 1