This commit is contained in:
tanglong 2025-07-24 11:40:55 +08:00
parent 19fc9d1963
commit 9bdd1b5236

View File

@ -1,5 +1,6 @@
 
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileSystemGlobbing.Internal;
using MQTTnet; using MQTTnet;
using MQTTnet.Client; using MQTTnet.Client;
using MQTTnet.Protocol; using MQTTnet.Protocol;
@ -112,40 +113,29 @@ namespace YD_AllHeartRates.Api.Mqtt
var heartRateEntities = new ConcurrentBag<HeartRateData>(); var heartRateEntities = new ConcurrentBag<HeartRateData>();
var jumpRopeEntities = new ConcurrentBag<JumpRopeData>(); var jumpRopeEntities = new ConcurrentBag<JumpRopeData>();
Parallel.ForEach(batch, msg => var deviceMap = _devices.ToDictionary(x => x.Code, x => x.StudentNo);
{ var studentMap = _studentList.ToDictionary(x => x.StudentNo, x => x);
if (string.IsNullOrWhiteSpace(msg.Payload)) return;
BlePayload payload; Parallel.ForEach(batch, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, msg =>
{
try try
{ {
payload = JsonSerializer.Deserialize<BlePayload>(msg.Payload, _jsonOpt); if (string.IsNullOrWhiteSpace(msg.Payload)) return;
if (payload == null) return; var payload = JsonSerializer.Deserialize<BlePayload>(msg.Payload, _jsonOpt);
} if (payload == null || payload.devices == null || payload.devices.Count == 0) return;
catch (JsonException ex)
{
_log.LogWarning(ex, "Payload 不是合法 JSON: {Json}", msg.Payload);
return;
}
var heartRateList = payload.devices.Where(x => x.bs_name.Contains("GTY0")).ToList();
var jumpRopeList = payload.devices.Where(x => x.bs_name.Contains("RS207")).ToList();
var scoreTime = DateTime.ParseExact(payload.send_time, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); var scoreTime = DateTime.ParseExact(payload.send_time, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
foreach (var ble in payload.devices)
foreach (var ble in heartRateList)
{ {
if (!deviceMap.TryGetValue(ble.bs_name, out var studentNo)) continue;
if (!studentMap.TryGetValue(studentNo, out var student)) continue;
if (string.IsNullOrWhiteSpace(ble.Broadcast_data)) continue; if (string.IsNullOrWhiteSpace(ble.Broadcast_data)) continue;
var studentNo = _devices.Where(x => x.Code == ble.bs_name).Select(x => x.StudentNo).FirstOrDefault();
if (string.IsNullOrEmpty(studentNo))
continue;
var student = _studentList.FirstOrDefault(x => x.StudentNo == studentNo);
if (student == null || student.GradeId == 0 || student.ClassId == 0) continue;
var data = ParseHexData(ble.Broadcast_data); var data = ParseHexData(ble.Broadcast_data);
if (data == null) continue; if (data == null) continue;
if (ble.bs_name.Contains("GTY0"))
{
int cd = Array.IndexOf(data, (byte)0xCD); int cd = Array.IndexOf(data, (byte)0xCD);
if (cd < 0 || data.Length < cd + 9) continue; if (cd < 0 || data.Length < cd + 9) continue;
@ -171,28 +161,12 @@ namespace YD_AllHeartRates.Api.Mqtt
}; };
heartRateEntities.Add(entity); heartRateEntities.Add(entity);
var heartRateKey = $"heartRate:{student.StudentNo}"; _caching.AddObject($"heartRate:{student.StudentNo}", entity, 60);
_caching.AddObject(heartRateKey, entity, 60); // 1分钟缓存 RedisHelper.SAdd($"school:{student.SchoolCode}:students", student.StudentNo);
// 更新学校学生编号集合Set
var studentSetKey = $"school:{student.SchoolCode}:students";
RedisHelper.SAdd(studentSetKey, student.StudentNo); // 自动去重
RedisHelper.Expire(studentSetKey, 60);
} }
foreach (var ble in jumpRopeList) else if (ble.bs_name.Contains("RS207"))
{ {
if (string.IsNullOrWhiteSpace(ble.Broadcast_data)) continue;
var studentNo = _devices.Where(x => x.Code == ble.bs_name).Select(x => x.StudentNo).FirstOrDefault();
if (string.IsNullOrEmpty(studentNo))
continue;
var student = _studentList.FirstOrDefault(x => x.StudentNo == studentNo);
if (student == null || student.GradeId == 0 || student.ClassId == 0) continue;
var data = ParseHexData(ble.Broadcast_data);
if (data == null) continue;
int mfIndex = IndexOfSequence(data, new byte[] { 0xFF, 0x04, 0xFF, 0xCF }); int mfIndex = IndexOfSequence(data, new byte[] { 0xFF, 0x04, 0xFF, 0xCF });
if (mfIndex < 0 || data.Length < mfIndex + 10) continue; if (mfIndex < 0 || data.Length < mfIndex + 10) continue;
@ -217,23 +191,10 @@ namespace YD_AllHeartRates.Api.Mqtt
StudentName = student.StudentName StudentName = student.StudentName
}; };
//if (!string.IsNullOrWhiteSpace(student.SchoolCode))
//{
// // WebSocket 推送
// await _wsSender.SendToSchoolAsync(student.SchoolCode, "heartRate", heartRateEntities);
// await _wsSender.SendToSchoolAsync(student.SchoolCode, "jumpRope", _jumpDailyMap.Values.ToList());
//}
var jumpKey = $"jumpRope:active:{student.StudentNo}:{DateTime.Now:yyyyMMdd}"; var jumpKey = $"jumpRope:active:{student.StudentNo}:{DateTime.Now:yyyyMMdd}";
var rawKey = $"jumpRope:raw:{student.StudentNo}:{DateTime.Now:yyyyMMdd}"; var rawKey = $"jumpRope:raw:{student.StudentNo}:{DateTime.Now:yyyyMMdd}";
// 当前缓存的总值(当天跳绳数据) var totalData = _caching.Get<JumpRopeData>(jumpKey) ?? new JumpRopeData
var totalData = _caching.Get<JumpRopeData>(jumpKey);
// 初始化总值(首次记录)
if (totalData == null)
{
totalData = new JumpRopeData
{ {
StudentNo = jumpData.StudentNo, StudentNo = jumpData.StudentNo,
JumpValue = 0, JumpValue = 0,
@ -241,12 +202,9 @@ namespace YD_AllHeartRates.Api.Mqtt
QuantityOfElectricity = jumpData.QuantityOfElectricity, QuantityOfElectricity = jumpData.QuantityOfElectricity,
ScoreTime = jumpData.ScoreTime ScoreTime = jumpData.ScoreTime
}; };
}
// 上一条原始累计值(用于计算差值)
var lastRaw = _caching.Get<JumpRopeData>(rawKey); var lastRaw = _caching.Get<JumpRopeData>(rawKey);
// 差值计算
int deltaJump = jumpData.JumpValue; int deltaJump = jumpData.JumpValue;
int deltaError = jumpData.ErrorNumber; int deltaError = jumpData.ErrorNumber;
@ -261,24 +219,19 @@ namespace YD_AllHeartRates.Api.Mqtt
: jumpData.ErrorNumber; : jumpData.ErrorNumber;
} }
// 汇总
totalData.JumpValue += deltaJump; totalData.JumpValue += deltaJump;
totalData.ErrorNumber += deltaError; totalData.ErrorNumber += deltaError;
totalData.QuantityOfElectricity = jumpData.QuantityOfElectricity; totalData.QuantityOfElectricity = jumpData.QuantityOfElectricity;
totalData.ScoreTime = jumpData.ScoreTime; totalData.ScoreTime = jumpData.ScoreTime;
// 写入缓存(总值 + 原始值)
_caching.AddObject(jumpKey, totalData, 28800); _caching.AddObject(jumpKey, totalData, 28800);
_caching.AddObject(rawKey, jumpData, 60); _caching.AddObject(rawKey, jumpData, 60);
}
// 记录活跃学生编号(便于定时入库) }
//RedisHelper.SAdd($"jumpRope:active:{DateTime.Now:yyyyMMdd}", student.StudentNo); }
catch (Exception ex)
//var studentSetKey = $"school:{student.SchoolCode}:students"; {
//var jumpKey = $"jumpRope:{student.StudentNo}"; _log.LogError(ex, "处理 BLE 消息异常");
//_caching.AddObject(jumpKey, jumpData, 60);
//RedisHelper.SAdd(studentSetKey, student.StudentNo);
} }
}); });