Files
workphone-sdk/sdk/app/services/device_fleet.py

113 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
设备列表融合WebSocket + MongoDB + ADB供 /devices 与多机注册聚合复用)
"""
from typing import Any, Dict, List
import asyncio
import re
from services.ws_hub import ws_hub
from services.device_manager import device_manager
from services.adb_device import adb_manager
from services.device_id_util import enrich_device_id_fields, sanitize_sensitive_fields
async def list_merged_local_devices() -> List[Dict[str, Any]]:
"""与 routers.devices.get_devices 逻辑一致,返回设备 dict 列表。"""
db_devices: List[dict] = []
try:
db_devices = await device_manager.get_all_devices()
except Exception:
pass
online_devices = {d["device_id"]: d for d in ws_hub.get_online_devices()}
online_serials = {
value
for d in online_devices.values()
for value in (d.get("device_id"), d.get("serial"), d.get("adb_serial"), d.get("wifi_serial"))
if value
}
online_fingerprints = {
d.get("fingerprint_hash")
for d in online_devices.values()
if d.get("fingerprint_hash")
}
online_models = {
d.get("model")
for d in online_devices.values()
if d.get("model")
}
try:
adb_serials = await asyncio.wait_for(adb_manager.async_scan_devices(), timeout=0.5)
except asyncio.TimeoutError:
adb_serials = list(adb_manager._scan_cache or [])
seen_ids: set = set()
devices: List[Dict[str, Any]] = []
for raw in db_devices:
device = dict(raw)
device_id = device["device_id"]
serial = device.get("serial") or device.get("adb_serial") or device.get("wifi_serial")
fingerprint = device.get("fingerprint_hash")
is_online_alias = (
device_id not in online_devices
and (
(serial and serial in online_serials)
or (fingerprint and fingerprint in online_fingerprints)
)
)
adb_serial = adb_manager.resolve_serial(device_id)
is_adb_alias = (
device_id not in online_devices
and adb_serial in adb_serials
and device_id != adb_serial
)
is_stale_synthetic_alias = (
device_id not in online_devices
and not serial
and isinstance(device_id, str)
and re.fullmatch(r"[0-9a-f]{32}", device_id)
and device.get("model") in online_models
)
if is_online_alias or is_adb_alias or is_stale_synthetic_alias:
continue
seen_ids.add(device_id)
if device_id in online_devices:
device = {**device, **online_devices[device_id]}
device["status"] = "online"
else:
device["status"] = "offline"
devices.append(enrich_device_id_fields(device))
for device_id, info in online_devices.items():
if device_id not in seen_ids:
seen_ids.add(device_id)
devices.append(enrich_device_id_fields(dict(info)))
for serial in adb_serials:
if serial not in seen_ids:
adb_dev = adb_manager.get_device(serial)
if adb_dev:
info = adb_dev.get_info()
real_serial = info.get("serial") or serial
fingerprint = device_manager.compute_fingerprint({"device_id": real_serial, **info})
is_wifi_adb_alias = isinstance(serial, str) and ":" in serial and info.get("model") in online_models
if real_serial in online_serials or fingerprint in online_fingerprints or is_wifi_adb_alias:
continue
devices.append(
enrich_device_id_fields(
{
"device_id": serial,
"model": info.get("model", "Unknown"),
"brand": info.get("brand", "Unknown"),
"android_version": info.get("android_version", "Unknown"),
"status": "adb",
"connection_type": "adb",
"display": info.get("display", {}),
}
)
)
return sanitize_sensitive_fields(devices)