Commit 0f9754825043d57496fc678083ba1b24a3baf5a8

Authored by jason
1 parent 6a02f533

feat:exercise

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 }
... ...