WatchSharedModels.swift 6.39 KB
import Foundation
import SwiftUI
import HealthKit

extension WatchLocalTheme{
    
    func description(for state: HRVStressState) -> (title: String?, image: Image?){
        switch state {
        case .wait:
            return (state.name, state.defaultThemeImage)
        case .stressful:
            var image: Image?
            if let stressfulImage,
               let uiImage = UIImage(data: stressfulImage){
                image = Image(uiImage: uiImage)
            }
            return (stressfulDescription, image)
        case .slightStress:
            var image: Image?
            if let slightStressfulImage,
               let uiImage = UIImage(data: slightStressfulImage){
                image = Image(uiImage: uiImage)
            }
            return (slightStressfulDescription, image)
        case .normal:
            var image: Image?
            if let normalImage,
               let uiImage = UIImage(data: normalImage){
                image = Image(uiImage: uiImage)
            }
            return (normalDescription, image)
        case .energetic:
            var image: Image?
            if let energeticImage,
               let uiImage = UIImage(data: energeticImage){
                image = Image(uiImage: uiImage)
            }
            return (energeticDescription, image)
        }
    }
}

enum HRVStressState: Int, Codable, CaseIterable{
    case wait
    case stressful
    case slightStress
    case normal
    case energetic
    
    var name: String{
        switch self {
        case .wait:
            return "等待数据"
        case .stressful:
            return "压力过载"
        case .slightStress:
            return "注意压力"
        case .normal:
            return "状态正常"
        case .energetic:
            return "活力满满"
        }
    }
    
    var themeColor: Color{
        switch self {
        case .energetic:
            return DFWatchFigmaColor.green
        case .normal:
            return DFWatchFigmaColor.blue
        case .slightStress:
            return DFWatchFigmaColor.orange
        case .stressful:
            return DFWatchFigmaColor.red
        case .wait:
            return DFWatchFigmaColor.grayBar
        }
    }
    
    var defaultThemeImage: Image{
        switch self {
        case .energetic:
            return Image(.themeDefaultLevel1)
        case .normal:
            return Image(.themeDefaultLevel2)
        case .slightStress:
            return Image(.themeDefaultLevel3)
        case .stressful:
            return Image(.themeDefaultLevel4)
        case .wait:
            return Image(.themeDefaultNoData)
        }
    }
}

struct WatchHRVData: Codable {
    var latest_hrv_time: Int?
    /// 最新的hrv
    var latest_hrv: Double?
    var hrv_state: HRVStressState?
    var latest_stress_time: Int?
    /// 直接加百分号
    var latest_stress_value: Double?
    var stress_state: HRVStressState?
    
    var friend_latest_hrv_time: Int?
    var friend_latest_hrv: Double?
    var friend_hrv_state: HRVStressState?
    
    var friend_latest_stress_time: Int?
    var friend_latest_stress_value: Double?
    var friend_stress_state: HRVStressState?
    
    var myHRVData: WatchHRVPersonalData{
        return WatchHRVPersonalData(isMe: true,
                                    latest_hrv: latest_hrv,
                                    latest_hrv_time: latest_hrv_time,
                                    hrv_state: hrv_state,
                                    latest_stress_time: latest_stress_time,
                                    latest_stress_value: latest_stress_value,
                                    stress_state: stress_state
        )
    }
    var otherHRVData: WatchHRVPersonalData{
        return WatchHRVPersonalData(isMe: false,
                                    latest_hrv: friend_latest_hrv,
                                    latest_hrv_time: friend_latest_hrv_time,
                                    hrv_state: friend_hrv_state,
                                    latest_stress_time: friend_latest_stress_time,
                                    latest_stress_value: friend_latest_stress_value,
                                    stress_state: friend_stress_state
        )
    }
}
struct WatchHRVPersonalData{
    var isMe: Bool
    
    var latest_hrv: Double?
    var latest_hrv_time: Int?
    var hrv_state: HRVStressState?
    
    var latest_stress_time: Int?
    var latest_stress_value: Double?
    var stress_state: HRVStressState?
}

struct ActivityTarget: Codable  {
    var id: Int?
    var create_time: Int?
    var update_time: Int?
    var user_id: Int?
    var move: Int?
    var step: Int?
    var stand: Int?
    var exercise: Int?
    var activity_move_mode: Int?
    var active_energy_burned: Double?
    var active_energy_burned_goal: Double?
    var apple_move_time: Double?
    var apple_move_time_goal: Double?
    var apple_exercise_time: Double?
    var exercise_time_goal: Double?
    var apple_stand_hours: Double?
    var stand_hours_goal: Double?
}


extension String {
    var url: URL? {
        URL(string: self)
    }

    var int: Int? {
        Int(self)
    }
}

extension Int {
    var string: String {
        String(self)
    }

    var double: Double {
        Double(self)
    }
}

extension Double {
    var int: Int {
        Int(self)
    }
}

extension Array where Element == Double {
    func average() -> Double {
        guard !isEmpty else { return 0 }
        return reduce(0, +) / Double(count)
    }
}

struct SleepStage {
    let stage: HKCategoryValueSleepAnalysis
    let startTime: Date
    let endTime: Date
    let duration: TimeInterval
}

struct SleepData {
    let startTime: Date
    let endTime: Date
    let duration: TimeInterval
    let sleepStages: [SleepStage]
    let totalSleepTime: TimeInterval
    let sleepEfficiency: Double?
}

enum HealthDataType: Int {
    case hrv = 1
    case heartRate = 2
    case spo2 = 3
    case move = 4
    case exercise = 5
    case stand = 6
    case steps = 7
    case walkingHeartRate = 8
    case restingHeartRate = 9
    case sleepingHeartRate = 10
    case sleepingWristTemperature = 11
    case respiratoryRate = 12
    case irregularHeartRhythm = 13
}

private struct DynamicCodingKey: CodingKey {
    var stringValue: String
    var intValue: Int?

    init?(stringValue: String) {
        self.stringValue = stringValue
    }

    init?(intValue: Int) {
        self.stringValue = "\(intValue)"
        self.intValue = intValue
    }
}