如何通过Python开发的Django web应用连接Bluetooth设备及实现方案
Django 集成蓝牙体温设备数据采集实现方案
该需求完全可实现。你已经完成了Python层面连接蓝牙设备、读取测温数据的核心逻辑,仅需要将这部分能力和Django的服务调度、数据存储能力做适配即可,核心要处理的是蓝牙操作的IO异步特性和Web服务的请求响应逻辑的兼容问题。
前置准备
- 原有可正常运行的蓝牙设备连接、数据读取Python代码(通常用
bleak、pybluez这类蓝牙库,优先选bleak,跨平台兼容性更好且原生支持异步) - 可用的Django项目基础环境,按需额外安装依赖:
celery(定时批量采集用)、channels(实时向前端推送采集数据用)
核心实现方案
根据你的使用场景可以选以下两种实现方式:
方案1:用户触发式单次采集(适合少量设备、按需拉取数据的场景)
直接把蓝牙读取逻辑封装成独立工具函数,放到Django视图中调用即可,实现成本最低:
- 新建蓝牙工具文件封装读取逻辑,比如在对应Django app下创建
bluetooth_utils.py:
# your_app/bluetooth_utils.py from bleak import BleakClient # 替换为你自己的测温蓝牙设备的特征值UUID、MAC地址等配置 TEMP_CHAR_UUID = "0000ffb2-0000-1000-8000-00805f9b34fb" async def get_body_temperature(device_mac: str) -> float | None: try: async with BleakClient(device_mac) as client: raw_data = await client.read_gatt_char(TEMP_CHAR_UUID) # 替换为你原有代码里的原始数据转体温值的处理逻辑 temperature = int.from_bytes(raw_data, byteorder="little") / 100 return temperature except Exception as e: print(f"读取设备{device_mac}失败: {str(e)}") return None
- 编写Django视图调用采集逻辑,Django 3.1+版本支持异步视图,也可以用同步视图嵌套异步调用:
# your_app/views.py from django.http import JsonResponse from django.views.decorators.http import require_http_methods from datetime import datetime import asyncio from .bluetooth_utils import get_body_temperature from .models import TemperatureRecord @require_http_methods(["GET"]) def collect_temp(request): device_mac = request.GET.get("device_mac") if not device_mac: return JsonResponse({"code": 400, "msg": "缺少设备MAC参数"}, status=400) temp = asyncio.run(get_body_temperature(device_mac)) if temp: # 采集成功后直接存入Django数据库 TemperatureRecord.objects.create( device_mac=device_mac, temp_value=temp, collect_time=datetime.now() ) return JsonResponse({"code": 200, "data": {"temperature": temp}, "msg": "采集成功"}) return JsonResponse({"code": 500, "msg": "设备连接失败或数据读取异常"}, status=500)
- 配置对应路由暴露接口,前端调用接口即可触发单次采集、拿到测温数据。
方案2:后台定时批量采集(适合多设备、需要7*24小时不间断采集的场景)
如果需要长期运行采集任务,不要把逻辑耦合到视图层,用Celery异步任务框架做定时调度即可:
- 完成Django+Celery基础环境配置后,把采集逻辑封装为Celery任务:
# your_app/tasks.py from celery import shared_task import asyncio from .bluetooth_utils import get_body_temperature from .models import Device, TemperatureRecord @shared_task def batch_collect_temp(): # 从Django数据库中拉取所有已激活的蓝牙设备MAC列表 active_devices = Device.objects.filter(is_active=True).values_list("mac", flat=True) for mac in active_devices: temp = asyncio.run(get_body_temperature(mac)) if temp: TemperatureRecord.objects.create(device_mac=mac, temp_value=temp)
- 配置Celery Beat定时规则,比如设置每5分钟执行一次全量设备采集,数据会自动存入Django数据库,前端查询时直接读库返回历史记录即可。
注意事项
- 运行Django服务的主机必须带蓝牙模块,且和测温设备处于蓝牙信号覆盖范围内;如果服务器无蓝牙模块,可以单独用边缘设备跑采集逻辑,将数据通过API上报到Django服务即可。
- 蓝牙连接属于IO密集型操作,高并发场景下不要用同步视图直接调用采集逻辑,容易阻塞服务,建议用Celery异步处理或者Django Channels做长连接异步处理。
- 提前在运行服务的主机上完成蓝牙设备配对,给服务进程开启蓝牙操作权限,避免权限不足导致连接失败。
内容的提问来源于stack exchange,提问作者MarkPT
相关产品推荐
相关产品推荐

