合入持久化刷卡语音消息的代码,暂未测试

This commit is contained in:
HycJack
2026-05-26 02:47:59 +08:00
parent e3059304b4
commit 1ffad03801
14 changed files with 1065 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
@@ -19,6 +20,7 @@ from services.device_identity_initializer import (
device_identity_initializer,
)
from services.device_update_manager import device_firmware_update_manager
from services.device_volume_manager import device_volume_manager
from services.offline_audio_cache import offline_audio_cache
from services.task_manager import task_manager
from utils.logger import session_logger as logger
@@ -119,6 +121,26 @@ class TalkingQMQTTService:
task_type="persistence",
)
# async def _sync_desired_volume(self, device_id: str, current_level) -> None:
# if current_level is None:
# return
# try:
# current_level_int = int(current_level)
# except (TypeError, ValueError):
# logger.warning(device_id, "volume", f"invalid current volume level: {current_level}")
# return
# desired_level = await device_volume_manager.get_configured_volume(device_id)
# if desired_level is None or desired_level == current_level_int:
# return
# logger.info(
# device_id,
# "volume",
# f"当前音量 {current_level_int} 与期望音量 {desired_level} 不一致,补发音量指令",
# )
# await self.send_volume_command(device_id, desired_level)
async def _handle_device_info(self, device_id: str, payload: dict):
data = payload.get("data", {})
d_id = data.get("id")
@@ -139,6 +161,7 @@ class TalkingQMQTTService:
volume=data.get("voice"),
),
)
# await self._sync_desired_volume(device_id, current_volume)
await self._publish(f"device/{device_id}/event_resp", {"msg_id": "000", "status": "success"})
async def _handle_gps_response(self, device_id: str, payload: dict):
@@ -198,6 +221,7 @@ class TalkingQMQTTService:
version_str=None,
),
)
# await self._sync_desired_volume(device_id, current_level)
async def _handle_ota_response(self, device_id: str, payload: dict):
status = payload.get("status")
@@ -293,8 +317,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
@@ -449,6 +472,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)}
@@ -530,13 +570,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"})