import Foundation #if canImport(JL_BLEKit) import JL_BLEKit #endif /// Device snapshot / target-feature queries. Mirrors `feature/DeviceInfoFeature.kt`. /// /// Returns a flat dictionary readable by the Dart `Jielihome.deviceSnapshot` /// caller. The Android schema (`name`, `firmwareVersion`, `battery`, ...) is /// preserved; iOS-specific extras (`bleAddr`, `btAddr`, `pidvid`) are added /// for completeness — Dart consumers ignore unknown keys. class DeviceInfoFeature { weak var server: JieliHomeServer? init(server: JieliHomeServer) { self.server = server } func snapshot(address: String) -> [String: Any?]? { #if canImport(JL_BLEKit) guard let entity = server?.connectFeature.currentEntity() as? JL_EntityM, entity.mUUID == address else { return nil } let model = entity.mCmdManager.outputDeviceModel() return [ "address": address, "name": entity.mPeripheral.name ?? "", "battery": Int(model.battery), "firmwareVersion": valueIfNotEmpty(model.versionFirmware), "hardwareVersion": valueIfNotEmpty(model.versionUBoot), "serialNumber": valueIfNotEmpty(model.pidvid), "manufacturer": valueIfNotEmpty(model.license), "model": valueIfNotEmpty(model.proCode), "btAddr": valueIfNotEmpty(model.btAddr), "bleAddr": valueIfNotEmpty(model.bleAddr), ] #else return nil #endif } func queryTargetInfo( address: String, mask: Int, completion: @escaping ([String: Any?]?, Error?) -> Void ) { #if canImport(JL_BLEKit) guard let entity = server?.connectFeature.currentEntity() as? JL_EntityM, entity.mUUID == address else { completion(nil, PluginError("TARGET_INFO_ERR", "no active session")) return } entity.mCmdManager.cmdTargetFeatureResult { [weak self] _, _, _ in let snap = self?.snapshot(address: address) if let s = snap { completion(s, nil) } else { completion(nil, PluginError("TARGET_INFO_ERR", "snapshot unavailable")) } } #else completion(nil, PluginError("TARGET_INFO_ERR", "JL_BLEKit not linked")) #endif } private func valueIfNotEmpty(_ s: String?) -> Any { guard let s = s, !s.isEmpty else { return NSNull() } return s } }