// // DeviceViewModels.swift // FireBoltt // // Created by lemo. on 2020/3/7. // Copyright © 2020 Sheldon. All rights reserved. // import UIKit import CoreLocation import RxSwift /// 本地天气缓存KEY fileprivate let LocalWeatherKEY = "LocalWeatherKEY" struct Weather: HandyJSON { var lowTemperature: String = "" var highTemperature: String = "" var currenTemperature: String = "" var weatherType: Int = 0 var date: String = "" } class DeviceViewModels: ViewModel, ViewModelType { struct Input { let syncData: Observable } struct Output { let syncState: Driver } /// 绑定状态 let isBinding = BehaviorRelay(value: false) // 头视图 let deviceName = BehaviorRelay(value: "") let connectState = BehaviorRelay(value: false) let powerState = BehaviorRelay(value: R.image.power_0()) let syncState = BehaviorRelay(value: MultiLanguageKey_FB.syncDataFB.localized) /// 数据源 let datasource = BehaviorRelay<[SectionModel]>.init(value: []) /// 强制升级固件 let mandatoryUpdate = BehaviorRelay(value: nil) /// 定位管理 private var locationManager: CLLocationManager? /// 固件有新版本 private var isNewFirmware: Bool = false override init() { super.init() BluetoothService.shared.powerState .bind(to: powerState) .disposed(by: rx.disposeBag) fbloadDefualtData() monitor() /// 加载功能列表 fbloadFuncation() } func transform(input: DeviceViewModels.Input) -> DeviceViewModels.Output { input.syncData .subscribe(onNext: { _ in if BluetoothService.shared.checkBleCmdEnable(isShow: true) { BluetoothService.shared.fbsendSyncDeviceData() } }) .disposed(by: rx.disposeBag) let syncState = BluetoothService.shared.syncState .flatMapLatest { (state) -> Observable in switch state { case .normal: return Observable.just(MultiLanguageKey_FB.syncDataFB.localized) case .syncing(let progrss): print("%@",progrss); return Observable.just("\(Int(progrss * 100))%") } }.asDriver(onErrorJustReturn: MultiLanguageKey_FB.syncDataFB.localized) return Output(syncState: syncState) } func fbloadDefualtData() { // 绑定状态 guard let deviceInfo = UserDefaultsManagerFrieBoltt.getDeviceInfo() else { return } isBinding.accept(true) deviceName.accept(deviceInfo.deviceName) // 连接状态 if BluetoothFireBoltt.shareInstance()!.isConnected { self.connectState.accept(true) self.connctDeviceConfig() } else { BluetoothFireBoltt.shareInstance()!.startAndStopReconnect(true) } } func monitor() { // 绑定成功 kNotificationCenter.rx.notification(Notification.Name(rawValue: BindingDeviceFireBoltt)) .subscribe(onNext: { [weak self] (notification) in guard let `self` = self else { return } self.fbloadDefualtData() }) .disposed(by: rx.disposeBag) // 连接状态 BluetoothService.shared.deviceConnectState .subscribe(onNext: { [weak self] (state) in guard let `self` = self else { return } self.connectState.accept(state) if state { self.fbloadDefualtData() } }) .disposed(by: rx.disposeBag) // 设备适配更新 BluetoothService.shared.adapterInfoUpdate .subscribe(onNext: { [weak self] (state) in self?.fbloadFuncation() }) .disposed(by: rx.disposeBag) // 设备配置刷新 kNotificationCenter.rx.notification(Notification.Name(rawValue: ReadProfileNotice)) .subscribe(onNext: { [weak self] (notification) in guard let `self` = self else { return } self.fbloadFuncation() }) .disposed(by: rx.disposeBag) // 解绑设备 kNotificationCenter.rx.notification(Notification.Name(rawValue: UnBindingDeviceFireBoltt)) .subscribe(onNext: { [weak self] (notification) in guard let `self` = self else { return } self.isBinding.accept(false) // 清空实时数据 UserDefaultsManagerFrieBoltt.deleteRealTimeData() BluetoothService.shared.clearRealtimeData() /// 清空设备信息 UserDefaultsManagerFrieBoltt.deleteDeviceInfo() }) .disposed(by: rx.disposeBag) // 云端固件信息 BluetoothService.shared.cloudFirmwareInfo .subscribe(onNext: { [weak self] (isNew, isMandatory) in self?.isNewFirmware = isNew if isNew == false { return } // 强制升级 if isMandatory { // 清空当前指令队列 BluetoothFireBoltt.shareInstance()?.removeCmdItem() let viewModel = FirmwareUpdateViewModels() self?.mandatoryUpdate.accept(viewModel) return } }) .disposed(by: rx.disposeBag) } } extension DeviceViewModels { func fbloadFuncation() { // 默认功能列表 let section1: [FunctionTypeFireBoltt] = [.findPhone, .remoteCamera] var section2: [FunctionTypeFireBoltt] = [.callRemind, .messageRemind, .notice] // var section3: [FunctionTypeFireBoltt] = [.unBinding] var section3: [FunctionTypeFireBoltt] = [] // 功能适配 if let adapterInfo = UserDefaultsManagerFrieBoltt.getDeviceInfo()?.adapterInfo { // Section2 if adapterInfo.notDisturb { section2.insert(.handUp, at: 0) } if adapterInfo.notDisturb { section2.append(.notDisturb) } if adapterInfo.heartRate { section2.append(.heartCheck) } if adapterInfo.bodyTemperature { section2.append(.tempeartureCheck) } if adapterInfo.alarmRemind { section2.append(.alarmClock) } if adapterInfo.drinkRemind { section2.append(.drinkRemind) } if adapterInfo.sedentaryRemind { section2.append(.sedentary) } if adapterInfo.telephoneBook { section2.append(.telephoneBook) } if adapterInfo.businessCard { section2.append(.businessCard) } if adapterInfo.theWallet { section2.append(.theWallet) } if adapterInfo.music { section2.append(.music) } // Section3 if adapterInfo.firmwareVersion { section3.insert(.firmwareUpgrade, at: 0) } if adapterInfo.wechatSport { section3.insert(.wechatSport, at: 1) } if adapterInfo.dailPush { section3.insert(.dialPush, at: 0) } } let funcations: [[FunctionTypeFireBoltt]] = [section1, section2, section3] var sections: [SectionModel] = [] funcations.forEach { (types) in var cellModels: [TableViewCellModel] = [] types.enumerated().forEach { (index, type) in let isBottomLine = index != types.count - 1 let isON = getSwitchState(type: type) var description: String? if type == .firmwareUpgrade, let firmwareVersion = GlobalDeviceProfileModel.shareInstance.firwareModel?.firmwareVersion { description = "V" + firmwareVersion } let cellModel = TableViewCellModel(title: type.title(), isSwitch: type.isSwitch(), description: description, isArrows: !type.isSwitch(), isOn: isON, image: UIImage(named: type.imgName()), isBottomLine: isBottomLine, functionType: type) if type == .firmwareUpgrade { cellModel.redPoint.accept(isNewFirmware) } cellModels.append(cellModel) } sections.append(SectionModel(model: "", items: cellModels)) } datasource.accept(sections) } /// 连接成功后配置数据 func connctDeviceConfig() { BluetoothService.shared.bloothPrepare() BluetoothService.shared.fbsendSyncDeviceData() // 发送天气预报 loadWeather() } /// 获取当前开关状态 /// - Parameter type: 功能类型 private func getSwitchState(type: FunctionTypeFireBoltt) -> Bool { switch type { case .handUp: return GlobalDeviceProfileModel.shareInstance.gestureModel?.Raise ?? false case .callRemind: return PushType.call.getSwitchState(currenValue: GlobalDeviceProfileModel.shareInstance.pushSetValue) case .messageRemind: return PushType.message.getSwitchState(currenValue: GlobalDeviceProfileModel.shareInstance.pushSetValue) default: return false } } } // MARK:- 天气同步 extension DeviceViewModels: CLLocationManagerDelegate { private func loadWeather() { // 本地是否已存在天气数据 let todayStr = DateClass.getCurrentTimeStr(formatStr: "yyyy-MM-dd") if let jsons = kUserDefualt.string(forKey: LocalWeatherKEY), let weathers: [Weather?] = [Weather].deserialize(from: jsons), let today = weathers.first, today?.date == todayStr { var tempWeathers: [Weather] = [] weathers.forEach { item in if let item = item { tempWeathers.append(item) } } if weathers.count > 0 { // 同步本地天气 BluetoothService.shared.setWeatherPushWithBleCmdType(weathers: tempWeathers) } return } // 获取权限 let location = CLLocationManager.locationServicesEnabled() if location { locationManager = CLLocationManager() locationManager?.delegate = self locationManager?.requestWhenInUseAuthorization() locationManager?.startUpdatingLocation() }else { showAlert(keyWindow.rootViewController!, MultiLanguageKey_FB.locationTipFB.localized, confirmText: "OK", handle: {}) } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let fristLocation = locations.first else { return } // 仅获取一次定位 locationManager?.delegate = nil // 获取天气同步 let lat = fristLocation.coordinate.latitude let lon = fristLocation.coordinate.longitude Observable.zip(ProviderRequest(APIManagerFireBoltt.getHeFengLiveWeather(lat: "\(lat)", lon: "\(lon)")).asObservable(),ProviderRequest(APIManagerFireBoltt.getHeFengForecastWeather(lat: "\(lat)", lon: "\(lon)")).asObservable()) .subscribe(onNext: { [weak self] (liveJson, forecastJson) in guard let `self` = self else { return } let liveData = liveJson["data"] let currenTemperature = liveData["tmp"].stringValue let forecastData = forecastJson["data"].arrayValue var weathers: [Weather] = [] // 当前天气 let weatherType = self.getWeatherCode(hfCode: liveData["cond_code"].stringValue) let currenData = forecastData[0] let lowTemperature = currenData["tmp_min"].stringValue let highTemperature = currenData["tmp_max"].stringValue let liveDate = currenData["date"].stringValue let currenWeather = Weather(lowTemperature: lowTemperature, highTemperature: highTemperature, currenTemperature: currenTemperature, weatherType: weatherType, date: liveDate) weathers.append(currenWeather) // 明后天天气 forecastData.enumerated().forEach { index, json in if index > 0 { let weatherType = self.getWeatherCode(hfCode: liveData["cond_code_n"].stringValue) let lowTemperature = json["tmp_min"].stringValue let highTemperature = json["tmp_max"].stringValue let date = currenData["date"].stringValue let weather = Weather(lowTemperature: lowTemperature, highTemperature: highTemperature, currenTemperature: "0", weatherType: weatherType, date: date) weathers.append(weather) } } BluetoothService.shared.setWeatherPushWithBleCmdType(weathers: weathers) // 缓存天气 kUserDefualt.set(weathers.toJSONString(), forKey: LocalWeatherKEY) }) .disposed(by: rx.disposeBag) } /// 和风天气code转协议指令code /// - Parameter hfCode: 和风天气状况code private func getWeatherCode(hfCode: String) -> Int { let codeInt = hfCode.integerValue if codeInt >= 100 && codeInt < 104 { return 0 }else if codeInt >= 104 && codeInt < 300 { return 1 }else if codeInt >= 300 && codeInt < 400 { return 2 }else if codeInt >= 400 && codeInt < 500 { return 3 } return 1 } }