Commit 10c6e004c4cb6d3fe7f79bafed04059401f5a77c

Authored by jason
1 parent 5507c724

feat:sleep data

HDFwear.xcodeproj/project.pbxproj
... ... @@ -284,6 +284,7 @@
284 284 8473FB622B4BF1A200409148 /* TaskManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8473FB612B4BF1A200409148 /* TaskManager.swift */; };
285 285 847482762B03793C0004F0C2 /* NewWeatherModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847482752B03793C0004F0C2 /* NewWeatherModel.swift */; };
286 286 847672B82B074E43007DC2DE /* NewBeiDouContactModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847672B72B074E43007DC2DE /* NewBeiDouContactModel.swift */; };
  287 + 847AF36E2B4CF35F00E3456E /* NewSleepModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847AF36D2B4CF35F00E3456E /* NewSleepModel.swift */; };
287 288 B212F1FD2A14CE0400781D59 /* LaunchSetting.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B212F1FF2A14CE0400781D59 /* LaunchSetting.storyboard */; };
288 289 B212F2052A14D28E00781D59 /* LaunchMyBodySettingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B212F2042A14D28E00781D59 /* LaunchMyBodySettingVC.swift */; };
289 290 B23AA1032A1879E200BB3902 /* SortPageSectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = B23AA1022A1879E200BB3902 /* SortPageSectionHeader.xib */; };
... ... @@ -660,6 +661,7 @@
660 661 8473FB612B4BF1A200409148 /* TaskManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskManager.swift; sourceTree = "<group>"; };
661 662 847482752B03793C0004F0C2 /* NewWeatherModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewWeatherModel.swift; sourceTree = "<group>"; };
662 663 847672B72B074E43007DC2DE /* NewBeiDouContactModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewBeiDouContactModel.swift; sourceTree = "<group>"; };
  664 + 847AF36D2B4CF35F00E3456E /* NewSleepModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewSleepModel.swift; sourceTree = "<group>"; };
663 665 847D1C4A2B009FAC0097A96E /* 20231111ReadMe.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = 20231111ReadMe.md; sourceTree = "<group>"; };
664 666 847D2DE42B3D575F001BA7EF /* 20240110ReadMe.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = 20240110ReadMe.md; sourceTree = "<group>"; };
665 667 B0BDC40FAF3CBA7B780ED655 /* Pods_HDFwear.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HDFwear.framework; sourceTree = BUILT_PRODUCTS_DIR; };
... ... @@ -1276,6 +1278,7 @@
1276 1278 6C6051BD2760C0CB00286B37 /* WeatherModel.swift */,
1277 1279 847482752B03793C0004F0C2 /* NewWeatherModel.swift */,
1278 1280 847672B72B074E43007DC2DE /* NewBeiDouContactModel.swift */,
  1281 + 847AF36D2B4CF35F00E3456E /* NewSleepModel.swift */,
1279 1282 );
1280 1283 path = Model;
1281 1284 sourceTree = "<group>";
... ... @@ -1610,6 +1613,7 @@
1610 1613 B279A37A2A4AC2F800A7C7B6 /* BluetoothManager+Function.swift in Sources */,
1611 1614 6C411EE1275DF6F3009B2E02 /* Data+Extension.swift in Sources */,
1612 1615 6C80835927F698B700C13EB2 /* BackgroundProtectionVC.swift in Sources */,
  1616 + 847AF36E2B4CF35F00E3456E /* NewSleepModel.swift in Sources */,
1613 1617 6C6F405C27434AC500F9473C /* ZCNavigationController.swift in Sources */,
1614 1618 6C41D0BE275F5DAD00747BE4 /* LoaderButtonAnimationDelegate.swift in Sources */,
1615 1619 6C41D0BC275F5DAD00747BE4 /* LoaderBallPulseRotateAnimation.swift in Sources */,
... ...
HDFwear/20240110ReadMe.md
... ... @@ -94,3 +94,9 @@ BluetoothManager+Function
94 94 压力数据
95 95 func parsePressureData (_ content: [UInt8])
96 96 接收: [237, 126, 0, 1, 128, 32, 0, 1, 0, 0, 172, 113]
  97 +
  98 +睡眠数据
  99 + func parseSleepData (_ content: [UInt8])
  100 + 发送: [237, 126, 0, 1, 0, 40, 0, 1, 0, 2, 6, 1, 140, 110]
  101 + 接收: [237, 126, 0, 1, 128, 25, 0, 0, 0, 77, 3, 7, 9, 101, 120, 119, 200, 0, 0, 14, 16, 10, 101, 120, 133, 216, 0, 0, 14, 16, 8, 101, 120, 147, 232, 0, 0, 14, 16, 7, 101, 120, 161, 248, 0, 0, 14, 16, 9, 101, 120, 176, 8, 0, 0, 14, 16, 10, 101, 120, 190, 24, 0, 0, 14, 16, 9, 101, 120, 204, 40, 0, 0, 14, 16, 101, 121, 46, 152, 101, 121, 60, 168, 0, 0, 14, 16, 224, 73]
  102 + 接收: [237, 126, 0, 1, 128, 25, 0, 1, 0, 1, 255, 79, 201]
... ...
HDFwear/Home/HomeViewController.swift
... ... @@ -770,9 +770,9 @@ extension HomeViewController: XMLParserDelegate {
770 770 if queryArray.contains("Sleep"), let index = queryArray.firstIndex(of: "Sleep") {
771 771 BluetoothManager.shared.getSleepHistoryData() {[weak self] sleepArray, error in
772 772 self?.queryArray.remove(at: index)
773   - if error == nil {
774   - SleepModel.addArray(sleepArray)
775   - }
  773 +// if error == nil {
  774 +// SleepModel.addArray(sleepArray)
  775 +// }
776 776 self?.syncPressure(day)
777 777 }
778 778 } else {
... ...
HDFwear/Home/Model/NewSleepModel.swift 0 → 100644
  1 +import UIKit
  2 +import HandyJSON
  3 +import SwiftDate
  4 +
  5 +enum NewSleepType: UInt8 {
  6 + case nightSleep = 1
  7 + case shortNap = 2
  8 + case nightSleepAndNap = 3
  9 +}
  10 +
  11 +enum NewSleepStatus: UInt8 {
  12 + case awake = 7
  13 + case rapidEyeMovement = 8
  14 + case lightSleep = 9
  15 + case deepSleep = 10
  16 +}
  17 +
  18 +class NewSleepModel: NSObject {
  19 + required override init() { }
  20 +
  21 + struct SleepFragment {
  22 + var sleepStatus: NewSleepStatus
  23 + var startTime: Date?
  24 + var duration: UInt32
  25 + }
  26 +
  27 + struct NapFragment {
  28 + var startTime: Date?
  29 + var endTime: Date?
  30 + var duration: UInt32
  31 + }
  32 +
  33 + var sleepType: NewSleepType = .nightSleep
  34 + var sleepFragmentCount: Int = 0
  35 + var sleepFragments: [SleepFragment] = []
  36 + var napFragments: [NapFragment] = []
  37 +
  38 + init(sleepType: NewSleepType, sleepFragmentCount: Int, sleepFragments: [SleepFragment], napFragments: [NapFragment]) {
  39 + self.sleepType = sleepType
  40 + self.sleepFragmentCount = sleepFragmentCount
  41 + self.sleepFragments = sleepFragments
  42 + self.napFragments = napFragments
  43 + }
  44 +
  45 + class func toSleepModel(_ data: [UInt8]) -> NewSleepModel {
  46 + let sleepModel = NewSleepModel()
  47 + guard data.count >= 1 else {
  48 + return sleepModel // 数据长度不够
  49 + }
  50 + sleepModel.sleepType = NewSleepType(rawValue:data[0]) ?? .nightSleep
  51 + switch sleepModel.sleepType {
  52 + case .nightSleep:
  53 + sleepModel.sleepFragmentCount = Int(data[1])
  54 + guard data.count >= 2 + 9 * sleepModel.sleepFragmentCount else {
  55 + return sleepModel
  56 + }
  57 + sleepModel.sleepFragments = sleepModel.parseNightSleepData(data: Array(data[2..<2 + 9 * sleepModel.sleepFragmentCount]))
  58 + case .shortNap:
  59 + sleepModel.napFragments = sleepModel.parseNapData(data: Array(data[2..<data.count]))
  60 + case .nightSleepAndNap:
  61 + sleepModel.sleepFragmentCount = Int(data[1])
  62 + guard data.count >= 2 + 9 * sleepModel.sleepFragmentCount else {
  63 + return sleepModel
  64 + }
  65 + sleepModel.sleepFragments = sleepModel.parseNightSleepData(data: Array(data[2..<2 + 9 * sleepModel.sleepFragmentCount]))
  66 + sleepModel.napFragments = sleepModel.parseNapData(data: Array(data[2 + 9 * sleepModel.sleepFragmentCount..<data.count]))
  67 + default:
  68 + break
  69 + }
  70 + return sleepModel
  71 + }
  72 +
  73 + func parseNightSleepData(data: [UInt8]) -> [SleepFragment] {
  74 + // 解析 SleepFragment 数组
  75 + var sleepFragments = [SleepFragment]()
  76 + // 将数组分成9个一组
  77 + for index in stride(from: 0, to: data.count, by: 9) {
  78 + let sleepStatus = NewSleepStatus(rawValue: data[index]) ?? .awake
  79 + let rawStartTime = UInt32(data[index + 1]) |
  80 + (UInt32(data[index + 2]) << 8) |
  81 + (UInt32(data[index + 3]) << 16) |
  82 + (UInt32(data[index + 4]) << 24)
  83 + let startTimeInterval = TimeInterval(rawStartTime)
  84 + let startTime = Date(timeIntervalSince1970: startTimeInterval)
  85 + let duration = UInt32(data[index + 5]) | (UInt32(data[index + 6]) << 8) | (UInt32(data[index + 7]) << 16) | (UInt32(data[index + 8]) << 24)
  86 +
  87 + let fragment = SleepFragment(sleepStatus: sleepStatus, startTime: startTime, duration: duration)
  88 + sleepFragments.append(fragment)
  89 + }
  90 + return sleepFragments
  91 + }
  92 +
  93 + func parseNapData(data: [UInt8]) -> [NapFragment] {
  94 + // 解析 NapFragment 数组
  95 + var napFragments = [NapFragment]()
  96 + // 将数组分成12个一组
  97 + for index in stride(from: 0, to: data.count, by: 12) {
  98 + let startTime = Date(timeIntervalSince1970: TimeInterval(UInt32(data[index]) | UInt32(data[index + 1]) << 8 | UInt32(data[index + 2]) << 16 | UInt32(data[index + 3]) << 24))
  99 + let endTime = Date(timeIntervalSince1970: TimeInterval(UInt32(data[index + 4]) | UInt32(data[index + 5]) << 8 | UInt32(data[index + 6]) << 16 | UInt32(data[index + 7]) << 24))
  100 + let duration = UInt32(data[index + 8]) | UInt32(data[index + 9]) << 8 | UInt32(data[index + 10]) << 16 | UInt32(data[index + 11]) << 24
  101 +
  102 + let napFragment = NapFragment(startTime: startTime, endTime: endTime, duration: duration)
  103 + napFragments.append(napFragment)
  104 + }
  105 + return napFragments
  106 + }
  107 +}
... ...
HDFwear/Mine/MineViewController.swift
... ... @@ -434,12 +434,11 @@ extension MineViewController: UITableViewDataSource, UITableViewDelegate {
434 434 let alert = UIAlertController(title: "plz select fetch type", message: nil, preferredStyle: .actionSheet)
435 435  
436 436 let archiveAction9 = UIAlertAction(title: "getSleepHistoryData", style: .default) { action in
437   - BluetoothManager.shared.getSleepHistoryData() { sleepArray, error in
  437 + BluetoothManager.shared.getSleepHistoryData(option: .now) { sleepModel, error in
438 438 if error != nil {
439 439 print("getSleepHistoryData" + (error?.description ?? ""))
440 440 }else {
441 441 print("getSleepHistoryData success")
442   - SleepModel.addArray(sleepArray)
443 442 }
444 443 }
445 444 }
... ...
HDFwear/Tools/BleMessage+Function.swift
... ... @@ -124,8 +124,8 @@ extension BleMessage {
124 124 return createDataPacket(key: .setNoDisturb, bytes: bytes)
125 125 }
126 126  
127   - func getSyncCmd(_ type: SyncType) -> Data {
128   - let bytes: [UInt8] = [type.rawValue]
  127 + func getSyncCmd(_ type: SyncType, _ option:SyncOption = .now) -> Data {
  128 + let bytes: [UInt8] = [type.rawValue, option.rawValue]
129 129 return createDataPacket(key: .setSynWatch, bytes: bytes)
130 130 }
131 131  
... ...
HDFwear/Tools/Bluetooth+Types.swift
... ... @@ -180,6 +180,11 @@ enum SyncType: UInt8 {
180 180 case other = 0xff
181 181 }
182 182  
  183 +enum SyncOption: UInt8 {
  184 + case now = 0x01
  185 + case history = 0x02
  186 +}
  187 +
183 188 enum SyncDay: Int {
184 189 case today = 0
185 190 case yesterday = -1
... ...
HDFwear/Tools/BluetoothManager+Function.swift
... ... @@ -212,57 +212,57 @@ extension BluetoothManager {
212 212  
213 213 //MARK: - 同步健康数据
214 214 //拉取数据
215   - func newGetData(type:SyncType, completion: ((_ error: Int?) -> ())? = nil) {
216   - let data = BleMessage.shared.getSyncCmd(type)
  215 + func newGetData(type:SyncType, option: SyncOption = .now, completion: ((_ error: Int?) -> ())? = nil) {
  216 + let data = BleMessage.shared.getSyncCmd(type, option)
217 217 self.setCmdClosure = completion
218 218 sendData(data)
219 219 }
220 220  
221 221 // 拉取电量数据
222   - func newGetBatteryData( completion: ((_ error: Int?) -> ())? = nil) {
223   - newGetData(type: .battery, completion: completion)
  222 + func newGetBatteryData(option: SyncOption = .now, completion: ((_ error: Int?) -> ())? = nil) {
  223 + newGetData(type: .battery, option: option, completion: completion)
224 224 }
225 225  
226 226 // 拉取GPS轨迹数据
227 227 //jtd! 需要使用特定的回调,这样才能够直接把数据回调出来
228   - func newGetGpsData( completion: ((_ error: Int?) -> ())? = nil) {
229   - newGetData(type: .gps, completion: completion)
  228 + func newGetGpsData(option: SyncOption = .now, completion: ((_ error: Int?) -> ())? = nil) {
  229 + newGetData(type: .gps, option: option, completion: completion)
230 230 }
231 231  
232   - //MARK: - history
  232 + //MARK: - old code
233 233 // 拉取睡眠数据
234   - func getSleepHistoryData( closure: SleepClosure? = nil) {
235   - let data = BleMessage.shared.getSyncCmd(.sleep)
  234 + func getSleepHistoryData(option: SyncOption = .now, closure: SleepClosure? = nil) {
  235 + let data = BleMessage.shared.getSyncCmd(.sleep, option)
236 236 newStartSyncHealthData(closure: closure, data: data, synType: .sleep)
237 237 }
238 238  
239 239 // 拉取血氧数据
240   - func getBloodOxygenHistoryData( closure: BloodOxygenClosure? = nil) {
241   - let data = BleMessage.shared.getSyncCmd(.bloodOxygen)
  240 + func getBloodOxygenHistoryData(option: SyncOption = .now, closure: BloodOxygenClosure? = nil) {
  241 + let data = BleMessage.shared.getSyncCmd(.bloodOxygen, option)
242 242 newStartSyncHealthData(closure: closure, data: data, synType: .bloodOxygen)
243 243 }
244 244  
245 245 // 拉取心跳数据
246   - func getHeartRateHistoryData( closure: HeartRateClosure? = nil) {
247   - let data = BleMessage.shared.getSyncCmd(.heartRate)
  246 + func getHeartRateHistoryData(option: SyncOption = .now, closure: HeartRateClosure? = nil) {
  247 + let data = BleMessage.shared.getSyncCmd(.heartRate, option)
248 248 newStartSyncHealthData(closure: closure, data: data, synType: .heartRate)
249 249 }
250 250  
251 251 // 拉取计步数据
252   - func getStepHistoryData( closure: StepClosure? = nil) {
253   - let data = BleMessage.shared.getSyncCmd(.step)
  252 + func getStepHistoryData(option: SyncOption = .now, closure: StepClosure? = nil) {
  253 + let data = BleMessage.shared.getSyncCmd(.step, option)
254 254 newStartSyncHealthData(closure: closure, data: data, synType: .step)
255 255 }
256 256  
257 257 // 拉取训练数据
258   - func getTrainHistoryData( closure: TrainClosure? = nil) {
259   - let data = BleMessage.shared.getSyncCmd(.train)
  258 + func getTrainHistoryData(option: SyncOption = .now, closure: TrainClosure? = nil) {
  259 + let data = BleMessage.shared.getSyncCmd(.train, option)
260 260 newStartSyncHealthData(closure: closure, data: data, synType: .train)
261 261 }
262 262  
263 263 // 拉取压力数据
264   - func getPressureHistoryData( closure: PressureClosure? = nil) {
265   - let data = BleMessage.shared.getSyncCmd(.pressure)
  264 + func getPressureHistoryData(option: SyncOption = .now, closure: PressureClosure? = nil) {
  265 + let data = BleMessage.shared.getSyncCmd(.pressure, option)
266 266 newStartSyncHealthData(closure: closure, data: data, synType: .pressure)
267 267 }
268 268  
... ... @@ -300,7 +300,7 @@ extension BluetoothManager {
300 300 case is SleepClosure:
301 301 if sleepClosure == nil {
302 302 sleepClosure = closure as? SleepClosure
303   - sleepClosure?([], -1002)
  303 + sleepClosure?(nil, -1002)
304 304 sleepClosure = nil
305 305 }
306 306 case is StepClosure:
... ... @@ -447,7 +447,13 @@ extension BluetoothManager {
447 447 case 0x8019:// 睡眠数据上报
448 448 print("睡眠数据上报")
449 449 let content = parseContentFromBytes(bytes)
450   - parseSleepData(content)
  450 + if (content.first == 0xff) {
  451 + for delegate in syncDelegateList {
  452 + delegate.didReceiveFinishCommand(0x8019)
  453 + }
  454 + }else {
  455 + parseSleepData(content)
  456 + }
451 457 case 0x8020:// 历史压力数据上报
452 458 print("历史压力数据上报")
453 459 let content = parseContentFromBytes(bytes)
... ... @@ -617,12 +623,11 @@ extension BluetoothManager {
617 623 func parseSleepData (_ content: [UInt8]) {
618 624 guard content.count > 0 else {
619 625 print("无有效的信息")
620   - sleepClosure?([], nil)
  626 + sleepClosure?(nil, nil)
621 627 return
622 628 }
623   - let array = SleepModel.toSleepArray(content)
624   - SleepModel.addArray(array)// 加入数据库
625   - sleepClosure?(array, nil)
  629 + let model = NewSleepModel.toSleepModel(content)
  630 + sleepClosure?(model, nil)
626 631 }
627 632  
628 633 // 实时步数,卡路里,距离数据
... ...
HDFwear/Tools/BluetoothManager.swift
... ... @@ -55,6 +55,8 @@ extension BluetoothSyncDelegate {
55 55 func didReceiveFindPhoneCommand(value: Int) { }
56 56 func didReceiveCallOff(){ }
57 57 func didReceiveCameraCommand(status: UInt8) { }
  58 +
  59 + func didReceiveFinishCommand(_ receiveDataType: Int) { }
58 60 }
59 61  
60 62  
... ... @@ -81,7 +83,7 @@ class BluetoothManager: NSObject {
81 83 var bloodPressureClosure: BloodPressureClosure?
82 84 typealias BloodOxygenClosure = (_ boArray: [BloodOxygenModel], _ error: Int?) -> Void
83 85 var bloodOxygenClosure: BloodOxygenClosure?
84   - typealias SleepClosure = (_ sleepArray: [SleepModel], _ error: Int?) -> Void
  86 + typealias SleepClosure = (_ sleepModel: NewSleepModel?, _ error: Int?) -> Void
85 87 var sleepClosure: SleepClosure?
86 88 typealias StepClosure = (_ stepArray: [StepModel], _ error: Int?) -> Void
87 89 var stepClosure: StepClosure?
... ... @@ -1271,7 +1273,7 @@ class BluetoothManager: NSObject {
1271 1273 heartRateClosure?([], -1001)
1272 1274 bloodPressureClosure?([], -1001)
1273 1275 bloodOxygenClosure?([], -1001)
1274   - sleepClosure?([], -1001)
  1276 + sleepClosure?(nil, -1001)
1275 1277 stepClosure?([], -1001)
1276 1278 trainClosure?(nil, -1001)
1277 1279 pressureClosure?([], -1001)
... ...