告警时主动刷新定位地址
This commit is contained in:
@@ -51,6 +51,8 @@ class TalkingQMQTTService:
|
||||
self._volume_command_lock = asyncio.Lock()
|
||||
self._volume_command_states: Dict[tuple[str, int], dict] = {}
|
||||
self._last_volume_command_time_ms = 0
|
||||
self._gps_waiter_lock = asyncio.Lock()
|
||||
self._gps_waiters: Dict[str, list[asyncio.Future]] = {}
|
||||
|
||||
self._msg_handlers: Dict[str, Callable[[str, dict], Awaitable[None]]] = {
|
||||
"000": self._handle_device_info,
|
||||
@@ -189,10 +191,8 @@ class TalkingQMQTTService:
|
||||
lon = data.get("longitude")
|
||||
logger.info(device_id, "", f"[GPS] 设备 {device_id} 位置: 纬度={lat}, 经度={lon}")
|
||||
|
||||
await self._schedule_persistence(
|
||||
device_id,
|
||||
"gps",
|
||||
location_service.report_mqtt_device_location(
|
||||
async def _persist_gps_and_notify():
|
||||
row = await location_service.report_mqtt_device_location(
|
||||
device_id=device_id,
|
||||
latitude=data.get("latitude"),
|
||||
longitude=data.get("longitude"),
|
||||
@@ -204,8 +204,10 @@ class TalkingQMQTTService:
|
||||
source=data.get("source"),
|
||||
battery_pct=data.get("battery_pct"),
|
||||
device_time=parsed_device_time,
|
||||
),
|
||||
)
|
||||
)
|
||||
await self._notify_gps_waiters(device_id, row)
|
||||
|
||||
await self._schedule_persistence(device_id, "gps", _persist_gps_and_notify())
|
||||
|
||||
async def _handle_volume_response(self, device_id: str, payload: dict):
|
||||
command_time = self._parse_command_time(payload.get("time"))
|
||||
@@ -399,7 +401,27 @@ class TalkingQMQTTService:
|
||||
async def _handle_alarm_report(self, device_id: str, payload: dict):
|
||||
logger.info(device_id, "", f"[告警] 设备 {device_id} 发送紧急报警")
|
||||
async def _record_alarm_and_notify():
|
||||
alarm_id = await device_alarm_service.record_alarm_event(device_id=device_id, source_msg_id="010")
|
||||
alarm_id = await device_alarm_service.record_alarm_event(
|
||||
device_id=device_id,
|
||||
source_msg_id="010",
|
||||
resolve_address=False,
|
||||
)
|
||||
if alarm_id:
|
||||
location = await self.query_gps_and_wait_for_location(
|
||||
device_id,
|
||||
timeout_seconds=settings.alarm_gps_query_timeout_seconds,
|
||||
)
|
||||
if location and location.get("lat") is not None and location.get("lng") is not None:
|
||||
await device_alarm_service.apply_alarm_location(
|
||||
alarm_id=alarm_id,
|
||||
device_id=device_id,
|
||||
location=location,
|
||||
)
|
||||
else:
|
||||
await device_alarm_service.resolve_alarm_current_location(
|
||||
alarm_id=alarm_id,
|
||||
device_id=device_id,
|
||||
)
|
||||
sms_notification_service.schedule_alarm_notification(device_id=device_id, alarm_id=alarm_id)
|
||||
|
||||
await self._schedule_persistence(device_id, "alarm_event", _record_alarm_and_notify())
|
||||
@@ -647,6 +669,36 @@ class TalkingQMQTTService:
|
||||
await self._publish(f"device/{device_id}/command", {"msg_id": "001"})
|
||||
return "001"
|
||||
|
||||
async def query_gps_and_wait_for_location(self, device_id: str, *, timeout_seconds: float) -> dict | None:
|
||||
timeout = max(0.1, float(timeout_seconds or 0))
|
||||
loop = asyncio.get_running_loop()
|
||||
future = loop.create_future()
|
||||
async with self._gps_waiter_lock:
|
||||
self._gps_waiters.setdefault(device_id, []).append(future)
|
||||
|
||||
try:
|
||||
await self.send_gps_query(device_id)
|
||||
return await asyncio.wait_for(future, timeout=timeout)
|
||||
except asyncio.TimeoutError:
|
||||
return None
|
||||
finally:
|
||||
async with self._gps_waiter_lock:
|
||||
waiters = self._gps_waiters.get(device_id)
|
||||
if waiters and future in waiters:
|
||||
waiters.remove(future)
|
||||
if waiters == []:
|
||||
self._gps_waiters.pop(device_id, None)
|
||||
|
||||
async def _notify_gps_waiters(self, device_id: str, row: dict | None) -> None:
|
||||
if row is None:
|
||||
return
|
||||
async with self._gps_waiter_lock:
|
||||
waiters = self._gps_waiters.pop(device_id, [])
|
||||
|
||||
for future in waiters:
|
||||
if not future.done():
|
||||
future.set_result(dict(row))
|
||||
|
||||
def _parse_command_time(self, value) -> int | None:
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user