Commit 0f9754825043d57496fc678083ba1b24a3baf5a8
1 parent
6a02f533
feat:exercise
Showing
8 changed files
with
149 additions
and
1 deletions
HDFwear.xcodeproj/project.pbxproj
... | ... | @@ -285,6 +285,7 @@ |
285 | 285 | 8473FB622B4BF1A200409148 /* TaskManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8473FB612B4BF1A200409148 /* TaskManager.swift */; }; |
286 | 286 | 847482762B03793C0004F0C2 /* NewWeatherModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847482752B03793C0004F0C2 /* NewWeatherModel.swift */; }; |
287 | 287 | 847672B82B074E43007DC2DE /* NewBeiDouContactModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847672B72B074E43007DC2DE /* NewBeiDouContactModel.swift */; }; |
288 | + 8477B04C2B5A243B0018ADA8 /* NewExerciseRealtimeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8477B04B2B5A243B0018ADA8 /* NewExerciseRealtimeModel.swift */; }; | |
288 | 289 | 847AF36E2B4CF35F00E3456E /* NewSleepModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847AF36D2B4CF35F00E3456E /* NewSleepModel.swift */; }; |
289 | 290 | 847B88EF2B5780CA00851EE7 /* NewIntensiveTimeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847B88EE2B5780CA00851EE7 /* NewIntensiveTimeModel.swift */; }; |
290 | 291 | 84DA399D2B4D3A5B008D34A9 /* NewGpsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DA399C2B4D3A5B008D34A9 /* NewGpsModel.swift */; }; |
... | ... | @@ -666,6 +667,7 @@ |
666 | 667 | 8473FB612B4BF1A200409148 /* TaskManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskManager.swift; sourceTree = "<group>"; }; |
667 | 668 | 847482752B03793C0004F0C2 /* NewWeatherModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewWeatherModel.swift; sourceTree = "<group>"; }; |
668 | 669 | 847672B72B074E43007DC2DE /* NewBeiDouContactModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewBeiDouContactModel.swift; sourceTree = "<group>"; }; |
670 | + 8477B04B2B5A243B0018ADA8 /* NewExerciseRealtimeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewExerciseRealtimeModel.swift; sourceTree = "<group>"; }; | |
669 | 671 | 847AF36D2B4CF35F00E3456E /* NewSleepModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewSleepModel.swift; sourceTree = "<group>"; }; |
670 | 672 | 847B88EE2B5780CA00851EE7 /* NewIntensiveTimeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewIntensiveTimeModel.swift; sourceTree = "<group>"; }; |
671 | 673 | 847D1C4A2B009FAC0097A96E /* 20231111ReadMe.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = 20231111ReadMe.md; sourceTree = "<group>"; }; |
... | ... | @@ -1290,6 +1292,7 @@ |
1290 | 1292 | 84DA399C2B4D3A5B008D34A9 /* NewGpsModel.swift */, |
1291 | 1293 | 845ADEA02B551C8E00C3AD73 /* NewStepModel.swift */, |
1292 | 1294 | 847B88EE2B5780CA00851EE7 /* NewIntensiveTimeModel.swift */, |
1295 | + 8477B04B2B5A243B0018ADA8 /* NewExerciseRealtimeModel.swift */, | |
1293 | 1296 | ); |
1294 | 1297 | path = Model; |
1295 | 1298 | sourceTree = "<group>"; |
... | ... | @@ -1688,6 +1691,7 @@ |
1688 | 1691 | 6C34A24A276DC74000849087 /* FindBraceletVC.swift in Sources */, |
1689 | 1692 | 6C58AC51275B66930028A849 /* Sequence+Extension.swift in Sources */, |
1690 | 1693 | 6C33CC6227E182FB0081AB98 /* CustomDialOldVC.swift in Sources */, |
1694 | + 8477B04C2B5A243B0018ADA8 /* NewExerciseRealtimeModel.swift in Sources */, | |
1691 | 1695 | 6C0AE838279166B10064D377 /* InfoPlist.strings in Sources */, |
1692 | 1696 | 6CA65306278142AE0063B916 /* ShareViewController.swift in Sources */, |
1693 | 1697 | 6C6F406027434B9C00F9473C /* UIStoryboard+Extension.swift in Sources */, | ... | ... |
HDFwear/20240126ReadMe.md
... | ... | @@ -107,4 +107,25 @@ BluetoothManager+Function |
107 | 107 | 接收: [237, 126, 0, 1, 128, 41, 0, 1, 0, 8, 49, 52, 52, 57, 51, 48, 55, 49, 16, 131] |
108 | 108 | |
109 | 109 | |
110 | +发起运动交互 | |
111 | + attension:要发起完整的运动流程,步骤:发送指令1,发送指令6,摇动手表 | |
112 | + status 1、准备查看运动状态 5、运动暂停 6、运动中 7、运动结束 | |
113 | + func newSetExerciseStatus(status: Int, type: Int, completion: ((_ error: Int?) -> ())? = nil) | |
114 | + 0x8027触发BluetoothSyncDelegate中的didReceiveExerciseStatus | |
115 | + 0x8023触发BluetoothSyncDelegate中的didReceiveExerciseRealtimeData | |
116 | + 发送: [237, 126, 0, 1, 0, 56, 0, 1, 0, 2, 1, 0, 50, 163] | |
117 | + 接收: [237, 126, 0, 1, 128, 39, 0, 1, 0, 1, 8, 127, 30] | |
118 | + 发送: [237, 126, 0, 1, 0, 56, 0, 1, 0, 2, 6, 0, 171, 52] | |
119 | + 接收: [237, 126, 0, 1, 128, 39, 0, 1, 0, 1, 0, 254, 22] | |
120 | + 接收: [237, 126, 0, 1, 128, 35, 0, 1, 0, 9, 0, 0, 0, 0, 64, 0, 0, 0, 0, 227, 68] | |
121 | + 接收: [237, 126, 0, 1, 128, 35, 0, 1, 0, 9, 0, 0, 0, 0, 64, 0, 0, 0, 0, 227, 68] | |
122 | + 接收: [237, 126, 0, 1, 128, 35, 0, 1, 0, 9, 0, 0, 0, 0, 73, 0, 0, 0, 0, 75, 56] | |
123 | + 接收: [237, 126, 0, 1, 128, 35, 0, 1, 0, 9, 0, 0, 0, 0, 82, 0, 0, 0, 0, 163, 157] | |
124 | + 接收: [237, 126, 0, 1, 128, 35, 0, 1, 0, 9, 0, 0, 0, 0, 91, 0, 0, 0, 0, 11, 225] | |
125 | + 接收: [237, 126, 0, 1, 128, 35, 0, 1, 0, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 98, 246] | |
126 | + 发送: [237, 126, 0, 1, 0, 9, 0, 1, 0, 7, 24, 1, 18, 17, 5, 3, 4, 161, 6] | |
127 | + 接收: [237, 126, 0, 1, 128, 1, 0, 1, 0, 5, 0, 1, 0, 9, 0, 76, 235] | |
128 | + | |
129 | + | |
130 | + | |
110 | 131 | 接受数据类 | ... | ... |
HDFwear/Home/Model/NewExerciseRealtimeModel.swift
0 → 100644
1 | +// | |
2 | +// NewExerciseRealtimeModel.swift | |
3 | +// HDFwear | |
4 | +// | |
5 | +// Created by admin on 2024/1/19. | |
6 | +// | |
7 | + | |
8 | +import Foundation | |
9 | +import UIKit | |
10 | +import HandyJSON | |
11 | +import SwiftDate | |
12 | + | |
13 | +class NewExerciseRealtimeModel: NSObject { | |
14 | + required override init() { } | |
15 | + | |
16 | + var hr: UInt32 = 0 | |
17 | + var step: UInt32 = 0 | |
18 | + var calorie: UInt32 = 0 | |
19 | + | |
20 | + | |
21 | + override var description: String { | |
22 | + return "NewExerciseRealtimeModel: HR=\(hr), Step=\(step), Calorie=\(calorie)" | |
23 | + } | |
24 | + | |
25 | + class func toExerciseRealtimeModel(_ data: [UInt8]) -> NewExerciseRealtimeModel? { | |
26 | + guard data.count >= 9 else { | |
27 | + return nil | |
28 | + } | |
29 | + let s = NewExerciseRealtimeModel() | |
30 | + s.hr = data[0..<1].reduce(0) { ($0 << 8) + UInt32($1) } | |
31 | + s.step = data[1..<5].reduce(0) { ($0 << 8) + UInt32($1) } | |
32 | + s.calorie = data[5..<9].reduce(0) { ($0 << 8) + UInt32($1) } | |
33 | + return s; | |
34 | + } | |
35 | +} | ... | ... |
HDFwear/Mine/MineViewController.swift
... | ... | @@ -36,6 +36,7 @@ class MineViewController: UIViewController { |
36 | 36 | |
37 | 37 | override func viewDidLoad() { |
38 | 38 | super.viewDidLoad() |
39 | + BluetoothManager.shared.registerSyncDelegate(self) | |
39 | 40 | setupUI() |
40 | 41 | |
41 | 42 | |
... | ... | @@ -398,6 +399,36 @@ extension MineViewController: UITableViewDataSource, UITableViewDelegate { |
398 | 399 | } |
399 | 400 | } |
400 | 401 | |
402 | + let archiveAction28a = UIAlertAction(title: "newSetExerciseStatus 1", style: .default) { action in | |
403 | + BluetoothManager.shared.newSetExerciseStatus(status: 1, type: 0) { error in | |
404 | + if error != nil { | |
405 | + print("newSetExerciseStatus" + (error?.description ?? "")) | |
406 | + }else { | |
407 | + print("newSetExerciseStatus success") | |
408 | + } | |
409 | + } | |
410 | + } | |
411 | + | |
412 | + let archiveAction28b = UIAlertAction(title: "newSetExerciseStatus 6", style: .default) { action in | |
413 | + BluetoothManager.shared.newSetExerciseStatus(status: 6, type: 0) { error in | |
414 | + if error != nil { | |
415 | + print("newSetExerciseStatus" + (error?.description ?? "")) | |
416 | + }else { | |
417 | + print("newSetExerciseStatus success") | |
418 | + } | |
419 | + } | |
420 | + } | |
421 | + | |
422 | + let archiveAction28c = UIAlertAction(title: "newSetExerciseStatus 7", style: .default) { action in | |
423 | + BluetoothManager.shared.newSetExerciseStatus(status: 7, type: 0) { error in | |
424 | + if error != nil { | |
425 | + print("newSetExerciseStatus" + (error?.description ?? "")) | |
426 | + }else { | |
427 | + print("newSetExerciseStatus success") | |
428 | + } | |
429 | + } | |
430 | + } | |
431 | + | |
401 | 432 | alert.addAction(archiveAction0) |
402 | 433 | alert.addAction(archiveAction1) |
403 | 434 | alert.addAction(archiveAction2) |
... | ... | @@ -422,6 +453,9 @@ extension MineViewController: UITableViewDataSource, UITableViewDelegate { |
422 | 453 | alert.addAction(archiveAction25) |
423 | 454 | alert.addAction(archiveAction26) |
424 | 455 | alert.addAction(archiveAction27) |
456 | + alert.addAction(archiveAction28a) | |
457 | + alert.addAction(archiveAction28b) | |
458 | + alert.addAction(archiveAction28c) | |
425 | 459 | |
426 | 460 | alert.addAction(UIAlertAction(title: "取消", style: .destructive, handler: nil)) |
427 | 461 | present(alert, animated: true, completion: nil) |
... | ... | @@ -661,3 +695,13 @@ extension MineViewController: UITableViewDataSource, UITableViewDelegate { |
661 | 695 | present(alert, animated: true, completion: nil) |
662 | 696 | } |
663 | 697 | } |
698 | + | |
699 | +extension MineViewController: BluetoothSyncDelegate { | |
700 | + func didReceiveExerciseStatus(value: Int) { | |
701 | + showDetailAlert(msg: "ExerciseStatus is " + String(value)) | |
702 | + } | |
703 | + | |
704 | + func didReceiveExerciseRealtimeData(realtimeData: NewExerciseRealtimeModel) { | |
705 | + showDetailAlert(msg: realtimeData.description) | |
706 | + } | |
707 | +} | ... | ... |
HDFwear/Tools/BleMessage+Function.swift
... | ... | @@ -236,4 +236,9 @@ extension BleMessage { |
236 | 236 | let bytes: [UInt8] = [byte] |
237 | 237 | return createDataPacket(key: .setMessageRemind, bytes: bytes) |
238 | 238 | } |
239 | + | |
240 | + func getExerciseStatusCmd(status: Int, type: Int) -> Data { | |
241 | + let bytes: [UInt8] = [UInt8(status), UInt8(type)] | |
242 | + return createDataPacket(key: .setExerciseStatus, bytes: bytes) | |
243 | + } | |
239 | 244 | } | ... | ... |
HDFwear/Tools/Bluetooth+Types.swift
... | ... | @@ -145,7 +145,7 @@ enum NewCmd: UInt8 { |
145 | 145 | case setHeartRateDetectInterval = 0x0032 |
146 | 146 | case setBloodOxygenLowRemind = 0x0034 |
147 | 147 | case setMessageRemind = 0x0035 |
148 | - | |
148 | + case setExerciseStatus = 0x0038 | |
149 | 149 | } |
150 | 150 | |
151 | 151 | enum SyncCmd: UInt8 { |
... | ... | @@ -219,3 +219,13 @@ enum WeekFlag: UInt8 { |
219 | 219 | case friday = 5 |
220 | 220 | case saturday = 6 |
221 | 221 | } |
222 | + | |
223 | +enum ExerciseStatus: UInt8 { | |
224 | + case sunday = 0 | |
225 | + case monday = 1 | |
226 | + case tuesday = 2 | |
227 | + case wednesday = 3 | |
228 | + case thursday = 4 | |
229 | + case friday = 5 | |
230 | + case saturday = 6 | |
231 | +} | ... | ... |
HDFwear/Tools/BluetoothManager+Function.swift
... | ... | @@ -219,6 +219,15 @@ extension BluetoothManager { |
219 | 219 | sendData(data) |
220 | 220 | } |
221 | 221 | |
222 | + // 发起运动交互 | |
223 | + // 这里的status 1 与文档描述有区别,与开发确认过 | |
224 | + // status 1、准备查看运动状态 5、运动暂停 6、运动中 7、运动结束 | |
225 | + func newSetExerciseStatus(status: Int, type: Int, completion: ((_ error: Int?) -> ())? = nil) { | |
226 | + let data = BleMessage.shared.getExerciseStatusCmd(status: status, type: type) | |
227 | + self.setCmdClosure = completion | |
228 | + sendData(data) | |
229 | + } | |
230 | + | |
222 | 231 | //MARK: - 同步健康数据 |
223 | 232 | //拉取数据 |
224 | 233 | func newGetData(type:SyncType, option: SyncOption = .now, completion: ((_ error: Int?) -> ())? = nil) { |
... | ... | @@ -548,6 +557,14 @@ extension BluetoothManager { |
548 | 557 | for delegate in syncDelegateList { |
549 | 558 | delegate.didReceiveCameraCommand(status: stauts) |
550 | 559 | } |
560 | + case 0x8023:// 运动实时数据 | |
561 | + print("运动实时数据") | |
562 | + let content = parseContentFromBytes(bytes) | |
563 | + if let realtimeData = NewExerciseRealtimeModel.toExerciseRealtimeModel(content) { | |
564 | + for delegate in syncDelegateList { | |
565 | + delegate.didReceiveExerciseRealtimeData(realtimeData: realtimeData) | |
566 | + } | |
567 | + } | |
551 | 568 | case 0x8025://手表户外运动定位轨迹 |
552 | 569 | print("gps轨迹") |
553 | 570 | let content = parseContentFromBytes(bytes) |
... | ... | @@ -558,6 +575,12 @@ extension BluetoothManager { |
558 | 575 | }else { |
559 | 576 | parseGpsData(content) |
560 | 577 | } |
578 | + case 0x8027://运动状态 | |
579 | + print("运动状态") | |
580 | + let status = Int(bytes[10]) | |
581 | + for delegate in syncDelegateList { | |
582 | + delegate.didReceiveExerciseStatus(value: status) | |
583 | + } | |
561 | 584 | case 0x8028://中高强度时长 |
562 | 585 | print("中高强度时长") |
563 | 586 | let content = parseContentFromBytes(bytes) | ... | ... |
HDFwear/Tools/BluetoothManager.swift
... | ... | @@ -40,6 +40,10 @@ protocol BluetoothSyncDelegate { |
40 | 40 | func didReceiveFindPhoneCommand(value: Int) |
41 | 41 | func didReceiveCallOff() |
42 | 42 | func didReceiveCameraCommand(status: UInt8)// 0x00 进入拍照 0x01 拍照 0x02 关闭 |
43 | + func didReceiveExerciseStatus(value: Int) | |
44 | + func didReceiveExerciseRealtimeData(realtimeData: NewExerciseRealtimeModel) | |
45 | + | |
46 | + func didReceiveFinishCommand(_ receiveDataType: Int) | |
43 | 47 | } |
44 | 48 | extension BluetoothSyncDelegate { |
45 | 49 | func didReceiveFindCommand(status: Bool) { } |
... | ... | @@ -55,6 +59,8 @@ extension BluetoothSyncDelegate { |
55 | 59 | func didReceiveFindPhoneCommand(value: Int) { } |
56 | 60 | func didReceiveCallOff(){ } |
57 | 61 | func didReceiveCameraCommand(status: UInt8) { } |
62 | + func didReceiveExerciseStatus(value: Int) { } | |
63 | + func didReceiveExerciseRealtimeData(realtimeData: NewExerciseRealtimeModel) { } | |
58 | 64 | |
59 | 65 | func didReceiveFinishCommand(_ receiveDataType: Int) { } |
60 | 66 | } | ... | ... |