From 6f1d87206375531bfa7adc0d1e2e70246c2e55b7 Mon Sep 17 00:00:00 2001 From: H Vs Date: Thu, 29 Aug 2024 11:55:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HealthMonitor.WebApi/Worker.cs | 394 ++++++++++++++++++++++++++++++++- 1 file changed, 392 insertions(+), 2 deletions(-) diff --git a/HealthMonitor.WebApi/Worker.cs b/HealthMonitor.WebApi/Worker.cs index 1845cd2..3639b26 100644 --- a/HealthMonitor.WebApi/Worker.cs +++ b/HealthMonitor.WebApi/Worker.cs @@ -546,6 +546,385 @@ namespace HealthMonitor.WebApi { #region 胎动延时计算 + /** + using (_logger.BeginScope(new Dictionary { ["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(imeiDel); + if (commonPHR != null) + { + var phr = await _serviceTDengine.GetBySerialNoAsync(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 + { + 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 + { + 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 + { + 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 + { + 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 { ["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(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;