""" Android uwb 组件 — UwbManager, RangingResult, RangingParameters, UwbAddress 等 方法签名完全对齐 Android SDK (UWB API) """ from typing import Any, Callable, Dict, List, Optional from .._core import Stub, AndroidOnlyError # ═══════════════════════════════════════════════════════════════ # UwbConstants # ═══════════════════════════════════════════════════════════════ class UwbConstants(Stub): """UwbConstants — UWB 常量""" STATUS_OK = 0 STATUS_FAILURE = 1 STATUS_INVALID_PARAMETERS = 2 STATUS_SESSION_DOES_NOT_EXIST = 3 STATUS_MAX_RANGING_ROUND_RETRY = 4 STATUS_RANGING_TX_FAILED = 5 STATUS_SESSION_STATE_CHANGE_EXCEPTION = 6 STATUS_UNKNOWN_ERROR = 255 CONFIG_ID_0 = 0 CONFIG_ID_1 = 1 CONFIG_ID_2 = 2 CONFIG_ID_3 = 3 MEASUREMENT_REPORT_TYPE_DEFERRED = 0 MEASUREMENT_REPORT_TYPE_NTF = 1 RANGING_UPDATE_RATE_AUTO = 0 RANGING_UPDATE_RATE_FREQUENCY_1_HZ = 1 RANGING_UPDATE_RATE_FREQUENCY_2_HZ = 2 RANGING_UPDATE_RATE_FREQUENCY_5_HZ = 5 RANGING_UPDATE_RATE_FREQUENCY_10_HZ = 10 RANGING_UPDATE_RATE_FREQUENCY_20_HZ = 20 RANGING_UPDATE_RATE_FREQUENCY_100_HZ = 100 RANGING_UPDATE_RATE_FREQUENCY_250_HZ = 250 # ═══════════════════════════════════════════════════════════════ # UwbAddress # ═══════════════════════════════════════════════════════════════ class UwbAddress(Stub): """UwbAddress — UWB 地址""" SHORT_MAC_ADDRESS = 0 EXTENDED_MAC_ADDRESS = 1 def __init__(self, address: bytes = b"", type_: int = SHORT_MAC_ADDRESS): super().__init__() self._address = address self._type = type_ def getAddress(self) -> bytes: return self._address def getType(self) -> int: return self._type def toString(self) -> str: return f"UwbAddress(type={self._type}, addr={self._address.hex()})" # ═══════════════════════════════════════════════════════════════ # AngleOfArrival # ═══════════════════════════════════════════════════════════════ class AngleOfArrival(Stub): """AngleOfArrival — 到达角""" STATUS_SUCCESS = 0 STATUS_FAILURE = 1 def __init__(self, azimuth: float = 0.0, elevation: float = 0.0, azimuthConfidence: float = 0.0, elevationConfidence: float = 0.0, status: int = STATUS_FAILURE): super().__init__() self._azimuth = azimuth self._elevation = elevation self._azimuth_confidence = azimuthConfidence self._elevation_confidence = elevationConfidence self._status = status def getAzimuth(self) -> float: return self._azimuth def getElevation(self) -> float: return self._elevation def getAzimuthConfidence(self) -> float: return self._azimuth_confidence def getElevationConfidence(self) -> float: return self._elevation_confidence # ═══════════════════════════════════════════════════════════════ # DistanceMeasurement # ═══════════════════════════════════════════════════════════════ class DistanceMeasurement(Stub): """DistanceMeasurement — 距离测量""" STATUS_SUCCESS = 0 STATUS_FAILURE = 1 def __init__(self, meters: float = 0.0, confidence: float = 0.0, standardDeviation: float = 0.0, status: int = STATUS_FAILURE): super().__init__() self._meters = meters self._confidence = confidence self._standard_deviation = standardDeviation self._status = status def getMeters(self) -> float: return self._meters def getConfidence(self) -> float: return self._confidence def getStandardDeviation(self) -> float: return self._standard_deviation # ═══════════════════════════════════════════════════════════════ # RangingResult # ═══════════════════════════════════════════════════════════════ class RangingResult(Stub): """RangingResult — 测距结果""" def __init__(self, uwbDevice: Any = None, remoteDevice: Any = None, status: int = 0, nofRounds: int = 0, nofMeasurements: int = 0, elapsedRealtimeNanos: int = 0, distanceMeasurement: Optional[DistanceMeasurement] = None, angleOfArrival: Optional[AngleOfArrival] = None, rssi: float = -90.0): super().__init__() self._uwb_device = uwbDevice self._remote_device = remoteDevice self._status = status self._nof_rounds = nofRounds self._nof_measurements = nofMeasurements self._elapsed_realtime_nanos = elapsedRealtimeNanos self._distance_measurement = distanceMeasurement self._angle_of_arrival = angleOfArrival self._rssi = rssi self._distance_reported = distanceMeasurement is not None self._aoa_reported = angleOfArrival is not None def getUwbDevice(self) -> Any: return self._uwb_device def getRemoteDevice(self) -> Any: return self._remote_device def getStatus(self) -> int: return self._status def getNofRounds(self) -> int: return self._nof_rounds def getNofMeasurements(self) -> int: return self._nof_measurements def getElapsedRealtimeNanos(self) -> int: return self._elapsed_realtime_nanos def getDistanceMeasurement(self) -> Optional[DistanceMeasurement]: return self._distance_measurement def getAngleOfArrival(self) -> Optional[AngleOfArrival]: return self._angle_of_arrival def getAngleOfArrivalAzimuth(self) -> float: if self._angle_of_arrival: return self._angle_of_arrival.getAzimuth() return 0.0 def getAngleOfArrivalElevation(self) -> float: if self._angle_of_arrival: return self._angle_of_arrival.getElevation() return 0.0 def getAngleOfArrivalAzimuthConfidence(self) -> float: if self._angle_of_arrival: return self._angle_of_arrival.getAzimuthConfidence() return 0.0 def getAngleOfArrivalElevationConfidence(self) -> float: if self._angle_of_arrival: return self._angle_of_arrival.getElevationConfidence() return 0.0 def getRssi(self) -> float: return self._rssi def isDistanceMeasurementReported(self) -> bool: return self._distance_reported def isAngleOfArrivalReported(self) -> bool: return self._aoa_reported # ═══════════════════════════════════════════════════════════════ # RangingParameters # ═══════════════════════════════════════════════════════════════ class RangingParameters(Stub): """RangingParameters — 测距参数""" class Builder(Stub): """RangingParameters.Builder — 测距参数构建器""" def __init__(self): super().__init__() self._uwb_config_id = 0 self._session_id = 0 self._sub_session_id = 0 self._ranging_update_rate = 1 self._slot_duration = 0 self._measurement_report_type = 0 self._number_of_controlee = 1 self._destination_addresses: List[UwbAddress] = [] self._device_configs: List[Any] = [] self._vendor_specific_data: List[Any] = [] def setUwbConfigId(self, configId: int) -> "RangingParameters.Builder": self._uwb_config_id = configId return self def setSessionId(self, sessionId: int) -> "RangingParameters.Builder": self._session_id = sessionId return self def setSubSessionId(self, subSessionId: int) -> "RangingParameters.Builder": self._sub_session_id = subSessionId return self def setRangingUpdateRate(self, rate: int) -> "RangingParameters.Builder": self._ranging_update_rate = rate return self def setSlotDuration(self, duration: int) -> "RangingParameters.Builder": self._slot_duration = duration return self def setMeasurementReportType(self, reportType: int) -> "RangingParameters.Builder": self._measurement_report_type = reportType return self def setNumberOfControlee(self, count: int) -> "RangingParameters.Builder": self._number_of_controlee = count return self def setDestinationAddresses(self, addrs: List[UwbAddress]) -> "RangingParameters.Builder": self._destination_addresses = addrs return self def setDeviceConfigs(self, configs: List[Any]) -> "RangingParameters.Builder": self._device_configs = configs return self def setVendorSpecificData(self, data: List[Any]) -> "RangingParameters.Builder": self._vendor_specific_data = data return self def build(self) -> "RangingParameters": rp = RangingParameters() rp._uwb_config_id = self._uwb_config_id rp._session_id = self._session_id rp._sub_session_id = self._sub_session_id rp._ranging_update_rate = self._ranging_update_rate rp._slot_duration = self._slot_duration rp._measurement_report_type = self._measurement_report_type rp._number_of_controlee = self._number_of_controlee rp._destination_addresses = self._destination_addresses rp._device_configs = self._device_configs rp._vendor_specific_data = self._vendor_specific_data return rp def __init__(self): super().__init__() # ═══════════════════════════════════════════════════════════════ # UwbConfiguration / RangingConfig (stubs) # ═══════════════════════════════════════════════════════════════ class UwbConfiguration(Stub): """UwbConfiguration — UWB 配置""" def __init__(self): super().__init__() class RangingConfig(Stub): """RangingConfig — 测距配置""" def __init__(self): super().__init__() # ═══════════════════════════════════════════════════════════════ # RangingSession # ═══════════════════════════════════════════════════════════════ class RangingSession(Stub): """RangingSession — 测距会话""" def __init__(self): super().__init__() self._open = False def open(self): self._open = True def close(self): self._open = False def reconfigure(self, params: RangingParameters): pass # ═══════════════════════════════════════════════════════════════ # UwbManager # ═══════════════════════════════════════════════════════════════ class UwbManager(Stub): """UwbManager — UWB 管理器""" # ═══════════════════════════════════════════════════════════ # UwbCallback # ═══════════════════════════════════════════════════════════ class UwbCallback(Stub): """UwbManager.UwbCallback — UWB 回调""" def onRangingResult(self, sessionId: int, result: RangingResult): pass def onRangingFailure(self, sessionId: int, reason: int): pass def onControleeResult(self, sessionId: int, status: int): pass _instance: Optional["UwbManager"] = None def __init__(self): super().__init__() @staticmethod def getInstance(context: Any = None) -> "UwbManager": if UwbManager._instance is None: UwbManager._instance = UwbManager() return UwbManager._instance def open(self, sessionId: int) -> RangingSession: session = RangingSession() session.open() return session def close(self, sessionId: int): pass def range(self, sessionId: int, params: RangingParameters, callback: UwbCallback): if callback: result = RangingResult( status=UwbConstants.STATUS_OK, distanceMeasurement=DistanceMeasurement( meters=1.5, confidence=0.8, standardDeviation=0.1, status=DistanceMeasurement.STATUS_SUCCESS ), rssi=-65.0 ) callback.onRangingResult(sessionId, result) def stopRange(self, sessionId: int): pass def addControlee(self, sessionId: int, address: UwbAddress): pass def removeControlee(self, sessionId: int, address: UwbAddress): pass def setMeasurementData(self, sessionId: int, data: bytes): pass def sendMeasurementData(self, sessionId: int, data: bytes): pass def getUwbDevice(self) -> Any: return None # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "UwbManager", "UwbConstants", "UwbAddress", "AngleOfArrival", "DistanceMeasurement", "RangingResult", "RangingParameters", "UwbConfiguration", "RangingConfig", "RangingSession", ]