接入基本设备

This commit is contained in:
suntao committed 2021-06-04 13:22:59 +08:00
1 parent 2f84f70a5f
commit 7729332f41
62 files changed
+2880 -86

No files matched your search

@@ -0,0 +1,49 @@
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 BatteryLevel : ICharacteristic
{
public Guid Uuid => ServiceUuids.Characteristics.BatteryLevel;
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.Battery).IdGuid;
private ICharacteristic _characteristicUnavailable = null;
public ICharacteristic CharacteristicUnavailable
{
get
{
return this._characteristicUnavailable;
}
}
public virtual bool IsOptional
{
get
{
return true;
}
}
public int BatteryLevelValue { get; private set; }
public void HandleAttributeReceived(byte[] data)
{
BatteryLevelValue = (int)data[0];
Debug.Log($"电量:{ BatteryLevelValue }");
}
public void SetUnavailable()
{
this._characteristicUnavailable = this;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b654b3a52c37e6f47b9823953c8fd5d1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
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;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
public class CyclingPowerMeasurement: ICharacteristic
{
public Guid Uuid
{
get
{
return ServiceUuids.Characteristics.CyclingPowerMeasurement;
}
}
public Guid ServiceUuid
{
get
{
return ServiceUuids.Get(ServiceUuids.CyclingPower).IdGuid;
}
}
public virtual bool IsOptional
{
get
{
return false;
}
}
private double wheelCircumference;
public int Power { get; private set; }
public CyclingPowerMeasurement(double wheelCircumference)
{
this.wheelCircumference = wheelCircumference;
}
public void HandleAttributeReceived(byte[] data)
{
this.Power = BitConverter.ToInt16(data, 2);
}
public void SetUnavailable()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b0646295dbaa0a4e951de9bd391e475
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,271 @@
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;
using Assets.Scripts.Devices.Ble.Extension;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
public class CyclingSpeedCadenceMeasurement : ICharacteristic
{
private CyclingSpeedCadenceMeasurement.IUpdate _currentUpdate;
private CyclingSpeedCadenceMeasurement.IUpdate _previousUpdate = new CyclingSpeedCadenceMeasurement.NullUpdate();
private const byte MaxNoEvents = (byte)4;
private byte _noCadenceEventCount;
private byte _noSpeedEventCount;
public Guid Uuid => ServiceUuids.Characteristics.CscMeasurement;
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.CyclingSpeedCadence).IdGuid;
public bool IsOptional => false;
public double Speed { get; private set; }
public int Cadence { get; private set; }
public double WheelCircumference { private get; set; }
public CyclingSpeedCadenceMeasurement(double wheelCircumference)
{
this.WheelCircumference = wheelCircumference;
}
public void HandleAttributeReceived(byte[] data)
{
//throw new NotImplementedException();
//Debug.Log(string.Join(",", data));
this._currentUpdate = new CyclingSpeedCadenceMeasurement.Update(data);
this.HandleCadenceUpdate();
this.HandleSpeedUpdate();
this._previousUpdate = this._currentUpdate;
}
private void HandleCadenceUpdate()
{
if (this._currentUpdate.HasCadence && (int)this._currentUpdate.CadenceEventCount != (int)this._previousUpdate.CadenceEventCount)
{
this._noCadenceEventCount = (byte)0;
if (this.CadenceTimeDifference() <= 0)
return;
this.Cadence = this.CalculateCadence();
}
else
{
this._noCadenceEventCount = (byte)((uint)this._noCadenceEventCount + 1U);
if ((int)this._noCadenceEventCount < 4)
return;
this.Cadence = 0;
}
}
private void HandleSpeedUpdate()
{
if (this._currentUpdate.HasSpeed && (int)this._currentUpdate.SpeedEventCount != (int)this._previousUpdate.SpeedEventCount)
{
this._noSpeedEventCount = (byte)0;
double num = this.CalculateSpeed();
if (num >= 150.0)
return;
this.Speed = num;
}
else
{
this._noSpeedEventCount = (byte)((uint)this._noSpeedEventCount + 1U);
if ((int)this._noSpeedEventCount < 4)
return;
this.Speed = 0.0;
}
}
private int CalculateCadence()
{
int num = this.CadenceEventDifference() * 61440 / this.CadenceTimeDifference();
if (num > (int)byte.MaxValue)
return (int)byte.MaxValue;
if (num < 0)
return 0;
return num;
}
private int CadenceTimeDifference()
{
if ((int)this._currentUpdate.CadenceTime1024 > (int)this._previousUpdate.CadenceTime1024)
return (int)this._currentUpdate.CadenceTime1024 - (int)this._previousUpdate.CadenceTime1024;
return (int)ushort.MaxValue - (int)this._previousUpdate.CadenceTime1024 + (int)this._currentUpdate.CadenceTime1024 + 1;
}
private int CadenceEventDifference()
{
if ((int)this._currentUpdate.CadenceEventCount > (int)this._previousUpdate.CadenceEventCount)
return (int)this._currentUpdate.CadenceEventCount - (int)this._previousUpdate.CadenceEventCount;
return (int)ushort.MaxValue - (int)this._previousUpdate.CadenceEventCount + (int)this._currentUpdate.CadenceEventCount + 1;
}
private double CalculateSpeed()
{
double num = (double)(ulong)(this.WheelCircumference / 10.0 * 36864.0 * (double)this.SpeedEventDifference() / (double)this.SpeedTimeDifference()) / 1000.0;
if (num >= 0.0)
return num;
return 0.0;
}
private int SpeedTimeDifference()
{
if ((int)this._currentUpdate.SpeedTime1024 > (int)this._previousUpdate.SpeedTime1024)
return (int)this._currentUpdate.SpeedTime1024 - (int)this._previousUpdate.SpeedTime1024;
return (int)ushort.MaxValue - (int)this._previousUpdate.SpeedTime1024 + (int)this._currentUpdate.SpeedTime1024 + 1;
}
private uint SpeedEventDifference()
{
if (this._currentUpdate.SpeedEventCount > this._previousUpdate.SpeedEventCount)
return this._currentUpdate.SpeedEventCount - this._previousUpdate.SpeedEventCount;
return (uint)(-1 - (int)this._previousUpdate.SpeedEventCount + (int)this._currentUpdate.SpeedEventCount + 1);
}
public void SetUnavailable()
{
//throw new NotImplementedException();
}
private interface IUpdate
{
bool HasCadence { get; }
bool HasSpeed { get; }
uint SpeedEventCount { get; }
ushort SpeedTime1024 { get; }
ushort CadenceEventCount { get; }
ushort CadenceTime1024 { get; }
}
private class Update : CyclingSpeedCadenceMeasurement.IUpdate
{
private static readonly byte WheelRevolutionsFlagBit = (byte)0;
private static readonly byte CrankRevolutionsFlagBit = (byte)1;
private readonly byte[] _data;
private byte Flags
{
get
{
return this._data[0];
}
}
public bool HasCadence
{
get
{
return PrimitiveExtensions.IsBitSet(this.Flags, (int)CyclingSpeedCadenceMeasurement.Update.CrankRevolutionsFlagBit);
}
}
public bool HasSpeed
{
get
{
return PrimitiveExtensions.IsBitSet(this.Flags, (int)CyclingSpeedCadenceMeasurement.Update.WheelRevolutionsFlagBit);
}
}
public uint SpeedEventCount
{
get
{
return BitConvertHelper.ToUInt32(this._data, 1);
}
}
public ushort SpeedTime1024
{
get
{
return BitConvertHelper.ToUInt16(this._data, 5);
}
}
public ushort CadenceEventCount
{
get
{
return BitConvertHelper.ToUInt16(this._data, this.HasSpeed ? 7 : 1);
}
}
public ushort CadenceTime1024
{
get
{
return BitConvertHelper.ToUInt16(this._data, this.HasSpeed ? 9 : 3);
}
}
public Update(byte[] data)
{
this._data = data;
}
}
private class NullUpdate : CyclingSpeedCadenceMeasurement.IUpdate
{
public bool HasCadence
{
get
{
return false;
}
}
public bool HasSpeed
{
get
{
return false;
}
}
public uint SpeedEventCount
{
get
{
return 0U;
}
}
public ushort SpeedTime1024
{
get
{
return (ushort)0;
}
}
public ushort CadenceEventCount
{
get
{
return (ushort)0;
}
}
public ushort CadenceTime1024
{
get
{
return (ushort)0;
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0ea4d73295288ad4a9f561a37246110a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,45 @@
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;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
public class FtmsFitnessMachineFeature : ICharacteristic
{
public Guid Uuid => ServiceUuids.Characteristics.FitnessMachineFeature;
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.Ftms).IdGuid;
public bool IsOptional => false;
public bool IsInclinationSupported
{
get; private set;
}
public bool IsInclinationTargetSettingSupported
{
get; private set;
}
public void HandleAttributeReceived(byte[] data)
{
//throw new NotImplementedException();
if (data.Length != 8)
return;
this.IsInclinationSupported = ByteExtensions.IsFlagSet(data[0], (byte)8);
//this.ResistanceLevelSupported = ByteExtensions.IsFlagSet(data[0], sbyte.MinValue);
this.IsInclinationTargetSettingSupported = ByteExtensions.IsFlagSet(data[4], 2);
}
public void SetUnavailable()
{
//throw new NotImplementedException();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c6095c96152da4c47870708061e1d5ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,220 @@
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;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
public class FtmsIndoorBikeData : ICharacteristic
{
private readonly ushort? _instantSpeedSubject = new ushort?();
private readonly ushort? _averageSpeedSubject = new ushort?();
private readonly ushort? _instantCadenceSubject = new ushort?();
private readonly ushort? _averageCadenceSubject = (new ushort?());
private readonly uint? _totalDistanceSubject = (new uint?());
private readonly short? _resistanceLevelSubject = (new short?());
private readonly short? _instantPowerSubject = (new short?());
private readonly short? _averagePowerSubject = (new short?());
private readonly ushort? _totalEnergySubject = (new ushort?());
private readonly ushort? _energyPerHourSubject = (new ushort?());
private readonly byte? _energyPerMinuteSubject = (new byte?());
private readonly byte? _heartRateSubject = (new byte?());
private readonly byte? _metabolicEquivalentSubject = (new byte?());
private readonly ushort? _elapsedTimeSubject = (new ushort?());
private readonly ushort? _remainingTimeSubject = (new ushort?());
public short? InstantPower
{
get
{
return this._instantPowerSubject;
}
}
public ushort? InstantCadence
{
get
{
return this._instantCadenceSubject;
}
}
public ushort? InstantSpeed
{
get
{
return this._instantSpeedSubject;
}
}
public Guid Uuid => ServiceUuids.Characteristics.IndoorBikeData;
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.Ftms).IdGuid;
public bool IsOptional => false;
public void HandleAttributeReceived(byte[] data)
{
if(data.Length < 2)
{
return;
}
List<FtmsIndoorBikeData.IndoorBikeDataField> list = new List<FtmsIndoorBikeData.IndoorBikeDataField>();
if (!ByteExtensions.IsFlagSetAtPosition(data[0], (byte)0))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousSpeed);
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)1))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.AverageSpeed);
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)2))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousCadence);
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)3))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.AverageCadence);
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)4))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.TotalDistance);
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)5))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.ResistanceLevel);
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)6))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousPower);
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)7))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.AveragePower);
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)0))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.ExpendedEnergy);
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)1))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.HeartRate);
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)2))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.MetabolicEquivalent);
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)3))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.ElapsedTime);
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)4))
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.RemainingTime);
int offset = 2;
foreach (FtmsIndoorBikeData.IndoorBikeDataField field in list)
offset += this.ParseField(data, offset, field);
}
public void SetUnavailable()
{
//throw new NotImplementedException();
}
private int ParseField(byte[] attribute, int offset, FtmsIndoorBikeData.IndoorBikeDataField field)
{
int fieldSize = FtmsIndoorBikeData.GetFieldSize(field);
if (attribute.Length < fieldSize + offset)
throw new ArgumentException("attribute");
switch (field)
{
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousSpeed:
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._instantSpeedSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.AverageSpeed:
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._averageSpeedSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousCadence:
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._instantCadenceSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.AverageCadence:
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._averageCadenceSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.TotalDistance:
ICharacteristicExtensions.HandleUint24AttributeValue((ICharacteristic)this, attribute, offset, this._totalDistanceSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.ResistanceLevel:
ICharacteristicExtensions.HandleShortAttributeValue((ICharacteristic)this, attribute, offset, this._resistanceLevelSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousPower:
ICharacteristicExtensions.HandleShortAttributeValue((ICharacteristic)this, attribute, offset, this._instantPowerSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.AveragePower:
ICharacteristicExtensions.HandleShortAttributeValue((ICharacteristic)this, attribute, offset, this._averagePowerSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.ExpendedEnergy:
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._totalEnergySubject);
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset + 2, this._energyPerHourSubject);
ICharacteristicExtensions.HandleByteAttributeValue((ICharacteristic)this, attribute, offset + 4, this._energyPerMinuteSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.HeartRate:
ICharacteristicExtensions.HandleByteAttributeValue((ICharacteristic)this, attribute, offset, this._heartRateSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.MetabolicEquivalent:
ICharacteristicExtensions.HandleByteAttributeValue((ICharacteristic)this, attribute, offset, this._metabolicEquivalentSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.ElapsedTime:
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._elapsedTimeSubject);
break;
case FtmsIndoorBikeData.IndoorBikeDataField.RemainingTime:
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._remainingTimeSubject);
break;
}
return fieldSize;
}
private static int GetFieldSize(FtmsIndoorBikeData.IndoorBikeDataField field)
{
int num = 0;
switch (field)
{
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousSpeed:
num = 2;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.AverageSpeed:
num = 2;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousCadence:
num = 2;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.AverageCadence:
num = 2;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.TotalDistance:
num = 3;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.ResistanceLevel:
num = 2;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousPower:
num = 2;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.AveragePower:
num = 2;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.ExpendedEnergy:
num = 5;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.HeartRate:
num = 1;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.MetabolicEquivalent:
num = 1;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.ElapsedTime:
num = 2;
break;
case FtmsIndoorBikeData.IndoorBikeDataField.RemainingTime:
num = 2;
break;
}
return num;
}
private enum IndoorBikeDataField
{
InstantaneousSpeed,
AverageSpeed,
InstantaneousCadence,
AverageCadence,
TotalDistance,
ResistanceLevel,
InstantaneousPower,
AveragePower,
ExpendedEnergy,
HeartRate,
MetabolicEquivalent,
ElapsedTime,
RemainingTime,
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e3577d5802131984c9463ba280183935
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,4 +1,5 @@
using Assets.Scripts.Ble;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,7 +9,7 @@ using UnityEngine;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
public class HeartRateMeasurement
public class HeartRateMeasurement : ICharacteristic
{
public Guid Uuid
{
@@ -26,6 +27,13 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
}
}
public bool IsOptional
{
get
{
return false;
}
}
private HrmFormat Format { get; set; }
// Token: 0x170005EB RID: 1515
@@ -39,7 +47,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
if (this.Format == HrmFormat.Short)
{
this.BeatsPerMinute = BitConvertHelper.ToUInt8(data, 1);
Debug.Log("心率:" + this.BeatsPerMinute);
//Debug.Log("心率:" + this.BeatsPerMinute);
return;
}
if (data.Length < 3)
@@ -49,6 +57,10 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
this.BeatsPerMinute = BitConvertHelper.ToUInt16(data, 1);
}
public void SetUnavailable()
{
}
[Flags]
private enum HrmFlags
{
@@ -0,0 +1,46 @@
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
public static class ICharacteristicExtensions
{
public static void HandleByteAttributeValue(this ICharacteristic characteristic, byte[] attribute, int offset, byte? subject)
{
if (attribute.Length < 1 + offset)
throw new ArgumentException("attribute");
byte num = attribute[offset];
subject =new byte?(num);
}
public static void HandleShortAttributeValue(this ICharacteristic characteristic, byte[] attribute, int offset, short? subject)
{
if (attribute.Length < 2 + offset)
throw new ArgumentException("attribute");
short num = BitConverter.ToInt16(attribute, offset);
subject= new short?(num);
}
public static void HandleUshortAttributeValue(this ICharacteristic characteristic, byte[] attribute, int offset, ushort? subject)
{
if (attribute.Length < 2 + offset)
throw new ArgumentException("attribute");
ushort num = BitConverter.ToUInt16(attribute, offset);
subject =new ushort?(num);
}
public static void HandleUint24AttributeValue(this ICharacteristic characteristic, byte[] attribute, int offset, uint? subject)
{
if (attribute.Length < 4 + offset - 1)
throw new ArgumentException("attribute");
byte[] numArray = new byte[4];
Buffer.BlockCopy((Array)attribute, offset, (Array)numArray, 0, 3);
uint num = BitConverter.ToUInt32(numArray, 0);
subject = (new uint?(num));
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 238bc68320174c9429b5958b5207b2c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,31 @@
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 ManufacturerNameCharacteristic : ICharacteristic
{
public Guid Uuid => ServiceUuids.Characteristics.ManufactureNameString;
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.DeviceInformation).IdGuid;
public bool IsOptional => true;
public void HandleAttributeReceived(byte[] data)
{
//throw new NotImplementedException();
Debug.Log(Encoding.UTF8.GetString(data));
}
public void SetUnavailable()
{
//throw new NotImplementedException();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f0a2af64ce8fe84cbdf0e5a14bbc8ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,31 @@
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 ModelNumberCharacteristic : ICharacteristic
{
public Guid Uuid => ServiceUuids.Characteristics.ModelNumber;
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.DeviceInformation).IdGuid;
public bool IsOptional => true;
public void HandleAttributeReceived(byte[] data)
{
//throw new NotImplementedException();
Debug.Log($"model number:\t{ Encoding.UTF8.GetString(data) }");
}
public void SetUnavailable()
{
//throw new NotImplementedException();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef489f56607ba2540b8954b67e1a4d3e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,205 @@
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;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
public class TacxFecNotify : ICharacteristic
{
public Guid Uuid => ServiceUuids.Characteristics.TacxFecRead;
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.TacxBle).IdGuid;
public virtual bool IsOptional
{
get
{
return false;
}
}
public double Speed { get; set; }
private int _Power;
public int Power
{
get
{
return _Power;
}
set
{
_Power = DeviceValueFilter.Power(value);
//Debug.Log(_Power);
}
}
private int _Cadence;
public int Cadence
{
get
{
return _Cadence;
}
set
{
_Cadence = DeviceValueFilter.Cadence(value);
}
}
public void HandleAttributeReceived(byte[] data)
{
//throw new NotImplementedException();
var responseId = data[2];
if (responseId != (byte)ANT_Managed_Library.ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E)
{
return;
}
var data1 = data.Skip(3).ToArray();
var pageNumber = data1[1];
switch (pageNumber)
{
case 16:
{
HandleGeneralDataPage(data1.Skip(1).ToArray());
}
break;
case 19:
{
//lastInstCadence = data1[5];
}
break;
case 21: //bike data
case 22: //Row data, same format as bike for cad and power
case 20: //Elliptical, same format as bike for cad and power
case 24: //Nordic Skier, same format as bike for cad and power
{
//lastInstCadence = data1[5];
//lastInstPower = (ushort)(data1[6] + (data1[7] << 8));
//System.Console.Out.WriteLine("Cadence:" + response.messageContents[5] + ",Power:" + (response.messageContents[6] + (response.messageContents[7] << 8)));
//System.Console.Out.WriteLine("SPM:"+response.messageContents[5]+"Power:"+(response.messageContents[6] + (response.messageContents[7] << 8)));
}
break;
case 25:
HandleTrainerDataPage(data1.Skip(1).ToArray());
break;
default:
break;
}
}
private void HandleGeneralDataPage(byte[] dataPayload)
{
try
{
byte equipmentType = dataPayload[1];
byte elapsedTime = dataPayload[2];
byte distanceTraveled = dataPayload[3];
//byte heartRate = dataPayload[6];
//FecPageHandler.HeartRateDataSource heartRateDataSource = (FecPageHandler.HeartRateDataSource)(dataPayload[7] & 3);
//bool traveledEnabled = (dataPayload[7] & 4) == 1;
//bool distanceTraveledEnabled = (dataPayload[7] & 8) == 1;
//FecPageHandler.FeState feState = (FecPageHandler.FeState)(dataPayload[7] & 128);
//bool lapToggle = (dataPayload[7] & 128) == 1;
//this._fecGeneralData = new FecGeneralData(equipmentType, elapsedTime, distanceTraveled, (short)num, feState, lapToggle, heartRate, heartRateDataSource, traveledEnabled, distanceTraveledEnabled);
bool traveledEnabled = ((int)dataPayload[7] & 4) == 1;
bool distanceTraveledEnabled = ((int)dataPayload[7] & 8) == 1;
int num1 = (int)dataPayload[4] | (int)dataPayload[5] << 8; // Instantaneous speed, m/s
Speed = (double)num1 / 1000.0 * 60.0 * 60.0 / 1000.0; //转换成公里/小时
//Console.WriteLine(num1 +"-----"+Speed);
//fecDevice.UpdateSpeed(new double?(value));
//PubCommData.Speed = num2;
//byte? b2 = (heartRate == 255) ? null : new byte?(heartRate);
//int? xl = b2.HasValue ? new int?((int)b2.GetValueOrDefault()) : 0;
//Console.WriteLine("最新速度" + Speed);
//Console.WriteLine("最新心率" + xl);
//string str = "";
//for (int i = 0; i < response.messageContents.Length; i++)
//{
// str += "," + response.messageContents[i];
//}
//PubCommData.sp = "速度:" + str;
}
catch (Exception)
{
}
}
private void HandleTrainerDataPage(byte[] dataPayload)
{
//if (response.messageContents.Length < 11) break;
//double value = 0;
//for (int i = 0; i < response.messageContents.Length; i++)
//{
// if (i < 8)
// {
// value += response.messageContents[i];
// }
//}
//double value1 = response.messageContents[10] * 256 + response.messageContents[9];
//double power = response.messageContents[7] * 256 + response.messageContents[6];
//Console.WriteLine("power:" + power);
//PubCommData.power = power;
try
{
if (dataPayload[5] > 0)
{
//Console.WriteLine(dataPayload[5] + "," + dataPayload[6]);//瞬时功率
}
byte num1 = dataPayload[1];
byte num2 = dataPayload[2];
int accumulatedPower = (int)dataPayload[3] | (int)dataPayload[4] << 8;
int instantaneousPower = (int)dataPayload[5] | ((int)dataPayload[6] & 15) << 8; //Watts
bool bikePowerCalibrationRequired = ((int)dataPayload[6] >> 4 & 1) == 1;
bool resistanceCalibrationRequired = ((int)dataPayload[6] >> 5 & 1) == 1;
bool userConfigurationRequired = ((int)dataPayload[6] >> 6 & 1) == 1;
bool speedIsTooLow = ((int)dataPayload[7] & 1) == 1;
bool speedIsTooHigh = ((int)dataPayload[7] & 2) == 1;
//PubCommData.power = instantaneousPower;
Power = instantaneousPower;
//bool bikePowerCalibrationRequired = (response.messageContents[6] >> 4 & 1) == 1;
//bool resistanceCalibrationRequired = (response.messageContents[6] >> 5 & 1) == 1;
//bool flag = (response.messageContents[6] >> 6 & 1) == 1;
//bool speedIsTooLow = (response.messageContents[7] & 1) == 1;
//bool speedIsTooHigh = (response.messageContents[7] & 2) == 1;
//FecPageHandler.FeState feState = (FecPageHandler.FeState)(dataPayload[7] & 112);
//bool lapToggle = (dataPayload[7] & 128) == 1;
//this._fecTrainerData = new FecTrainerData((int)eventCount, (int)b, accumulatedPower, num, bikePowerCalibrationRequired, resistanceCalibrationRequired, flag, speedIsTooLow, speedIsTooHigh, feState, lapToggle);
//device.UpdatePower(new int?(num));
byte? nullable = (int)num2 == (int)byte.MaxValue ? new byte?() : new byte?(num2);
int? cadence = nullable.HasValue ? new int?((int)nullable.GetValueOrDefault()) : new int?();
this.Cadence = cadence.GetValueOrDefault();
//Console.WriteLine($"power:{ instantaneousPower },Cadence:{ cadence }, data:{ string.Join(",", dataPayload) }");
if (!userConfigurationRequired)
return;
//UpdateUserConfiguration();
}
catch (Exception)
{
}
}
public virtual void SetUnavailable()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 640f21041d0bf6347b1e48669c9a8691
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,39 @@
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;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
public class TacxFecWrite : ICharacteristic
{
public virtual bool IsOptional
{
get
{
return false;
}
}
public Guid Uuid => ServiceUuids.Characteristics.TacxFecRead;
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.TacxBle).IdGuid;
public void HandleAttributeReceived(byte[] data)
{
}
public void WriteMessageToControlPoint()
{
}
public virtual void SetUnavailable()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6c9564a0124aa5946b25bdd1a97ade2c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: