using Assets.Scripts.Ble; using Assets.Scripts.Devices.Ble.Interfaces; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace Assets.Scripts.Devices.Ble.Characteristic { public class FtmsRowerData : ICharacteristic { /// /// 划桨频率 /// public uint StrokeRate { get; private set; } = 0; /// /// 划桨次数 /// public UInt16 StrokeCount { get; private set; } = 0; /// /// 平均划桨频率 /// public int AverageStrokeRate { get; private set; } = 0; public UInt32 TotalDistance { get; private set; } = 0; /// /// 即时配速 /// public UInt16 InstantaneousPace { get; private set; } = 0; /// /// 平均配速 /// public UInt16 AveragePace { get; private set; } = 0; public int InstantaneousPower { get; private set; } = 0; public int AveragePower { get; private set; } = 0; public int ResistanceLevel { get; private set; } = 0; /// /// 运行时间 /// public int ElapsedTime { get; private set; } = 0; public int TotalEnergy { get; private set; } = 0; public int EnergyPerHour { get; private set; } = 0; public int EnergyPerMinute { get; private set; } = 0; public Guid Uuid => ServiceUuids.Characteristics.RowerData; public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.Ftms).IdGuid; public bool IsOptional => false; public RowerDataFlag Flags; //拉力相关 public event EventHandler PullChanged; private ushort _pullValue; public ushort PullValue { get { return _pullValue; } set { _pullValue = value; if (this.PullChanged != null) { this.PullChanged(this, new EventArgs()); } } } public bool MoreDataFlag { get { return this.Flags.HasFlag(RowerDataFlag.MoreData); } } public void HandleAttributeReceived(byte[] data) { if (data == null || data.Length < 2) { throw new ArgumentException("数据异常" + string.Join(",", data)); } //throw new NotImplementedException(); //if(data[0] == 1) //{ // return; //} var output = ""; output += "收到消息:" + string.Join("\t", data); this.Flags = (RowerDataFlag)BitConverter.ToUInt16(data, 0); int b = 2; if (!this.MoreDataFlag) { //this.instantSpeed = new double?((double)BitConverter.ToUInt16(data, (int)b) * 0.01); this.StrokeRate = (uint)Math.Round(BitConvertHelper.ToUInt8(data, b) / 2d); b += 1; this.StrokeCount = BitConvertHelper.ToUInt16(data, b); b += 2; b += this.SizeOfDataForFlag(RowerDataFlag.MoreData); } //平均浆频 if (this.Flags.HasFlag(RowerDataFlag.AverageStrokeRate)) { var vvv = BitConvertHelper.ToUInt8(data, (int)b) / 2; //Debug.WriteLine($"平均浆频:{ vvv }"); output += $" 平均浆频:{ vvv }"; this.AverageStrokeRate = vvv; b += this.SizeOfDataForFlag(RowerDataFlag.AverageStrokeRate); //output += $" 次数:{ BitConvertHelper.ToUInt16(data, b) }"; //b += 3; } if (this.Flags.HasFlag(RowerDataFlag.TotalDistance)) { var vvv = BitConvertHelper.ToUInt24(data, (int)b); output += $" 总距离{ vvv }米"; b += this.SizeOfDataForFlag(RowerDataFlag.TotalDistance); this.TotalDistance = vvv; } if (this.Flags.HasFlag(RowerDataFlag.InstantaneousPace)) { //this.InstantCadence = new int?((int)(BitConvertHelper.ToUInt16(data, (int)b) / 2)); this.InstantaneousPace = BitConvertHelper.ToUInt16(data, b); b += this.SizeOfDataForFlag(RowerDataFlag.InstantaneousPace); } if (this.Flags.HasFlag(RowerDataFlag.AveragePace)) { this.AveragePace = BitConvertHelper.ToUInt16(data, b); b += this.SizeOfDataForFlag(RowerDataFlag.AveragePace); } if (this.Flags.HasFlag(RowerDataFlag.InstantPower)) { var power = new int?((int)BitConvertHelper.ToInt16(data, (int)b)); output += $" 功率:{ power }"; this.InstantaneousPower = power.GetValueOrDefault(0); b += this.SizeOfDataForFlag(RowerDataFlag.InstantPower); } if (this.Flags.HasFlag(RowerDataFlag.AveragePower)) { //var power = new int?((int)BitConverter.ToInt16(data, (int)b)); this.AveragePower = BitConvertHelper.ToInt16(data, b); b += this.SizeOfDataForFlag(RowerDataFlag.AveragePower); } if (this.Flags.HasFlag(RowerDataFlag.ResistanceLevel)) { this.ResistanceLevel = BitConvertHelper.ToInt16(data, b); b += this.SizeOfDataForFlag(RowerDataFlag.ResistanceLevel); } if (this.Flags.HasFlag(RowerDataFlag.ExpendedEnergy)) { this.TotalEnergy = BitConvertHelper.ToInt16(data, b); b += 2; this.EnergyPerHour = BitConvertHelper.ToInt16(data, b); b += 2; this.EnergyPerMinute = data[b]; b += 1; //b += this.SizeOfDataForFlag(RowerDataFlag.ExpendedEnergy); } if (this.Flags.HasFlag(RowerDataFlag.HeartRate)) { //this.HeartRate = new int?((int)BitConverter.ToUInt8(data, (int)b)); //(int)data[(int)b]; b += this.SizeOfDataForFlag(RowerDataFlag.HeartRate); } if (this.Flags.HasFlag(RowerDataFlag.MetabolicEquivalent)) { b += this.SizeOfDataForFlag(RowerDataFlag.MetabolicEquivalent); } if (this.Flags.HasFlag(RowerDataFlag.ElapsedTime)) { this.ElapsedTime = BitConvertHelper.ToInt16(data, b); b += this.SizeOfDataForFlag(RowerDataFlag.ElapsedTime); } if (this.Flags.HasFlag(RowerDataFlag.RemainingTime)) { b += this.SizeOfDataForFlag(RowerDataFlag.RemainingTime); } if (this.Flags.HasFlag(RowerDataFlag.Pull)) { List list = new List(); for (int pullB = 4; pullB < data.Length; pullB += 2) { var val = BitConverter.ToUInt16(data, pullB); list.Add(val); PullValue = val; } Debug.Log("拉力:" + string.Join(",",list)); } //Debug.Log("原始数据:" + string.Join(",", data)); } public void Reset() { this.StrokeRate = 0; this.StrokeCount = 0; this.AverageStrokeRate = 0; this.TotalDistance = 0; this.InstantaneousPace = 0; this.AveragePace = 0; this.InstantaneousPower = 0; this.AveragePower = 0; this.ResistanceLevel = 0; this.TotalEnergy = 0; this.EnergyPerHour = 0; this.EnergyPerMinute = 0; this.ElapsedTime = 0; } public int SizeOfDataForFlag(RowerDataFlag flag) { int num = 0; switch (flag) { //case RowerDataFlag.MoreData: // break; case RowerDataFlag.AverageStrokeRate: num = 1; break; case RowerDataFlag.TotalDistance: num = 3; break; case RowerDataFlag.InstantaneousPace: num = 2; break; case RowerDataFlag.AveragePace: num = 2; break; case RowerDataFlag.InstantPower: num = 2; break; case RowerDataFlag.AveragePower: num = 2; break; case RowerDataFlag.ResistanceLevel: num = 2; break; case RowerDataFlag.ExpendedEnergy: num = 5; break; case RowerDataFlag.HeartRate: num = 1; break; case RowerDataFlag.MetabolicEquivalent: num = 1; break; case RowerDataFlag.ElapsedTime: num = 2; break; case RowerDataFlag.RemainingTime: num = 2; break; default: break; } return num; } public void SetUnavailable() { //throw new NotImplementedException(); } //254 0是前七字節 1 41是第二包 1 64是拉力 [Flags] public enum RowerDataFlag { MoreData = 1, AverageStrokeRate = 2, TotalDistance = 4, InstantaneousPace = 8, AveragePace = 16, InstantPower = 32, AveragePower = 64, ResistanceLevel = 128, ExpendedEnergy = 256, HeartRate = 512, MetabolicEquivalent = 1024, ElapsedTime = 2048, RemainingTime = 4096, //单周期能耗 SingleEnergy = 8192, //拉力曲綫 Pull = 16384 } private byte SizeOfDataForFlag1(RowerDataFlag flag) { if (flag <= RowerDataFlag.InstantPower) { //if (flag <= RowerDataFlag.AverageCadence) //{ // if (flag - RowerDataFlag.MoreData > 1 && flag != RowerDataFlag.InstantCadence && flag != RowerDataFlag.AverageCadence) // { // return 0; // } //} //else { if (flag == RowerDataFlag.TotalDistance) { return 3; } if (flag != RowerDataFlag.ResistanceLevel && flag != RowerDataFlag.InstantPower) { return 0; } } } else if (flag <= RowerDataFlag.HeartRate) { if (flag != RowerDataFlag.AveragePower) { if (flag == RowerDataFlag.ExpendedEnergy) { return 5; } if (flag != RowerDataFlag.HeartRate) { return 0; } return 1; } } else { if (flag != RowerDataFlag.MetabolicEquivalent && flag != RowerDataFlag.ElapsedTime && flag != RowerDataFlag.RemainingTime) { return 0; } return 0; } return 2; } } }