持久化设备留言待收听状态并支持重启恢复

This commit is contained in:
stu2not
2026-05-19 14:06:16 +08:00
parent 3164d81bb0
commit 6e104201fb
21 changed files with 1147 additions and 68 deletions

View File

@@ -6,11 +6,12 @@ from typing import Awaitable, Callable, Dict, Optional
import aiomqtt
from banban.service.binding import BindingService
from banban.service.binding import binding_service
from banban.service.device_alarm import device_alarm_service
from banban.service.device_setting import device_setting_service
from banban.service.im import im_service
from banban.service.location import location_service
from banban.service.pending_voice_message import pending_voice_message_service
from config import settings
from services.card_service import card_service
from services.device_target_cache import device_target_cache
@@ -275,8 +276,7 @@ class TalkingQMQTTService:
nfc_uuid = data.get("uuid")
# 卡片与设备绑定
# await card_service.activate_card(device_id=device_id, card_uuid=nfc_uuid)
service = BindingService()
result = await service.finalize_nfc_bind(device_id=device_id, card_uuid=nfc_uuid)
result = await binding_service.finalize_nfc_bind(device_id=device_id, card_uuid=nfc_uuid)
if result is None:
logger.warning(device_id, "", "[NFC bind] no pending bind session found")
return
@@ -431,6 +431,23 @@ class TalkingQMQTTService:
is_owner = await card_service.check_card_ownership(nfc_uuid, device_id)
if is_owner:
playback_items = await pending_voice_message_service.get_playback_items(
target_device_id=device_id,
)
if playback_items:
params = {
f"url_{k}": item.audio_url
for k, item in enumerate(playback_items, start=1)
}
payload = {"msg_id": "005", "type": 0, "params": params}
published = await self._publish(topic, payload)
if published:
await pending_voice_message_service.mark_delivered(
[item.pending_id for item in playback_items]
)
await offline_audio_cache.clear_audio_urls(device_id)
return
audio_urls = await offline_audio_cache.pop_audio_urls(device_id)
if audio_urls:
params = {f"url_{k}": audio_url for k, audio_url in enumerate(audio_urls, start=1)}
@@ -511,13 +528,15 @@ class TalkingQMQTTService:
if not self._connected:
await self.connect()
async def _publish(self, topic: str, payload: dict):
async def _publish(self, topic: str, payload: dict) -> bool:
await self._ensure_connected()
try:
await self._client.publish(topic, json.dumps(payload, ensure_ascii=False), qos=self.qos)
logger.info("", "", f"mqtt publish topic={topic} payload={payload}")
return True
except Exception as exc:
logger.error("", "", f"mqtt publish failed: {exc}")
return False
async def send_gps_query(self, device_id: str) -> str:
await self._publish(f"device/{device_id}/command", {"msg_id": "001"})