补充设备初始化留言与OTA后端能力
This commit is contained in:
@@ -9,19 +9,19 @@ import aiomqtt
|
||||
from banban.service.binding import BindingService
|
||||
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 config import settings
|
||||
from services.card_service import card_service
|
||||
from services.offline_audio_cache import offline_audio_cache
|
||||
import aiomqtt
|
||||
from banban.service.location import location_service
|
||||
from database.models import ChildLocationCurrent
|
||||
from datetime import datetime
|
||||
from services.device_target_cache import device_target_cache
|
||||
from services.device_identity_initializer import (
|
||||
DeviceIdentityInitializationError,
|
||||
device_identity_initializer,
|
||||
)
|
||||
from services.device_update_manager import device_firmware_update_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
|
||||
from services.task_manager import task_manager
|
||||
|
||||
class TalkingQMQTTService:
|
||||
_instance = None
|
||||
@@ -55,6 +55,7 @@ class TalkingQMQTTService:
|
||||
"009": self._handle_remote_sleep_wake_response,
|
||||
"010": self._handle_alarm_report,
|
||||
"011": self._handle_short_press_message,
|
||||
"012": self._handle_device_identity_init,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@@ -80,12 +81,16 @@ class TalkingQMQTTService:
|
||||
if not parts or parts[0] != "device":
|
||||
continue
|
||||
|
||||
device_id = parts[1] if len(parts) >= 2 else "unknown"
|
||||
if not device_id.startswith(f"{self.device_prefix}_"):
|
||||
continue
|
||||
|
||||
payload = json.loads(message.payload.decode("utf-8"))
|
||||
msg_id = payload.get("msg_id")
|
||||
|
||||
device_id = parts[1] if len(parts) >= 2 else "unknown"
|
||||
topic_kind = parts[2] if len(parts) >= 3 else ""
|
||||
if msg_id == "012" and topic_kind != "event":
|
||||
continue
|
||||
if msg_id != "012" and not device_id.startswith(f"{self.device_prefix}_"):
|
||||
continue
|
||||
|
||||
handler = self._msg_handlers.get(msg_id)
|
||||
if handler:
|
||||
await handler(device_id, payload)
|
||||
@@ -185,7 +190,36 @@ class TalkingQMQTTService:
|
||||
async def _handle_ota_response(self, device_id: str, payload: dict):
|
||||
status = payload.get("status")
|
||||
data = payload.get("data", {})
|
||||
if status == "success":
|
||||
progress = data.get("progress")
|
||||
try:
|
||||
progress_value = float(progress) if progress is not None else None
|
||||
except (TypeError, ValueError):
|
||||
progress_value = None
|
||||
|
||||
if status == "accepted":
|
||||
await self._schedule_persistence(
|
||||
device_id,
|
||||
"ota",
|
||||
device_firmware_update_manager.update_firmware_update(
|
||||
device_id=device_id,
|
||||
firmware_version=data.get("version") or data.get("new_version") or "unknown",
|
||||
update_status="accepted",
|
||||
progress=progress_value if progress_value is not None else 0.0,
|
||||
),
|
||||
)
|
||||
elif status == "updating":
|
||||
await self._schedule_persistence(
|
||||
device_id,
|
||||
"ota",
|
||||
device_firmware_update_manager.update_firmware_update(
|
||||
device_id=device_id,
|
||||
firmware_version=data.get("version") or data.get("new_version") or "updating",
|
||||
update_status="updating",
|
||||
progress=progress_value,
|
||||
),
|
||||
)
|
||||
elif status == "success":
|
||||
new_version = data.get("new_version") or data.get("version")
|
||||
await self._schedule_persistence(
|
||||
device_id,
|
||||
"ota",
|
||||
@@ -194,13 +228,33 @@ class TalkingQMQTTService:
|
||||
power=None,
|
||||
volume=None,
|
||||
signal_strength=None,
|
||||
version_str=data.get("new_version"),
|
||||
version_str=new_version,
|
||||
),
|
||||
)
|
||||
await self._schedule_persistence(
|
||||
device_id,
|
||||
"ota",
|
||||
device_firmware_update_manager.update_firmware_update(
|
||||
device_id=device_id,
|
||||
firmware_version=new_version or "unknown",
|
||||
update_status="success",
|
||||
progress=100.0,
|
||||
),
|
||||
)
|
||||
elif status == "failed":
|
||||
await self._schedule_persistence(
|
||||
device_id,
|
||||
"ota",
|
||||
device_firmware_update_manager.update_firmware_update(
|
||||
device_id=device_id,
|
||||
firmware_version=data.get("version") or data.get("new_version") or "unknown",
|
||||
update_status="failed",
|
||||
progress=progress_value,
|
||||
),
|
||||
)
|
||||
elif status != "accepted":
|
||||
logger.warning(device_id, "", f"[OTA] command failed: {payload}")
|
||||
else:
|
||||
logger.warning(device_id, "", f"[OTA] 设备 {device_id} 升级异常: {payload}")
|
||||
logger.warning(device_id, "", f"[OTA] unknown status: {payload}")
|
||||
|
||||
async def _handle_nfc_notice_response(self, device_id: str, payload: dict):
|
||||
status = payload.get("status")
|
||||
@@ -283,8 +337,35 @@ class TalkingQMQTTService:
|
||||
params = payload.get("params", {})
|
||||
nfc_uuid = params.get("uuid")
|
||||
logger.info(device_id, "", f"[短按留言] 设备 {device_id} 短按发送留言, UUID={nfc_uuid}")
|
||||
media_file_key = str(params.get("media_file_key") or params.get("audio_url") or "").strip()
|
||||
if media_file_key:
|
||||
try:
|
||||
await im_service.create_device_parent_leave_message(
|
||||
device_id=device_id,
|
||||
media_file_key=media_file_key,
|
||||
media_duration_ms=params.get("media_duration_ms"),
|
||||
media_mime_type=params.get("media_mime_type"),
|
||||
media_size_bytes=params.get("media_size_bytes"),
|
||||
media_transcript_text=params.get("media_transcript_text"),
|
||||
client_msg_id=params.get("client_msg_id"),
|
||||
ext_json=params.get("ext_json") if isinstance(params.get("ext_json"), dict) else None,
|
||||
)
|
||||
logger.info(device_id, "", f"[短按留言] 设备 {device_id} 留言已写入家长会话")
|
||||
except Exception as exc:
|
||||
logger.warning(device_id, "", f"[短按留言] 设备 {device_id} 留言写入失败: {exc}")
|
||||
await self._publish(
|
||||
f"device/{device_id}/event_resp",
|
||||
{
|
||||
"msg_id": "011",
|
||||
"status": "failed",
|
||||
"message": str(exc),
|
||||
},
|
||||
)
|
||||
return
|
||||
|
||||
payload = {
|
||||
"msg_id": "011",
|
||||
"status": "success",
|
||||
"type": 0,
|
||||
"params": {
|
||||
"url": f"http://{settings.server_host}:{settings.server_port}/assets/audio/message_ok.mp3"
|
||||
@@ -292,6 +373,30 @@ class TalkingQMQTTService:
|
||||
}
|
||||
await self._publish(f"device/{device_id}/event_resp", payload)
|
||||
|
||||
async def _handle_device_identity_init(self, imei: str, payload: dict):
|
||||
try:
|
||||
result = await device_identity_initializer.initialize_by_imei(imei)
|
||||
except DeviceIdentityInitializationError as exc:
|
||||
logger.warning(imei, "", f"[设备初始化] IMEI初始化失败: {exc}")
|
||||
await self._publish(
|
||||
f"device/{imei}/event_resp",
|
||||
{
|
||||
"msg_id": "012",
|
||||
"status": "failed",
|
||||
"message": str(exc),
|
||||
},
|
||||
)
|
||||
return
|
||||
|
||||
response_payload = {
|
||||
"msg_id": "012",
|
||||
"params": {
|
||||
"device_id": result.device_id,
|
||||
"device_sn": result.serial_number,
|
||||
},
|
||||
}
|
||||
await self._publish(f"device/{imei}/event_resp", response_payload)
|
||||
|
||||
async def _send_nfc_listen_response(self, device_id: str, nfc_uuid: str):
|
||||
topic = f"device/{device_id}/event_resp"
|
||||
card = await card_service.get_card_by_uuid(nfc_uuid)
|
||||
|
||||
Reference in New Issue
Block a user