新手环

This commit is contained in:
tanglong 2026-03-10 09:54:46 +08:00
parent d7eaf1af8b
commit 4183408f15
20 changed files with 42 additions and 26 deletions

View File

@ -0,0 +1,6 @@
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 无法为 YD_AllHeartRates.Commons.Dto.ResponseMsg 生成存根: 类型没有对程序集可见的构造函数。构造函数本身或参数可能不可见。。
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 无法为 YD_AllHeartRates.Commons.MemoryCaches.MemoryCacheSetup 生成存根: 类型没有对程序集可见的构造函数。构造函数本身或参数可能不可见。。
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 无法为 YD_AllHeartRates.Commons.Middlewares.SystemExceptionApplicationBuilderExtensions 生成存根: 类型没有对程序集可见的构造函数。构造函数本身或参数可能不可见。。
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 无法为 YD_AllHeartRates.Commons.Utils.Util 生成存根: 类型没有对程序集可见的构造函数。构造函数本身或参数可能不可见。。
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 正在跳过 method System.Int32 YD_AllHeartRates.Commons.Utils.Util.GetRank(!!0 score),method System.Int32 YD_AllHeartRates.Commons.Utils.Util.GetRank(!!0 score) unstubbable: 无法同时指定类约束和 "class" 或 "struct" 约束
C:\Users\tangl\Desktop\Git\YD_AllHeartRates.Api\YD_AllHeartRates.Api\Fakes\YD_AllHeartRates.Commons.fakes : warning : 正在跳过 method System.String YD_AllHeartRates.Commons.Utils.Util.GetRankStr(!!0 score),method System.String YD_AllHeartRates.Commons.Utils.Util.GetRankStr(!!0 score) unstubbable: 无法同时指定类约束和 "class" 或 "struct" 约束

View File

@ -191,21 +191,29 @@ namespace YD_AllHeartRates.Api.Mqtt
if (!studentHMap.TryGetValue(ble.bs_name, out var student))
return;
if (payloadLength < 17) return; // payload 不够长,丢弃
if (payloadLength < 17 || payloadStart + payloadLength > data.Length)
return;
ushort vendorId = (ushort)(data[payloadStart] | (data[payloadStart + 1] << 8));
int battery = data[payloadStart + 2];
int heartRate = data[payloadStart + 3];
int calorie = data[payloadStart + 4];
int hrv = data[payloadStart + 5];
int statusFlag = data[payloadStart + 6];
int step = data[payloadStart + 7] | (data[payloadStart + 8] << 8);
int intensity = data[payloadStart + 9];
string deviceNo = Encoding.ASCII.GetString(data, payloadStart + 10, 7).TrimEnd('\0');
// 厂商ID 3字节
byte[] vendorBytes = new byte[3];
Array.Copy(data, payloadStart, vendorBytes, 0, 3);
ushort vendorId = (ushort)(vendorBytes[0] | (vendorBytes[1] << 8));
Console.WriteLine($"HR={heartRate}, Battery={battery}, Step={step}, Intensity={intensity}, Device={deviceNo}");
int battery = data[payloadStart + 3]; // 电量
int heartRate = data[payloadStart + 4]; // 心率
int calorie = data[payloadStart + 5];
int hrv = data[payloadStart + 6];
int statusFlag = data[payloadStart + 7];
if (heartRate <= 30 || heartRate > 220) return;
int step = data[payloadStart + 8] | (data[payloadStart + 9] << 8);
int intensity = data[payloadStart + 10];
string deviceNo = Encoding.ASCII.GetString(data, payloadStart + 11, 7).TrimEnd('\0');
Console.WriteLine($"Vendor={BitConverter.ToString(vendorBytes)}, Battery={battery}, HR={heartRate}, Step={step}, Intensity={intensity}, Device={deviceNo}");
if (heartRate <= 30 || heartRate > 220)
return;
var entity = new HeartRateData
{
@ -228,8 +236,6 @@ namespace YD_AllHeartRates.Api.Mqtt
RedisHelper.SAdd($"school:{student.SchoolCode}:students", student.StudentNo);
}
else if (ble.bs_name.Contains("RS207"))
{
//if (!deviceJMap.TryGetValue(ble.bs_name, out var studentNo)) continue;
@ -342,24 +348,28 @@ namespace YD_AllHeartRates.Api.Mqtt
payloadLength = 0;
int idx = 0;
while (idx < length - 1)
{
byte len = data[idx++]; // 段长度
if (len == 0 || idx + len > length) break; // 越界或无效
byte len = data[idx++]; // 段长度
byte type = data[idx]; // 段类型
if (len == 0 || idx + len > length)
break;
if (type == 0xFF) // 找到有效心率段
byte type = data[idx]; // 段首字节
// 找到厂商数据段
if (type == 0xFF)
{
payloadStart = idx + 1; // payload 从 type 后开始
payloadLength = len - 1; // payload 长度 = len - 1
payloadStart = idx; // 从0xFF开始解析
payloadLength = len; // 整段长度
return true;
}
idx += len; // 跳过当前段,idx 指向下一段的长度字节
idx += len; // 跳到下一段
}
return false; // 没有找到
return false;
}
private async Task RunJumpSyncLoopAsync(CancellationToken token)
{

View File

@ -14,7 +14,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("YD_AllHeartRates.Api")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+aa2d4b8c22d757dc2b820c6e8f17252bcba733a0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d7eaf1af8ba5ff0957dfc95149cfa9877fd1f0c8")]
[assembly: System.Reflection.AssemblyProductAttribute("YD_AllHeartRates.Api")]
[assembly: System.Reflection.AssemblyTitleAttribute("YD_AllHeartRates.Api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
003458ec85ddf870152c7f82e2efc09346dff244d6e553ff6114752ffb5b77ff
cdc9bcd3b212d4cf2ddf231e1d9fba93f70c653e918f5653040a21227de2658c

View File

@ -14,7 +14,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("YD_AllHeartRates.Commons")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+aa2d4b8c22d757dc2b820c6e8f17252bcba733a0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d7eaf1af8ba5ff0957dfc95149cfa9877fd1f0c8")]
[assembly: System.Reflection.AssemblyProductAttribute("YD_AllHeartRates.Commons")]
[assembly: System.Reflection.AssemblyTitleAttribute("YD_AllHeartRates.Commons")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
e4ff97a3a2a2d381ade9bb02ffafa53f744c9336f6f75562dddf1a77ca5fa0bc
744316f83df41653b66bcfd20658eb8eaf1df2cbf71e10432cf6edd85276f4e2