From 02f11474b391b029e009f0602ead4ea4293f5a73 Mon Sep 17 00:00:00 2001 From: HycJack <772403255@qq.com> Date: Mon, 27 Apr 2026 18:50:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0mqtt=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E5=8D=8F=E8=AE=AE=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E8=BF=98=E5=B7=AE=E5=B0=86=E8=AE=BE=E5=A4=87=E4=B8=8A=E6=8A=A5?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=BF=9D=E5=AD=98=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E5=92=8C=E9=9F=B3=E9=A2=91=E6=95=B0=E6=8D=AE=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E4=BA=91=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- talkingq-url/api/__init__.py | 2 - talkingq-url/banban/routers/__init__.py | 3 + .../{api => banban/routers}/mqtt_router.py | 44 +++- .../{api => banban/schemas}/mqtt_models.py | 0 talkingq-url/docs/mqtt协议_V1.3.txt | 190 ++++++++++++++++++ 5 files changed, 227 insertions(+), 12 deletions(-) rename talkingq-url/{api => banban/routers}/mqtt_router.py (82%) rename talkingq-url/{api => banban/schemas}/mqtt_models.py (100%) create mode 100644 talkingq-url/docs/mqtt协议_V1.3.txt diff --git a/talkingq-url/api/__init__.py b/talkingq-url/api/__init__.py index 34f9fc4..fc295de 100644 --- a/talkingq-url/api/__init__.py +++ b/talkingq-url/api/__init__.py @@ -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路由 diff --git a/talkingq-url/banban/routers/__init__.py b/talkingq-url/banban/routers/__init__.py index a166022..e05a878 100644 --- a/talkingq-url/banban/routers/__init__.py +++ b/talkingq-url/banban/routers/__init__.py @@ -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"] \ No newline at end of file diff --git a/talkingq-url/api/mqtt_router.py b/talkingq-url/banban/routers/mqtt_router.py similarity index 82% rename from talkingq-url/api/mqtt_router.py rename to talkingq-url/banban/routers/mqtt_router.py index d6d9a8c..6934516 100644 --- a/talkingq-url/api/mqtt_router.py +++ b/talkingq-url/banban/routers/mqtt_router.py @@ -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) diff --git a/talkingq-url/api/mqtt_models.py b/talkingq-url/banban/schemas/mqtt_models.py similarity index 100% rename from talkingq-url/api/mqtt_models.py rename to talkingq-url/banban/schemas/mqtt_models.py diff --git a/talkingq-url/docs/mqtt协议_V1.3.txt b/talkingq-url/docs/mqtt协议_V1.3.txt new file mode 100644 index 0000000..279c450 --- /dev/null +++ b/talkingq-url/docs/mqtt协议_V1.3.txt @@ -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 +