@@ -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 | |||
{ | |||
/// <summary> | |||
/// 孕周期 | |||
/// </summary> | |||
public int[] PregnancyPeriod { get; set; } | |||
/// <summary> | |||
/// 正常胎动(次/小时) | |||
/// </summary> | |||
public int[] NormalMovementRange { get; set; } | |||
/// <summary> | |||
/// 12小时胎动(次) | |||
/// </summary> | |||
public int[] TwelveHourMovementRange { get; set; } | |||
/// <summary> | |||
/// 胎动中间值(次/小时) | |||
/// </summary> | |||
public int MedianMovement { get; set; } | |||
/// <summary> | |||
/// 胎动起始值(次/小时) | |||
/// </summary> | |||
public int InitialMovement { get; set; } | |||
/// <summary> | |||
/// 备注 | |||
/// </summary> | |||
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; | |||
} | |||
} | |||
} |
@@ -254,7 +254,11 @@ namespace HealthMonitor.Service.Biz | |||
#endregion | |||
#region 平台下发胎心监测参数 | |||
/// <summary> | |||
/// 胎心设置 | |||
/// </summary> | |||
@@ -328,8 +332,6 @@ namespace HealthMonitor.Service.Biz | |||
return false; | |||
} | |||
} | |||
/// <summary> | |||
/// 下发胎心数据 | |||
/// </summary> | |||
@@ -340,7 +342,7 @@ namespace HealthMonitor.Service.Biz | |||
/// <returns></returns> | |||
public async Task<bool> 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<bool> 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<KeyValuePair<string, string>> headers = new() | |||
{ | |||
new KeyValuePair<string, string>("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<string> getAccessToken2(string serialno) | |||
{ | |||
var getTokenUrl = $"{_configService.IotAuth}/getAccessToken2"; | |||
@@ -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 => | |||
@@ -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<FetalMovementNormalValueRange> _logger; | |||
public FetalMovementNormalValueRangeCacheManager(ILogger<FetalMovementNormalValueRange> logger) | |||
{ | |||
_logger = logger; | |||
} | |||
public List<FetalMovementNormalValueRange> GetFetalMovements() | |||
{ | |||
return new List<FetalMovementNormalValueRange> | |||
{ | |||
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, "减少,但因人而异。胎儿入盆,空间受限") | |||
}; | |||
} | |||
} | |||
} |
@@ -15,13 +15,13 @@ namespace HealthMonitor.Service.Cache | |||
{ | |||
_logger = logger; | |||
} | |||
public List<FhrPhrMap> GetHeartRatesMap() | |||
public List<FhrPhrMap> GetHeartRatesMap() | |||
{ | |||
return new List<FhrPhrMap> | |||
{ | |||
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}) | |||
}; | |||
} | |||
} | |||
@@ -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); | |||
} | |||
} | |||
} | |||
} |
@@ -174,6 +174,7 @@ namespace HealthMonitor.WebApi | |||
.AddSingleton<PersonCacheManager>() | |||
.AddSingleton<DeviceCacheManager>() | |||
.AddSingleton<FhrPhrMapCacheManager>() | |||
.AddSingleton<FetalMovementNormalValueRangeCacheManager>() | |||
.AddSingleton<BloodPressReferenceValueCacheManager>(); | |||
#endregion | |||
@@ -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<HisGpsFetalHeartRate> _hisFetalHeartApiClient; | |||
@@ -50,6 +56,7 @@ namespace HealthMonitor.WebApi | |||
IOptions<BoodPressResolverConfig> optionBoodPressResolver, PackageProcess processor, | |||
TDengineDataSubcribe tdEngineDataSubcribe, TDengineService serviceDengine, | |||
GpsLocationHistoryAccessorClient<HisGpsFetalHeartRate> 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<PregnancyCommonHeartRateModel>(); | |||
if (fchr != null) | |||
{ | |||
// 获取孕妇心率数据接近最近2小时的数据 | |||
var phr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(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<QueryFilterCondition> | |||
{ | |||
new () | |||
{ | |||
Key=nameof(HisGpsFetalHeartRate.Serialno), | |||
Value=imeiDel, | |||
ValueType=QueryValueTypeEnum.String, | |||
Operator=QueryOperatorEnum.Equal | |||
} | |||
}, | |||
OrderBys = new List<OrderByCondition> | |||
{ | |||
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); | |||
} | |||
} | |||
} |