|
|
@@ -546,6 +546,385 @@ namespace HealthMonitor.WebApi |
|
|
|
{ |
|
|
|
|
|
|
|
#region 胎动延时计算 |
|
|
|
/** |
|
|
|
using (_logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = $"FM-{imeiDel}-{DateTime.Now.ToString("yyyyMMddHHmmss")}" })) |
|
|
|
{ |
|
|
|
var watchConfig = await _deviceCacheMgr.GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(imeiDel, "0067"); |
|
|
|
_logger.LogInformation($"触发胎动计算,设备配置{JsonConvert.SerializeObject(watchConfig)}"); |
|
|
|
var isFetalHeartEnable = watchConfig != null && (int)watchConfig["enabled"]! == 1; |
|
|
|
if (isFetalHeartEnable) |
|
|
|
{ |
|
|
|
var edoc = DateTimeUtil.ToDateTime(watchConfig!["EDOC"]!.ToString()); |
|
|
|
// 已经建模 |
|
|
|
var commonPHR = await _serviceTDengine.GetLastAsync<PregnancyCommonHeartRateModel>(imeiDel); |
|
|
|
if (commonPHR != null) |
|
|
|
{ |
|
|
|
var phr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(imeiDel, 7); |
|
|
|
_logger.LogInformation($"{imeiDel} 计算胎动数据 "); |
|
|
|
|
|
|
|
var fmNow = DateTime.Now; |
|
|
|
// 两小时前 |
|
|
|
var fmNowSubtract = fmNow.AddMinutes(-fmNow.Minute).AddSeconds(-fmNow.Second).AddMilliseconds(-fmNow.Millisecond); |
|
|
|
|
|
|
|
var fetalMovementSampleTime = DateTimeUtil.ConvertToTimeStamp(fmNowSubtract).ToString()[..10]; |
|
|
|
|
|
|
|
// 统计开始时间 |
|
|
|
var statStartTime = fmNowSubtract.AddHours(-2); |
|
|
|
// 统计结束时间 |
|
|
|
var statEndTime = fmNowSubtract; |
|
|
|
|
|
|
|
var isFetalMovementExisted = await _deviceCacheMgr.FetalMovementIsExistedAsync(imeiDel, fetalMovementSampleTime); |
|
|
|
_logger.LogInformation($"{imeiDel} 胎动记录{isFetalMovementExisted},数据采样时间:{fetalMovementSampleTime}|{fmNowSubtract.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) |
|
|
|
{ |
|
|
|
// 读取胎心数据 |
|
|
|
GeneralParam param = new() |
|
|
|
{ |
|
|
|
Filters = new List<QueryFilterCondition> |
|
|
|
{ |
|
|
|
new () |
|
|
|
{ |
|
|
|
Key=nameof(HisGpsFetalHeartRate.Serialno), |
|
|
|
Value=imeiDel, |
|
|
|
ValueType=QueryValueTypeEnum.String, |
|
|
|
Operator=QueryOperatorEnum.Equal |
|
|
|
}, |
|
|
|
//new () |
|
|
|
//{ |
|
|
|
// Key=nameof(HisGpsFetalHeartRate.SampleTime), |
|
|
|
// Value=sampleTime, |
|
|
|
// ValueType=QueryValueTypeEnum.String, |
|
|
|
// Operator=QueryOperatorEnum.GreaterEqual |
|
|
|
//}, |
|
|
|
}, |
|
|
|
OrderBys = new List<OrderByCondition> |
|
|
|
{ |
|
|
|
new (){ |
|
|
|
IsDesc=true, |
|
|
|
Key=nameof(HisGpsFetalHeartRate.SampleTime) |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
var fetalHeartRateIsAbnormal = 0; |
|
|
|
var fhr = await _hisFetalHeartApiClient.GetFirstAsync(param, imeiDel[^2..], null, new RequestHeader { RequestId = Guid.NewGuid().ToString("D") }); |
|
|
|
|
|
|
|
// 胎心数据时间与胎动时间一致 |
|
|
|
var time = long.Parse(fhr.SampleTime.Length < 13 ? fhr.SampleTime.PadRight(13, '0') : fhr.SampleTime); |
|
|
|
var fhrSampleTime = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(time); |
|
|
|
|
|
|
|
// 胎心数据时间与胎动时间一致,最后一条胎心数据与胎动数据的小时差不大于2 |
|
|
|
if ((DateTime.Now.Hour - fhrSampleTime.Hour) <= 2) |
|
|
|
{ |
|
|
|
var duringMins = Math.Abs((phrRange.First() - phrRange.Last()).TotalMinutes); |
|
|
|
//在餐后时间段(8:00~10:00,12:00~14:00,18:00~20:00,22:00~24:00)取中间值。其他时间段取正常起始值 |
|
|
|
bool isInTimeRanges = IsLastUpdateInTimeRanges(phrRange.First()); |
|
|
|
|
|
|
|
int pregnancyWeeks = (DateTime.Now - edoc.AddDays(-280)).Days / 7; |
|
|
|
if (pregnancyWeeks >= 12 && pregnancyWeeks <= 50) |
|
|
|
{ |
|
|
|
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($"{imeiDel} segmentCountFMIndex: {i} -- fetalMovementSampleTime:{fetalMovementSampleTime}|{midNight.AddHours(2 * i).ToString("yyyy-MM-dd HH:mm:ss")} -- statStartTime: {statStartTime} -- statEndTime: {statEndTime}-- isFetalMovementExisted: {isFetalMovementExisted} "); |
|
|
|
|
|
|
|
#region 生理健康与胎动的关系 |
|
|
|
/// (步数)运动步数超过1500步则加1; |
|
|
|
/// (体温)低烧则胎动减1,高烧胎动减2;低烧是37.3~38.5,38.6以上是高烧。 |
|
|
|
/// (血压)血压收缩压大于160则加1。 |
|
|
|
/// (心理)心理压力高加2,压力中加1; |
|
|
|
|
|
|
|
var fetalMovementStepVar = 0; |
|
|
|
var fetalMovementTempVar = 0; |
|
|
|
var fetalMovementBpVar = 0; |
|
|
|
var fetalMovementPpVar = 0; |
|
|
|
var fetalMovementFhrVar = 0; |
|
|
|
// 步数 |
|
|
|
if (true) |
|
|
|
{ |
|
|
|
var step = await _personCacheMgr.GetStepPeriodicityAsync(imeiDel); |
|
|
|
if (step != null) |
|
|
|
{ |
|
|
|
if (DateTime.Now.Hour - ((DateTime)step?.LastUpdate!).Hour <= 2) |
|
|
|
{ |
|
|
|
if (step.Steps > 1500) fetalMovementStepVar = 1; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogWarning($"{imeiDel} 周期步数 时间无效"); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogWarning($"{imeiDel} 周期步数无数据"); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 体温 |
|
|
|
if (true) |
|
|
|
{ |
|
|
|
var temp = await _personCacheMgr.GetTemperaturePeriodicityAsync(imeiDel); |
|
|
|
if (temp != null) |
|
|
|
{ |
|
|
|
if (DateTime.Now.Hour - ((DateTime)temp?.LastUpdate!).Hour <= 2) |
|
|
|
{ |
|
|
|
// 中烧 |
|
|
|
if (temp.Temperature >= 37.3M && temp.Temperature <= 38.5M) |
|
|
|
{ |
|
|
|
fetalMovementTempVar = -1; |
|
|
|
} |
|
|
|
// 高烧 |
|
|
|
if (temp.Temperature >= 38.6M) |
|
|
|
{ |
|
|
|
fetalMovementTempVar = -2; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogWarning($"{imeiDel} 周期体温 时间无效"); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogWarning($"{imeiDel} 周期体温无数据"); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// 血压 |
|
|
|
if (true) |
|
|
|
{ |
|
|
|
var bp = await _personCacheMgr.GetBloodPressPeriodicityAsync(imeiDel); |
|
|
|
if (bp != null) |
|
|
|
{ |
|
|
|
if (DateTime.Now.Hour - ((DateTime)bp?.LastUpdate!).Hour <= 2) |
|
|
|
{ |
|
|
|
if (bp.SystolicValue > 160) |
|
|
|
{ |
|
|
|
fetalMovementBpVar = 1; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogWarning($"{imeiDel} 周期血压 时间无效"); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogWarning($"{imeiDel} 周期血压无数据"); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
// 心理 |
|
|
|
if (true) |
|
|
|
{ |
|
|
|
//-1 不处理, |
|
|
|
//0 正常, |
|
|
|
//1 轻度, |
|
|
|
//2 中度; |
|
|
|
//3 重度; |
|
|
|
GeneralParam psychResultParam = new() |
|
|
|
{ |
|
|
|
Filters = new List<QueryFilterCondition> |
|
|
|
{ |
|
|
|
new () |
|
|
|
{ |
|
|
|
Key=nameof(HisGpsPsychResult.Serialno), |
|
|
|
Value=imeiDel, |
|
|
|
ValueType=QueryValueTypeEnum.String, |
|
|
|
Operator=QueryOperatorEnum.Equal |
|
|
|
}, |
|
|
|
//new () |
|
|
|
//{ |
|
|
|
// Key=nameof(HisGpsFetalHeartRate.SampleTime), |
|
|
|
// Value=sampleTime, |
|
|
|
// ValueType=QueryValueTypeEnum.String, |
|
|
|
// Operator=QueryOperatorEnum.GreaterEqual |
|
|
|
//}, |
|
|
|
}, |
|
|
|
OrderBys = new List<OrderByCondition> |
|
|
|
{ |
|
|
|
new (){ |
|
|
|
IsDesc=true, |
|
|
|
Key=nameof(HisGpsPsychResult.Serialno) |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
var psych = await _hisPsychResultApiClient.GetFirstAsync(psychResultParam, imeiDel[^2..], null, new RequestHeader { RequestId = Guid.NewGuid().ToString("D") }); |
|
|
|
if (psych != null) |
|
|
|
{ |
|
|
|
if (psych?.StressScore == 2) |
|
|
|
{ |
|
|
|
fetalMovementPpVar = 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (psych?.StressScore == 3) |
|
|
|
{ |
|
|
|
fetalMovementPpVar = 2; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogWarning($"{imeiDel} 周期心理压力无数据"); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 胎心与胎动的关系 |
|
|
|
/// 胎心值过缓时,则胎动数量减1;胎心值过速时,则胎动也加1。 |
|
|
|
/// 此值允许在上限值上继续增加,在下限值上继续减少,最小值为0。 |
|
|
|
/// 告警上限阀值 |
|
|
|
|
|
|
|
//1表示偏高;2表示偏低 |
|
|
|
if (true) |
|
|
|
{ |
|
|
|
if (fhr.IsAbnormal == 2) |
|
|
|
{ |
|
|
|
fetalMovementPpVar = -1; |
|
|
|
} |
|
|
|
|
|
|
|
if (fhr.IsAbnormal == 1) |
|
|
|
{ |
|
|
|
fetalMovementPpVar = 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
_logger.LogInformation($"{imeiDel} 原始胎动值:{fetalMovementValue}, 步数参数变动值:{fetalMovementStepVar},体温参数变动值:{fetalMovementTempVar},血压参数变动值:{fetalMovementBpVar},心理压力参数变动值:{fetalMovementPpVar},胎心参数变动值:{fetalMovementFhrVar}"); |
|
|
|
|
|
|
|
|
|
|
|
fetalMovementValue = fetalMovementValue + fetalMovementStepVar + fetalMovementTempVar + fetalMovementBpVar + fetalMovementPpVar + fetalMovementFhrVar; |
|
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"{imeiDel} 孕周:{pregnancyWeeks},胎动数据采样时间:{fetalMovementSampleTime}|{fmNowSubtract.ToString("yyyy-MM-dd HH:mm:ss")}, 采样周期:{statStartTime}-{statEndTime}, 原始胎动值:{fetalMovementMapValue}, 佩戴时间 :{duringMins}|{phrRange.Last()}-{phrRange.First()}, 胎动计算值:{fetalMovementValue}, 胎动最终值:{fetalMovement} 已完成."); |
|
|
|
|
|
|
|
// 获取胎心数据状态与胎动数据状态一致 |
|
|
|
//etalHeartRateIsAbnormal= fhr.IsAbnormal; |
|
|
|
var feltalMovementIsAbnormal = fetalHeartRateIsAbnormal; |
|
|
|
|
|
|
|
await _serviceIotApi.SetFetalMovementConfig(imeiDel, fetalMovement, fetalMovementSampleTime, feltalMovementIsAbnormal); |
|
|
|
|
|
|
|
// 保存到MySQL数据库 |
|
|
|
HisGpsFetalMovement fm = new() |
|
|
|
{ |
|
|
|
FetalMovementId = Guid.NewGuid().ToString("D"), |
|
|
|
PersonId = commonPHR!.PersonId, |
|
|
|
Serialno = imeiDel, |
|
|
|
CreateTime = DateTime.Now, |
|
|
|
IsAbnormal = feltalMovementIsAbnormal, |
|
|
|
FetalMovementValue = fetalMovement, |
|
|
|
SampleTime = fetalMovementSampleTime, |
|
|
|
Method = 1, |
|
|
|
IsDisplay = 1, |
|
|
|
DeviceKey = commonPHR!.DeviceKey |
|
|
|
}; |
|
|
|
await _hisFetalMovementApiClient.AddAsync(fm).ConfigureAwait(false); |
|
|
|
|
|
|
|
var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(imeiDel).ConfigureAwait(false); |
|
|
|
var fmMsgId = $"{imeiDel}-{fetalMovementSampleTime}-{Guid.NewGuid().ToString("D")[^3..]}"; |
|
|
|
var fmMsgTime = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(long.Parse(fetalMovementSampleTime.Length < 13 ? fetalMovementSampleTime.PadRight(13, '0') : fetalMovementSampleTime)).ToString("yyyy-MM-dd HH:mm:ss"); |
|
|
|
// 胎动数据推送到第三方 |
|
|
|
var topic = "topic.push.third"; |
|
|
|
var fmThridMsg = new |
|
|
|
{ |
|
|
|
messageId = fmMsgId, |
|
|
|
topic = topic, |
|
|
|
time = fmMsgTime, |
|
|
|
data = new |
|
|
|
{ |
|
|
|
imei = imeiDel, |
|
|
|
value = fetalMovement, |
|
|
|
isAbnormal = feltalMovementIsAbnormal, |
|
|
|
type = "fetalMovement" |
|
|
|
} |
|
|
|
}; |
|
|
|
await _serviceMqProcess.ProcessIMEIEventMessageAsync(fmMsgId, topic, 31, fmThridMsg).ConfigureAwait(false); |
|
|
|
|
|
|
|
// 胎动数据推送到微信 |
|
|
|
if (feltalMovementIsAbnormal != 0) |
|
|
|
{ |
|
|
|
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 = imeiDel, |
|
|
|
alarmTypeId = 12, |
|
|
|
alarmDeviceName = imeiDel, |
|
|
|
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(imeiDel, fetalMovementSampleTime, fm); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogWarning($"{imeiDel} 孕周 {pregnancyWeeks},超出胎动计算范围"); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogWarning($"{imeiDel} 最后一条胎心数据与胎动数据的小时差大于2,不计算胎动数据"); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogInformation($"{imeiDel} 胎动记录{isFetalMovementExisted},数据采样时间:{fetalMovementSampleTime}|{fmNowSubtract.ToString("yyyy-MM-dd HH:mm:ss")}, 周期:{statStartTime}-{statEndTime} 不足两条,不能判断是否持续佩戴"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_logger.LogInformation($"{imeiDel} 胎动记录{isFetalMovementExisted},数据采样时间:{fetalMovementSampleTime}|{fmNowSubtract.ToString("yyyy-MM-dd HH:mm:ss")}, 周期:{statStartTime}-{statEndTime} 已处理"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
*/ |
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 胎动延时计算(再延时) |
|
|
|
using (_logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = $"FM-{imeiDel}-{DateTime.Now.ToString("yyyyMMddHHmmss")}" })) |
|
|
|
{ |
|
|
|
var watchConfig = await _deviceCacheMgr.GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(imeiDel, "0067"); |
|
|
@@ -572,6 +951,16 @@ namespace HealthMonitor.WebApi |
|
|
|
// 统计结束时间 |
|
|
|
var statEndTime = fmNowSubtract; |
|
|
|
|
|
|
|
// 最后一条 |
|
|
|
PregnancyHeartRateModel lastPhr = await _serviceTDengine.GetLastAsync<PregnancyHeartRateModel>(imeiDel); |
|
|
|
Thread thread = new(async () => { |
|
|
|
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
thread.Start(); |
|
|
|
|
|
|
|
|
|
|
|
var isFetalMovementExisted = await _deviceCacheMgr.FetalMovementIsExistedAsync(imeiDel, fetalMovementSampleTime); |
|
|
|
_logger.LogInformation($"{imeiDel} 胎动记录{isFetalMovementExisted},数据采样时间:{fetalMovementSampleTime}|{fmNowSubtract.ToString("yyyy-MM-dd HH:mm:ss")}, 周期:{statStartTime}-{statEndTime} 开始"); |
|
|
|
|
|
|
@@ -920,6 +1309,7 @@ namespace HealthMonitor.WebApi |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion |
|
|
|
} |
|
|
|
else |
|
|
@@ -1588,13 +1978,13 @@ namespace HealthMonitor.WebApi |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
var c = 0; |
|
|
|
while (true) |
|
|
|
{ |
|
|
|
var c = 0; |
|
|
|
|
|
|
|
var segmentStatStartTime = boundaryStatStartTime.AddMinutes(c * INTERVAL_FHR); |
|
|
|
var segmentStatEndTime = segmentStatStartTime.AddMinutes(INTERVAL_FHR); |
|
|
|
c++; |
|
|
|
|
|
|
|
var statStartTime = segmentStatStartTime; |
|
|
|
var statEndTime = segmentStatEndTime; |
|
|
|
|
|
|
|