diff --git a/HealthMonitor.WebApi/Worker.cs b/HealthMonitor.WebApi/Worker.cs
index 405be8d..0e483be 100644
--- a/HealthMonitor.WebApi/Worker.cs
+++ b/HealthMonitor.WebApi/Worker.cs
@@ -1763,246 +1763,117 @@ namespace HealthMonitor.WebApi
}
- private async Task SaveAndPushFetalHeartRateEndFreqHeartRateAsync(HisGpsHeartRate heartRate, PregnancyCommonHeartRateModel commonPHR, int upperAlarmThreshold, int lowerAlarmThreshold, string sampleTime, DateTime statStartTime, DateTime statEndTime)
+
+ ///
+ /// 高频胎心处理
+ /// 1. 高频数据触发连续12个值都是正常的的高频心率处理
+ /// 2. 高频结束后的highFreqSampleTimes=0的高频心率处理
+ /// 3. 高频结束后的在highFreqSampleTimes>0 正常心率触发的高频心率处理(常态)
+ /// 4. 高频结束后的时间倒序的正常心率触发的高频心率处理
+ /// 5. 高频结束后计算胎心数据,防止结束后与常规心理的胎心处理过长,定时器时长highFreqSampleInterval触发的高频心率处理
+ /// 高频结束后超过9分钟且不在阈值内才告警
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task SaveAndPushFetalHeartRateEndFreqHeartRateAsync(HisGpsHeartRate heartRate, PregnancyCommonHeartRateModel commonPHR, int highFreqSampleTimes, int upperAlarmThreshold, int lowerAlarmThreshold, string sampleTime, DateTime statStartTime, DateTime statEndTime)
{
// 计算胎心=孕妇心率*系数
- /**
- var fetalHeartRate = SafeType.SafeInt(phrValue * commonPHR?.StatModeAvgFprCoefficient!);
- fetalHeartRate = fetalHeartRate > 220 ? 220 : fetalHeartRate; // 胎心的最大值调整为220,超过都按该值220输出
- if (fetalHeartRate >= 220)
- {
- // 先使用最小系数计算
- var statMaxValueFprCoefficient = commonPHR?.StatMaxValueFprCoefficient!;
- var statMinValueFprCoefficient = commonPHR?.StatMinValueFprCoefficient!;
- var coefficient = statMaxValueFprCoefficient < statMinValueFprCoefficient ? statMaxValueFprCoefficient : statMinValueFprCoefficient;
- fetalHeartRate = SafeType.SafeInt(phrValue * coefficient);
- if (fetalHeartRate < 220)
- {
- _logger.LogWarning($"{heartRate.Serialno} 使用极值系数 {coefficient} ,建模数据可能出现异常,请检查");
- }
- else
- {
- fetalHeartRate = 220;
- _logger.LogWarning($"{heartRate.Serialno} 使用所有系数都不能放映实际,建模数据可能出现异常,请检查");
- }
- }
- */
- #region 胎心系数使用基于心率与中位数对比
+ #region 胎心系数使用基于心率与众数对比
var coefficient = 0f;
- // 孕妇心率少于中位数,取StatMinValueFprCoefficient
+ /**
+ // 孕妇心率少于众数,取StatMinValueFprCoefficient
if (heartRate.HeartRate < commonPHR!.Mode)
{
coefficient = commonPHR.StatMinValueFprCoefficient!;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率少于中位数,使用最小值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 孕妇心率少于众数,使用最小值系数 {coefficient}");
}
- // 孕妇心率大于中位数,取StatMaxValueFprCoefficient与StatModeAvgFprCoefficient中少的那个
+ // 孕妇心率大于众数,取StatMaxValueFprCoefficient与StatModeAvgFprCoefficient中少的那个
else if (heartRate.HeartRate > commonPHR.Mode)
{
if (commonPHR.StatModeAvgFprCoefficient > commonPHR.StatMaxValueFprCoefficient)
{
coefficient = commonPHR.StatMaxValueFprCoefficient!;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于中位数,使用最大值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于众数,使用最大值系数 {coefficient}");
}
else
{
coefficient = commonPHR.StatModeAvgFprCoefficient!;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于中位数,使用均值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于众数,使用均值系数 {coefficient}");
}
}
else
{
coefficient = commonPHR.StatModeAvgFprCoefficient;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率等于中位数,使用均值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 孕妇心率等于众数,使用均值系数 {coefficient}");
}
- #endregion
+ */
- var fetalHeartRate = SafeType.SafeInt(heartRate.HeartRate! * coefficient);
- // 胎心的最大值调整为220,超过都按该值220输出
- fetalHeartRate = fetalHeartRate >= 220 ? 220 : fetalHeartRate;
- var isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0);
- var phrFreqstatus = await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);
- if (phrFreqstatus == null) isAbnormal = 0;
- var statsusDesc = (phrFreqstatus == null) ? "常规" : "高频";
- _logger.LogInformation($"{heartRate.Serialno} 在 {statsusDesc} 状态,生成胎心值:{fetalHeartRate},统计周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}");
- //if (!isFreq)
- //{
- // statStartTime = heartRate.LastUpdate;
- //
- //}
- // 保存到 数据服务 MySQL 数据库
- HisGpsFetalHeartRate gpsFetalHeartRate = new()
- {
- FetalHeartRateId = Guid.NewGuid().ToString("D"),
- PersonId = commonPHR!.PersonId,
- Serialno = heartRate.Serialno,
- HeartRate = fetalHeartRate,
- SampleTime = sampleTime.Length > 10 ? sampleTime.Substring(0, 10) : sampleTime,
- IsAbnormal = isAbnormal,
- StatStartTime = statStartTime,
- StatEndTime = statEndTime,//commonPHR.StatEndTime,
- CreateTime = DateTime.Now,
- Method = 1,
- IsDisplay = 1,
- DeviceKey = commonPHR!.DeviceKey
- };
- await _hisFetalHeartApiClient.AddAsync(gpsFetalHeartRate).ConfigureAwait(false);
+ ///1、高频最小值>心率,取高频最小值系数
+ ///2、高频最小值 < 心率 < 众数,取众数系数与高频最小值系数较小值
+ ///3、众数 < 心率 < 高频最大值,取众数系数与高频最大值系数较小值
+ ///4、心率 > 高频最大值,取高频最大值系数
- // 推送到api/v1/open/OpenIot/SetFetalHeartRateConfig
- // 推送最后一条常规心率计算的胎心数据到iot设备
- #region 推送最后一条常规心率计算的胎心数据到iot设备
-
- // 高频(<=12)-常规
- var lastPhr = await _serviceTDengine.GetLastAsync(heartRate.Serialno);
- if (lastPhr.MessageId == heartRate.MessageId && phrFreqstatus == null)
- {
- await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal);
- _logger.LogInformation($"{heartRate.Serialno} 推送最后一条常规心率计算的胎心数据到iot设备,高频(<=12)-常规");
- }
- // 高频(13)-常规-高频(13)
- if (phrFreqstatus != null)
+ // 1、高频最小值>心率,取高频最小值系数
+ if (commonPHR.MinValue > heartRate.HeartRate)
{
- var phr = await _serviceTDengine.GetBySerialNoAsync(heartRate.Serialno, 1);
- phr = phr.OrderByDescending(i => i.LastUpdate).ToList();
- // 获取高频数据
- var freqCollection = new List();
- PregnancyHeartRateModel? previousItem = null;
- foreach (var item in phr)
- {
- if (previousItem != null)
- {
- var timeNextDiff = (previousItem!.LastUpdate - item.LastUpdate).TotalSeconds;
- if (timeNextDiff <= 60)
- {
- freqCollection.Add(item);
- }
- }
- // 高频最后一条
- if (lastPhr.MessageId == item.MessageId)
- {
- freqCollection.Add(item);
- }
-
- previousItem = item;
- }
- //去除高频
- foreach (var item in freqCollection)
- {
- phr.Remove(item);
- }
- lastPhr = phr.FirstOrDefault();
- if (lastPhr?.MessageId == heartRate.MessageId)
- {
- await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal);
- _logger.LogInformation($"{heartRate.Serialno} 推送最后一条常规心率计算的胎心数据到iot设备,高频(13)-常规-高频(13)");
- }
+ coefficient = commonPHR.StatMinValueFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 高频最小值>心率,取高频最小值系数 {coefficient}");
}
- #endregion
-
- #region 高频心率计算胎心数据到iot设备
- // 高频(17) ,连续12个高频正常,也不停止且数据偏高和偏低也推送到iot
- if (phrFreqstatus != null && isAbnormal != 0)
+ // 2、高频最小值 < 心率 < 众数,取众数系数与高频最小值系数较小值
+ if (commonPHR.MinValue < heartRate.HeartRate && heartRate.HeartRate < commonPHR.Mode)
{
- await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal);
- }
- #endregion
- var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(heartRate.Serialno).ConfigureAwait(false);
- var fhrMsgId = $"{heartRate.Serialno}-{sampleTime}-{Guid.NewGuid().ToString("D")[^3..]}";
- var fhrMsgTime = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(long.Parse(sampleTime.Length < 13 ? sampleTime.PadRight(13, '0') : sampleTime)).ToString("yyyy-MM-dd HH:mm:ss");
- // 胎心数据推送到第三方
- var topic = "topic.push.third";
- var fhrThridMsg = new
- {
- messageId = fhrMsgId,
- topic = topic,
- time = fhrMsgTime,
- data = new
+ if (commonPHR.StatModeAvgFprCoefficient > commonPHR.StatMinValueFprCoefficient)
{
- imei = heartRate.Serialno,
- value = fetalHeartRate,
- isAbnormal,
- type = "fetalHeart"
+ coefficient = commonPHR.StatMinValueFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 高频最小值 < 心率 < 众数,平均值系数大于最小值系数,使用最小值系数 {coefficient}");
}
- };
- await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, 31, fhrThridMsg).ConfigureAwait(false);
-
- // 胎心数据推送到微信
- if (isAbnormal != 0)
- {
-
- topic = "topic.push.wx";
- var fhrMsg = new
+ else
{
- messageId = fhrMsgId,
- topic = topic,
- time = fhrMsgTime,
- data = new
- {
- deviceId = device?.DeviceId,
- imei = heartRate.Serialno,
- alarmTypeId = 12,
- alarmDeviceName = heartRate.Serialno,
- alarmRemarks = JsonConvert.SerializeObject(new { fetalHeartValue = fetalHeartRate, isAbnormal = isAbnormal }),
- address = string.Empty,
- deviceKey = device?.DeviceId
- }
- };
- await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, fhrMsg).ConfigureAwait(false);
-
+ coefficient = commonPHR.StatModeAvgFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 高频最小值 < 心率 < 众数,平均值系数小于最小值系数,使用均值系数 {coefficient}");
+ }
}
- }
-
- ///
- /// 高频胎心处理
- /// 1. 高频数据触发连续12个值都是正常的的高频心率处理
- /// 2. 高频结束后的highFreqSampleTimes=0的高频心率处理
- /// 3. 高频结束后的在highFreqSampleTimes>0 正常心率触发的高频心率处理(常态)
- /// 4. 高频结束后的时间倒序的正常心率触发的高频心率处理
- /// 5. 高频结束后计算胎心数据,防止结束后与常规心理的胎心处理过长,定时器时长highFreqSampleInterval触发的高频心率处理
- /// 高频结束后超过9分钟且不在阈值内才告警
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- private async Task SaveAndPushFetalHeartRateEndFreqHeartRateAsync(HisGpsHeartRate heartRate, PregnancyCommonHeartRateModel commonPHR, int highFreqSampleTimes, int upperAlarmThreshold, int lowerAlarmThreshold, string sampleTime, DateTime statStartTime, DateTime statEndTime)
- {
- // 计算胎心=孕妇心率*系数
- #region 胎心系数使用基于心率与中位数对比
- var coefficient = 0f;
- // 孕妇心率少于中位数,取StatMinValueFprCoefficient
- if (heartRate.HeartRate < commonPHR!.Mode)
- {
- coefficient = commonPHR.StatMinValueFprCoefficient!;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率少于中位数,使用最小值系数 {coefficient}");
- }
- // 孕妇心率大于中位数,取StatMaxValueFprCoefficient与StatModeAvgFprCoefficient中少的那个
- else if (heartRate.HeartRate > commonPHR.Mode)
+ // 3、众数 < 心率 < 高频最大值,取众数系数与高频最大值系数较小值
+ if (commonPHR.Mode < heartRate.HeartRate && heartRate.HeartRate < commonPHR.MaxValue)
{
if (commonPHR.StatModeAvgFprCoefficient > commonPHR.StatMaxValueFprCoefficient)
{
coefficient = commonPHR.StatMaxValueFprCoefficient!;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于中位数,使用最大值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 众数 < 心率 < 高频最大值,平均值系数大于最最大值系数,使用最大值系数 {coefficient}");
}
else
{
coefficient = commonPHR.StatModeAvgFprCoefficient!;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于中位数,使用均值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 众数 < 心率 < 高频最大值,平均值系数小于最小值系数,使用均值系数 {coefficient}");
}
}
- else
+
+ // 4、心率 > 高频最大值,取高频最大值系数
+
+ if (heartRate.HeartRate > commonPHR.MaxValue)
{
- coefficient = commonPHR.StatModeAvgFprCoefficient;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率等于中位数,使用均值系数 {coefficient}");
+ coefficient = commonPHR.StatMaxValueFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 心率 > 高频最大值,取高频最大值系数 {coefficient}");
+ }
+
+ if (heartRate.HeartRate == commonPHR.Mode)
+ {
+ coefficient = commonPHR.StatModeAvgFprCoefficient!;
+
+ _logger.LogInformation($"{heartRate.Serialno} 心率 == 众数,取均值系数 {coefficient}");
}
+
#endregion
var fetalHeartRate = SafeType.SafeInt(heartRate.HeartRate! * coefficient);
@@ -2258,6 +2129,13 @@ namespace HealthMonitor.WebApi
return freqCollection;
}
+ ///
+ /// 周期性常规心率计算胎心值
+ ///
+ ///
+ ///
+ ///
+ ///
public async Task CalculateNormalFetalHeartRateIntervalAsync(HisGpsHeartRate heartRate, PregnancyCommonHeartRateModel commonPHR,int highFreqSampleInterval)
{
var daysPhr = await _serviceTDengine.GetBySerialNoAsync(heartRate.Serialno, 7);
@@ -2371,33 +2249,94 @@ namespace HealthMonitor.WebApi
heartRate.HeartRate = (int)avgPhr;
- #region 胎心系数使用基于心率与中位数对比
+ #region 胎心系数使用基于心率与众数对比
var coefficient = 0f;
- // 孕妇心率少于中位数,取StatMinValueFprCoefficient
+ /**
+ // 孕妇心率少于众数,取StatMinValueFprCoefficient
if (heartRate.HeartRate < commonPHR!.Mode)
{
coefficient = commonPHR.StatMinValueFprCoefficient!;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率少于中位数,使用最小值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 孕妇心率少于众数,使用最小值系数 {coefficient}");
}
- // 孕妇心率大于中位数,取StatMaxValueFprCoefficient与StatModeAvgFprCoefficient中少的那个
+ // 孕妇心率大于众数,取StatMaxValueFprCoefficient与StatModeAvgFprCoefficient中少的那个
else if (heartRate.HeartRate > commonPHR.Mode)
{
if (commonPHR.StatModeAvgFprCoefficient > commonPHR.StatMaxValueFprCoefficient)
{
coefficient = commonPHR.StatMaxValueFprCoefficient!;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于中位数,使用最大值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于众数,使用最大值系数 {coefficient}");
}
else
{
coefficient = commonPHR.StatModeAvgFprCoefficient!;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于中位数,使用均值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 孕妇心率大于众数,使用均值系数 {coefficient}");
}
}
else
{
coefficient = commonPHR.StatModeAvgFprCoefficient;
- _logger.LogInformation($"{heartRate.Serialno} 孕妇心率等于中位数,使用均值系数 {coefficient}");
+ _logger.LogInformation($"{heartRate.Serialno} 孕妇心率等于众数,使用均值系数 {coefficient}");
+ }
+ */
+
+
+ ///1、高频最小值>心率,取高频最小值系数
+ ///2、高频最小值 < 心率 < 众数,取众数系数与高频最小值系数较小值
+ ///3、众数 < 心率 < 高频最大值,取众数系数与高频最大值系数较小值
+ ///4、心率 > 高频最大值,取高频最大值系数
+
+ // 1、高频最小值>心率,取高频最小值系数
+ if (commonPHR.MinValue > heartRate.HeartRate)
+ {
+ coefficient = commonPHR.StatMinValueFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 高频最小值>心率,取高频最小值系数 {coefficient}");
+ }
+
+ // 2、高频最小值 < 心率 < 众数,取众数系数与高频最小值系数较小值
+ if (commonPHR.MinValue commonPHR.StatMinValueFprCoefficient)
+ {
+ coefficient = commonPHR.StatMinValueFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 高频最小值 < 心率 < 众数,平均值系数大于最小值系数,使用最小值系数 {coefficient}");
+ }
+ else
+ {
+ coefficient = commonPHR.StatModeAvgFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 高频最小值 < 心率 < 众数,平均值系数小于最小值系数,使用均值系数 {coefficient}");
+ }
}
+
+ // 3、众数 < 心率 < 高频最大值,取众数系数与高频最大值系数较小值
+ if (commonPHR.Mode < heartRate.HeartRate && heartRate.HeartRate < commonPHR.MaxValue)
+ {
+ if (commonPHR.StatModeAvgFprCoefficient > commonPHR.StatMaxValueFprCoefficient)
+ {
+ coefficient = commonPHR.StatMaxValueFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 众数 < 心率 < 高频最大值,平均值系数大于最最大值系数,使用最大值系数 {coefficient}");
+ }
+ else
+ {
+ coefficient = commonPHR.StatModeAvgFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 众数 < 心率 < 高频最大值,平均值系数小于最小值系数,使用均值系数 {coefficient}");
+ }
+ }
+
+ // 4、心率 > 高频最大值,取高频最大值系数
+
+ if (heartRate.HeartRate > commonPHR.MaxValue)
+ {
+ coefficient = commonPHR.StatMaxValueFprCoefficient!;
+ _logger.LogInformation($"{heartRate.Serialno} 心率 > 高频最大值,取高频最大值系数 {coefficient}");
+ }
+
+ if (heartRate.HeartRate == commonPHR.Mode)
+ {
+ coefficient = commonPHR.StatModeAvgFprCoefficient!;
+
+ _logger.LogInformation($"{heartRate.Serialno} 心率 == 众数,取均值系数 {coefficient}");
+ }
+
#endregion
#region 胎心阈值判断
@@ -3034,22 +2973,7 @@ namespace HealthMonitor.WebApi
}
}
- //private DateTime GetSampleTimeFromLastUpdate(DateTime lastUpdate,int interval)
- //{
- // DateTime nowInterval = lastUpdate;
- // //if (nowInterval.Second > 0)
- // //{
- // // nowInterval = nowInterval.AddMinutes(1);
- // //}
- // // 计算last_update到上一间隔的分钟数
- // int minutesToSubtract = nowInterval.Minute % interval;
-
- // // 计算上一间隔的时间
- // DateTime previousInterval = nowInterval.AddMinutes(-minutesToSubtract).AddSeconds(-nowInterval.Second).AddMilliseconds(-nowInterval.Millisecond);
-
- // return previousInterval;
- //}
-
+
public static DateTime GetSampleTimeFromLastUpdate(DateTime lastUpdate, int interval)
{
// 获取当前的分钟