diff --git a/HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs b/HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs index 0efc63d..8517f90 100644 --- a/HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs +++ b/HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs @@ -440,17 +440,21 @@ namespace HealthMonitor.Service.Resolver // 判断是否够highFreqSampleTimes,540s if (ts < highFreqSampleTimes) { - /// 不够10分钟最近12个数据的最小值生成胎心值 - heartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - _logger.LogInformation($"{heartRate.Serialno} 不够10分钟最近12个数据的最小值 {heartRate.HeartRate} 生成胎心值"); - + /// 不够10分钟最近12个数据生成胎心值 + int selectedHrValue = SelectValueFromFreqHeartRate(heartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + + heartRate.HeartRate = selectedHrValue; + _logger.LogInformation($"{heartRate.Serialno} 不够10分钟最近12个数据中取 {heartRate.HeartRate} 生成胎心值"); + heartRate.LastUpdate = lastFreqHr.LastUpdate; } else { - heartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - /// 超过10分钟最近12个数据的最小值生成胎心值 - _logger.LogInformation($"{heartRate.Serialno} 超过10分钟最近12个数据的最小值 {heartRate.HeartRate} 生成胎心值"); + + /// 超过10分钟最近12个数据生成胎心值 + int selectedHrValue = SelectValueFromFreqHeartRate(heartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + heartRate.HeartRate = selectedHrValue; + _logger.LogInformation($"{heartRate.Serialno} 超过10分钟最近12个数据中取 {heartRate.HeartRate} 生成胎心值"); } _logger.LogInformation($"{heartRate.Serialno} 高频数据触发连续12个值都是正常的的高频心率处理"); await SaveAndPushFetalHeartRateEndFreqHeartRateAsync(heartRate, commonPHR,highFreqSampleTimes ,upperAlarmThreshold, lowerAlarmThreshold, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString(), phrFreqstatus!.LastUpdate, FreqStatsEnd); @@ -487,7 +491,8 @@ namespace HealthMonitor.Service.Resolver var lastPhr = phr.OrderByDescending(i => i.LastUpdate) .Where(i => i.LastUpdate >= phrFreqstatus?.LastUpdate) .Skip(1) // 去除首条 - .Where(i => i.PregnancyHeartRate < triggerHighFreqLow || i.PregnancyHeartRate > triggerHighFreqHigh); + .Where(i => i.PregnancyHeartRate < triggerHighFreqLow || i.PregnancyHeartRate > triggerHighFreqHigh) + .ToList(); //.Select(i => i.PregnancyHeartRate); //.Average(); @@ -510,17 +515,19 @@ namespace HealthMonitor.Service.Resolver // 判断是否够highFreqSampleTimes,540s if (ts < highFreqSampleTimes) { - /// 不够10分钟最近12个数据的最小值生成胎心值 - heartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - _logger.LogInformation($"{heartRate.Serialno} 不够10分钟最近12个数据的最小值 {heartRate.HeartRate} 生成胎心值"); + /// 不够10分钟最近12个数据生成胎心值 + int selectedHrValue = SelectValueFromFreqHeartRate(heartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + heartRate.HeartRate = selectedHrValue; + _logger.LogInformation($"{heartRate.Serialno} 不够10分钟最近12个数据中取 {heartRate.HeartRate} 生成胎心值"); heartRate.LastUpdate = lastFreqHr.LastUpdate; } else { - heartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - /// 超过10分钟最近12个数据的最小值生成胎心值 - _logger.LogInformation($"{heartRate.Serialno} 超过10分钟最近12个数据的最小值 {heartRate.HeartRate} 生成胎心值"); + int selectedHrValue = SelectValueFromFreqHeartRate(heartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + heartRate.HeartRate = selectedHrValue; + /// 超过10分钟最近12个数据生成胎心值 + _logger.LogInformation($"{heartRate.Serialno} 超过10分钟最近12个数据中取 {heartRate.HeartRate} 生成胎心值"); } _logger.LogInformation($"{heartRate.Serialno} 高频结束后的highFreqSampleTimes=0的高频心率处理"); await SaveAndPushFetalHeartRateEndFreqHeartRateAsync(heartRate, commonPHR, highFreqSampleTimes, upperAlarmThreshold, lowerAlarmThreshold, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString(), phrFreqstatus!.LastUpdate, FreqStatsEnd); @@ -560,7 +567,7 @@ namespace HealthMonitor.Service.Resolver // 判断是否够highFreqSampleTimes,540s var lastPhr = filterPhr .OrderByDescending(i => i.LastUpdate) - .Take(stopHighFreqSampleCount); + .Take(stopHighFreqSampleCount).ToList(); // 最后一条高频心率 var lastFreqHr = lastPhr.First(); @@ -569,17 +576,19 @@ namespace HealthMonitor.Service.Resolver if (ts < highFreqSampleTimes) { - /// 不够10分钟最近12个数据的最小值生成胎心值 - heartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - _logger.LogInformation($"{heartRate.Serialno} 不够10分钟最近12个数据的最小值 {heartRate.HeartRate} 生成胎心值"); + /// 不够10分钟最近12个数据的成胎心值 + int selectedHrValue = SelectValueFromFreqHeartRate(heartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + heartRate.HeartRate = selectedHrValue; + _logger.LogInformation($"{heartRate.Serialno} 不够10分钟最近12个数据中取 {heartRate.HeartRate} 生成胎心值"); heartRate.LastUpdate = lastFreqHr.LastUpdate; } else { - heartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - /// 超过10分钟最近12个数据的最小值生成胎心值 - _logger.LogInformation($"{heartRate.Serialno} 超过10分钟最近12个数据的最小值 {heartRate.HeartRate} 生成胎心值"); + int selectedHrValue = SelectValueFromFreqHeartRate(heartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + heartRate.HeartRate = selectedHrValue; + /// 超过10分钟最近12个数据的生成胎心值 + _logger.LogInformation($"{heartRate.Serialno} 超过10分钟最近12个数据的中取 {heartRate.HeartRate} 生成胎心值"); } _logger.LogInformation($"{heartRate.Serialno} 高频结束后的在highFreqSampleTimes>0 正常心率(通常情况)触发的高频心率处理"); await SaveAndPushFetalHeartRateEndFreqHeartRateAsync(heartRate, commonPHR, highFreqSampleTimes, upperAlarmThreshold, lowerAlarmThreshold, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString(), phrFreqstatus!.LastUpdate, FreqStatsEnd); @@ -612,21 +621,7 @@ namespace HealthMonitor.Service.Resolver .OrderByDescending(i => i.LastUpdate); // 取得高频数据 var freqCollection = phrFlashBack.ToList(); - //var freqCollection = new List(); - //PregnancyHeartRateModel? previousItem = null; - - //foreach (var item in phrFlashBack) - //{ - // if (previousItem != null) - // { - // var timeNextDiff = (previousItem!.LastUpdate - item.LastUpdate).TotalSeconds; - // if (timeNextDiff <= highFreqSampleInterval) - // { - // freqCollection.Add(item); - // } - // } - // previousItem = item; - //} + _logger.LogInformation($"{heartRate.Serialno} 高频数据个数{freqCollection.Count},触发高频开始时间{phrFreqstatus!.LastUpdate}"); if (freqCollection.Count > stopHighFreqSampleCount) @@ -644,24 +639,27 @@ namespace HealthMonitor.Service.Resolver // 判断是否够highFreqSampleTimes,540s var lastPhr = freqCollection .OrderByDescending(i => i.LastUpdate) - .Take(stopHighFreqSampleCount); + .Take(stopHighFreqSampleCount) + .ToList(); // 最后一条高频心率 var lastFreqHr = lastPhr.First(); var ts = DateTimeUtil.GetTimeDifferenceInSeconds((DateTime)lastFreqHr.LastUpdate!, phrFreqstatus!.LastUpdate); if (ts < highFreqSampleTimes) { - /// 不够10分钟最近12个数据的最小值生成胎心值 - heartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - _logger.LogInformation($"{heartRate.Serialno} 不够10分钟最近12个数据的最小值 {heartRate.HeartRate} 生成胎心值"); + /// 不够10分钟最近12个数据生成胎心值 + int selectedHrValue = SelectValueFromFreqHeartRate(heartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + heartRate.HeartRate = selectedHrValue; + _logger.LogInformation($"{heartRate.Serialno} 不够10分钟最近12个数据中取 {heartRate.HeartRate} 生成胎心值"); heartRate.LastUpdate = lastFreqHr.LastUpdate; } else { - heartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - /// 超过10分钟最近12个数据的最小值生成胎心值 - _logger.LogInformation($"{heartRate.Serialno} 超过10分钟最近12个数据的最小值 {heartRate.HeartRate} 生成胎心值"); + int selectedHrValue = SelectValueFromFreqHeartRate(heartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + heartRate.HeartRate = selectedHrValue; + /// 超过10分钟最近12个数据生成胎心值 + _logger.LogInformation($"{heartRate.Serialno} 超过10分钟最近12个数据中取 {heartRate.HeartRate} 生成胎心值"); } _logger.LogInformation($"{heartRate.Serialno} 高频结束后的时间倒序的正常心率触发的高频心率处理"); await SaveAndPushFetalHeartRateEndFreqHeartRateAsync(heartRate, commonPHR, highFreqSampleTimes, upperAlarmThreshold, lowerAlarmThreshold, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString(), phrFreqstatus!.LastUpdate, FreqStatsEnd); @@ -769,77 +767,10 @@ namespace HealthMonitor.Service.Resolver } } - /// - /// (逐条计算)常规心率计算胎心数据 - /// - /// - /// - /// - /// - /// - /// - /** - private async Task CalculateNormalFetalHeartRateAsync(HisGpsHeartRate heartRate, int upperAlarmThreshold, int lowerAlarmThreshold, int intervalFHR, PregnancyCommonHeartRateModel? commonPHR) - { - // 上15分钟的数据 - // 获取当前时间 - DateTime nowInterval = (DateTime)heartRate.LastUpdate!; - if (nowInterval.Second > 0) - { - nowInterval = nowInterval.AddMinutes(1); - } - // 计算last_update到上一间隔的分钟数 - int minutesToSubtract = nowInterval.Minute % intervalFHR; - - // 计算上一间隔的时间 - DateTime previousInterval = nowInterval.AddMinutes(-minutesToSubtract).AddSeconds(-nowInterval.Second).AddMilliseconds(-nowInterval.Millisecond); - - // 使用 last_update 上一刻 - var sampleTimeFHR = DateTimeUtil.ConvertToTimeStamp(previousInterval).ToString(); - - // 计算last_update到下一间隔的分钟数 - int minutesToAdd = intervalFHR - (nowInterval.Minute % intervalFHR); - if (minutesToAdd == intervalFHR) - { - minutesToAdd = 0; // 如果已经是间隔,则不需要增加分钟 - } - - // 计算下一间隔的时间 - DateTime nextInterval = nowInterval.AddMinutes(minutesToAdd) - .AddSeconds(-nowInterval.Second) - .AddMilliseconds(-nowInterval.Millisecond); - - var daysPhr = await _serviceTDengine.GetBySerialNoAsync(heartRate.Serialno, 7); - - var normalPhrStatStartTime = nextInterval.AddMinutes(-intervalFHR); + - var normalPhrStatEndTime = nextInterval; - _logger.LogInformation($"{heartRate.Serialno} 计算胎心数据, 周期:{normalPhrStatStartTime}-{normalPhrStatEndTime} "); - var filteredPhr = daysPhr - // 使用 last_update 下一刻 - .Where(i => i.LastUpdate <= normalPhrStatEndTime && i.LastUpdate >= normalPhrStatStartTime) - .ToList(); - if (filteredPhr.Count == 0) - { - _logger.LogWarning($"{heartRate.Serialno} 周期:{normalPhrStatStartTime}-{normalPhrStatEndTime} 孕妇心率数据不足,{filteredPhr.Count}条记录"); - return; - } - var phrValue = filteredPhr.Count == 1 - ? filteredPhr.First().PregnancyHeartRate - : filteredPhr.Average(i => i.PregnancyHeartRate); - - //await SaveAndPushFreqFetalHeartRateAsync(heartRate, commonPHR!, upperAlarmThreshold, lowerAlarmThreshold, phrValue, sampleTimeFHR); - //await SaveAndPushFetalHeartRateAsync(heartRate, commonPHR!, upperAlarmThreshold, lowerAlarmThreshold, phrValue, sampleTimeFHR, normalPhrStatStartTime, normalPhrStatEndTime); - heartRate.HeartRate = (int)phrValue; - //await SaveAndPushFetalHeartRateEndFreqHeartRateAsync(heartRate, commonPHR!, upperAlarmThreshold, lowerAlarmThreshold, sampleTimeFHR, normalPhrStatStartTime, normalPhrStatEndTime); - - - } - */ - - /// /// 延时计算 /// @@ -865,6 +796,40 @@ namespace HealthMonitor.Service.Resolver _logger.LogInformation($"{heartRate.Serialno}--{heartRate.MessageId} 触发延时计算常规胎心"); } + + /// + /// 从高频心率数据中取心率值计算胎心值 + /// + /// + /// + /// + /// + /// + private int SelectValueFromFreqHeartRate(HisGpsHeartRate heartRate, int triggerHighFreqHigh, int triggerHighFreqLow, List lastPhr) + { + // 连续12个心率的值的最小值 + var selectedHrValue = lastPhr.Select(i => i.PregnancyHeartRate).Min(); + _logger.LogInformation($"{heartRate.Serialno} 最近12个数据的最小值 {selectedHrValue}"); + /// 高频状态下,取值心率低于高频最小值阀值,则需要取最大值进行计算。刚好跟大于高频最大值阀值刚好相反 + if (selectedHrValue < triggerHighFreqLow) + { + // 低于高频最小值阀值,则需要取最大值 + var selectedHrMax = lastPhr.Select(i => i.PregnancyHeartRate).Max(); + _logger.LogInformation($"{heartRate.Serialno} 最近12个数据的最小值 {selectedHrValue},低于高频最小值阀值 {triggerHighFreqLow},取最近12个数据的最大值{selectedHrMax}作为心率"); + selectedHrValue = selectedHrMax; + } + + if (selectedHrValue > triggerHighFreqHigh) + { + var selectedHrMin = lastPhr.Select(i => i.PregnancyHeartRate).Min(); + _logger.LogInformation($"{heartRate.Serialno} 最近12个数据的最小值 {selectedHrValue},低于高频最大值阀值 {triggerHighFreqHigh},最近12个数据的最小值{selectedHrMin}作为心率"); + selectedHrValue = selectedHrMin; + } + + return selectedHrValue; + } + + /// /// 高频胎心处理 /// 1. 高频数据触发连续12个值都是正常的的高频心率处理 diff --git a/HealthMonitor.WebApi/Worker.cs b/HealthMonitor.WebApi/Worker.cs index 0e483be..4e9145e 100644 --- a/HealthMonitor.WebApi/Worker.cs +++ b/HealthMonitor.WebApi/Worker.cs @@ -313,6 +313,11 @@ namespace HealthMonitor.WebApi // 告警下限阀值 var lowerAlarmThreshold = (int)watchConfig["lowerAlarmThreshold"]!; + // 触发高频监测的心率上限值 + var triggerHighFreqHigh = (int)watchConfig["triggerHighFreqHigh"]!; + // 触发高频监测的心率下限值 + var triggerHighFreqLow = (int)watchConfig["triggerHighFreqLow"]!; + // 高频心率采样间隔 highFreqSampleInterval = highFreqSampleInterval+5,增加5秒兼容(最小highFreqSampleInterval=60) var highFreqSampleInterval = (int)watchConfig!["highFreqSampleInterval"]! >= 60 ? (int)watchConfig!["highFreqSampleInterval"]! + 5 : 60; @@ -357,18 +362,24 @@ namespace HealthMonitor.WebApi var ts = DateTimeUtil.GetTimeDifferenceInSeconds((DateTime)lastFreqHr.LastUpdate!, phrFreqstatus!.LastUpdate); if (ts < highFreqSampleTimes) { - triggerHeartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - /// 不够10分钟最近12个数据的最小值生成胎心值 - _logger.LogInformation($"{triggerHeartRate.Serialno} 不够10分钟最近12个数据的最小值 {triggerHeartRate.HeartRate} 生成胎心值"); + //triggerHeartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); + /// 不够10分钟最近12个数据生成胎心值 + + int selectedHrValue = SelectValueFromFreqHeartRate(triggerHeartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + triggerHeartRate.HeartRate = selectedHrValue; + _logger.LogInformation($"{triggerHeartRate.Serialno} 不够10分钟最近12个数据数据中取 {triggerHeartRate.HeartRate} 生成胎心值"); } else { - triggerHeartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); - /// 超过10分钟最近12个数据的最小值生成胎心值 - _logger.LogInformation($"{triggerHeartRate.Serialno} 超过10分钟最近12个数据的最小值 {triggerHeartRate.HeartRate} 生成胎心值"); + //triggerHeartRate.HeartRate = lastPhr.Select(i => i.PregnancyHeartRate).Min(); + int selectedHrValue = SelectValueFromFreqHeartRate(triggerHeartRate, triggerHighFreqHigh, triggerHighFreqLow, lastPhr); + triggerHeartRate.HeartRate = selectedHrValue; + /// 超过10分钟最近12个数据生成胎心值 + _logger.LogInformation($"{triggerHeartRate.Serialno} 超过10分钟最近12个数据数据中取 {triggerHeartRate.HeartRate} 生成胎心值"); } + triggerHeartRate.LastUpdate = lastFreqHr.LastUpdate; @@ -1763,6 +1774,37 @@ namespace HealthMonitor.WebApi } + /// + /// 从高频心率数据中取心率值计算胎心值 + /// + /// + /// + /// + /// + /// + private int SelectValueFromFreqHeartRate(HisGpsHeartRate heartRate, int triggerHighFreqHigh, int triggerHighFreqLow, List lastPhr) + { + // 连续12个心率的值的最小值 + var selectedHrValue = lastPhr.Select(i => i.PregnancyHeartRate).Min(); + _logger.LogInformation($"{heartRate.Serialno} 最近12个数据的最小值 {selectedHrValue}"); + /// 高频状态下,取值心率低于高频最小值阀值,则需要取最大值进行计算。刚好跟大于高频最大值阀值刚好相反 + if (selectedHrValue < triggerHighFreqLow) + { + // 低于高频最小值阀值,则需要取最大值 + var selectedHrMax = lastPhr.Select(i => i.PregnancyHeartRate).Max(); + _logger.LogInformation($"{heartRate.Serialno} 最近12个数据的最小值 {selectedHrValue},低于高频最小值阀值 {triggerHighFreqLow},取最近12个数据的最大值{selectedHrMax}作为心率"); + selectedHrValue = selectedHrMax; + } + + if (selectedHrValue > triggerHighFreqHigh) + { + var selectedHrMin = lastPhr.Select(i => i.PregnancyHeartRate).Min(); + _logger.LogInformation($"{heartRate.Serialno} 最近12个数据的最小值 {selectedHrValue},低于高频最大值阀值 {triggerHighFreqHigh},最近12个数据的最小值{selectedHrMin}作为心率"); + selectedHrValue = selectedHrMin; + } + + return selectedHrValue; + } /// /// 高频胎心处理