Merge branch 'dev_cyp1' into dev_ar_cyp
# Conflicts: # Assets/Plugins/Android/unityandroidbluetoothlelib.jar # Assets/Resources/UI/language.json # Assets/Scenes/MainScene.unity # Assets/Scripts/Devices/Ble/mobile/BleMobileInterface.cs # Assets/Scripts/Devices/Ble/mobile/BleMobileThread.cs # Assets/Scripts/Scenes/MainController.cs # Assets/Scripts/UI/Prefab/Panel/RowerHomeScript.cs # Assets/Scripts/UI/Prefab/Rower/RowerDeviceView.cs # Assets/Scripts/UI/Prefab/Rower/RowerGraphChartFeed.cs # Assets/Scripts/UIManager.cs
This commit is contained in:
commit
1d015706db
41 files changed
+14379
-166815
No files matched your search
@@ -1,4 +1,5 @@
|
||||
using Assets.Scripts.Devices.Ble.Characteristic;
|
||||
using Assets.Scripts.Ble.Commands;
|
||||
using Assets.Scripts.Devices.Ble.Characteristic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -14,5 +15,6 @@ namespace Assets.Scripts.Devices.Ant.Interfaces
|
||||
void Reset();
|
||||
void SetResistanceLevel(ushort v);
|
||||
void C2GetStatus(byte[] bs);
|
||||
void SendCommand(RowerCommand command,int data = 0);
|
||||
}
|
||||
}
|
||||
@@ -48,5 +48,13 @@ namespace Assets.Scripts
|
||||
{
|
||||
return (uint)((int)bytes[startIndex] | (int)bytes[startIndex + 1] << 8 | (int)bytes[startIndex + 2] << 16);
|
||||
}
|
||||
public static byte[] HexToByteArray(string hex)
|
||||
{
|
||||
hex=hex.Replace(" ", "");
|
||||
return Enumerable.Range(0, hex.Length)
|
||||
.Where(x => x % 2 == 0)
|
||||
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,7 +128,7 @@ namespace Assets.Scripts.Devices.Ble
|
||||
Debug.Log("断开设备" + this.Name);
|
||||
|
||||
//App.MainDeviceAdapter.PrintStatus();
|
||||
this.State = DeviceState.Disconnected;
|
||||
//this.State = DeviceState.Disconnected;
|
||||
|
||||
this.hwInterface.DisconnectPeripheral(this.peripheralInfo, () => {
|
||||
//App.MainDeviceAdapter.PrintStatus();
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Assets.Scripts.Devices.Ble
|
||||
|
||||
private IDictionary<string, BleDevice> discoveredDevices = new Dictionary<string, BleDevice>();
|
||||
|
||||
private IBleWinHwInterface hwInterface { get; set; }
|
||||
public IBleWinHwInterface hwInterface { get; private set; }
|
||||
public BleDeviceAdapter(IBleWinHwInterface bleWinHwInterface)
|
||||
{
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class C2RowerData : ICharacteristic, IRowerCommonData
|
||||
{
|
||||
public static string JUSTROW_HEX = "F1 76 07 01 01 01 13 02 01 01 61 F2";
|
||||
public static string TERMINATEWORKOUT_HEX = "F1 76 04 13 02 01 02 62 F2";
|
||||
public static string FIXEDDISTANCE_HEX = "F1 76 18 01 01 03 03 05 80 00 00 07 D0 05 05 80 00 00 01 90 14 01 01 13 02 01 01 28 F2";
|
||||
public static string FIXEDTIME_HEX = "F1 76 07 01 01 01 13 02 01 01 61 F2";
|
||||
|
||||
public Guid Uuid => ServiceUuids.Characteristics.C2RowerData35;
|
||||
|
||||
public Guid ServiceUuid => ServiceUuids.Characteristics.C2Service;
|
||||
@@ -27,7 +32,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
_isEnabled = value;
|
||||
if (EnableChanged != null)
|
||||
{
|
||||
EnableChanged(_isEnabled, new EventArgs());
|
||||
EnableChanged(_isEnabled, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,16 +51,18 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
_pullValue = value;
|
||||
if (this.PullChanged != null)
|
||||
{
|
||||
this.PullChanged(this, new EventArgs());
|
||||
this.PullChanged(this, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsUserDefined { get; set; }
|
||||
|
||||
public static bool isReadyStatus { get; private set; }
|
||||
public static RowerTaskPanel.RowerType rowerType { get; private set; }
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
Debug.Log("数据" + string.Join(",", data));
|
||||
|
||||
if (data[0] == 0x35)
|
||||
{
|
||||
PeakDriveForce = LbsToNewton(Convert.ToDouble(BitConvertHelper.ToUInt16(data, 13)) / 10, true);
|
||||
@@ -63,20 +70,19 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
ElapsedTime = (int)(Convert.ToDouble(BitConvertHelper.ToUInt24(data, 1)) / 100);
|
||||
TotalDistance = (uint)(Convert.ToDouble(BitConvertHelper.ToUInt24(data, 4)) / 10);
|
||||
StrokeCount = BitConvertHelper.ToUInt16(data, 19);
|
||||
Debug.Log($"峰力值:{PeakDriveForce} 均力值{AverageDriveForce}");
|
||||
}
|
||||
else if (data[0] == 0x3d)
|
||||
{
|
||||
//老款表头不支持
|
||||
List<ushort> r = new List<ushort>();
|
||||
//List<ushort> r = new List<ushort>();
|
||||
for (int i = 3; i < data.Length; i += 2)
|
||||
{
|
||||
ushort pull = data[i] < 5 ? (ushort)0 : Convert.ToUInt16(Math.Round(LbsToNewton(data[i], true)));
|
||||
r.Add(pull);
|
||||
ushort pull = data[i] < 10 ? (ushort)0 : Convert.ToUInt16(Math.Round(LbsToNewton(data[i], true)));
|
||||
//r.Add(pull);
|
||||
PullValue = pull;
|
||||
}
|
||||
|
||||
Debug.Log("拉力曲线:" + string.Join(",", r));
|
||||
// Debug.Log("拉力曲线:" + string.Join(",", r));
|
||||
}
|
||||
else if (data[0] == 0x31)
|
||||
{
|
||||
@@ -87,26 +93,31 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
rowerType = new RowerTaskPanel.RowerType();
|
||||
rowerType.type = 1;
|
||||
rowerType.value = value;
|
||||
IsUserDefined = true;
|
||||
}
|
||||
else if (status == 0)
|
||||
{
|
||||
rowerType = new RowerTaskPanel.RowerType();
|
||||
rowerType.type = 2;
|
||||
rowerType.value = value / 100;
|
||||
IsUserDefined = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rowerType = null;
|
||||
IsUserDefined = false;
|
||||
}
|
||||
Debug.Log($"里程:{TotalDistance}峰力值:{PeakDriveForce} 均力值{AverageDriveForce} ReadyStatus:{isReadyStatus} TIME{DateTime.Now}");
|
||||
//isReadyStatus = data[9] == 0;
|
||||
var time = ((data[3] << 16) + (data[2] << 8) + data[1]) / 100;
|
||||
Debug.Log("划船时间" + time);
|
||||
isReadyStatus = data[9] == 0;
|
||||
if (RowerResChanged != null)
|
||||
{
|
||||
RowerResChanged.Invoke(data[19], new EventArgs());
|
||||
}
|
||||
var hasChanged = data[19] != ResistanceLevel;
|
||||
ResistanceLevel = data[19];
|
||||
if (RowerResChanged != null && hasChanged)
|
||||
{
|
||||
RowerResChanged.Invoke(this, null);
|
||||
}
|
||||
//isReadyStatus = data[2] == 1 || data[2] == 129;
|
||||
}
|
||||
else if (data[0] == 0x32)
|
||||
@@ -126,17 +137,20 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
InstantaneousPower = BitConvertHelper.ToUInt16(data, 4);
|
||||
//TotalEnergy = BitConvertHelper.ToUInt16(data, 6);
|
||||
}
|
||||
//else if (data[0] == 0x39)
|
||||
//{
|
||||
// AverageStrokeRate = (int)data[11];
|
||||
// ResistanceLevel = (int)data[16];
|
||||
//}
|
||||
else if (data[0] == 0x39)
|
||||
{
|
||||
ElapsedTime = (int)(Convert.ToDouble(BitConvertHelper.ToUInt24(data, 5)) / 100);
|
||||
TotalDistance = (uint)(Convert.ToDouble(BitConvertHelper.ToUInt24(data, 8)) / 10);
|
||||
CompleteEvent?.Invoke(this, null);
|
||||
}
|
||||
Debug.Log("数据" + string.Join(",", data) + $" | {ElapsedTime}-{TotalDistance}");
|
||||
//else if (data[0] == 34)
|
||||
//{
|
||||
// isReadyStatus = data[2] == 1 || data[2] == 129;
|
||||
//}
|
||||
}
|
||||
public event EventHandler StartEvent;
|
||||
public event EventHandler CompleteEvent;
|
||||
private double LbsToNewton(double lbs,bool isKg = false) => 4.4482216 * lbs * (isKg ? (1f / 9.8f) : 1f);
|
||||
public void SetUnavailable()
|
||||
{
|
||||
@@ -155,7 +169,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
/// 平均划桨频率
|
||||
/// </summary>
|
||||
public int AverageStrokeRate { get; set; } = 0;
|
||||
private UInt32 _totalDistance = 0;
|
||||
private UInt32 _totalDistance = 1;
|
||||
public UInt32 TotalDistance
|
||||
{
|
||||
get => _totalDistance;
|
||||
@@ -163,7 +177,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
if (_totalDistance == 0 && value != 0 && StartEvent != null)
|
||||
{
|
||||
StartEvent.Invoke(null, new EventArgs());
|
||||
StartEvent.Invoke(this, null);
|
||||
}
|
||||
_totalDistance = value;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
/// </summary>
|
||||
public int AverageStrokeRate { get; set; } = 0;
|
||||
|
||||
private UInt32 _totalDistance = 0;
|
||||
private UInt32 _totalDistance = 1;
|
||||
public UInt32 TotalDistance
|
||||
{
|
||||
get => _totalDistance;
|
||||
@@ -33,16 +33,17 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
if (_totalDistance == 0 && value != 0 && StartEvent != null)
|
||||
{
|
||||
StartEvent.Invoke(null, new EventArgs());
|
||||
StartEvent.Invoke(this, null);
|
||||
}
|
||||
_totalDistance = value;
|
||||
}
|
||||
}
|
||||
//private UInt16 _instantaneousPace = 0;
|
||||
//private UInt16 _instantaneousPace = 1;
|
||||
/// <summary>
|
||||
/// 即时配速
|
||||
/// </summary>
|
||||
public UInt16 InstantaneousPace { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 平均配速
|
||||
/// </summary>
|
||||
@@ -61,7 +62,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
var device = App.MainDeviceAdapter.GetDevices().FirstOrDefault(d => (d.State == DeviceState.Connected) && d.Sensor == SensorType.Rower);
|
||||
if (device == null) return 0;
|
||||
if (device.Name.Contains("Think"))
|
||||
if (device.Name.Contains("Think") || device.Name.Contains("PF"))
|
||||
{
|
||||
return thinkRes;
|
||||
}
|
||||
@@ -93,6 +94,10 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
public event EventHandler PullChanged;
|
||||
//开始事件
|
||||
public event EventHandler StartEvent;
|
||||
//结束事件
|
||||
public event EventHandler CompleteEvent;
|
||||
//日志事件
|
||||
public event EventHandler LogEvent;
|
||||
private ushort _pullValue;
|
||||
public ushort PullValue
|
||||
{
|
||||
@@ -102,7 +107,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
_pullValue = value;
|
||||
if (this.PullChanged != null)
|
||||
{
|
||||
this.PullChanged(this, new EventArgs());
|
||||
this.PullChanged(this, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,6 +118,8 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
return this.Flags.HasFlag(RowerDataFlag.MoreData);
|
||||
}
|
||||
}
|
||||
private string[] deviceNamePool = new string[] {"Think","PF" };
|
||||
private List<ushort> tempPullList = new List<ushort>();
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
@@ -126,9 +133,8 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
// return;
|
||||
//}
|
||||
var output = "";
|
||||
output += "收到消息:" + string.Join("\t", data);
|
||||
|
||||
|
||||
output += "收到消息:" + string.Join(",", data);
|
||||
|
||||
this.Flags = (RowerDataFlag)BitConverter.ToUInt16(data, 0);
|
||||
int b = 2;
|
||||
if (!this.MoreDataFlag)
|
||||
@@ -156,6 +162,11 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
var vvv = BitConvertHelper.ToUInt24(data, (int)b);
|
||||
output += $" 总距离{ vvv }米";
|
||||
if (vvv < 10)
|
||||
{
|
||||
LogEvent?.Invoke(DateTime.Now.ToString() + ":" + output,null);
|
||||
//App.cacheList.Add(DateTime.Now.ToString() + ":" + output);
|
||||
}
|
||||
b += this.SizeOfDataForFlag(RowerDataFlag.TotalDistance);
|
||||
|
||||
this.TotalDistance = vvv;
|
||||
@@ -186,11 +197,13 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
}
|
||||
if (this.Flags.HasFlag(RowerDataFlag.ResistanceLevel))
|
||||
{
|
||||
this.commonRes = BitConvertHelper.ToInt16(data, b);
|
||||
var newRes = BitConvertHelper.ToInt16(data, b);
|
||||
var resChanged = newRes != this.commonRes;
|
||||
this.commonRes = newRes;
|
||||
var device = App.MainDeviceAdapter.GetDevices().FirstOrDefault(d => (d.State == DeviceState.Connected) && d.Sensor == SensorType.Rower);
|
||||
if (device != null && !device.Name.Contains("Think") && RowerResChanged != null)
|
||||
if (resChanged && device != null && deviceNamePool.FirstOrDefault(x => device.Name.ToLower().Contains(x.ToLower())) == null && RowerResChanged != null)
|
||||
{
|
||||
RowerResChanged.Invoke(this.commonRes, null);
|
||||
RowerResChanged.Invoke(this, null);
|
||||
}
|
||||
b += this.SizeOfDataForFlag(RowerDataFlag.ResistanceLevel);
|
||||
}
|
||||
@@ -225,27 +238,29 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
}
|
||||
if (this.Flags.HasFlag(RowerDataFlag.ThinkDragFactor))
|
||||
{
|
||||
var originRes = BitConvertHelper.ToInt16(data, b + 1);
|
||||
var thinkResChanged = originRes != this.thinkRes;
|
||||
this.thinkRes = BitConvertHelper.ToInt16(data, b + 1);
|
||||
var device = App.MainDeviceAdapter.GetDevices().FirstOrDefault(d => (d.State == DeviceState.Connected) && d.Sensor == SensorType.Rower);
|
||||
if (device != null && device.Name.Contains("Think") && RowerResChanged != null)
|
||||
if (thinkResChanged && device != null && deviceNamePool.FirstOrDefault(x=>device.Name.ToLower().Contains(x.ToLower()))!=null && RowerResChanged != null)
|
||||
{
|
||||
RowerResChanged.Invoke(this.thinkRes, null);
|
||||
RowerResChanged.Invoke(this, null);
|
||||
}
|
||||
b += this.SizeOfDataForFlag(RowerDataFlag.ThinkDragFactor);
|
||||
}
|
||||
if (this.Flags.HasFlag(RowerDataFlag.Pull))
|
||||
{
|
||||
List<ushort> list = new List<ushort>();
|
||||
for (int pullB = 4; pullB < data.Length; pullB += 2)
|
||||
{
|
||||
var val = BitConverter.ToUInt16(data, pullB);
|
||||
val = Convert.ToUInt16(((double)val) /9.8f);
|
||||
list.Add(val);
|
||||
tempPullList.Add(val);
|
||||
PullValue = val;
|
||||
|
||||
}
|
||||
Debug.Log("拉力列表:" + string.Join(",", tempPullList));
|
||||
|
||||
if (pullList == null) pullList = new List<ushort>();
|
||||
foreach (var pull in list)
|
||||
foreach (var pull in tempPullList)
|
||||
{
|
||||
if (pull == 0)
|
||||
{
|
||||
@@ -258,16 +273,17 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
}
|
||||
pullList.Add(pull);
|
||||
}
|
||||
Debug.Log("拉力:" + string.Join(",",list));
|
||||
tempPullList.Clear();
|
||||
|
||||
}
|
||||
}
|
||||
List<ushort> pullList;
|
||||
List<ushort> pullList { get; set; }
|
||||
public void Reset()
|
||||
{
|
||||
this.StrokeRate = 0;
|
||||
this.StrokeCount = 0;
|
||||
this.AverageStrokeRate = 0;
|
||||
this.TotalDistance = 0;
|
||||
//this.TotalDistance = 0;
|
||||
this.InstantaneousPace = 0;
|
||||
this.AveragePace = 0;
|
||||
this.InstantaneousPower = 0;
|
||||
|
||||
@@ -6,7 +6,14 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Ble.Commands
|
||||
{
|
||||
public enum CommandResponseCode
|
||||
public enum RowerCommand
|
||||
{
|
||||
JustRow = 1,
|
||||
FixedDistance=2,
|
||||
FixedTime = 3,
|
||||
}
|
||||
|
||||
public enum CommandResponseCode
|
||||
{
|
||||
// Token: 0x04000FEB RID: 4075
|
||||
Success = 1,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Ble.Commands;
|
||||
using Assets.Scripts.Devices.Ant.Interfaces;
|
||||
using Assets.Scripts.Devices.Ble.Characteristic;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
@@ -21,7 +22,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
public C2RowerData c2RowerData { get => _c2RowerData; }
|
||||
private List<BleServiceInfo> Services;
|
||||
private BleCharacteristicInfo controlPointCharacteristic;
|
||||
private BleCharacteristicInfo c2Control;
|
||||
private BleCharacteristicInfo c2Control { get; set; }
|
||||
|
||||
public FtmsRower(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Rower)
|
||||
{
|
||||
@@ -53,6 +54,8 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
Debug.Log("中控台获取");
|
||||
this.controlPointCharacteristic = character;
|
||||
C2RowerData.IsEnabled = false;
|
||||
//Thread.Sleep(100);
|
||||
//Reset();
|
||||
}
|
||||
else if (character.MatchGuid(ServiceUuids.Characteristics.RowerData))
|
||||
{
|
||||
@@ -101,7 +104,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
}
|
||||
else if (character.MatchGuid(ServiceUuids.Characteristics.C2RowerControl))
|
||||
{
|
||||
Debug.Log("c2划船机控制台");
|
||||
Debug.Log($"c2划船机控制台{character.Id}");
|
||||
this.c2Control = character;
|
||||
}
|
||||
}
|
||||
@@ -171,6 +174,26 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
}
|
||||
}
|
||||
|
||||
public void SendCommand(RowerCommand command,int data = 0)
|
||||
{
|
||||
if (!C2RowerData.IsEnabled)
|
||||
return;
|
||||
switch (command)
|
||||
{
|
||||
case RowerCommand.JustRow:
|
||||
SetJustRow();
|
||||
break;
|
||||
case RowerCommand.FixedDistance:
|
||||
SetFixedDistance(data);
|
||||
break;
|
||||
case RowerCommand.FixedTime:
|
||||
SetFixedTime(data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (C2RowerData.IsEnabled == true)
|
||||
@@ -188,23 +211,110 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
if (this.controlPointCharacteristic != null)
|
||||
{
|
||||
Debug.Log("发送重置命令" + this.controlPointCharacteristic.ToString());
|
||||
//App.cacheList.Add(DateTime.Now.ToString() + ":发送重置命令" + this.controlPointCharacteristic.ToString());
|
||||
hwInterface.WriteCharacteristic(this.controlPointCharacteristic, new byte[] { 0x01 });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="workoutType">训练类型:0,1,2(里程不分段),3(里程分段),4(时间不分段),5,6,7,8~13</param>
|
||||
public void SetWorkoutType(int workoutType)
|
||||
{
|
||||
var typeHex = workoutType.ToString("X2");
|
||||
var checkSum = "00";
|
||||
var data = BitConvertHelper.HexToByteArray($"F1 76 03 01 01 {typeHex} {checkSum} F2");//"F1 76 03 01 01 03 76 F2"//03?
|
||||
checkSum = GetChecksumHexString(data);
|
||||
data = BitConvertHelper.HexToByteArray($"F1 76 03 01 01 {typeHex} {checkSum} F2");
|
||||
hwInterface.WriteCharacteristic(this.c2Control, data);
|
||||
Thread.Sleep(5);
|
||||
}
|
||||
public void SetConfigureWorkout()
|
||||
{
|
||||
var data = BitConvertHelper.HexToByteArray("F1 76 03 14 01 01 61 F2"); //03?
|
||||
hwInterface.WriteCharacteristic(this.c2Control, data);
|
||||
Thread.Sleep(5);
|
||||
}
|
||||
public void SetScreenState()
|
||||
{
|
||||
var data = BitConvertHelper.HexToByteArray("F1 76 04 13 02 01 01 63 F2"); //04?
|
||||
hwInterface.WriteCharacteristic(this.c2Control, data);
|
||||
}
|
||||
public void SetPoll()
|
||||
{
|
||||
var data = BitConvertHelper.HexToByteArray($"F1 76 07 8D 93 A3 A0 A8 B3 B6 C1 F2");
|
||||
hwInterface.WriteCharacteristic(this.c2Control, data);
|
||||
}
|
||||
public void SetJustRow()
|
||||
{
|
||||
var data = BitConvertHelper.HexToByteArray("F1 76 07 01 01 01 13 02 01 01 61 F2");
|
||||
Debug.Log($"SetJustRow:{string.Join(",", data)}");
|
||||
hwInterface.WriteCharacteristic(this.c2Control, data);
|
||||
Thread.Sleep(5);
|
||||
SetScreenState();
|
||||
}
|
||||
public void SetFixedDistance(int distance)
|
||||
{
|
||||
if (distance < 100)
|
||||
return;
|
||||
|
||||
SetWorkoutType(3);
|
||||
|
||||
var hexditance = distance.ToString("X4");
|
||||
var checkSum = "00";
|
||||
var data = BitConvertHelper.HexToByteArray($"F1 76 07 03 05 80 00 00 {hexditance} {checkSum} F2");//F1 76 07 03 05 80 00 00 {hexditance} {checkSum} F2
|
||||
checkSum = GetChecksumHexString(data);
|
||||
data = BitConvertHelper.HexToByteArray($"F1 76 07 03 05 80 00 00 {hexditance} {checkSum} F2");//07?
|
||||
hwInterface.WriteCharacteristic(this.c2Control, data);
|
||||
Thread.Sleep(5);
|
||||
|
||||
SetConfigureWorkout();
|
||||
|
||||
SetScreenState();
|
||||
|
||||
}
|
||||
private string GetChecksumHexString(byte[] data)
|
||||
{
|
||||
var res = data[1];
|
||||
for (int i = 2; i < data.Length-2; i++)
|
||||
{
|
||||
res ^= data[i];
|
||||
}
|
||||
return res.ToString("X2");
|
||||
}
|
||||
public void SetFixedTime(int mins)
|
||||
{
|
||||
SetWorkoutType(5);
|
||||
Thread.Sleep(5);
|
||||
var timeHex = (mins * 100).ToString("X6");
|
||||
var checkNum = "00";
|
||||
var data = BitConvertHelper.HexToByteArray($"F1 76 07 03 05 00 00 {timeHex} {checkNum} F2");
|
||||
checkNum = GetChecksumHexString(data);
|
||||
data = BitConvertHelper.HexToByteArray($"F1 76 07 03 05 00 00 {timeHex} {checkNum} F2");
|
||||
hwInterface.WriteCharacteristic(this.c2Control, data);
|
||||
Thread.Sleep(5);
|
||||
SetConfigureWorkout();
|
||||
Thread.Sleep(5);
|
||||
SetScreenState();
|
||||
}
|
||||
|
||||
public void SetResistanceLevel(ushort v)
|
||||
{
|
||||
if (C2RowerData.IsEnabled == true)
|
||||
{
|
||||
//等对csafe协议研究透彻后写
|
||||
////等对csafe协议研究透彻后写
|
||||
//if (this.c2Control != null)
|
||||
//{
|
||||
// var data = new byte[] { 0x29 }.Concat(BitConverter.GetBytes(v)).ToArray();
|
||||
// byte checksum = (byte)((byte)(data[0] ^ data[1]) ^ data[2]);
|
||||
// var r = new byte[] { 0xF1 }.Concat(data).Concat(new byte[] { checksum, 0xf2 }) .ToArray();
|
||||
// Debug.Log($"设置阻力{v}, {string.Join(",", r)}");
|
||||
// hwInterface.WriteCharacteristic(this.c2Control, r);
|
||||
//02312131 = > 03010103
|
||||
//var data = new byte[] { 0x76 }.Concat(BitConverter.GetBytes(v)).ToArray();
|
||||
//byte checksum = (byte)((byte)(data[0] ^ data[1]) ^ data[2]);
|
||||
//var r = new byte[] { 0xF1 }.Concat(data).Concat(new byte[] { checksum, 0xf2 }).ToArray();
|
||||
//Debug.Log($"设置阻力{v}, {string.Join(",", r)}");
|
||||
//
|
||||
// var data = BitConvertHelper.HexToByteArray("F1 76 07 01 01 01 13 02 01 01 61 F2");
|
||||
// hwInterface.WriteCharacteristic(this.c2Control, data);
|
||||
//}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace Assets.Scripts.Devices.Ble.Interfaces
|
||||
int ResistanceLevel { get; set; }
|
||||
void Reset();
|
||||
event EventHandler StartEvent;
|
||||
event EventHandler CompleteEvent;//结束事件
|
||||
event EventHandler RowerResChanged;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using UnityEngine;
|
||||
@@ -116,6 +117,10 @@ namespace Assets.Scripts.Ble
|
||||
private void ManagerStatusChanged(BleMobileThread sender, WclBleManagerStatus status)
|
||||
{
|
||||
this.BleState = BleMobileInterface.StateFromNativeState(status);
|
||||
if (this.BleState == BleState.Off)
|
||||
{
|
||||
ClearAllCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
private void WatcherScanInfoReceived(BleMobileThread sender, string address, string name, int rssi,string[] uuids)
|
||||
@@ -236,6 +241,7 @@ namespace Assets.Scripts.Ble
|
||||
IsSuccess = true,
|
||||
Error = null
|
||||
};
|
||||
PeripheralDisconnected(address, info);//连接前断开
|
||||
callback?.Invoke(self, info, s);
|
||||
this.callbacks.Remove(info);
|
||||
Debug.Log("连接成功!" + info.Name);
|
||||
@@ -337,8 +343,6 @@ namespace Assets.Scripts.Ble
|
||||
{
|
||||
characteristicsDiscoveredCallbacks.Remove(characteristicsDiscoveredCallback.First().Key);
|
||||
}
|
||||
|
||||
peripheralDisconnectedEvent(this, info, null, false);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -348,6 +352,7 @@ namespace Assets.Scripts.Ble
|
||||
BluetoothLEHardwareInterface.DisconnectPeripheral(peripheral.Address, (address) =>
|
||||
{
|
||||
Debug.Log("断开回调"+ address);
|
||||
PeripheralDisconnected(address,peripheral);
|
||||
peripheralDisconnectedEvent(this, peripheral, null, true);
|
||||
callback?.Invoke();
|
||||
});
|
||||
@@ -374,6 +379,17 @@ namespace Assets.Scripts.Ble
|
||||
{
|
||||
bleMobileThread?.Stop();
|
||||
}
|
||||
|
||||
public void ClearAllCallbacks()
|
||||
{
|
||||
callbacks?.Clear();
|
||||
servicesCallbacks?.Clear();
|
||||
characteristicNotificationCallbacks?.Clear();
|
||||
characteristicReadCallbacks?.Clear();
|
||||
characteristicsDiscoveredCallbacks?.Clear();
|
||||
_discoveredCallback = null;
|
||||
_pCache?.Clear();
|
||||
}
|
||||
|
||||
//发现服务列表
|
||||
public void DiscoverServices(BlePeripheralInfo peripheral, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse<List<BleServiceInfo>>> callback)
|
||||
@@ -398,10 +414,11 @@ namespace Assets.Scripts.Ble
|
||||
{
|
||||
this.characteristicNotificationCallbacks.Add(characteristic.Peripheral, callback);
|
||||
}
|
||||
Debug.Log("SubscribeCharacteristic" + characteristic.Peripheral.Name + characteristic.Service.ToString() + characteristic.Service.ToString());
|
||||
Thread.Sleep(50);
|
||||
Debug.Log("SubscribeCharacteristic" + characteristic.Peripheral.Name + characteristic.Service.ToString() + characteristic.Id.ToString());
|
||||
BluetoothLEHardwareInterface.SubscribeCharacteristicWithDeviceAddress(characteristic.Peripheral.Address, characteristic.Service.ToString(), characteristic.Id.ToString(), (a,b)=>
|
||||
{
|
||||
Debug.Log("返回特征值," + a + "," + b);
|
||||
Debug.Log("返回特征值," + a + "," + b+DateTime.Now.ToString());
|
||||
}, (deviceAddress, characteristric, bytes) =>
|
||||
{
|
||||
if (characteristicReadEvent != null)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using System.Timers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble
|
||||
{
|
||||
@@ -35,76 +36,17 @@ namespace Assets.Scripts.Devices.Ble
|
||||
this.managerStatusChanged -= value;
|
||||
}
|
||||
}
|
||||
WclBleManagerStatus statusEnum = WclBleManagerStatus.RadioOff;
|
||||
WclBleManagerStatus statusEnum = WclBleManagerStatus.RadioOn;
|
||||
internal BleMobileThread() {
|
||||
var self = this;
|
||||
//初始蓝牙
|
||||
BluetoothLEHardwareInterface.Initialize(true, false, () => {
|
||||
statusEnum = WclBleManagerStatus.RadioOn;
|
||||
managerInitialized?.Invoke(self);
|
||||
},
|
||||
(error) => {
|
||||
statusEnum = WclBleManagerStatus.RadioOff;
|
||||
BluetoothLEHardwareInterface.Log("Error: " + error);
|
||||
if (error.Contains("Bluetooth LE Not Enabled"))
|
||||
BluetoothLEHardwareInterface.BluetoothEnable(true);
|
||||
}, (status) => {
|
||||
|
||||
statusEnum = WclBleManagerStatus.RadioOn;
|
||||
switch (status)
|
||||
{
|
||||
case 13:
|
||||
statusEnum = WclBleManagerStatus.RadioOff;
|
||||
break;
|
||||
case 11:
|
||||
statusEnum = WclBleManagerStatus.RadioOn;
|
||||
break;
|
||||
}
|
||||
if (managerStatusChanged != null)
|
||||
{
|
||||
managerStatusChanged.Invoke(self, statusEnum);
|
||||
}
|
||||
});
|
||||
Initialize();//初始蓝牙
|
||||
}
|
||||
|
||||
public void StartWatcher() {
|
||||
var self = this;
|
||||
if (statusEnum == WclBleManagerStatus.RadioOff)
|
||||
{
|
||||
//Initialize();
|
||||
BluetoothLEHardwareInterface.BluetoothEnable(true);
|
||||
BluetoothLEHardwareInterface.Initialize(true, false, () =>
|
||||
{
|
||||
statusEnum = WclBleManagerStatus.RadioOn;
|
||||
managerInitialized?.Invoke(self);
|
||||
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(ServiceUuids.GetServiceUuidList().ToArray(), null, (address, name, rssi, bytes) =>
|
||||
{
|
||||
ScanInfoReceived?.Invoke(self, address, name, rssi, bytes);
|
||||
}, true);
|
||||
},
|
||||
(error) =>
|
||||
{
|
||||
statusEnum = WclBleManagerStatus.RadioOff;
|
||||
BluetoothLEHardwareInterface.Log("Error: " + error);
|
||||
if (error.Contains("Bluetooth LE Not Enabled"))
|
||||
BluetoothLEHardwareInterface.BluetoothEnable(true);
|
||||
}, (status) =>
|
||||
{
|
||||
|
||||
statusEnum = WclBleManagerStatus.RadioOn;
|
||||
switch (status)
|
||||
{
|
||||
case 13:
|
||||
statusEnum = WclBleManagerStatus.RadioOff;
|
||||
break;
|
||||
case 11:
|
||||
statusEnum = WclBleManagerStatus.RadioOn;
|
||||
break;
|
||||
}
|
||||
if (managerStatusChanged != null)
|
||||
{
|
||||
managerStatusChanged.Invoke(self, statusEnum);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -114,6 +56,53 @@ namespace Assets.Scripts.Devices.Ble
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
public void Initialize()
|
||||
{
|
||||
Debug.Log("Initialize");
|
||||
var self = this;
|
||||
BluetoothLEHardwareInterface.BluetoothEnable(true);
|
||||
BluetoothLEHardwareInterface.Initialize(true, false, () =>
|
||||
{
|
||||
statusEnum = WclBleManagerStatus.RadioOn;
|
||||
managerInitialized?.Invoke(self);
|
||||
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(ServiceUuids.GetServiceUuidList().ToArray(), null, (address, name, rssi, bytes) =>
|
||||
{
|
||||
ScanInfoReceived?.Invoke(self, address, name, rssi, bytes);
|
||||
}, true);
|
||||
},
|
||||
(error) =>
|
||||
{
|
||||
statusEnum = WclBleManagerStatus.RadioOff;
|
||||
BluetoothLEHardwareInterface.Log("Error: " + error);
|
||||
if (error.Contains("Bluetooth LE Not Enabled"))
|
||||
BluetoothLEHardwareInterface.BluetoothEnable(true);
|
||||
}, (status) =>
|
||||
{
|
||||
statusEnum = WclBleManagerStatus.RadioOn;
|
||||
switch (status)
|
||||
{
|
||||
case 10:
|
||||
statusEnum = WclBleManagerStatus.RadioOff;
|
||||
break;
|
||||
case 13:
|
||||
statusEnum = WclBleManagerStatus.RadioOff;
|
||||
break;
|
||||
case 11:
|
||||
statusEnum = WclBleManagerStatus.RadioOff;
|
||||
break;
|
||||
case 12:
|
||||
statusEnum = WclBleManagerStatus.RadioOn;
|
||||
break;
|
||||
default:
|
||||
statusEnum = WclBleManagerStatus.RadioOff;
|
||||
break;
|
||||
}
|
||||
if (managerStatusChanged != null)
|
||||
{
|
||||
managerStatusChanged.Invoke(self, statusEnum);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
|
||||
@@ -119,5 +119,17 @@ namespace Assets.Scripts.Devices
|
||||
str += "---------------------------\r\n";
|
||||
Debug.Log(str);
|
||||
}
|
||||
|
||||
public BleDeviceAdapter GetBleDeviceAdapter()
|
||||
{
|
||||
foreach (var item in adapters)
|
||||
{
|
||||
var bleadapter = (BleDeviceAdapter)item;
|
||||
if (bleadapter != null) {
|
||||
return bleadapter;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user