// // 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 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 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 = 5 key = .contact3 } 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]) -> Data { let data = getSendData(cmd: .set, key: .custom, bytes: bytes) var mdata = Data(repeating: 0x00, count: 120) mdata[0..<13] = data[0..<13] 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 } } }