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); + } } }