in src/ble/ble_uart_peripheral.py [0:0]
def run(self):
# Note: Bluepy is not thread safe so can't run Rx loop in a seperate thread. Need to Rx and Tx sequentially.
# Also can't safely poll connection state during read / write operations
# Have set Rx timeout low (0.1 secs) to avoid long delays.
# Initilie the BLE Peripheral connection.
log.info('Rx/Tx thread started for BLE Device: {}, initilising connection.....'.format(self.ble_mac))
self._ble_init_connect()
while self.thread_running:
try:
#############################################
## Transmit BLE messages
while not self._tx_queue.empty() and self.thread_running:
# Parse and send messages in queue
tx_object = self._tx_queue.get_nowait()
with_ble_response = tx_object['with_ble_response']
message_object = tx_object['message_object']
log.info('Publishing To BLE MAC: {} - tx_object: {}'.format(self.ble_mac, tx_object))
json_message = json.dumps(message_object) + '\n'
payload_bytes = bytes(json_message.encode('utf-8'))
self._uart_rx.write(payload_bytes, with_ble_response)
#############################################
## Receive BLE messages - handled by BleUartDelegate (callbacks)
if self.thread_running:
self._ble_peripheral.waitForNotifications(0.1)
#############################################
## Catch Rx/Tx exceptions, mostly expected due to lost BLE connection.
except Exception as err:
# If thread still running, attempt to re-initilise the BLE device connection
if (self.thread_running):
log.error('BLE Mac {} error: {} - attempting to reconnect.'.format(self.ble_mac, err))
# Give time for the BLE device to disconnect and start re-advertsing beacon
# also prevents fast exceptions loops when device is not reachable.
self._disconect_ble()
time.sleep(5)
# Attempt to reconnect.
self._ble_init_connect()
# Clear the BLE connection if leaving the running thread.
self._disconect_ble()
log.info('Exiting the BLE Peripheral Rx/Tx process loop for BLE Mac: {}'.format(self.ble_mac))