Execute Python Scripts via BLE Using BleuIO and Your Mobile Phone
August 8, 2025
This project demonstrates how to execute a Python script wirelessly from your mobile phone using a BleuIO dongle. By sending simple text commands over Bluetooth Low Energy (BLE) through the Serial Port Service (SPS), the Python script can trigger actions. In our case, the script will retrieve and display CO2, temperature, and humidity values from a nearby BLE air quality monitoring sensor called HibouAir.
This approach opens up many possibilities for interactive projects, sensor monitoring, and remote control applications — all without the need for internet connectivity.
Prerequisites
Hardware
- BleuIO USB dongle
- HibouAir air quality monitor
- Computer (Mac or Windows)
- Mobile phone with nRF Connect or similar BLE app
Software
- Python 3 installed on your computer
pyserial
library (pip install pyserial
)- nRF Connect (iOS / Android)
Setting up the BleuIO Dongle
Begin by plugging your BleuIO dongle into the computer. Open a BLE terminal such as the BleuIO Web Terminal or any serial monitor and enable the Serial Port Service. You can do this by entering:
ATASPS1
AT+ADVSTART
This enables the SPS service, ensures incoming data is displayed as ASCII text, and starts advertising so your phone can connect.
The Python Script
The Python script connects to the BleuIO dongle over a serial port and listens for incoming BLE messages. When it receives one of four possible commands — CO2
, TEMP
, HUM
, or ALL
— it triggers a scan using the AT+FINDSCANDATA=220069=3
command. Here 220069 is the boardID of HibouAir sensor which we will use to retrieve air quality data in real time. This scans for nearby BLE devices broadcasting the matching advertising data. From the latest packet received, the script decodes and extracts the relevant sensor values.
Below is the complete script. Update the port
variable to match your BleuIO’s serial port location.
import serial
import time
import re
def send_and_wait(ser, at_cmd):
ser.write((at_cmd + '\r\n').encode())
time.sleep(2)
output = []
while ser.in_waiting:
line = ser.readline().decode('utf-8', errors='ignore').strip()
output.append(line)
return output
def extract_last_adv_hex(lines):
adv_lines = [l for l in lines if "Device Data [ADV]:" in l]
if not adv_lines:
return None
last_line = adv_lines[-1]
match = re.search(r'([0-9A-Fa-f]{40,})$', last_line)
if match:
return match.group(1)
return None
def parse_co2_temp_hum(adv):
pos = adv.find("5B0705")
if pos == -1:
return None
def parse_val(offset, reverse=True, scale=1.0, signed=False):
raw = adv[pos + offset : pos + offset + 4]
if reverse:
raw = ''.join(reversed([raw[i:i+2] for i in range(0, 4, 2)]))
val = int(raw, 16)
if signed and val > 32767:
val -= 65536
return val / scale
temp_raw = parse_val(22, scale=1, signed=True)
temp = temp_raw / 10
hum = parse_val(26, scale=10)
co2 = int(adv[pos + 46 : pos + 50], 16)
return {
"temp": round(temp, 1),
"hum": round(hum, 1),
"co2": co2
}
# --- Main Loop ---
port = "/dev/cu.usbmodem4048FDEBA6D01"
baudrate = 115200
try:
with serial.Serial(port, baudrate, timeout=1) as ser:
print("Listening for BLE SPS command...")
while True:
line = ser.readline().decode('utf-8', errors='ignore').strip()
if line:
#print(f" Received: {line}")
cmd = line.replace("[Received]:", "").strip().upper()
if cmd in ["CO2", "TEMP", "HUM", "ALL"]:
print(" Scanning for environmental data...")
results = send_and_wait(ser, "AT+FINDSCANDATA=0504220069=3")
adv = extract_last_adv_hex(results)
if adv:
data = parse_co2_temp_hum(adv)
if data:
if cmd == "CO2":
print(f" CO2: {data['co2']} ppm")
elif cmd == "TEMP":
print(f" Temp: {data['temp']} °C")
elif cmd == "HUM":
print(f" Hum: {data['hum']} %")
elif cmd == "ALL":
print(f" Temp: {data['temp']} °C")
print(f" Hum: {data['hum']} %")
print(f" CO2: {data['co2']} ppm")
else:
print(" Could not decode sensor values.")
else:
print(" No advertising data found.")
except serial.SerialException as e:
print("Serial error:", e)
How It Works
Once the script is running, it keeps the serial connection to the BleuIO open and listens for BLE SPS messages sent from the phone. When a command is received, it is cleaned to remove any extra text added by the dongle, then matched against one of the four recognized keywords. If a match is found, the script asks the dongle to scan for nearby advertising packets from a device matching our filter. The script extracts the CO2, temperature, and humidity values, then displays the requested data based on the command.
For example, sending CO2
from the phone will only display the CO2 value, while sending ALL
will show all three measurements.
Testing the Project
Run the script on your computer, then use the nRF Connect app on your phone to connect to the BleuIO dongle. Locate the SPS write characteristic (UUID ending in ...5CBA
) and send a command in Text mode. Try sending CO2
, TEMP
, HUM
, and ALL
to see the different outputs. You should see the values appear in your terminal almost instantly after each command is sent.
Output
Use Cases and Expanding the Idea
This setup goes beyond simply reading CO2, temperature, and humidity. At its core, it is a BLE command-to-script bridge — meaning you can trigger any Python action from your phone without needing Wi-Fi or internet access.
In real-world use, this could be applied to:
- Remote environmental monitoring: Trigger on-demand scans for sensor readings in greenhouses, offices, or laboratories.
- IoT control panels: Send commands to control connected devices, such as turning fans or air purifiers on when CO2 levels rise.
- Data logging systems: Store sensor readings in a file or database only when requested, helping conserve storage and processing power.
- Event-based automation: Pair with external hardware like Raspberry Pi GPIO pins to trigger physical actions when commands are received.
Because the commands are just plain text, the possibilities for customization are endless. You could add more commands to control different hardware, run different scripts, or even communicate with multiple BLE devices. This same approach can also integrate with web dashboards, cloud services, or data visualization tools to make the results more accessible and actionable.
This project shows how simple it is to control Python scripts and interact with BLE sensor data using BleuIO and your phone. By combining the SPS profile with AT commands, you can create flexible, interactive tools that can be extended for various IoT applications — from remote environmental monitoring to interactive control systems.