diff --git a/HealthMonitor.Model/Cache/FetalMovementNormalValueRange.cs b/HealthMonitor.Model/Cache/FetalMovementNormalValueRange.cs
new file mode 100644
index 0000000..400178b
--- /dev/null
+++ b/HealthMonitor.Model/Cache/FetalMovementNormalValueRange.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HealthMonitor.Model.Cache
+{
+ public class FetalMovementNormalValueRange
+ {
+ ///
+ /// 孕周期
+ ///
+ public int[] PregnancyPeriod { get; set; }
+ ///
+ /// 正常胎动(次/小时)
+ ///
+ public int[] NormalMovementRange { get; set; }
+ ///
+ /// 12小时胎动(次)
+ ///
+ public int[] TwelveHourMovementRange { get; set; }
+ ///
+ /// 胎动中间值(次/小时)
+ ///
+ public int MedianMovement { get; set; }
+ ///
+ /// 胎动起始值(次/小时)
+ ///
+ public int InitialMovement { get; set; }
+ ///
+ /// 备注
+ ///
+ public string Remarks { get; set; }
+
+ public FetalMovementNormalValueRange(int[] pregnancyPeriod, int[] normalMovementRange, int[] twelveHourMovementRange, int medianMovement, int initialMovement, string remarks)
+ {
+ PregnancyPeriod = pregnancyPeriod;
+ NormalMovementRange = normalMovementRange;
+ TwelveHourMovementRange = twelveHourMovementRange;
+ MedianMovement = medianMovement;
+ InitialMovement = initialMovement;
+ Remarks = remarks;
+ }
+ }
+}
diff --git a/HealthMonitor.Service/Biz/IotApiService.cs b/HealthMonitor.Service/Biz/IotApiService.cs
index 8b7e297..02d9ae3 100644
--- a/HealthMonitor.Service/Biz/IotApiService.cs
+++ b/HealthMonitor.Service/Biz/IotApiService.cs
@@ -254,7 +254,11 @@ namespace HealthMonitor.Service.Biz
#endregion
+
#region 平台下发胎心监测参数
+
+
+
///
/// 胎心设置
///
@@ -328,8 +332,6 @@ namespace HealthMonitor.Service.Biz
return false;
}
}
-
-
///
/// 下发胎心数据
///
@@ -340,7 +342,7 @@ namespace HealthMonitor.Service.Biz
///
public async Task SetFetalHeartRateConfig(string serialno, int fhr, string sampeTime, int isAbnormal)
{
-
+
try
{
#region 读取缓存
@@ -369,8 +371,8 @@ namespace HealthMonitor.Service.Biz
_logger.LogInformation($" SetFetalHeartRateConfig Token TelpoManufactorId: {tokenAuthData}");
var data = new
{
- imei= serialno,
- heartValue= fhr,
+ imei = serialno,
+ heartValue = fhr,
sampeTime,
isAbnormal
};
@@ -383,16 +385,70 @@ namespace HealthMonitor.Service.Biz
return resJToken?["message"]?.ToString().Equals("ok") ?? false;
#endregion
-
+
}
catch (Exception ex)
{
_logger.LogError($"{nameof(SetFetalHeartRateConfig)} 下发胎心数据异常:{ex.Message}, {ex.StackTrace}");
return false;
}
-
+
+ }
+
+ public async Task SetFetalMovementConfig(string serialno,int fm, string sampeTime, int isAbnormal)
+ {
+ try
+ {
+ #region 读取缓存
+ // db7.HashGet("TELPO#GPSDEVICE_WATCH_CONFIG_HASH","861281060086083_0067")
+ var watchConfig = await _deviceCacheMgr.GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(serialno, "0067");
+ if (watchConfig == null)
+ {
+ return false;
+ }
+
+ #endregion
+
+ #region 获取B端 Token
+ string tokenAuthData = await getAccessToken2(serialno).ConfigureAwait(false);
+ if (tokenAuthData == null)
+ {
+ return false;
+ }
+ #endregion
+
+ #region 下发数据
+ List> headers = new()
+ {
+ new KeyValuePair("AccessToken", tokenAuthData)
+ };
+ _logger.LogInformation($" SetFetalHeartRateConfig Token TelpoManufactorId: {tokenAuthData}");
+ var data = new
+ {
+ imei = serialno,
+ movementValue = fm,
+ sampeTime,
+ isAbnormal
+ };
+
+ var setUrl = $"{_configService.IotCore}/SetFetalMovementConfig";
+ _logger.LogInformation($"{setUrl} 请求 {JsonConvert.SerializeObject(JsonConvert.SerializeObject(data))}");
+ var res = await _httpHelper.HttpToPostAsync(setUrl, data, headers).ConfigureAwait(false);
+ _logger.LogInformation($"{setUrl} 响应 {res}");
+ var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken;
+ return resJToken?["message"]?.ToString().Equals("ok") ?? false;
+
+ #endregion
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"{nameof(SetFetalMovementConfig)} 下发胎动数据异常:{ex.Message}, {ex.StackTrace}");
+ return false;
+ }
+
}
+
private async Task getAccessToken2(string serialno)
{
var getTokenUrl = $"{_configService.IotAuth}/getAccessToken2";
diff --git a/HealthMonitor.Service/Biz/db/TDengineService.cs b/HealthMonitor.Service/Biz/db/TDengineService.cs
index a7dd14f..490b0f4 100644
--- a/HealthMonitor.Service/Biz/db/TDengineService.cs
+++ b/HealthMonitor.Service/Biz/db/TDengineService.cs
@@ -973,17 +973,17 @@ namespace HealthMonitor.Service.Biz.db
return null;
}
long.TryParse(watchConfig["EDOC"]!.ToString(), out long edoc);
- // "EDOC": "1720860180652",EDOC -280 days =怀孕时间
-
+ // "EDOC": "1720860180652",当前时间 - (EDOC - 280) days =怀孕时间
+ edoc = edoc.ToString().Length == 10 ? edoc * 1000 : edoc;
int pregnancyWeek = (DateTime.Now-DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(edoc).AddDays(-280)).Days / 7;
- _logger.LogInformation($"EDOC:{edoc},NOW:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},SinceNOW:{DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(edoc).AddDays(-280).ToString("yyyy-MM-dd HH:mm:ss")},怀孕周数 {pregnancyWeek}");
+ _logger.LogInformation($"IMEI {serialNo},EDOC:{edoc},NOW:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},SinceNOW:{DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(edoc).AddDays(-280).ToString("yyyy-MM-dd HH:mm:ss")},怀孕周数 {pregnancyWeek}");
var statMaxValueFprCoefficient = 0;
var statMinValueFprCoefficient = 0;
var StatModeAvgFprCoefficient = 0;
- // 20-40周之间
- if (pregnancyWeek >= 12 && pregnancyWeek <= 40)
+ // 20-45周之间
+ if (pregnancyWeek >= 12 && pregnancyWeek <= 45)
{
var map= fhrMap
.Where(i =>
diff --git a/HealthMonitor.Service/Cache/FetalMovementNormalValueRangeCacheManager.cs b/HealthMonitor.Service/Cache/FetalMovementNormalValueRangeCacheManager.cs
new file mode 100644
index 0000000..a774bbb
--- /dev/null
+++ b/HealthMonitor.Service/Cache/FetalMovementNormalValueRangeCacheManager.cs
@@ -0,0 +1,33 @@
+using HealthMonitor.Model.Cache;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HealthMonitor.Service.Cache
+{
+ public class FetalMovementNormalValueRangeCacheManager
+ {
+ private readonly ILogger _logger;
+ public FetalMovementNormalValueRangeCacheManager(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public List GetFetalMovements()
+ {
+ return new List
+ {
+ new (new int[] {12, 20}, new int[] {1, 3}, new int[] {10, 30}, 2, 1, "初次感觉到胎动"),
+ new (new int[] {21, 24}, new int[] {2, 4}, new int[] {20, 40}, 3, 2, "胎动逐渐增强"),
+ new (new int[] {25, 28}, new int[] {3, 5}, new int[] {30, 50}, 4, 3, "胎动更加明显"),
+ new (new int[] {29, 32}, new int[] {6, 8}, new int[] {60, 80}, 7, 6, "胎动达到高峰"),
+ new (new int[] {33, 36}, new int[] {5, 7}, new int[] {50, 70}, 6, 5, "胎动频繁且有力"),
+ new (new int[] {37, 40}, new int[] {3, 5}, new int[] {30, 50}, 4, 3, "胎动可能因空间减少而减少"),
+ new (new int[] {41, 50}, new int[] {2, 4}, new int[] {20, 40}, 3, 2, "减少,但因人而异。胎儿入盆,空间受限")
+ };
+ }
+ }
+}
diff --git a/HealthMonitor.Service/Cache/FhrPhrMapCacheManager.cs b/HealthMonitor.Service/Cache/FhrPhrMapCacheManager.cs
index d34a573..b6b7319 100644
--- a/HealthMonitor.Service/Cache/FhrPhrMapCacheManager.cs
+++ b/HealthMonitor.Service/Cache/FhrPhrMapCacheManager.cs
@@ -15,13 +15,13 @@ namespace HealthMonitor.Service.Cache
{
_logger = logger;
}
- public List GetHeartRatesMap()
+ public List GetHeartRatesMap()
{
return new List
{
new FhrPhrMap(new int[] {12, 20}, new int[] {120, 170}, 162, new int[] {60, 100}, new int[] {50, 80}),
new FhrPhrMap(new int[] {21, 30}, new int[] {110, 160}, 147, new int[] {60, 100}, new int[] {40, 70}),
- new FhrPhrMap(new int[] {31, 40}, new int[] {110, 160}, 139, new int[] {60, 100}, new int[] {40, 70})
+ new FhrPhrMap(new int[] {31, 45}, new int[] {110, 160}, 139, new int[] {60, 100}, new int[] {40, 70})
};
}
}
diff --git a/HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs b/HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs
index c856ca1..c1b2ac8 100644
--- a/HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs
+++ b/HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs
@@ -11,6 +11,7 @@ using HealthMonitor.Service.Sub.Topic.Model;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
+using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -199,29 +200,69 @@ namespace HealthMonitor.Service.Resolver
#region 定时计算胎心数据触发器 {interval} 秒后
var fetalKey = $"health_monitor/schedule_push/cal_fetal_heart_rate/imei/{heartRate.Serialno}";
- var scheduleFetalPush = await _serviceEtcd.GetValAsync(fetalKey).ConfigureAwait(false);
- if (string.IsNullOrWhiteSpace(scheduleFetalPush))
+ await SetIntervalTriggerAsync(fetalKey, heartRate.Serialno, 60 * 15);
+
+ //var scheduleFetalPush = await _serviceEtcd.GetValAsync(fetalKey).ConfigureAwait(false);
+ //if (string.IsNullOrWhiteSpace(scheduleFetalPush))
+ //{
+ // //var fetalInterval = (int)watchConfig["interval"]!;
+ // var fetalInterval = 60 * 15;
+ // var fetalNow= DateTime.Now;
+ // var fetalTimeNextRun = fetalNow.Add(TimeSpan.FromSeconds(fetalInterval));
+ // var fetalTTL = fetalInterval;
+ // var data = new
+ // {
+ // imei = heartRate.Serialno,
+ // create_time = fetalNow.ToString("yyyy-MM-dd HH:mm:ss"),
+ // fetalTTL,
+ // next_run_time = fetalTimeNextRun.ToString("yyyy-MM-dd HH:mm:ss")
+ // };
+ // var result = JsonConvert.SerializeObject(data);
+ // await _serviceEtcd.PutValAsync(fetalKey, result, fetalTTL, false).ConfigureAwait(false);
+ //}
+
+ #endregion
+
+ #region 定时计算胎动数据触发器 0 点开始
+ var fetalMovementKey = $"health_monitor/schedule_push/cal_fetal_movement/imei/{heartRate.Serialno}";
+ /// 计算 0 点秒数
+ DateTime now = DateTime.Now;
+ var rand = new Random();
+ var pushSec = rand.Next(59);
+ int pushMin = int.TryParse(heartRate.Serialno.AsSpan(heartRate.Serialno.Length - 1), out pushMin) ? pushMin : 10;
+ DateTime nextRunTime = new (now.Year, now.Month, now.Day, 0, pushMin, pushSec);
+ TimeSpan timeUntilNextRun = nextRunTime - now;
+ if (timeUntilNextRun < TimeSpan.Zero)
{
- //var fetalInterval = (int)watchConfig["interval"]!;
- var fetalInterval = 60 * 15;
- var fetalNow= DateTime.Now;
- var fetalTimeNextRun = fetalNow.Add(TimeSpan.FromSeconds(fetalInterval));
- var fetalTTL = fetalInterval;
- var data = new
- {
- imei = heartRate.Serialno,
- create_time = fetalNow.ToString("yyyy-MM-dd HH:mm:ss"),
- fetalTTL,
- next_run_time = fetalTimeNextRun.ToString("yyyy-MM-dd HH:mm:ss")
- };
- var result = JsonConvert.SerializeObject(data);
- await _serviceEtcd.PutValAsync(fetalKey, result, fetalTTL, false).ConfigureAwait(false);
+ timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromDays(1));
+ nextRunTime += timeUntilNextRun;
}
- #endregion
- }
+ var ttl = (long)timeUntilNextRun.TotalSeconds;
+
+ await SetIntervalTriggerAsync(fetalMovementKey, heartRate.Serialno, ttl);
+ //var scheduleFetalMovementPush = await _serviceEtcd.GetValAsync(fetalMovementKey).ConfigureAwait(false);
+ //if (string.IsNullOrWhiteSpace(scheduleFetalMovementPush))
+ //{
+ // var fetalMovementInterval = 60 * 15;
+ // var fetalMovementNow = DateTime.Now;
+ // var fetalMovementTimeNextRun = fetalMovementNow.Add(TimeSpan.FromSeconds(fetalMovementInterval));
+ // var fetalMovementTTL = fetalMovementInterval;
+ // var data = new
+ // {
+ // imei = heartRate.Serialno,
+ // create_time = fetalMovementNow.ToString("yyyy-MM-dd HH:mm:ss"),
+ // fetalMovementTTL,
+ // next_run_time = fetalMovementTimeNextRun.ToString("yyyy-MM-dd HH:mm:ss")
+ // };
+ // var result = JsonConvert.SerializeObject(data);
+ // await _serviceEtcd.PutValAsync(fetalKey, result, fetalMovementTTL, false).ConfigureAwait(false);
+ //}
+
+ #endregion
+ }
#region 定时下发触发器(定时建模)
var key = $"health_monitor/schedule_push/pregnancy_heart_rate/imei/{heartRate.Serialno}";
@@ -333,5 +374,25 @@ namespace HealthMonitor.Service.Resolver
await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal);
}
}
+
+ private async Task SetIntervalTriggerAsync(string key,string imei, long interval)
+ {
+ // var key = $"health_monitor/schedule_push/{type}/imei/{imei}";
+ var schedulePush = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false);
+ if (string.IsNullOrWhiteSpace(schedulePush))
+ {
+ var now = DateTime.Now;
+ var timeNextRun = now.Add(TimeSpan.FromSeconds(interval));
+ var data = new
+ {
+ imei,
+ create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
+ ttl = interval,
+ next_run_time = timeNextRun.ToString("yyyy-MM-dd HH:mm:ss")
+ };
+ var result = JsonConvert.SerializeObject(data);
+ await _serviceEtcd.PutValAsync(key, result, interval, false).ConfigureAwait(false);
+ }
+ }
}
}
diff --git a/HealthMonitor.WebApi/Program.cs b/HealthMonitor.WebApi/Program.cs
index 482271e..9934426 100644
--- a/HealthMonitor.WebApi/Program.cs
+++ b/HealthMonitor.WebApi/Program.cs
@@ -174,6 +174,7 @@ namespace HealthMonitor.WebApi
.AddSingleton()
.AddSingleton()
.AddSingleton()
+ .AddSingleton()
.AddSingleton();
#endregion
diff --git a/HealthMonitor.WebApi/Worker.cs b/HealthMonitor.WebApi/Worker.cs
index afcc4db..1d2bd00 100644
--- a/HealthMonitor.WebApi/Worker.cs
+++ b/HealthMonitor.WebApi/Worker.cs
@@ -4,6 +4,7 @@ using Google.Protobuf.WellKnownTypes;
using HealthMonitor.Common;
using HealthMonitor.Common.helper;
using HealthMonitor.Core.Common.Extensions;
+using HealthMonitor.Core.Pipeline;
using HealthMonitor.Model.Config;
using HealthMonitor.Model.Service;
using HealthMonitor.Model.Service.Mapper;
@@ -17,12 +18,16 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+using System;
using System.Reflection;
using System.Threading.Channels;
using TDengineDriver;
using TDengineTMQ;
using TelpoDataService.Util.Clients;
+using TelpoDataService.Util.Entities.GpsCard;
using TelpoDataService.Util.Entities.GpsLocationHistory;
+using TelpoDataService.Util.Models;
+using TelpoDataService.Util.QueryObjects;
namespace HealthMonitor.WebApi
{
@@ -40,6 +45,7 @@ namespace HealthMonitor.WebApi
private readonly BloodPressReferenceValueCacheManager _bpRefValCacheManager;
private readonly PersonCacheManager _personCacheMgr;
private readonly DeviceCacheManager _deviceCacheMgr;
+ private readonly FetalMovementNormalValueRangeCacheManager _mgrFetalMovementNormalValueRangeCache;
private readonly GpsLocationHistoryAccessorClient _hisFetalHeartApiClient;
@@ -50,6 +56,7 @@ namespace HealthMonitor.WebApi
IOptions optionBoodPressResolver, PackageProcess processor,
TDengineDataSubcribe tdEngineDataSubcribe, TDengineService serviceDengine,
GpsLocationHistoryAccessorClient hisFetalHeartApiClient,
+ FetalMovementNormalValueRangeCacheManager fetalMovementNormalValueRangeCacheMgr,
HttpHelper httpHelper, EtcdService serviceEtcd, DeviceCacheManager deviceCacheMgr)
{
_logger = logger;
@@ -65,6 +72,7 @@ namespace HealthMonitor.WebApi
_personCacheMgr = personCacheMgr;
_deviceCacheMgr = deviceCacheMgr;
_hisFetalHeartApiClient = hisFetalHeartApiClient;
+ _mgrFetalMovementNormalValueRangeCache = fetalMovementNormalValueRangeCacheMgr;
}
public override Task StartAsync(CancellationToken cancellationToken)
@@ -286,28 +294,133 @@ namespace HealthMonitor.WebApi
#region 注册定时计算胎心数据触发器 {interval} 秒后
//var fetalKey = $"health_monitor/schedule_push/cal_fetal_heart_rate/imei/{imeiDel}";
- var fetalKey = key;
- var scheduleFetalPush = await _serviceEtcd.GetValAsync(fetalKey).ConfigureAwait(false);
- if (string.IsNullOrWhiteSpace(scheduleFetalPush))
+ //var fetalKey = key;
+ //var scheduleFetalPush = await _serviceEtcd.GetValAsync(fetalKey).ConfigureAwait(false);
+ //if (string.IsNullOrWhiteSpace(scheduleFetalPush))
+ //{
+ // // var fetalInterval = (int)watchConfig!["interval"]!;
+ // var fetalInterval = 60 * 15;
+
+ // var fetalNow = DateTime.Now;
+ // var fetalTimeNextRun = fetalNow.Add(TimeSpan.FromSeconds(fetalInterval));
+ // var fetalTTL = fetalInterval;
+ // var data = new
+ // {
+ // imei = imeiDel,
+ // create_time = fetalNow.ToString("yyyy-MM-dd HH:mm:ss"),
+ // fetalTTL,
+ // next_run_time = fetalTimeNextRun.ToString("yyyy-MM-dd HH:mm:ss")
+ // };
+ // var result = JsonConvert.SerializeObject(data);
+ // await _serviceEtcd.PutValAsync(fetalKey, result, fetalTTL, false).ConfigureAwait(false);
+ //}
+
+ await SetIntervalTriggerAsync(key, imeiDel, 60 * 15);
+
+ #endregion
+ }
+ }
+
+
+ }
+
+ //health_monitor/schedule_push/cal_fetal_movement/imei/
+ else if (key.Contains("health_monitor/schedule_push/cal_fetal_movement/imei/"))
+ {
+ // 计算胎动数据
+ var watchConfig = await _deviceCacheMgr.GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(imeiDel, "0067");
+ var isFetalHeartEnable = watchConfig != null && (int)watchConfig["enabled"]! == 1;
+ if (isFetalHeartEnable)
+ {
+ // 检查胎心建模
+ var fchr = await _serviceTDengine.GetLastAsync();
+ if (fchr != null)
+ {
+ // 获取孕妇心率数据接近最近2小时的数据
+ var phr = await _serviceTDengine.GetBySerialNoAsync(imeiDel, 1);
+ var now = DateTime.Now;
+ var ago2hrs = now.AddHours(-2);
+ var phrRange = phr.Where(i => i.LastUpdate >= ago2hrs)
+ .OrderByDescending(i => i.LastUpdate)
+ .Select(i => i.LastUpdate)
+ .ToList();
+
+ if (phrRange.Count >= 2)
{
- // var fetalInterval = (int)watchConfig!["interval"]!;
- var fetalInterval = 60 * 15;
+ var duringMins = (phrRange.First() - phrRange.Last()).TotalMinutes;
+ //在餐后时间段(8:00~10:00,12:00~14:00,18:00~20:00,22:00~24:00)取中间值。其他时间段取正常起始值
+ bool isInTimeRanges = IsNowInTimeRanges();
- var fetalNow = DateTime.Now;
- var fetalTimeNextRun = fetalNow.Add(TimeSpan.FromSeconds(fetalInterval));
- var fetalTTL = fetalInterval;
- var data = new
+ long.TryParse(watchConfig!["EDOC"]!.ToString(), out long edoc);
+
+ int pregnancyWeeks = (DateTime.Now - DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(edoc).AddDays(-280)).Days / 7;
+ if (pregnancyWeeks >= 12 && pregnancyWeeks <= 50)
{
- imei = imeiDel,
- create_time = fetalNow.ToString("yyyy-MM-dd HH:mm:ss"),
- fetalTTL,
- next_run_time = fetalTimeNextRun.ToString("yyyy-MM-dd HH:mm:ss")
- };
- var result = JsonConvert.SerializeObject(data);
- await _serviceEtcd.PutValAsync(fetalKey, result, fetalTTL, false).ConfigureAwait(false);
+ 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);
+
+ var sampleTime = DateTimeUtil.ConvertToTimeStamp(DateTime.Now).ToString();
+ // 告警上限阀值
+ var upperAlarmThreshold = (int)watchConfig["upperAlarmThreshold"]!;
+ // 告警下限阀值
+ var lowerAlarmThreshold = (int)watchConfig["lowerAlarmThreshold"]!;
+
+ GeneralParam param = new()
+ {
+ Filters = new List
+ {
+ new ()
+ {
+ Key=nameof(HisGpsFetalHeartRate.Serialno),
+ Value=imeiDel,
+ ValueType=QueryValueTypeEnum.String,
+ Operator=QueryOperatorEnum.Equal
+ }
+ },
+ OrderBys = new List
+ {
+ new() {
+ IsDesc=true,
+ Key=nameof(HisGpsFetalHeartRate.CreateTime)
+ }
+ }
+ };
+ var frh = await _hisFetalHeartApiClient.GetFirstAsync(param, imeiDel.Substring(imeiDel.Length - 2), null, new RequestHeader { RequestId = Guid.NewGuid().ToString("D") }).ConfigureAwait(false);
+ if (frh != null)
+ {
+ var fetalHeartRate = frh.HeartRate;
+ var isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0);
+ // 推送到api/v1/open/OpenIot/SetFetalMovementConfig
+ await _serviceIotApi.SetFetalMovementConfig(imeiDel, fetalMovement, sampleTime, isAbnormal);
+ // 保存到MySQL数据库
+ }
+ }
+
}
- #endregion
+
}
+
+ #region 定时计算胎动数据触发器 2小时后
+ await SetIntervalTriggerAsync(key, imeiDel, 60 * 60 * 2);
+ #endregion
}
@@ -646,5 +759,41 @@ namespace HealthMonitor.WebApi
}
+ private async Task SetIntervalTriggerAsync(string key, string imei, long interval)
+
+ {
+ // var key = $"health_monitor/schedule_push/{type}/imei/{imei}";
+ var schedulePush = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false);
+ if (string.IsNullOrWhiteSpace(schedulePush))
+ {
+ var now = DateTime.Now;
+ var timeNextRun = now.Add(TimeSpan.FromSeconds(interval));
+ var data = new
+ {
+ imei,
+ create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
+ ttl = interval,
+ next_run_time = timeNextRun.ToString("yyyy-MM-dd HH:mm:ss")
+ };
+ var result = JsonConvert.SerializeObject(data);
+ await _serviceEtcd.PutValAsync(key, result, interval, false).ConfigureAwait(false);
+ }
+ }
+
+ public static bool IsNowInTimeRanges()
+ {
+ var now = DateTime.Now.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);
+ }
}
}