浏览代码

高频心率数据大于等于stopHighFreqSampleCount个才计算胎心数据

datasub12_fetal_heart_rate_0
H Vs 3 个月前
父节点
当前提交
b21e679896
共有 1 个文件被更改,包括 151 次插入342 次删除
  1. +151
    -342
      HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs

+ 151
- 342
HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs 查看文件

@@ -165,7 +165,7 @@ namespace HealthMonitor.Service.Resolver
// interval (分钟)
var intervalFHR = (int)watchConfig["interval"]!;

var fetalHeartRateIsAbnormal = 0;

var phr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(heartRate.Serialno, 7);
if (phr.Count >= 30)
@@ -196,7 +196,7 @@ namespace HealthMonitor.Service.Resolver
}
#endregion

#region 计算胎心和胎动数据
#region 计算胎心数据(按心率时间LastUpdate)
var commonPHR = await _serviceTDengine.GetLastAsync<PregnancyCommonHeartRateModel>(heartRate.Serialno);
if (commonPHR == null)
{
@@ -209,8 +209,7 @@ namespace HealthMonitor.Service.Resolver
await _serviceTDengine.InsertAsync<PregnancyCommonHeartRateModel>("hm_pchr", commonPHR!);
_logger.LogInformation($"保存TDengine完成");
}
#region 计算胎心数据(按心率时间LastUpdate)

// 获取最近的两个记录,并计算它们的 LastUpdate 时间差
var firstTwoPhr = phr.OrderByDescending(i => i.LastUpdate).Take(2).Select(i => i.LastUpdate).ToList();
var timeDiff = firstTwoPhr[0] - firstTwoPhr[1];
@@ -220,6 +219,8 @@ namespace HealthMonitor.Service.Resolver

// 高频统计结束时间
var FreqStatsEnd = DateTime.Now;


// 高频心率启动
if (timeDiffInSeconds <= highFreqSampleInterval)
{
@@ -249,7 +250,8 @@ namespace HealthMonitor.Service.Resolver
// 高频数据不建模
FreqStatsEnd = (DateTime)heartRate.LastUpdate!;
_logger.LogInformation($"{heartRate.Serialno} 高频状态已经持续{(FreqStatsEnd - phrFreqstatus!.LastUpdate).TotalSeconds} 秒,连续 {stopHighFreqSampleCount} 次采样心率正常,将下发指令");
await SaveAndPushFreqFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString());
//await SaveAndPushFreqFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString());
await SaveAndPushFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString(), phrFreqstatus!.LastUpdate, FreqStatsEnd);

// 删除高频状态的首条记录
await _deviceCacheMgr.DelPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);
@@ -259,10 +261,11 @@ namespace HealthMonitor.Service.Resolver
}
#endregion
}
// 高频心率结束或常心率
// 高频心率结束或常心率
else
{
var phrFreqstatus = await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);
// 高频心率结束
if (phrFreqstatus != null)
{
/// 在highFreqSampleTimes=0一直异常(大于等于triggerHighFreqLow,少于等于triggerHighFreqHig),
@@ -282,7 +285,8 @@ namespace HealthMonitor.Service.Resolver
FreqStatsEnd = firstTwoPhr[1];
_logger.LogInformation($"{heartRate.Serialno} 高频状态已经持续{(FreqStatsEnd - phrFreqstatus!.LastUpdate).TotalSeconds} 秒,highFreqSampleTimes={highFreqSampleTimes}秒,即将结束高频状态,将下发指令");

await SaveAndPushFreqFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString());
//await SaveAndPushFreqFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString());
await SaveAndPushFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString(), phrFreqstatus!.LastUpdate, FreqStatsEnd);

}

@@ -290,279 +294,77 @@ namespace HealthMonitor.Service.Resolver
/// 取所有值的平均值,推送胎心数据到api/v1/open/OpenIot/SetFetalHeartRateConfig
if (highFreqSampleTimes > 0 && heartRate.LastUpdate >= (phrFreqstatus?.LastUpdate.AddSeconds(highFreqSampleTimes)))
{
var filterPhr = phr
.Where(i => i.LastUpdate >= phrFreqstatus?.LastUpdate);

var avgPhr = filterPhr
.OrderByDescending(i => i.LastUpdate)
.Skip(1) // 去除首条
.Take(12) // 计算最后12条
//.Where(i => i.PregnancyHeartRate < triggerHighFreqLow || i.PregnancyHeartRate > triggerHighFreqHigh)
.Select(i => i.PregnancyHeartRate).Average();
// 推送胎心数据到 api/v1/open/OpenIot/SetFetalHeartRateConfig
// 计算一般心率得到胎心系数
//await SaveAndPushFetalHeartRateAsync(heartRate, upperAlarmThreshold, lowerAlarmThreshold, avgPhr);
//await SaveAndPushFreqFetalHeartRateAsync(heartRate, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(DateTime.Now).ToString());
//await SaveAndPushFreqFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(DateTime.Now).ToString());
// 高频数据不建模
FreqStatsEnd = firstTwoPhr[1];
_logger.LogInformation($"{heartRate.Serialno} 高频状态已经持续{(FreqStatsEnd - phrFreqstatus!.LastUpdate).TotalSeconds} 秒,超过约定的 {highFreqSampleTimes} 秒,即将结束高频状态,将下发指令");

await SaveAndPushFreqFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString());
}

// 删除高频状态的首条记录
await _deviceCacheMgr.DelPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);

_logger.LogInformation($"{heartRate.Serialno} 超时结束高频心率状态 timeDiffInSeconds {timeDiffInSeconds},highFreqSampleInterval:{highFreqSampleInterval},高频状态持续{(firstTwoPhr[1] - phrFreqstatus!.LastUpdate).TotalSeconds} 秒");
}
// 正常心率
else
{

// 上15分钟的数据
// 获取当前时间
DateTime nowInterval = (DateTime)heartRate.LastUpdate!;

// 计算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<PregnancyHeartRateModel>(heartRate.Serialno, 7);

var normalPhrStatStartTime = nextInterval;

var normalPhrStatEndTime = nextInterval.AddMinutes(-intervalFHR);

_logger.LogInformation($"{heartRate.Serialno} 计算胎心数据, 周期:{normalPhrStatStartTime}-{normalPhrStatEndTime} ");
var filteredPhr = daysPhr
// 使用 last_update 下一刻
.Where(i => i.LastUpdate <= normalPhrStatStartTime && i.LastUpdate >= normalPhrStatEndTime)
.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);

var fetalHeartRate = SafeType.SafeInt(phrValue * commonPHR?.StatModeAvgFprCoefficient!);


fetalHeartRateIsAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0);
fetalHeartRateIsAbnormal = 0;// 不是高频数据,按正常值
/* HisGpsFetalHeartRate gpsFetalHeartRate = new()
{
FetalHeartRateId = Guid.NewGuid().ToString("D"),
PersonId = commonPHR!.PersonId,
Serialno = heartRate.Serialno,
HeartRate = fetalHeartRate,
SampleTime = sampleTimeFHR.Length > 10 ? sampleTimeFHR.Substring(0, 10) : sampleTimeFHR,
IsAbnormal = fetalHeartRateIsAbnormal,
StatStartTime = filteredPhr.OrderBy(i => i.LastUpdate).First().LastUpdate,
StatEndTime = filteredPhr.OrderBy(i => i.LastUpdate).Last().LastUpdate,
CreateTime = DateTime.Now,
Method = 1,
IsDisplay = 1,
DeviceKey = commonPHR!.DeviceKey
};
// 保存到 数据服务 MySQL 数据库
await _hisFetalHeartApiClient.AddAsync(gpsFetalHeartRate).ConfigureAwait(false);

// 推送到api/v1/open/OpenIot/SetFetalHeartRateConfig
await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTimeFHR, fetalHeartRateIsAbnormal);

// 推送送微信
if (fetalHeartRateIsAbnormal != 0)
{
var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(heartRate.Serialno).ConfigureAwait(false);
var fhrMsgId = $"{heartRate.Serialno}-{sampleTimeFHR}-{Guid.NewGuid().ToString("D")[^3..]}";
var topic = "topic.push.wx";
var fhrMsg = new
{
messageId = fhrMsgId,
topic = topic,
time = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(long.Parse(sampleTimeFHR.Length < 13 ? sampleTimeFHR.PadRight(13, '0') : sampleTimeFHR)).ToString("yyyy-MM-dd HH:mm:ss"),
data = new
{
deviceId = device?.DeviceId,
imei = heartRate.Serialno,
alarmTypeId = 12,
alarmDeviceName = heartRate.Serialno,
alarmRemarks = JsonConvert.SerializeObject(new { fetalHeartValue = fetalHeartRate, isAbnormal = fetalHeartRateIsAbnormal }),
address = string.Empty,
deviceKey = device?.DeviceId
}
};
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, fhrMsg).ConfigureAwait(false);
}

*/
await SaveAndPushFreqFetalHeartRateAsync(heartRate, commonPHR!, upperAlarmThreshold, lowerAlarmThreshold, phrValue, sampleTimeFHR, false);


}
}

#endregion

#region 计算胎动数据(按心率时间LastUpdate)
/**
_logger.LogInformation($"{heartRate.Serialno} 计算胎动数据 ");

var fetalMovementNow = (DateTime)heartRate.LastUpdate!;

var midNight = new DateTime(fetalMovementNow.Year, fetalMovementNow.Month, fetalMovementNow.Day, 0, 0, 0);

TimeSpan fetalMovementTS = fetalMovementNow - midNight;

// 当天每隔2小时的段数,取整数部分
int segmentCountFM = (int)(fetalMovementTS.TotalHours / 2);

for (int i = 0; i < segmentCountFM; i++)
{
// 每两小时
var fetalMovementSampleTime = DateTimeUtil.ConvertToTimeStamp(midNight.AddHours(2 * i)).ToString()[..10];
// 统计开始时间
var statStartTime = midNight.AddHours(2 * i);
// 统计结束时间
var statEndTime = midNight.AddHours(2 * (i+1));

var isFetalMovementExisted = await _deviceCacheMgr.FetalMovementIsExistedAsync(heartRate.Serialno, fetalMovementSampleTime);
_logger.LogInformation($"{heartRate.Serialno} 胎动记录{isFetalMovementExisted},数据采样时间:{fetalMovementSampleTime}|{midNight.AddHours(2 * i).ToString("yyyy-MM-dd HH:mm:ss")}, 周期:{statStartTime}-{statEndTime} 开始");

if (!isFetalMovementExisted)
{
/// 开始计算
var phrRange = phr.Where(i => i.LastUpdate >= statStartTime && i.LastUpdate<= statEndTime)
.OrderByDescending(i => i.LastUpdate)
.Select(i => i.LastUpdate)
.ToList();
// 判断是否有持续佩戴
if (phrRange.Count >= 2)
{
var duringMins = Math.Abs((phrRange.First()- statStartTime).TotalMinutes);
//在餐后时间段(8:00~10:00,12:00~14:00,18:00~20:00,22:00~24:00)取中间值。其他时间段取正常起始值
bool isInTimeRanges = IsLastUpdateInTimeRanges(fetalMovementNow);

int pregnancyWeeks = (DateTime.Now - edoc.AddDays(-280)).Days / 7;
if (pregnancyWeeks >= 12 && pregnancyWeeks <= 50)
// 获取高频心率数据个数
var filterPhr = phr
.Where(i => i.LastUpdate >= phrFreqstatus?.LastUpdate)
.Skip(1)
.ToList();

//var freqCollection = new List<PregnancyHeartRateModel>();
//PregnancyHeartRateModel? previousItem = null;

//foreach (var item in filterPhr)
//{
// if (previousItem != null)
// {
// var timeNextDiff = (previousItem!.LastUpdate - item.LastUpdate).TotalSeconds;
// if (timeNextDiff <= highFreqSampleInterval)
// {
// freqCollection.Add(item);
// }
// }
// previousItem = item;
//}
_logger.LogInformation($"{heartRate.Serialno} {phrFreqstatus?.LastUpdate.ToString("yyyy-MM-dd HH:mm:ss")}--{firstTwoPhr[1].ToString("yyyy-MM-dd HH:mm:ss")} 产生高频心率数量 {filterPhr.Count} 条");

// 高频心率数据大于等于stopHighFreqSampleCount/12个才计算胎心数据
if (filterPhr.Count >= stopHighFreqSampleCount)
{
var fetalMovementMap = _mgrFetalMovementNormalValueRangeCache.GetFetalMovements();

var fetalMovementMapValue = isInTimeRanges ? fetalMovementMap
.Where(i =>
i.PregnancyPeriod![0] <= pregnancyWeeks &&
i.PregnancyPeriod[1] >= pregnancyWeeks)
.Select(i => i.MedianMovement)
.FirstOrDefault()
:
fetalMovementMap
.Where(i =>
i.PregnancyPeriod![0] <= pregnancyWeeks &&
i.PregnancyPeriod[1] >= pregnancyWeeks)
.Select(i => i.InitialMovement)
.FirstOrDefault()
;

var fetalMovementValue = (fetalMovementMapValue * duringMins * 2) / 120;
// 四舍五入
var fetalMovement = (int)Math.Round(fetalMovementValue, 0, MidpointRounding.AwayFromZero);
// _logger.LogInformation($"{heartRate.Serialno} segmentCountFMIndex: {i} -- fetalMovementSampleTime:{fetalMovementSampleTime}|{midNight.AddHours(2 * i).ToString("yyyy-MM-dd HH:mm:ss")} -- statStartTime: {statStartTime} -- statEndTime: {statEndTime}-- isFetalMovementExisted: {isFetalMovementExisted} ");

_logger.LogInformation($"{heartRate.Serialno} 胎动数据采样时间:{fetalMovementSampleTime}|{midNight.AddHours(2 * i).ToString("yyyy-MM-dd HH:mm:ss")}, 采样周期:{statStartTime}-{statEndTime}, 原始胎动值:{fetalMovementMapValue}, 佩戴时间 :{duringMins}|{statStartTime}-{phrRange.First()}, 胎动计算值:{fetalMovementValue}, 胎动最终值:{fetalMovement} 已完成.");

// 获取胎心数据状态与胎动数据状态一致
var feltalMovementIsAbnormal = fetalHeartRateIsAbnormal;
//var feltalMovementIsAbnormal = 0;
// 推送到api/v1/open/OpenIot/SetFetalMovementConfig

await _serviceIotApi.SetFetalMovementConfig(heartRate.Serialno, fetalMovement, fetalMovementSampleTime, feltalMovementIsAbnormal);
// 保存到MySQL数据库
HisGpsFetalMovement fm = new()
{
FetalMovementId = Guid.NewGuid().ToString("D"),
PersonId = commonPHR!.PersonId,
Serialno = heartRate.Serialno,
CreateTime = DateTime.Now,
IsAbnormal = feltalMovementIsAbnormal,
FetalMovementValue = fetalMovement,
SampleTime = fetalMovementSampleTime,
Method = 1,
IsDisplay = 1,
DeviceKey = commonPHR!.DeviceKey
};
await _hisFetalMovementApiClient.AddAsync(fm).ConfigureAwait(false);

// 发送到微信
if (feltalMovementIsAbnormal != 0)
{
var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(heartRate.Serialno).ConfigureAwait(false);
var fmMsgId = $"{heartRate.Serialno}-{fetalMovementSampleTime}-{Guid.NewGuid().ToString("D")[^3..]}";
var topic = "topic.push.wx";
var fmMsg = new
{
messageId = Guid.NewGuid().ToString("D"),
topic = topic,
time = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(long.Parse(fetalMovementSampleTime.Length < 13 ? fetalMovementSampleTime.PadRight(13, '0') : fetalMovementSampleTime)).ToString("yyyy-MM-dd HH:mm:ss"),
data = new
{
deviceId = device?.DeviceId,
imei = heartRate.Serialno,
alarmTypeId = 12,
alarmDeviceName = heartRate.Serialno,
alarmRemarks = JsonConvert.SerializeObject(new { fetalMovementValue = fetalMovement, isAbnormal = feltalMovementIsAbnormal }),
address = string.Empty,
deviceKey = device?.DeviceId
}
};
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fmMsgId, topic, fmMsg).ConfigureAwait(false);
}
// 设置入库缓存记录
await _deviceCacheMgr.SetFetalMovementAsync(heartRate.Serialno, fetalMovementSampleTime,fm);
var avgPhr = filterPhr
.OrderByDescending(i => i.LastUpdate)
.Take(stopHighFreqSampleCount) // 计算最后12条
//.Where(i => i.PregnancyHeartRate < triggerHighFreqLow || i.PregnancyHeartRate > triggerHighFreqHigh)
.Select(i => i.PregnancyHeartRate).Average();
// 高频数据不建模
FreqStatsEnd = firstTwoPhr[1];
_logger.LogInformation($"{heartRate.Serialno} 高频状态已经持续{(FreqStatsEnd - phrFreqstatus!.LastUpdate).TotalSeconds} 秒,超过约定的 {highFreqSampleTimes} 秒,即将结束高频状态,将下发指令");

//await SaveAndPushFreqFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString());
await SaveAndPushFetalHeartRateAsync(heartRate, commonPHR, upperAlarmThreshold, lowerAlarmThreshold, avgPhr, DateTimeUtil.ConvertToTimeStamp(phrFreqstatus!.LastUpdate).ToString(), phrFreqstatus!.LastUpdate, FreqStatsEnd);

}
else
{
_logger.LogWarning($"{heartRate.Serialno} 孕周 {pregnancyWeeks},超出胎动计算范围");
_logger.LogInformation($"{heartRate.Serialno} 高频心率的数据不足{stopHighFreqSampleCount}条,不进行胎心计算");
}
}
//不满足持续10分钟highFreqSampleTimes
else
{
_logger.LogInformation($"{heartRate.Serialno} 胎动记录{isFetalMovementExisted},数据采样时间:{fetalMovementSampleTime}|{midNight.AddHours(2 * i).ToString("yyyy-MM-dd HH:mm:ss")}, 周期:{statStartTime}-{statEndTime} 不足两条,不能判断是否持续佩戴");

_logger.LogInformation($"{heartRate.Serialno} 高频持续时间不足{highFreqSampleTimes},只持续{(firstTwoPhr[1] - phrFreqstatus!.LastUpdate).TotalSeconds} 秒");
}

// 删除高频状态的首条记录
await _deviceCacheMgr.DelPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);

_logger.LogInformation($"{heartRate.Serialno} 超时结束高频心率状态 timeDiffInSeconds {timeDiffInSeconds},highFreqSampleInterval:{highFreqSampleInterval},高频状态持续{(firstTwoPhr[1] - phrFreqstatus!.LastUpdate).TotalSeconds} 秒");

// 计算本次平常心率的胎心数据
await CalculateNormalFetalHeartRateAsync(heartRate, upperAlarmThreshold, lowerAlarmThreshold, intervalFHR, commonPHR);

}
// 平常心率
else
{
_logger.LogInformation($"{heartRate.Serialno} 胎动记录{isFetalMovementExisted},数据采样时间:{fetalMovementSampleTime}|{midNight.AddHours(2 * i).ToString("yyyy-MM-dd HH:mm:ss")}, 周期:{statStartTime}-{statEndTime} 已处理");
// 计算本次平常心率的胎心数据
await CalculateNormalFetalHeartRateAsync(heartRate, upperAlarmThreshold, lowerAlarmThreshold, intervalFHR, commonPHR);
}

}
*/
#endregion

#endregion
}
@@ -588,68 +390,83 @@ namespace HealthMonitor.Service.Resolver
//}

}
/// <summary>
/// 平常心率计算胎心数据
/// </summary>
/// <param name="heartRate"></param>
/// <param name="upperAlarmThreshold"></param>
/// <param name="lowerAlarmThreshold"></param>
/// <param name="intervalFHR"></param>
/// <param name="commonPHR"></param>
/// <returns></returns>
private async Task CalculateNormalFetalHeartRateAsync(HisGpsHeartRate heartRate, int upperAlarmThreshold, int lowerAlarmThreshold, int intervalFHR, PregnancyCommonHeartRateModel? commonPHR)
{
// 上15分钟的数据
// 获取当前时间
DateTime nowInterval = (DateTime)heartRate.LastUpdate!;

//private async Task SaveAndPushFetalHeartRateAsync(HisGpsHeartRate heartRate, int upperAlarmThreshold, int lowerAlarmThreshold, double avgPhr)
//{
// var commonPHR = await _serviceTDengine.InitPregnancyCommonHeartRateModeAsync(heartRate.Serialno);
// if (commonPHR != null)
// {
// // 保存到TDengine数据库
// await _serviceTDengine.InsertAsync<PregnancyCommonHeartRateModel>("hm_pchr", commonPHR);
// // 计算胎心=孕妇心率*系数
// var fetalHeartRate = SafeType.SafeInt(avgPhr * commonPHR?.StatModeAvgFprCoefficient!);
// var sampleTime = DateTimeUtil.ConvertToTimeStamp(DateTime.Now).ToString();
// var isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0);

// // 保存到 数据服务 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 = commonPHR.StatStartTime,
// StatEndTime = commonPHR.StatEndTime,
// CreateTime = DateTime.Now,
// Method = 1,
// IsDisplay = 1,
// DeviceKey = commonPHR!.DeviceKey
// };
// await _hisFetalHeartApiClient.AddAsync(gpsFetalHeartRate).ConfigureAwait(false);
// // 推送到api/v1/open/OpenIot/SetFetalHeartRateConfig
// await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal);
// // 推送到微信
// var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(heartRate.Serialno).ConfigureAwait(false);
// var deviceId = device?.DeviceId;
// var msg = new
// {
// messageId = "",
// topic = "topic.push.wx",
// time=""
// };
// }
//}
// 计算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<PregnancyHeartRateModel>(heartRate.Serialno, 7);
var normalPhrStatStartTime = nextInterval;
var normalPhrStatEndTime = nextInterval.AddMinutes(-intervalFHR);
_logger.LogInformation($"{heartRate.Serialno} 计算胎心数据, 周期:{normalPhrStatStartTime}-{normalPhrStatEndTime} ");
var filteredPhr = daysPhr
// 使用 last_update 下一刻
.Where(i => i.LastUpdate <= normalPhrStatStartTime && i.LastUpdate >= normalPhrStatEndTime)
.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);
}

/// <summary>
///
///
/// </summary>
/// <param name="heartRate"></param>
/// <param name="commonPHR"></param>
/// <param name="upperAlarmThreshold"></param>
/// <param name="lowerAlarmThreshold"></param>
/// <param name="phr"></param>
/// <param name="sampleTime">使用高频心率的首条last_update</param>
/// <param name="isFreq"></param>
/// <param name="phrValue"></param>
/// <param name="sampleTime"></param>
/// <param name="statStartTime"></param>
/// <param name="statEndTime"></param>
/// <returns></returns>
private async Task SaveAndPushFreqFetalHeartRateAsync(HisGpsHeartRate heartRate, PregnancyCommonHeartRateModel commonPHR, int upperAlarmThreshold, int lowerAlarmThreshold, double phr,string sampleTime,bool isFreq = true)
private async Task SaveAndPushFetalHeartRateAsync(HisGpsHeartRate heartRate, PregnancyCommonHeartRateModel commonPHR, int upperAlarmThreshold, int lowerAlarmThreshold, double phrValue, string sampleTime,DateTime statStartTime, DateTime statEndTime)
{
// 计算胎心=孕妇心率*系数
var fetalHeartRate = SafeType.SafeInt(phr * commonPHR?.StatModeAvgFprCoefficient!);
var fetalHeartRate = SafeType.SafeInt(phrValue * commonPHR?.StatModeAvgFprCoefficient!);
//fetalHeartRate = fetalHeartRate > 220 ? 220 : fetalHeartRate; // 胎心的最大值调整为220,超过都按该值220输出
if (fetalHeartRate >= 220)
{
@@ -657,22 +474,27 @@ namespace HealthMonitor.Service.Resolver
var statMaxValueFprCoefficient = commonPHR?.StatMaxValueFprCoefficient!;
var statMinValueFprCoefficient = commonPHR?.StatMinValueFprCoefficient!;
var coefficient = statMaxValueFprCoefficient < statMinValueFprCoefficient ? statMaxValueFprCoefficient : statMinValueFprCoefficient;
fetalHeartRate = SafeType.SafeInt(phr * coefficient);
fetalHeartRate = SafeType.SafeInt(phrValue * coefficient);
if (fetalHeartRate < 220)
{
// 倒推系数
_logger.LogWarning($"{heartRate.Serialno} 使用极值系数 {coefficient} ,建模数据可能出现异常,请检查");
}
else
{
fetalHeartRate = 220;
// 倒推系数
_logger.LogWarning($"{heartRate.Serialno} 使用所有系数都不能放映实际,建模数据可能出现异常,请检查");
}
}

var isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0);
if (!isFreq) isAbnormal = 0;
var phrFreqstatus = await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);
if (phrFreqstatus == null) isAbnormal = 0;
//if (!isFreq)
//{
// statStartTime = heartRate.LastUpdate;
//
//}
// 保存到 数据服务 MySQL 数据库
HisGpsFetalHeartRate gpsFetalHeartRate = new()
{
@@ -682,8 +504,8 @@ namespace HealthMonitor.Service.Resolver
HeartRate = fetalHeartRate,
SampleTime = sampleTime.Length > 10 ? sampleTime.Substring(0, 10) : sampleTime,
IsAbnormal = isAbnormal,
StatStartTime = commonPHR.StatStartTime,
StatEndTime = commonPHR.StatEndTime,
StatStartTime = statStartTime,
StatEndTime = statEndTime,//commonPHR.StatEndTime,
CreateTime = DateTime.Now,
Method = 1,
IsDisplay = 1,
@@ -705,14 +527,15 @@ namespace HealthMonitor.Service.Resolver
messageId = fhrMsgId,
topic = topic,
time = fhrMsgTime,
data=new {
data = new
{
imei = heartRate.Serialno,
value= fetalHeartRate,
value = fetalHeartRate,
isAbnormal,
type= "fetalHeart"
type = "fetalHeart"
}
};
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, 31,fhrThridMsg).ConfigureAwait(false);
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fhrMsgId, topic, 31, fhrThridMsg).ConfigureAwait(false);

// 胎心数据推送到微信
if (isAbnormal != 0)
@@ -739,6 +562,7 @@ namespace HealthMonitor.Service.Resolver

}
}

private async Task SetIntervalTriggerAsync(string key,string imei, long interval)
{
// var key = $"health_monitor/schedule_push/{type}/imei/{imei}";
@@ -758,21 +582,6 @@ namespace HealthMonitor.Service.Resolver
await _serviceEtcd.PutValAsync(key, result, interval, false).ConfigureAwait(false);
}
}

public static bool IsLastUpdateInTimeRanges(DateTime lastUpdate)
{
var now = lastUpdate.TimeOfDay;

var timeRanges = new List<(TimeSpan Start, TimeSpan End)>
{
// 8:00~10:00,12:00~14:00,18:00~20:00,22:00~24:00
(new TimeSpan(8, 0, 0), new TimeSpan(10, 0, 0)),
(new TimeSpan(12, 0, 0), new TimeSpan(14, 0, 0)),
(new TimeSpan(18, 0, 0), new TimeSpan(20, 0, 0)),
(new TimeSpan(22, 0, 0), new TimeSpan(24, 0, 0))
};

return timeRanges.Any(range => now >= range.Start && now <= range.End);
}
}
}

正在加载...
取消
保存