BleMessage.swift 9.07 KB
//
//  BleMessage.swift
//  Twear
//
//  Created by yangbin on 2021/12/8.
//

import UIKit
import SwiftDate
import SwiftUI

class BleMessage: NSObject {
    static let shared = BleMessage()
    
    func getSettingCmd() -> Data {
        return getSendData(cmd: .set, key: .setting, bytes: [])
    }

    func getUserCmd(_ user: UserInfoModel) -> Data {
        let userBytes = [UInt8(user.gender), UInt8(user.age), UInt8(user.height), UInt8(user.weight), UInt8(user.stepsGoal >> 16 & 0xFF), UInt8(user.stepsGoal >> 8 & 0xFF), UInt8(user.stepsGoal & 0xFF), 0x00]
        return getSendData(cmd: .set, key: .user, bytes: userBytes)
    }
    
    func getUnitCmd(_ distance: DistanceUnit, _ temperature: TemperatureUnit) -> Data {
        return getSendData(cmd: .set, key: .unit, bytes: [distance.rawValue, temperature.rawValue])
    }
    

    
    func getTimeCmd(format: TimeFormat) -> Data {
        let date = DateInRegion().date
        let timeBytes: [UInt8] = [UInt8(date.year%100), UInt8(date.month), UInt8(date.day), UInt8(date.hour), UInt8(date.minute), UInt8(date.second), format.rawValue]
        return getSendData(cmd: .set, key: .time, bytes: timeBytes)
    }
    
    func getCameraCmd(_ open: Bool) -> Data {
        return getSendData(cmd: .device, key: open ? .openCamera : .exitCamera, bytes: [0x01])
    }
    
    func getFindCmd(_ status: Bool) -> Data {
        return getSendData(cmd: .find, key: .find_device, bytes: [])
    }
    
    func getBatteryCmd() -> Data {
        return getSendData(cmd: .device, key: .battery, bytes: [])
    }
    
    func getLanguageCmd(language: AppSettings.Language, timeFormat: TimeFormat, screenOnTime: Int, pair: UInt8) -> Data {
        if language == .system {
            return getSendData(cmd: .set, key: .language, bytes: [AppSettings.localeLanguage().cmd, timeFormat.rawValue, UInt8(screenOnTime), 0x01])
        } else {
            return getSendData(cmd: .set, key: .language, bytes: [language.cmd, timeFormat.rawValue, UInt8(screenOnTime), pair])
        }
    }
    
    
    func getWeatherCmd(_ array: [WeatherModel]) -> Data {
        var weatherBytes: [UInt8] = []
        for weather in array {
            weatherBytes.append(contentsOf: weather.toBytes())
        }
        return getSendData(cmd: .weather, key: .weather, bytes: (weatherBytes))
    }
    
    func getMessagePush(_ push: MessagePushModel) -> Data {
        return getSendData(cmd: .set, key: .push, bytes: [UInt8(push.value & 0xFF), UInt8(push.value >> 8)])
    }
    
    func getAlarmClockCmd(_ array: [AlarmClockModel]) -> Data {
        var alarmClockBytes: [UInt8] = [UInt8](repeating: 0, count: 30)
        for (i, alarm) in array.enumerated() {
            alarmClockBytes[i*5] = UInt8(alarm.date.hour)
            alarmClockBytes[i*5+1] = UInt8(alarm.date.minute)
            alarmClockBytes[i*5+2] = UInt8(alarm.cycle)
            alarmClockBytes[i*5+3] = 0x01
            alarmClockBytes[i*5+4] = alarm.isOn ? 0x01 : 0x00
        }
        return getSendData(cmd: .set, key: .alarmClock, bytes: alarmClockBytes)
    }
    
    func getDrinkWaterCmd(_ remind: RemindModel) -> Data {
        let bytes: [UInt8] = [remind.isOn ? 0x01 : 0x00, UInt8(remind.startDate.hour),  UInt8(remind.startDate.minute), UInt8(remind.endDate.hour), UInt8(remind.endDate.minute), 127, UInt8(remind.interval & 0xFF), UInt8(remind.interval >> 8)]
        return getSendData(cmd: .set, key: .drink, bytes: bytes)
    }
    
    func getSedentaryCmd(_ remind: RemindModel) -> Data {
        let target = remind.interval/60*100
        let bytes: [UInt8] = [remind.isOn ? 0x01 : 0x00, UInt8(remind.startDate.hour), UInt8(remind.endDate.hour), 127, UInt8(remind.interval & 0xFF), UInt8(remind.interval >> 8),  UInt8(target & 0xFF), UInt8(target >> 8)]
        return getSendData(cmd: .set, key: .sedentary, bytes: bytes)
    }
    
    func getNotDisturbCmd(_ remind: RemindModel) -> Data {
        let bytes: [UInt8] = [remind.isOn ? 0x01 : 0x00, UInt8(remind.startDate.hour), UInt8(remind.startDate.minute), UInt8(remind.endDate.hour), UInt8(remind.endDate.minute)]
        return getSendData(cmd: .remind, key: .disturb, bytes: bytes)
    }
    
    
    func getWristCmd(_ bool: Bool) -> Data {
        let bytes: [UInt8] = bool ? [0x01, 0x01, 0x01] : [0x00, 0x00, 0x00]
        return getSendData(cmd: .device, key: .wrist, bytes: bytes)
    }
    func getAutoMeasureCmd(_ bool: Bool) -> Data {
        let bytes: [UInt8] = bool ? [0x01] : [0x00]
        return getSendData(cmd: .device, key: .autoMeasure, bytes: bytes)
    }
    
    
    func getMenstrualCmd(_ menstrual: MenstrualCalendarModel) -> Data {
        var status: UInt8 = 0x01
        var type: MenstrualDateModel
        if menstrual.newType == nil {
            type = menstrual.type!
        } else {
            type = menstrual.newType!
        }
        switch type {
        case .menstrualPeriod:
            status = 0x04
        case .fertilePeriod:
            status = 0x02
        case .safetyPeriod:
            status = 0x01
        case .ovulationDay:
            status = 0x03
        default:
            status = 0x01
        }
        let bytes: [UInt8] = [status, UInt8(menstrual.days), UInt8(menstrual.whichDay)]
        return getSendData(cmd: .set, key: .menstrual, bytes: bytes)
    }
    func getCardCmd(_ string: String, type: Int) -> Data {
        var cardBytes: [UInt8] = [UInt8(type)]
        for (i, scalar) in string.unicodeScalars.enumerated() {
//            if i < 20 {
                cardBytes.append(UInt8(scalar.value & 0xFF))
                cardBytes.append(UInt8(scalar.value >> 8))
//            }
        }
        return getSendData(cmd: .set, key: .card, bytes: cardBytes)
    }
    
    func getPayCmd(_ string: String, type: Int) -> Data {
        var payBytes: [UInt8] = [UInt8(type)]
        for scalar in string.unicodeScalars {
            payBytes.append(UInt8(scalar.value & 0xFF))
            payBytes.append(UInt8(scalar.value >> 8))
        }
        return getSendData(cmd: .set, key: .pay, bytes: payBytes)
    }
    
    func getSyncContactsCmd(_ contacts: [ContactModel], num: Int) -> Data {
        var contactBytes: [UInt8] = []
        var startIndex: Int = 0
        var key: SetCmd = .contact1
        if num == 2 {
            startIndex = 2
            key = .contact2
        } else if num == 3 {
            startIndex = 4
            key = .contact3
        } else if num == 4 {
            startIndex = 6
            key = .battery
        }
        for (i, contact) in contacts.enumerated() {
            contactBytes.append(contentsOf: contact.toBytes(startIndex+i+1))
            print(contact.toBytes(startIndex+i+1))
        }
//        print(contactBytes)
        return getSendData(cmd: .set, key: key, bytes: contactBytes)
    }
    

    
    
    func getSyncCmd(_ type: SyncType, day: SyncDay = .today) -> Data {
        let date = DateInRegion().date + day.rawValue.days
        let syncBytes: [UInt8] = [type.rawValue, UInt8(date.year%100), UInt8(date.month), UInt8(date.day), 0x00, 0x00, 0x00]
        return getSendData(cmd: .sync, key: .sync, bytes: syncBytes)
    }
    
    func getSyncDialCmd(bytes: [UInt8]) -> Data {
        return getSendData(cmd: .set, key: .dial, bytes: bytes)
    }
    
    func getCustomDialCmd(bytes: [UInt8], color: Int, position: Int) -> Data {
        let data = getSendData(cmd: .set, key: .custom, bytes: bytes)
        var mdata = Data(repeating: 0x00, count: 120)
        mdata[0..<13] = data[0..<13]
        mdata[13] = UInt8(color)
        mdata[14] = UInt8(position)
        print([UInt8](mdata))
        return mdata
    }
    
    func getFirmwareCmd() -> Data {
        return getSendData(cmd: .firmware, key: .firmware, bytes: [])
    }
    
    
    func getSendData(cmd: BleCmd, key: SetCmd, bytes: [UInt8]) -> Data {
        let ack: UInt8 = 0
        let err: UInt8 = 0
        let version: UInt8 = 0
        let serial: UInt16 = 1

        
        if key == .custom {
            let count = bytes.count/5
            var mBytes: [UInt8] = [cmd.rawValue, 0x00, key.rawValue, UInt8(count >> 8), UInt8(count & 0xFF)]
            mBytes.append(contentsOf: bytes)
            
            let crc8 = crc8(bytes: mBytes)
            let dataLength = count + 1
            var header: [UInt8] = [0xBA, ack << 5 | err << 4 | version, UInt8(serial >> 8), UInt8(serial & 0xFF), UInt8(crc8 >> 8), UInt8(crc8 & 0xFF), UInt8(dataLength >> 8), UInt8(dataLength & 0xFF)]
            header.append(contentsOf: mBytes)
            let data = Data(bytes: header, count: header.count)
            return data
        } else {
            var mBytes: [UInt8] = [cmd.rawValue, 0x00, key.rawValue, UInt8(bytes.count >> 8), UInt8(bytes.count & 0xFF)]
            mBytes.append(contentsOf: bytes)
            
            let crc8 = crc8(bytes: mBytes)
            
            var header: [UInt8] = [0xBA, ack << 5 | err << 4 | version, UInt8(serial >> 8), UInt8(serial & 0xFF), UInt8(crc8 >> 8), UInt8(crc8 & 0xFF), UInt8(mBytes.count >> 8), UInt8(mBytes.count & 0xFF)]
            header.append(contentsOf: mBytes)
            let data = Data(bytes: header, count: header.count)
            return data
        }
 
        
    }
    
    
    
    
    
    
}