最新打包配置;适配wahoo

This commit is contained in:
Caiyanpeng committed 2022-08-29 11:12:53 +08:00
1 parent 74bdd26924
commit b830b5961a
20 files changed
+280 -189

No files matched your search

+2
View File
@@ -211,6 +211,8 @@ public static class App
public static List<string> cacheList = new List<string>();
static App()
{
Debug.Log((byte)(10.01548687 * 10));
//Debug.Log(BitConverter.ToUInt16(new byte[] {220,2 },0));
InitLanguage();
#if !UNITY_EDITOR
//Host = "http://pf.juze.pro/";
+2 -1
View File
@@ -294,6 +294,7 @@ namespace Assets.Scripts.Devices.Ant
void antChannel_channelResponse_FeSearch(ANT_Response response)
{
//删除扫描不到的设备
var now = DateTime.Now;
var needRemoveList = discoveredDevices.Where(c => (now - c.LastActiveTime).TotalSeconds > 5 && c.State == DeviceState.Disconnected).ToList();
@@ -430,7 +431,7 @@ namespace Assets.Scripts.Devices.Ant
u.DeviceTypeId == device.searchProfile.deviceType.ToString()))
return;
if (device.Sensor == SensorType.Trainer || device.Sensor == SensorType.Power)
if (device.Sensor == SensorType.Trainer || device.Sensor == SensorType.FtmsTrainer || device.Sensor == SensorType.Power)
{
if (discoveredDevices.Any(s => s.Sensor == device.Sensor && (s.State == DeviceState.Connected || s.State == DeviceState.Connecting)))
{
@@ -5,48 +5,24 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
[Flags]
public enum TrainerDataFlag
{
MoreData = 1,
Cadence = 4,
Power = 64
}
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 int? InstantPower { get; set; }
public int? InstantCadence { get; set; }
public double? InstantSpeed { get; set; }
public Guid Uuid => ServiceUuids.Characteristics.IndoorBikeData;
@@ -55,43 +31,27 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
public bool IsOptional => false;
public TrainerDataFlag Flags;
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);
this.Flags = (TrainerDataFlag)BitConverter.ToUInt16(data, 0);
int b = 2;
if (Flags.HasFlag(TrainerDataFlag.Cadence))
{
this.InstantSpeed = BitConverter.ToUInt16(data, b) / 100f;
this.InstantCadence = (ushort)(BitConverter.ToUInt16(data, b + 2) / 2);
b += this.SizeOfDataForFlag(TrainerDataFlag.Cadence);
}
if (Flags.HasFlag(TrainerDataFlag.Power))
{
this.InstantPower = BitConverter.ToUInt16(data, b);
b += this.SizeOfDataForFlag(TrainerDataFlag.Power);
}
//Debug.Log("速度:" + this.InstantSpeed + "踏频:" + this.InstantCadence + "功率:" + this.InstantPower);
}
public void SetUnavailable()
@@ -99,58 +59,6 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
//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;
@@ -216,5 +124,22 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
ElapsedTime,
RemainingTime,
}
public int SizeOfDataForFlag(TrainerDataFlag flag)
{
int num = 0;
switch (flag)
{
//case RowerDataFlag.MoreData:
// break;
case TrainerDataFlag.MoreData: num = 2; break;
case TrainerDataFlag.Power: num = 2; break;
case TrainerDataFlag.Cadence: num = 4; break;
default:
break;
}
return num;
}
}
}
+32 -20
View File
@@ -8,18 +8,18 @@ using UnityEngine;
namespace Assets.Scripts.Devices.Ble.Devices
{
public class Ftms : BleDevice, ISpeedDevice, IPowerDevice, ICadenceDevice, ITrainerDevice
public class Ftms : BleDevice, ISpeedDevice, IPowerDevice, ICadenceDevice, ITrainerDevice, IRequiresRiderWeight
{
public int Power { get => _ftmsIndoorBikeData.InstantPower.GetValueOrDefault(0); set => throw new NotImplementedException(); }
public double Speed { get => _ftmsIndoorBikeData.InstantSpeed.GetValueOrDefault(0); set => throw new NotImplementedException(); }
public int Cadence { get => _ftmsIndoorBikeData.InstantCadence.GetValueOrDefault(0); set => throw new NotImplementedException(); }
public double RiderWeight { get; set; }
private FtmsIndoorBikeData _ftmsIndoorBikeData;
private List<BleServiceInfo> Services;
private BleCharacteristicInfo controlPointCharacteristic;
public Ftms(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface) :base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Trainer)
public Ftms(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface) :base(peripheralInfo, bleWinHwInterface, Ant.SensorType.FtmsTrainer)
{
this._ftmsIndoorBikeData = new FtmsIndoorBikeData();
base.Characteristics.Add(this._ftmsIndoorBikeData);
@@ -39,7 +39,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
{
if (character.MatchGuid(ServiceUuids.Characteristics.IndoorBikeData))
{
//Debug.Log("功率功能");
//Debug.Log("Ftms功率功能");
this.hwInterface.SubscribeCharacteristic(character, (hw, cha, res) =>
{
@@ -80,11 +80,12 @@ namespace Assets.Scripts.Devices.Ble.Devices
public void SetResistanceMode(double value)
{
//throw new NotImplementedException();
var data = new byte[]
{
(byte)4,
(byte)0.1
(byte)(value * 10)
};
}
@@ -99,24 +100,35 @@ namespace Assets.Scripts.Devices.Ble.Devices
/// <param name="grade"></param>
public void SetTrackResistance(double grade)
{
if (this.State != Ant.DeviceState.Connected)
return;
if (controlPointCharacteristic == null)
return;
if (grade < 0) grade = 0;
if (grade > 10) grade = 10;
if (this.controlPointCharacteristic != null)
{
var data = new byte[]
{
(byte)4,
(byte)(grade * 10)
};
this.hwInterface.WriteCharacteristic(this.controlPointCharacteristic, data);
}
//if (this.State != Ant.DeviceState.Connected)
// return;
//if (controlPointCharacteristic == null)
// return;
short windSpeed = 0;
short value2 = (short)(grade);
byte rollingResistanceCoefficient = (byte)(0.004 * 10000);
byte windResistanceCoefficient = 0;
var data = new List<byte>();// { 17, (byte)windSpeed, (byte)value2, rollingResistanceCoefficient, windResistanceCoefficient };
data.Add(17);
data.AddRange(BitConverter.GetBytes(windSpeed));
data.AddRange(BitConverter.GetBytes(value2));
data.AddRange(BitConverter.GetBytes(rollingResistanceCoefficient));
data.AddRange(BitConverter.GetBytes(windResistanceCoefficient));
//short windSpeed = 0;
//short value2 = (short)(grade);
//byte rollingResistanceCoefficient = (byte)(0.004 * 10000);
//byte windResistanceCoefficient = 0;
//var data = new List<byte>();// { 17, (byte)windSpeed, (byte)value2, rollingResistanceCoefficient, windResistanceCoefficient };
//data.Add(17);
//data.AddRange(BitConverter.GetBytes(windSpeed));
//data.AddRange(BitConverter.GetBytes(value2));
//data.AddRange(BitConverter.GetBytes(rollingResistanceCoefficient));
//data.AddRange(BitConverter.GetBytes(windResistanceCoefficient));
this.hwInterface.WriteCharacteristic(this.controlPointCharacteristic, data.ToArray());
//this.hwInterface.WriteCharacteristic(this.controlPointCharacteristic, data.ToArray());
}
}
}
@@ -130,7 +130,7 @@ namespace Assets.Scripts.Ble
}
if(item.IdByteArray == ServiceUuids.Ftms)
{
sensor = SensorType.Trainer;
sensor = SensorType.FtmsTrainer;
}
else if(item.IdByteArray == ServiceUuids.HeartRate)
{
@@ -195,6 +195,8 @@ namespace Assets.Scripts.Ble
return Get(ServiceUuids.PowerBeam).IdGuid;
case SensorType.Trainer:
return Get(ServiceUuids.TacxBle).IdGuid;
case SensorType.FtmsTrainer:
return Get(ServiceUuids.Ftms).IdGuid;
default:
return Guid.Empty;
}
@@ -151,6 +151,10 @@ namespace Assets.Scripts.Ble
{
sensor = SensorType.Trainer;
}
else if (item.IdByteArray == ServiceUuids.Ftms)
{
sensor = SensorType.FtmsTrainer;
}
}
};
@@ -28,11 +28,11 @@ namespace Assets.Scenes.Ride.Scripts
public AbstractDevice CurrentTrainer
{
get {
var devices = App.MainDeviceAdapter.GetDevices().Where(d => d.State == DeviceState.Connected && (d.Sensor == SensorType.Trainer));
var devices = App.MainDeviceAdapter.GetDevices().Where(d => d.State == DeviceState.Connected && (d.Sensor == SensorType.Trainer || d.Sensor == SensorType.FtmsTrainer));
_device = null;//重置设备状态
if (devices.Count() > 0)
{
_device = devices.OrderByDescending(d => d.Sensor == SensorType.Trainer).First();
_device = devices.OrderByDescending(d => d.Sensor == SensorType.Trainer || d.Sensor == SensorType.FtmsTrainer).First();
var RiderWeight = (_device as IRequiresRiderWeight).RiderWeight;
if (RiderWeight == 0)
{
@@ -141,10 +141,10 @@ namespace Assets.Scenes.Ride.Scripts
public bool CheckAnt()
{
//_antConnector = AntConnector.Instance();
var devices = App.MainDeviceAdapter.GetDevices().Where(d => d.State == DeviceState.Connected && (d.Sensor == SensorType.Trainer || d.Sensor == SensorType.Power));
var devices = App.MainDeviceAdapter.GetDevices().Where(d => d.State == DeviceState.Connected && (d.Sensor == SensorType.Trainer || d.Sensor == SensorType.FtmsTrainer || d.Sensor == SensorType.Power));
if (devices.Count() > 0)
{
_device = devices.OrderByDescending(d => d.Sensor == SensorType.Trainer).First();
_device = devices.OrderByDescending(d => d.Sensor == SensorType.Trainer || d.Sensor == SensorType.FtmsTrainer).First();
if (_device != null && _device is IRequiresRiderWeight)
{
(_device as IRequiresRiderWeight).RiderWeight = App.CurrentUser.Weight;
@@ -216,10 +216,9 @@ namespace Assets.Scenes.Ride.Scripts
{
return (IPowerDevice)power;
}
if (powerDevices.Any())
{
return (IPowerDevice)powerDevices.FirstOrDefault();
return (IPowerDevice)powerDevices.FirstOrDefault(d=>d.Sensor == SensorType.Trainer || d.Sensor == SensorType.FtmsTrainer);
}
return null;
@@ -47,8 +47,8 @@ namespace Assets.Scenes.Ride.Scripts
/// </summary>
protected override void Compute()
{
//计算数据
//speed = mainController.UpDateSpeed();
//计算数据
speed = mainController.UpDateSpeed();
try
{
heartRate = mainController.UpDateHeart();
@@ -57,10 +57,10 @@ namespace Assets.Scenes.Ride.Scripts
weight = App.CurrentUser.Weight;
bicycleWeight = App.CurrentUser.BicycleWeight;
#if UNITY_EDITOR
power = 300;
power = 300;
#endif
mainController.TrackResistance(currentSlope * App.RideSetting.Sensitivity / 100);
}
}
catch (Exception ex)
{
Debug.Log(ex.Message);
@@ -184,7 +184,8 @@ public class ConnectDeviceModal : PFUIPanel
devices = App.MainDeviceAdapter.GetDevices().Where(d => d.Sensor == SensorType || (d is ISpeedDevice && d.State == DeviceState.Connected)).OrderBy(d => d.Priority).ToList();
break;
case SensorType.Trainer:
devices = App.MainDeviceAdapter.GetDevices().Where(d => d.Sensor == SensorType && d is ITrainerDevice).ToList();
case SensorType.FtmsTrainer:
devices = App.MainDeviceAdapter.GetDevices().Where(d => (d.Sensor == SensorType || d.Sensor == SensorType.FtmsTrainer) && d is ITrainerDevice).ToList();
break;
case SensorType.VirtualPower:
break;
@@ -230,7 +230,7 @@ public class DeviceView : MonoBehaviour
powerUnit.text = "BPM";
}
else if (SensorType == SensorType.Trainer)
else if (SensorType == SensorType.Trainer || SensorType == SensorType.FtmsTrainer)
{
sprite0 = Resources.Load<Sprite>("Images/Devices/Trainer_1");
sprite1 = Resources.Load<Sprite>("Images/Devices/Trainer_1");
@@ -387,6 +387,7 @@ public class DeviceView : MonoBehaviour
case SensorType.Speed:
return App.GetLocalString("Speed Meter");
case SensorType.Trainer:
case SensorType.FtmsTrainer:
return App.GetLocalString("Smart Trainer");
case SensorType.VirtualPower:
break;
@@ -414,6 +415,7 @@ public class DeviceView : MonoBehaviour
case SensorType.Speed:
return (connectedDevice as ISpeedDevice).Speed.ToString("f1");
case SensorType.Trainer:
case SensorType.FtmsTrainer:
//powerValue.text = (connectedDevice as IPowerDevice).Power.ToString();
//cadenceValue.GetComponent<Text>().text = (connectedDevice as ICadenceDevice).Cadence.ToString();
//speedValue.GetComponent<Text>().text = (connectedDevice as ISpeedDevice).Speed.ToString();
@@ -462,7 +464,8 @@ public class DeviceView : MonoBehaviour
case SensorType.Speed:
return devices.FirstOrDefault(d => d is ISpeedDevice);
case SensorType.Trainer:
var item3 = devices.FirstOrDefault(d => d.Sensor == SensorType.Trainer);
case SensorType.FtmsTrainer:
var item3 = devices.FirstOrDefault(d => d.Sensor == SensorType.Trainer || d.Sensor == SensorType.FtmsTrainer);
return item3;
case SensorType.VirtualPower:
break;