@@ -1060,198 +1060,201 @@ namespace HealthMonitor.Service.Resolver | |||
/// <param name="statEndTime"></param> | |||
/// <returns></returns> | |||
private async Task SaveAndPushFetalHeartRateEndFreqHeartRateAsync( | |||
HisGpsHeartRate heartRate, | |||
PregnancyCommonHeartRateModel commonPHR, | |||
int highFreqSampleTimes, | |||
int upperAlarmThreshold, | |||
int lowerAlarmThreshold, | |||
string sampleTime, | |||
DateTime statStartTime, | |||
DateTime statEndTime, | |||
List<PregnancyHeartRateModel> lastPhr, | |||
int triggerHighFreqHigh, | |||
HisGpsHeartRate heartRate, | |||
PregnancyCommonHeartRateModel commonPHR, | |||
int highFreqSampleTimes, | |||
int upperAlarmThreshold, | |||
int lowerAlarmThreshold, | |||
string sampleTime, | |||
DateTime statStartTime, | |||
DateTime statEndTime, | |||
List<PregnancyHeartRateModel> lastPhr, | |||
int triggerHighFreqHigh, | |||
int triggerHighFreqLow) | |||
{ | |||
#region 选择心率值计算胎心 | |||
try | |||
{ | |||
#region 选择心率值计算胎心 | |||
/// 12个心率数据判定上限处理模式还是下限处理模式: | |||
/// 1、12个数据的最大值 > 高频上限阀值,则按上限模式进行计算。取12个值的最小值心率值转换为胎心值。 | |||
/// | |||
/// 2、12个数据的最小值 < 高频下限阀值,则按下限模式进行计算。取正常范围内的最小值心率值转换为胎心值,不产生告警。 | |||
/// 如果正常范围内没有值,则取异常范围最大值心率值转换为胎心值,并产生胎心过缓告警。 | |||
/// 12个心率数据判定上限处理模式还是下限处理模式: | |||
/// 1、12个数据的最大值 > 高频上限阀值,则按上限模式进行计算。取12个值的最小值心率值转换为胎心值。 | |||
/// | |||
/// 2、12个数据的最小值 < 高频下限阀值,则按下限模式进行计算。取正常范围内的最小值心率值转换为胎心值,不产生告警。 | |||
/// 如果正常范围内没有值,则取异常范围最大值心率值转换为胎心值,并产生胎心过缓告警。 | |||
var phrFreqstatus = await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno); | |||
var isAbnormal = 0; | |||
//取正常范围内的最小值心率值转换为胎心值,不产生告警。 | |||
var lastNormalPhr = lastPhr.Where(i => i.PregnancyHeartRate > triggerHighFreqLow && i.PregnancyHeartRate < triggerHighFreqHigh); | |||
var phrFreqstatus = await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno); | |||
var isAbnormal = 0; | |||
int selectedHrValue = (int)heartRate.HeartRate!; | |||
//取正常范围内的最小值心率值转换为胎心值,不产生告警。 | |||
var lastNormalPhr = lastPhr.Where(i => i.PregnancyHeartRate > triggerHighFreqLow && i.PregnancyHeartRate < triggerHighFreqHigh); | |||
if (lastPhr.Select(i => i.PregnancyHeartRate).Max() > triggerHighFreqHigh) | |||
{ | |||
// 取12个值的最小值心率值转换为胎心值。 | |||
selectedHrValue = lastPhr.Select(i => i.PregnancyHeartRate).Min(); | |||
} | |||
int selectedHrValue = (int)heartRate.HeartRate!; | |||
if (lastPhr.Select(i => i.PregnancyHeartRate).Min() < triggerHighFreqLow) | |||
{ | |||
// 有正常值 | |||
if (lastNormalPhr.Any()) | |||
{ | |||
// 2个数据的最小值 < 高频下限阀值,则按下限模式进行计算。取正常范围内的最小值心率值转换为胎心值,不产生告警 | |||
selectedHrValue = lastPhr | |||
.Where(i => i.PregnancyHeartRate > triggerHighFreqLow && i.PregnancyHeartRate < triggerHighFreqHigh) | |||
.Select(i => i.PregnancyHeartRate) | |||
.Min(); | |||
} | |||
// 无正常值 | |||
if (!lastNormalPhr.Any()) | |||
if (lastPhr.Select(i => i.PregnancyHeartRate).Max() > triggerHighFreqHigh) | |||
{ | |||
selectedHrValue = lastPhr | |||
.Where(i => i.PregnancyHeartRate > triggerHighFreqLow && i.PregnancyHeartRate < triggerHighFreqHigh) | |||
.Select(i => i.PregnancyHeartRate) | |||
.Max(); | |||
// 取12个值的最小值心率值转换为胎心值。 | |||
selectedHrValue = lastPhr.Select(i => i.PregnancyHeartRate).Min(); | |||
} | |||
} | |||
_logger.LogInformation($"{heartRate.Serialno} 高频选择心率值:{selectedHrValue}"); | |||
var fetalHeartRate = await _serviceTDengine.GetFetalHeartRateAsync(heartRate.Serialno, selectedHrValue); | |||
#endregion | |||
#region 判断是否够highFreqSampleTimes,540s | |||
var ts = DateTimeUtil.GetTimeDifferenceInSeconds((DateTime)heartRate.LastUpdate!, phrFreqstatus!.LastUpdate); | |||
// 判断是否够highFreqSampleTimes,540s | |||
///高频时长不足10分钟停止高频的胎心值生成说明:最近12个数据的最小值生成胎心值, | |||
///对于小于高频下限阀值取高频下限阀值进行转换; | |||
///对于高于高频上限阀值取高频上限阀值进行转换。并输出相关日志后续进行数据分析。 | |||
if (ts < highFreqSampleTimes) | |||
{ | |||
if (fetalHeartRate > upperAlarmThreshold) | |||
if (lastPhr.Select(i => i.PregnancyHeartRate).Min() < triggerHighFreqLow) | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,计算胎心值 {fetalHeartRate} 高于高频警告上限阀值{upperAlarmThreshold},最后胎心值{upperAlarmThreshold},并且不告警"); | |||
fetalHeartRate = upperAlarmThreshold; | |||
// 有正常值 | |||
if (lastNormalPhr.Any()) | |||
{ | |||
// 12个数据的最小值 < 高频下限阀值,则按下限模式进行计算。取正常范围内的最小值心率值转换为胎心值,不产生告警 | |||
selectedHrValue = lastNormalPhr | |||
.Select(i => i.PregnancyHeartRate) | |||
.Min(); | |||
} | |||
// 无正常值 | |||
if (!lastNormalPhr.Any()) | |||
{ | |||
selectedHrValue = lastPhr | |||
.Select(i => i.PregnancyHeartRate) | |||
.Max(); | |||
} | |||
} | |||
else if (fetalHeartRate < lowerAlarmThreshold) | |||
_logger.LogInformation($"{heartRate.Serialno} 高频选择心率值:{selectedHrValue}"); | |||
var fetalHeartRate = await _serviceTDengine.GetFetalHeartRateAsync(heartRate.Serialno, selectedHrValue); | |||
_logger.LogInformation($"高频状态计算,由高频心率 {selectedHrValue} 根据胎心算法转换的胎心值 {fetalHeartRate}"); | |||
#endregion | |||
#region 判断是否够highFreqSampleTimes,540s | |||
var ts = DateTimeUtil.GetTimeDifferenceInSeconds((DateTime)heartRate.LastUpdate!, phrFreqstatus!.LastUpdate); | |||
// 判断是否够highFreqSampleTimes,540s | |||
///高频时长不足10分钟停止高频的胎心值生成说明:最近12个数据的最小值生成胎心值, | |||
///对于小于高频下限阀值取高频下限阀值进行转换; | |||
///对于高于高频上限阀值取高频上限阀值进行转换。并输出相关日志后续进行数据分析。 | |||
if (ts < highFreqSampleTimes) | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,计算胎心值 {fetalHeartRate} 低于高频警告下限阀值 {lowerAlarmThreshold},最后胎心值{lowerAlarmThreshold},并且不告警"); | |||
fetalHeartRate = lowerAlarmThreshold; | |||
if (fetalHeartRate > upperAlarmThreshold) | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,计算胎心值 {fetalHeartRate} 高于高频警告上限阀值{upperAlarmThreshold},最后胎心值{upperAlarmThreshold},并且不告警"); | |||
fetalHeartRate = upperAlarmThreshold; | |||
} | |||
else if (fetalHeartRate < lowerAlarmThreshold) | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,计算胎心值 {fetalHeartRate} 低于高频警告下限阀值 {lowerAlarmThreshold},最后胎心值{lowerAlarmThreshold},并且不告警"); | |||
fetalHeartRate = lowerAlarmThreshold; | |||
} | |||
else | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,在高频警告下限阀值 {lowerAlarmThreshold} 和 高频警告上限阀值:{upperAlarmThreshold}之间,最后胎心值{fetalHeartRate},并且不告警"); | |||
} | |||
isAbnormal = 0; | |||
} | |||
// 超过highFreqSampleTimes,540s | |||
else | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,在高频警告下限阀值 {lowerAlarmThreshold} 和 高频警告上限阀值:{upperAlarmThreshold}之间,最后胎心值{fetalHeartRate},并且不告警"); | |||
} | |||
isAbnormal = 0; | |||
} | |||
// 超过highFreqSampleTimes,540s | |||
else | |||
{ | |||
if (fetalHeartRate > 220) | |||
{ | |||
fetalHeartRate = 220; | |||
_logger.LogWarning($"{heartRate.Serialno} 大于220,按220输出,计算因子:孕妇心率 {heartRate.HeartRate},周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
} | |||
if (fetalHeartRate > 220) | |||
{ | |||
fetalHeartRate = 220; | |||
_logger.LogWarning($"{heartRate.Serialno} 大于220,按220输出,计算因子:孕妇心率 {heartRate.HeartRate},周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
} | |||
// 胎心的最小值调整为90,超过都按该值90 | |||
if (fetalHeartRate < 90) | |||
{ | |||
fetalHeartRate = 90; | |||
_logger.LogWarning($"{heartRate.Serialno} 小于90,按90输出,计算因子:孕妇心率 {heartRate.HeartRate}, 周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
} | |||
isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0); | |||
// 胎心的最小值调整为90,超过都按该值90 | |||
if (fetalHeartRate < 90) | |||
{ | |||
fetalHeartRate = 90; | |||
_logger.LogWarning($"{heartRate.Serialno} 小于90,按90输出,计算因子:孕妇心率 {heartRate.HeartRate}, 周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
} | |||
isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0); | |||
if (!lastNormalPhr.Any()) | |||
{ | |||
// 偏低(过缓) | |||
isAbnormal = 2; | |||
if (!lastNormalPhr.Any()) | |||
{ | |||
// 偏低(过缓) | |||
isAbnormal = 2; | |||
} | |||
} | |||
} | |||
#endregion | |||
#endregion | |||
_logger.LogInformation($"{heartRate.Serialno} 在 高频 状态,生成胎心值:{fetalHeartRate},统计周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
// 保存到 数据服务 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); | |||
#region 高频心率计算胎心数据到iot设备 | |||
//if (phrFreqstatus != null && isAbnormal != 0) | |||
//{ | |||
// await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal); | |||
//} | |||
// 高频有数据都推送到iot | |||
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 | |||
_logger.LogInformation($"{heartRate.Serialno} 在 高频 状态,生成胎心值:{fetalHeartRate},统计周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
// 保存到 数据服务 MySQL 数据库 | |||
HisGpsFetalHeartRate gpsFetalHeartRate = new() | |||
{ | |||
imei = heartRate.Serialno, | |||
value = fetalHeartRate, | |||
isAbnormal, | |||
type = "fetalHeart" | |||
} | |||
}; | |||
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, 31, fhrThridMsg).ConfigureAwait(false); | |||
// 胎心数据推送到微信 | |||
if (isAbnormal != 0) | |||
{ | |||
topic = "topic.push.wx"; | |||
var fhrMsg = 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); | |||
#region 高频心率计算胎心数据到iot设备 | |||
//if (phrFreqstatus != null && isAbnormal != 0) | |||
//{ | |||
// await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal); | |||
//} | |||
// 高频有数据都推送到iot | |||
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 | |||
{ | |||
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 | |||
value = fetalHeartRate, | |||
isAbnormal, | |||
type = "fetalHeart" | |||
} | |||
}; | |||
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, fhrMsg).ConfigureAwait(false); | |||
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, 31, fhrThridMsg).ConfigureAwait(false); | |||
} | |||
} | |||
// 胎心数据推送到微信 | |||
if (isAbnormal != 0) | |||
{ | |||
topic = "topic.push.wx"; | |||
var fhrMsg = new | |||
{ | |||
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); | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{heartRate.Serialno} 计算高频心率出错{ex.Message}\n{ex.StackTrace}"); | |||
} | |||
} | |||
private async Task SetIntervalTriggerAsync(string key, string imei, long interval, HisGpsHeartRate heartRate) | |||
{ | |||
@@ -391,6 +391,7 @@ namespace HealthMonitor.WebApi | |||
var lastPhr = phrInFreqstatus; | |||
_logger.LogInformation($"{triggerHeartRate.Serialno} 高频结束后计算胎心数据,防止结束后与常规心理的胎心处理过长,定时器时长highFreqSampleInterval触发的高频心率处理"); | |||
triggerHeartRate.HeartRate= lastPhr.First().PregnancyHeartRate; | |||
await SaveAndPushFetalHeartRateEndFreqHeartRateAsync(triggerHeartRate, commonPHR, highFreqSampleTimes, upperAlarmThreshold, lowerAlarmThreshold, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString(), phrFreqstatus!.LastUpdate, FreqStatsEnd, lastPhr, triggerHighFreqHigh, triggerHighFreqLow); | |||
} | |||
else | |||
@@ -2305,182 +2306,187 @@ namespace HealthMonitor.WebApi | |||
int triggerHighFreqHigh, | |||
int triggerHighFreqLow) | |||
{ | |||
#region 选择心率值计算胎心 | |||
/// 12个心率数据判定上限处理模式还是下限处理模式: | |||
/// 1、12个数据的最大值 > 高频上限阀值,则按上限模式进行计算。取12个值的最小值心率值转换为胎心值。 | |||
/// | |||
/// 2、12个数据的最小值 < 高频下限阀值,则按下限模式进行计算。取正常范围内的最小值心率值转换为胎心值,不产生告警。 | |||
/// 如果正常范围内没有值,则取异常范围最大值心率值转换为胎心值,并产生胎心过缓告警。 | |||
try | |||
{ | |||
#region 选择心率值计算胎心 | |||
/// 12个心率数据判定上限处理模式还是下限处理模式: | |||
/// 1、12个数据的最大值 > 高频上限阀值,则按上限模式进行计算。取12个值的最小值心率值转换为胎心值。 | |||
/// | |||
/// 2、12个数据的最小值 < 高频下限阀值,则按下限模式进行计算。取正常范围内的最小值心率值转换为胎心值,不产生告警。 | |||
/// 如果正常范围内没有值,则取异常范围最大值心率值转换为胎心值,并产生胎心过缓告警。 | |||
var phrFreqstatus = await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno); | |||
var isAbnormal = 0; | |||
//取正常范围内的最小值心率值转换为胎心值,不产生告警。 | |||
var lastNormalPhr = lastPhr.Where(i => i.PregnancyHeartRate > triggerHighFreqLow && i.PregnancyHeartRate < triggerHighFreqHigh); | |||
var phrFreqstatus = await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno); | |||
var isAbnormal = 0; | |||
int selectedHrValue = (int)heartRate.HeartRate!; | |||
//取正常范围内的最小值心率值转换为胎心值,不产生告警。 | |||
var lastNormalPhr = lastPhr.Where(i => i.PregnancyHeartRate > triggerHighFreqLow && i.PregnancyHeartRate < triggerHighFreqHigh); | |||
if (lastPhr.Select(i => i.PregnancyHeartRate).Max() > triggerHighFreqHigh) | |||
{ | |||
// 取12个值的最小值心率值转换为胎心值。 | |||
selectedHrValue = lastPhr.Select(i => i.PregnancyHeartRate).Min(); | |||
} | |||
int selectedHrValue = (int)heartRate.HeartRate!; | |||
if (lastPhr.Select(i => i.PregnancyHeartRate).Min() < triggerHighFreqLow) | |||
{ | |||
// 有正常值 | |||
if (lastNormalPhr.Any()) | |||
{ | |||
// 2个数据的最小值 < 高频下限阀值,则按下限模式进行计算。取正常范围内的最小值心率值转换为胎心值,不产生告警 | |||
selectedHrValue = lastPhr | |||
.Where(i => i.PregnancyHeartRate > triggerHighFreqLow && i.PregnancyHeartRate < triggerHighFreqHigh) | |||
.Select(i => i.PregnancyHeartRate) | |||
.Min(); | |||
} | |||
// 无正常值 | |||
if (!lastNormalPhr.Any()) | |||
if (lastPhr.Select(i => i.PregnancyHeartRate).Max() > triggerHighFreqHigh) | |||
{ | |||
selectedHrValue = lastPhr | |||
.Where(i => i.PregnancyHeartRate > triggerHighFreqLow && i.PregnancyHeartRate < triggerHighFreqHigh) | |||
.Select(i => i.PregnancyHeartRate) | |||
.Max(); | |||
// 取12个值的最小值心率值转换为胎心值。 | |||
selectedHrValue = lastPhr.Select(i => i.PregnancyHeartRate).Min(); | |||
} | |||
} | |||
_logger.LogInformation($"{heartRate.Serialno} 高频选择心率值:{selectedHrValue}"); | |||
var fetalHeartRate = await _serviceTDengine.GetFetalHeartRateAsync(heartRate.Serialno, selectedHrValue); | |||
#endregion | |||
#region 判断是否够highFreqSampleTimes,540s | |||
var ts = DateTimeUtil.GetTimeDifferenceInSeconds((DateTime)heartRate.LastUpdate!, phrFreqstatus!.LastUpdate); | |||
// 判断是否够highFreqSampleTimes,540s | |||
///高频时长不足10分钟停止高频的胎心值生成说明:最近12个数据的最小值生成胎心值, | |||
///对于小于高频下限阀值取高频下限阀值进行转换; | |||
///对于高于高频上限阀值取高频上限阀值进行转换。并输出相关日志后续进行数据分析。 | |||
if (ts < highFreqSampleTimes) | |||
{ | |||
if (fetalHeartRate > upperAlarmThreshold) | |||
if (lastPhr.Select(i => i.PregnancyHeartRate).Min() < triggerHighFreqLow) | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,计算胎心值 {fetalHeartRate} 高于高频警告上限阀值{upperAlarmThreshold},最后胎心值{upperAlarmThreshold},并且不告警"); | |||
fetalHeartRate = upperAlarmThreshold; | |||
// 有正常值 | |||
if (lastNormalPhr.Any()) | |||
{ | |||
// 12个数据的最小值 < 高频下限阀值,则按下限模式进行计算。取正常范围内的最小值心率值转换为胎心值,不产生告警 | |||
selectedHrValue = lastNormalPhr | |||
.Select(i => i.PregnancyHeartRate) | |||
.Min(); | |||
} | |||
// 无正常值 | |||
if (!lastNormalPhr.Any()) | |||
{ | |||
selectedHrValue = lastPhr | |||
.Select(i => i.PregnancyHeartRate) | |||
.Max(); | |||
} | |||
} | |||
else if (fetalHeartRate < lowerAlarmThreshold) | |||
_logger.LogInformation($"{heartRate.Serialno} 高频选择心率值:{selectedHrValue}"); | |||
var fetalHeartRate = await _serviceTDengine.GetFetalHeartRateAsync(heartRate.Serialno, selectedHrValue); | |||
_logger.LogInformation($"高频状态计算,由高频心率 {selectedHrValue} 根据胎心算法转换的胎心值 {fetalHeartRate}"); | |||
#endregion | |||
#region 判断是否够highFreqSampleTimes,540s | |||
var ts = DateTimeUtil.GetTimeDifferenceInSeconds((DateTime)heartRate.LastUpdate!, phrFreqstatus!.LastUpdate); | |||
// 判断是否够highFreqSampleTimes,540s | |||
///高频时长不足10分钟停止高频的胎心值生成说明:最近12个数据的最小值生成胎心值, | |||
///对于小于高频下限阀值取高频下限阀值进行转换; | |||
///对于高于高频上限阀值取高频上限阀值进行转换。并输出相关日志后续进行数据分析。 | |||
if (ts < highFreqSampleTimes) | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,计算胎心值 {fetalHeartRate} 低于高频警告下限阀值 {lowerAlarmThreshold},最后胎心值{lowerAlarmThreshold},并且不告警"); | |||
fetalHeartRate = lowerAlarmThreshold; | |||
if (fetalHeartRate > upperAlarmThreshold) | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,计算胎心值 {fetalHeartRate} 高于高频警告上限阀值{upperAlarmThreshold},最后胎心值{upperAlarmThreshold},并且不告警"); | |||
fetalHeartRate = upperAlarmThreshold; | |||
} | |||
else if (fetalHeartRate < lowerAlarmThreshold) | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,计算胎心值 {fetalHeartRate} 低于高频警告下限阀值 {lowerAlarmThreshold},最后胎心值{lowerAlarmThreshold},并且不告警"); | |||
fetalHeartRate = lowerAlarmThreshold; | |||
} | |||
else | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,在高频警告下限阀值 {lowerAlarmThreshold} 和 高频警告上限阀值:{upperAlarmThreshold}之间,最后胎心值{fetalHeartRate},并且不告警"); | |||
} | |||
isAbnormal = 0; | |||
} | |||
// 超过highFreqSampleTimes,540s | |||
else | |||
{ | |||
_logger.LogWarning($"{heartRate.Serialno} 高频持续不足10分钟,在高频警告下限阀值 {lowerAlarmThreshold} 和 高频警告上限阀值:{upperAlarmThreshold}之间,最后胎心值{fetalHeartRate},并且不告警"); | |||
} | |||
isAbnormal = 0; | |||
} | |||
// 超过highFreqSampleTimes,540s | |||
else | |||
{ | |||
if (fetalHeartRate > 220) | |||
{ | |||
fetalHeartRate = 220; | |||
_logger.LogWarning($"{heartRate.Serialno} 大于220,按220输出,计算因子:孕妇心率 {heartRate.HeartRate},周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
} | |||
if (fetalHeartRate > 220) | |||
{ | |||
fetalHeartRate = 220; | |||
_logger.LogWarning($"{heartRate.Serialno} 大于220,按220输出,计算因子:孕妇心率 {heartRate.HeartRate},周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
} | |||
// 胎心的最小值调整为90,超过都按该值90 | |||
if (fetalHeartRate < 90) | |||
{ | |||
fetalHeartRate = 90; | |||
_logger.LogWarning($"{heartRate.Serialno} 小于90,按90输出,计算因子:孕妇心率 {heartRate.HeartRate}, 周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
} | |||
isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0); | |||
// 胎心的最小值调整为90,超过都按该值90 | |||
if (fetalHeartRate < 90) | |||
{ | |||
fetalHeartRate = 90; | |||
_logger.LogWarning($"{heartRate.Serialno} 小于90,按90输出,计算因子:孕妇心率 {heartRate.HeartRate}, 周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
} | |||
isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0); | |||
if (!lastNormalPhr.Any()) | |||
{ | |||
// 偏低(过缓) | |||
isAbnormal = 2; | |||
if (!lastNormalPhr.Any()) | |||
{ | |||
// 偏低(过缓) | |||
isAbnormal = 2; | |||
} | |||
} | |||
} | |||
#endregion | |||
_logger.LogInformation($"{heartRate.Serialno} 在 高频 状态,生成胎心值:{fetalHeartRate},统计周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
// 保存到 数据服务 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); | |||
#endregion | |||
#region 高频心率计算胎心数据到iot设备 | |||
//if (phrFreqstatus != null && isAbnormal != 0) | |||
//{ | |||
// await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal); | |||
//} | |||
// 高频有数据都推送到iot | |||
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 | |||
_logger.LogInformation($"{heartRate.Serialno} 在 高频 状态,生成胎心值:{fetalHeartRate},统计周期:{statStartTime.ToString("yyyy-MM-dd HH:mm:ss")}----{statEndTime.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||
// 保存到 数据服务 MySQL 数据库 | |||
HisGpsFetalHeartRate gpsFetalHeartRate = new() | |||
{ | |||
imei = heartRate.Serialno, | |||
value = fetalHeartRate, | |||
isAbnormal, | |||
type = "fetalHeart" | |||
} | |||
}; | |||
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, 31, fhrThridMsg).ConfigureAwait(false); | |||
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); | |||
// 胎心数据推送到微信 | |||
if (isAbnormal != 0) | |||
{ | |||
#region 高频心率计算胎心数据到iot设备 | |||
topic = "topic.push.wx"; | |||
var fhrMsg = new | |||
//if (phrFreqstatus != null && isAbnormal != 0) | |||
//{ | |||
// await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal); | |||
//} | |||
// 高频有数据都推送到iot | |||
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 | |||
{ | |||
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 | |||
value = fetalHeartRate, | |||
isAbnormal, | |||
type = "fetalHeart" | |||
} | |||
}; | |||
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, fhrMsg).ConfigureAwait(false); | |||
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, 31, fhrThridMsg).ConfigureAwait(false); | |||
// 胎心数据推送到微信 | |||
if (isAbnormal != 0) | |||
{ | |||
topic = "topic.push.wx"; | |||
var fhrMsg = new | |||
{ | |||
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); | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{heartRate.Serialno} 计算高频心率出错{ex.Message}\n{ex.StackTrace}"); | |||
} | |||
} | |||
@@ -2492,30 +2498,6 @@ namespace HealthMonitor.WebApi | |||
/// <returns></returns> | |||
private static List<PregnancyHeartRateModel> GetNonFreqPregnancyHeartRate(List<PregnancyHeartRateModel> phr, int highFreqSampleInterval) | |||
{ | |||
//phr = phr.OrderByDescending(i => i.LastUpdate).ToList(); | |||
//var result = new List<PregnancyHeartRateModel>(); | |||
//PregnancyHeartRateModel? previousItem = null; | |||
//foreach (var item in phr) | |||
//{ | |||
// if (previousItem != null) | |||
// { | |||
// var timeNextDiff =(previousItem!.LastUpdate - item.LastUpdate).TotalSeconds; | |||
// if (timeNextDiff > highFreqSampleInterval) | |||
// { | |||
// result.Add(previousItem); | |||
// } | |||
// } | |||
// previousItem = item; | |||
//} | |||
//// 添加上一个 | |||
//if (previousItem != null) | |||
//{ | |||
// result.Add(previousItem); | |||
//} | |||
//return result; | |||
#region 反向 | |||
var phr1 = phr.OrderByDescending(i => i.LastUpdate).ToList(); | |||