2021-11-08 13:07:08 +08:00

274 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Assets.Scripts.Ble;
using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Devices.Ant.Interfaces;
using Assets.Scripts.Devices.Ble.Characteristic;
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.Devices
{
public class Tacx : BleDevice, IPowerDevice, ICadenceDevice, ISpeedDevice, ITrainerDevice, IRequiresRiderWeight
{
public int Power { get => tacxFecNotify.Power; set => throw new NotImplementedException(); }
public int Cadence { get => tacxFecNotify.Cadence; set => throw new NotImplementedException(); }
public double Speed { get => tacxFecNotify.Speed; set => throw new NotImplementedException(); }
public double RiderWeight { get; set; }
private List<BleServiceInfo> Services;
private TacxFecNotify tacxFecNotify;
private BleCharacteristicInfo tacxFecWriteCharacteristic;
private TacxFecWrite tacxFecWrite;
private List<Guid> otherGuids = new List<Guid>()
{
new Guid("0000fff0-0000-1000-8000-00805f9b34fb"),
new Guid("0000180a-0000-1000-8000-00805f9b34fb"),
new Guid("00001826-0000-1000-8000-00805f9b34fb"),
new Guid("c1fe406e-a3b5-93f3-e0a9-e50e24dcca9e"),
};
/// <summary>
/// 当前坡度当切换到其他模式的时候需要把坡度设置为0
/// </summary>
private double _grade = 0;
public Tacx(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Trainer)
{
tacxFecNotify = new TacxFecNotify();
base.Characteristics.Add(tacxFecNotify);
tacxFecWrite = new TacxFecWrite();
base.Characteristics.Add(tacxFecWrite);
bleWinHwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback;
//bleWinHwInterface.WriteCharacteristic()
}
protected override void CreateServices(List<BleServiceInfo> discoveredServices)
{
this.Services = discoveredServices;
foreach (var service in this.Services)
{
hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) =>
{
if(!base.CheckPendingServiceCharacteristicsResponse(service1, response))
{
return;
}
foreach (var character in response.Data)
{
if (character.MatchGuid(ServiceUuids.Characteristics.TacxFecRead))
{
//Debug.Log("功率功能");
this.hwInterface.SubscribeCharacteristic(character, (hw, cha, res) =>
{
//Debug.Log("1111111111111111111111");
});
}
else if (character.MatchGuid(ServiceUuids.Characteristics.TacxFecWrite))
{
this.tacxFecWriteCharacteristic = character;
}
}
});
}
}
private void CharacteristicReadMainCallback(IBleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
{
foreach (var item in base.Characteristics)
{
if (characteristic.MatchGuid(item.Uuid) || otherGuids.Contains(characteristic.Id))
{
Debug.Log(string.Join(",", response.Data));
item.HandleAttributeReceived(response.Data);
}
}
}
public void SetErgMode(int targetPower)
{
Debug.Log("目标功率1");
if (this.State != Ant.DeviceState.Connected)
return;
if (tacxFecWriteCharacteristic == null)
return;
Debug.Log($"目标功率:{ targetPower }");
List<byte> data = new List<byte> { 164, 9, 79, 5, 49,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
(byte)(targetPower & byte.MaxValue),
(byte)(targetPower >> 8 & byte.MaxValue)
};
byte checksum = (byte)0;
data.ForEach(b => checksum ^= b);
data.Add(checksum);
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
}
/// <summary>
/// 阻力模式
/// </summary>
/// <param name="value"></param>
public void SetResistanceMode(double value)
{
if (this.State != Ant.DeviceState.Connected)
return;
if (tacxFecWriteCharacteristic == null)
return;
if(_grade > 0)
{
this.SetTrackResistance(0);
}
double resistance = value / 100 * 200;
List<byte> data = new List<byte> { 164, 9, 79, 5, 48,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
(byte)resistance
};
byte checksum = (byte)0;
data.ForEach(b => checksum ^= b);
data.Add(checksum);
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
}
/// <summary>
/// 风阻
/// </summary>
/// <param name="height">海拔高度,单位米</param>
public void SetWindResistance(double? height = null)
{
if (this.State != Ant.DeviceState.Connected)
return;
if (tacxFecWriteCharacteristic == null)
return;
if (_grade > 0)
{
this.SetTrackResistance(0);
}
byte windResistance = 0;
if (height.HasValue)
{
//Wind Resistance Coefficient [kg/m] = Frontal Surface Area [m2] x Drag Coefficient x Air Density[kg / m3]
var wr = 0.40 * 1.0 * AirDensity.GetAirDensity(height.Value);
if (wr > 1.86)
{
wr = 1.86;
}
windResistance = (byte)(Convert.ToInt32(Math.Round(wr, 2) / 0.01));
Console.WriteLine($"风阻系数:{ windResistance }");
}
byte id = 79;
byte size = 9;
byte channel = 5;
List<byte> data = new List<byte> { 164, size, id, channel, 50,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
windResistance,
byte.MaxValue,
byte.MaxValue,
};
byte checksum = (byte)0;
data.ForEach(b => checksum ^= b);
data.Add(checksum);
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
}
/// <summary>
/// 轨道阻力
/// </summary>
/// <param name="grade">坡度百分比的值,单位是%</param>
public void SetTrackResistance(double grade)
{
if (this.State != Ant.DeviceState.Connected)
return;
if (tacxFecWriteCharacteristic == null)
return;
_grade = grade;
if (_grade > 15)
{
_grade = 15;
}
else if (_grade < -5)
{
_grade = -5;
}
var gradeValue = Convert.ToInt32((grade + 200) * 100);
var gradeBytes = BitConverter.GetBytes(gradeValue);
byte id = 79;
byte size = 9;
byte channel = 5;
List<byte> data = new List<byte> { 164, size, id, channel, 51,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
byte.MaxValue,
gradeBytes[0],
gradeBytes[1],
byte.MaxValue,
};
byte checksum = (byte)0;
data.ForEach(b => checksum ^= b);
data.Add(checksum);
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
}
private void UpdateUserConfiguration(double weight)
{
var _weight = (int)(weight * 100);
if (this.State != Ant.DeviceState.Connected)
return;
if (tacxFecWriteCharacteristic == null)
return;
byte id = 79;
byte size = 4;
byte channel = 5;
List<byte> data = new List<byte> { 164, size, id, channel, 55,
(byte) (_weight & (int) byte.MaxValue),
(byte) (_weight >> 8 & (int) byte.MaxValue),
byte.MaxValue,
(byte) 143,
(byte) 12,
(byte) 70,
(byte) 0
};
byte checksum = (byte)0;
data.ForEach(b => checksum ^= b);
data.Add(checksum);
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
}
}
}