添加mqtt相关对接协议逻辑,还差将设备上报数据保存数据库和音频数据上传云存储

This commit is contained in:
HycJack
2026-04-27 18:50:59 +08:00
parent e9a69577db
commit 02f11474b3
5 changed files with 227 additions and 12 deletions

View File

@@ -4,7 +4,6 @@ from api.roles import router as roles_router
from api.auth import router as auth_router
from api.device_control import router as device_control_router
from api.ota import router as ota_router # 新增OTA路由
from api.mqtt_router import router as mqtt_router # 新增MQTT路由
api_router = APIRouter()
api_router.include_router(websocket_router, tags=["WebSocket"])
@@ -12,5 +11,4 @@ api_router.include_router(roles_router, tags=["Roles"])
api_router.include_router(auth_router, tags=["Auth"])
api_router.include_router(device_control_router, tags=["Device Control"])
api_router.include_router(ota_router, tags=["OTA"]) # 注册OTA路由
api_router.include_router(mqtt_router, tags=["MQTT"]) # 注册MQTT路由

View File

@@ -8,6 +8,7 @@ from banban.routers.devices import router as devices_router
from banban.routers.im import router as im_router
from banban.routers.parents import router as parents_router
from banban.routers.wechat_auth import router as wechat_auth_router
from banban.routers.mqtt_router import router as mqtt_router
# 统一创建一个主路由,前缀为 /banban
banban_router = APIRouter(prefix="/banban")
@@ -21,5 +22,7 @@ banban_router.include_router(device_im_router, tags=["banban-device-im"])
banban_router.include_router(device_location_router, tags=["banban-device-location"])
banban_router.include_router(im_router, tags=["banban-im"])
banban_router.include_router(parents_router, tags=["banban-parents"])
banban_router.include_router(mqtt_router, tags=["banban-mqtt"])
__all__ = ["banban_router"]

View File

@@ -2,7 +2,7 @@ import logging
from typing import Optional
from fastapi import APIRouter, HTTPException, Query
from services.offline_audio_cache import offline_audio_cache
from api.mqtt_models import (
from banban.schemas.mqtt_models import (
GPSQueryRequest,
VolumeRequest,
OTARequest,
@@ -18,7 +18,7 @@ from handlers.mqtt_handler import TalkingQMQTTService
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/mqtt", tags=["MQTT 服务"])
router = APIRouter(prefix="/mqtt", tags=["MQTT 服务"])
async def _get_service() -> TalkingQMQTTService:
@@ -29,35 +29,50 @@ async def _get_service() -> TalkingQMQTTService:
@router.post("/gps", response_model=CommandResponse, summary="GPS位置查询")
async def query_gps(req: GPSQueryRequest):
async def query_gps(
req: GPSQueryRequest,
current_user_id: int = Depends(get_current_user_id)
):
service = await _get_service()
msg_id = await service.send_gps_query(req.device_id)
return CommandResponse(msg_id=msg_id, device_id=req.device_id)
@router.post("/volume", response_model=CommandResponse, summary="音量调节")
async def set_volume(req: VolumeRequest):
async def set_volume(
req: VolumeRequest,
current_user_id: int = Depends(get_current_user_id)
):
service = await _get_service()
msg_id = await service.send_volume_command(req.device_id, req.level)
return CommandResponse(msg_id=msg_id, device_id=req.device_id)
@router.post("/ota", response_model=CommandResponse, summary="OTA升级")
async def start_ota(req: OTARequest):
async def start_ota(
req: OTARequest,
current_user_id: int = Depends(get_current_user_id)
):
service = await _get_service()
msg_id = await service.send_ota_command(req.device_id, req.url, req.version)
return CommandResponse(msg_id=msg_id, device_id=req.device_id)
@router.post("/nfc/notice", response_model=CommandResponse, summary="NFC留言下发提示")
async def send_nfc_notice(req: NFCNoticeRequest):
async def send_nfc_notice(
req: NFCNoticeRequest,
current_user_id: int = Depends(get_current_user_id)
):
service = await _get_service()
msg_id = await service.send_nfc_notice(req.device_id, req.url)
return CommandResponse(msg_id=msg_id, device_id=req.device_id)
@router.post("/nfc/listen", response_model=CommandResponse, summary="NFC收听留言")
async def nfc_listen(req: NFCListenRequest):
async def nfc_listen(
req: NFCListenRequest,
current_user_id: int = Depends(get_current_user_id)
):
service = await _get_service()
topic = f"device/{req.device_id}/event"
payload = {
@@ -69,19 +84,28 @@ async def nfc_listen(req: NFCListenRequest):
@router.post("/nfc/unread", response_model=CommandResponse, summary="设置NFC未读留言")
async def set_nfc_unread(req: NFCUnreadRequest):
async def set_nfc_unread(
req: NFCUnreadRequest,
current_user_id: int = Depends(get_current_user_id)
):
await offline_audio_cache.add_audio_url(req.device_id, req.url)
return CommandResponse(msg_id="", device_id=req.device_id, message="已设置未读留言")
@router.delete("/nfc/unread/{device_id}", response_model=CommandResponse, summary="清除NFC未读留言定时推送")
async def clear_nfc_unread(device_id: str):
async def clear_nfc_unread(
device_id: str,
current_user_id: int = Depends(get_current_user_id)
):
await offline_audio_cache.clear_audio_urls(device_id)
return CommandResponse(msg_id="", device_id=device_id, message="已清除未读留言")
@router.post("/nfc/bind", response_model=CommandResponse, summary="NFC绑定卡片")
async def bind_nfc(req: NFCBindRequest):
async def bind_nfc(
req: NFCBindRequest,
current_user_id: int = Depends(get_current_user_id)
):
service = await _get_service()
msg_id = await service.send_bind_nfc_command(req.device_id, req.uuid)
return CommandResponse(msg_id=msg_id, device_id=req.device_id)

View File

@@ -0,0 +1,190 @@
device/TalkingQ_xxx/command # 服务器下发命令(下行)
device/TalkingQ_xxx/response # 设备响应(上行)
device/TalkingQ_xxx/event # 设备主动事件
device/TalkingQ_xxx/event_resp # 事件返回
消息格式JSON
device/TalkingQ_xxx/event
0.设备定时10分钟上报信息
{
"msg_id": "000",
"data": {
"id":"TalkingQ_xxx",
"power": 70, 每个间隔10从10-100
"signal": 3, 信号强度1是最弱的 5是最强
"voice":60, 每个间隔20从40-100
"version":"v1.0"
}
}
服务器返回
device/TalkingQ_xxx/event_resp
{
"msg_id": "000",
"status": "success"
}
1. GPS位置查询
device/TalkingQ_xxx/command
服务器下发:
{
"msg_id": "001"
}
device/TalkingQ_xxx/response
4G模块响应
{
"msg_id": "001",
"status": "success",
"data": {
"latitude": 39.9042,
"longitude": 116.4074
}
}
2. 音量调节
device/TalkingQ_xxx/command
服务器下发:
{
"msg_id": "002",
"params": {
"level": 70
}
}
device/TalkingQ_xxx/response
4G模块响应
{
"msg_id": "002",
"status": "success",
"data": {
"current_level": 70
}
}
3. OTA升级
device/TalkingQ_xxx/command
服务器下发:
{
"msg_id": "003",
"params": {
"url": "https://ota.example.com/firmware/v2.1.0.bin",
"version": "2.1.0"
}
}
device/TalkingQ_xxx/response
4G模块响应立即确认
{
"msg_id": "003",
"status": "accepted",
"data": {
"current_version": "2.0.5",
"target_version": "2.1.0"
}
}
升级完成
{
"msg_id": "003",
"status": "success",
"data": {
"new_version": "2.1.0"
}
}
4、NFC留言下发提示
device/TalkingQ_xxx/command
如果设备在线且有未读留言服务器定时10分钟下发一次
{
"msg_id": "004",
"params": {
"url": "http://xxx.mp3" //您有新的留言请注意查收
}
}
device/TalkingQ_xxx/response
4G模块响应
{
"msg_id": "004",
"status": "success",
}
5、收听留言
device/TalkingQ_xxx/event
NFC触发设备端上报
{
"msg_id": "005",
"params": {
"uuid": "53C12B6DA20001"
}
}
6、NFC绑定uuid
device/TalkingQ_xxx/command
{
"msg_id": "006",
}
device/TalkingQ_xxx/response
4G模块响应
{
"msg_id": "006",
"status": "success",
"data": {
"uuid": "xxxx"
}
}
7、开关状态
device/TalkingQ_xxx/command
{
"msg_id": "007",
"type": 0 , //0查询状态 1 控制打开和关闭
"status":0, //只有type为1的时候生效 0关闭 1 打开
}
device/TalkingQ_xxx/response
4G模块响应
{
"msg_id": "007",
"status": "success",
"data": {
"status": "on" //on或off 返回当前状态
}
}
//如果不是本机本地UUID则下发“你好你的朋友已在线请留言”
//如果本机本地UUID但没有留言"你好,已没可读留言"
服务器下发
device/TalkingQ_xxx/event_resp
{
"msg_id": "005",
"status": "success",
"type": 0, //0代表收听留言 1 代表需要发送留言
"params": {
"url_1": "http://xxx.mp3"
"url_2": "http://xxx.mp3"
}
}
{
"msg_id": "005",
"type": 0,
"params":
{
"url_1": "http://175.24.73.253:8080/assets/audio/no_message.mp3"
}
}
TalkingQ_XQSN00001003 TQ_XQSN000000001003
53C12B6DA20001
53D92B6DA20001
set id TalkingQ_XQSN00001003
set sn TQ_XQSN000000001003
TalkingQ_XQSN00001004 TQ_XQSN000000001004
53E12B6DA20001
53D12B6DA20001