Browse Source

胎动计算

datasub12_fetal_heart_rate_0
H Vs 4 months ago
parent
commit
f92d31d769
8 changed files with 395 additions and 49 deletions
  1. +46
    -0
      HealthMonitor.Model/Cache/FetalMovementNormalValueRange.cs
  2. +63
    -7
      HealthMonitor.Service/Biz/IotApiService.cs
  3. +5
    -5
      HealthMonitor.Service/Biz/db/TDengineService.cs
  4. +33
    -0
      HealthMonitor.Service/Cache/FetalMovementNormalValueRangeCacheManager.cs
  5. +2
    -2
      HealthMonitor.Service/Cache/FhrPhrMapCacheManager.cs
  6. +79
    -18
      HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs
  7. +1
    -0
      HealthMonitor.WebApi/Program.cs
  8. +166
    -17
      HealthMonitor.WebApi/Worker.cs

+ 46
- 0
HealthMonitor.Model/Cache/FetalMovementNormalValueRange.cs View File

@@ -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;
}
}
}

+ 63
- 7
HealthMonitor.Service/Biz/IotApiService.cs View File

@@ -254,7 +254,11 @@ namespace HealthMonitor.Service.Biz


#endregion #endregion



#region 平台下发胎心监测参数 #region 平台下发胎心监测参数


/// <summary> /// <summary>
/// 胎心设置 /// 胎心设置
/// </summary> /// </summary>
@@ -328,8 +332,6 @@ namespace HealthMonitor.Service.Biz
return false; return false;
} }
} }


/// <summary> /// <summary>
/// 下发胎心数据 /// 下发胎心数据
/// </summary> /// </summary>
@@ -340,7 +342,7 @@ namespace HealthMonitor.Service.Biz
/// <returns></returns> /// <returns></returns>
public async Task<bool> SetFetalHeartRateConfig(string serialno, int fhr, string sampeTime, int isAbnormal) public async Task<bool> SetFetalHeartRateConfig(string serialno, int fhr, string sampeTime, int isAbnormal)
{ {
try try
{ {
#region 读取缓存 #region 读取缓存
@@ -369,8 +371,8 @@ namespace HealthMonitor.Service.Biz
_logger.LogInformation($" SetFetalHeartRateConfig Token TelpoManufactorId: {tokenAuthData}"); _logger.LogInformation($" SetFetalHeartRateConfig Token TelpoManufactorId: {tokenAuthData}");
var data = new var data = new
{ {
imei= serialno,
heartValue= fhr,
imei = serialno,
heartValue = fhr,
sampeTime, sampeTime,
isAbnormal isAbnormal
}; };
@@ -383,16 +385,70 @@ namespace HealthMonitor.Service.Biz
return resJToken?["message"]?.ToString().Equals("ok") ?? false; return resJToken?["message"]?.ToString().Equals("ok") ?? false;


#endregion #endregion
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError($"{nameof(SetFetalHeartRateConfig)} 下发胎心数据异常:{ex.Message}, {ex.StackTrace}"); _logger.LogError($"{nameof(SetFetalHeartRateConfig)} 下发胎心数据异常:{ex.Message}, {ex.StackTrace}");
return false; 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) private async Task<string> getAccessToken2(string serialno)
{ {
var getTokenUrl = $"{_configService.IotAuth}/getAccessToken2"; var getTokenUrl = $"{_configService.IotAuth}/getAccessToken2";


+ 5
- 5
HealthMonitor.Service/Biz/db/TDengineService.cs View File

@@ -973,17 +973,17 @@ namespace HealthMonitor.Service.Biz.db
return null; return null;
} }
long.TryParse(watchConfig["EDOC"]!.ToString(), out long edoc); 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; 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 statMaxValueFprCoefficient = 0;
var statMinValueFprCoefficient = 0; var statMinValueFprCoefficient = 0;
var StatModeAvgFprCoefficient = 0; var StatModeAvgFprCoefficient = 0;
// 20-40周之间
if (pregnancyWeek >= 12 && pregnancyWeek <= 40)
// 20-45周之间
if (pregnancyWeek >= 12 && pregnancyWeek <= 45)
{ {
var map= fhrMap var map= fhrMap
.Where(i => .Where(i =>


+ 33
- 0
HealthMonitor.Service/Cache/FetalMovementNormalValueRangeCacheManager.cs View File

@@ -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, "减少,但因人而异。胎儿入盆,空间受限")
};
}
}
}

+ 2
- 2
HealthMonitor.Service/Cache/FhrPhrMapCacheManager.cs View File

@@ -15,13 +15,13 @@ namespace HealthMonitor.Service.Cache
{ {
_logger = logger; _logger = logger;
} }
public List<FhrPhrMap> GetHeartRatesMap()
public List<FhrPhrMap> GetHeartRatesMap()
{ {
return new List<FhrPhrMap> 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[] {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[] {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})
}; };
} }
} }


+ 79
- 18
HealthMonitor.Service/Resolver/PregnancyHeartRateResolver.cs View File

@@ -11,6 +11,7 @@ using HealthMonitor.Service.Sub.Topic.Model;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using SqlSugar;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -199,29 +200,69 @@ namespace HealthMonitor.Service.Resolver


#region 定时计算胎心数据触发器 {interval} 秒后 #region 定时计算胎心数据触发器 {interval} 秒后
var fetalKey = $"health_monitor/schedule_push/cal_fetal_heart_rate/imei/{heartRate.Serialno}"; 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 定时下发触发器(定时建模) #region 定时下发触发器(定时建模)
var key = $"health_monitor/schedule_push/pregnancy_heart_rate/imei/{heartRate.Serialno}"; 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); 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);
}
}
} }
} }

+ 1
- 0
HealthMonitor.WebApi/Program.cs View File

@@ -174,6 +174,7 @@ namespace HealthMonitor.WebApi
.AddSingleton<PersonCacheManager>() .AddSingleton<PersonCacheManager>()
.AddSingleton<DeviceCacheManager>() .AddSingleton<DeviceCacheManager>()
.AddSingleton<FhrPhrMapCacheManager>() .AddSingleton<FhrPhrMapCacheManager>()
.AddSingleton<FetalMovementNormalValueRangeCacheManager>()
.AddSingleton<BloodPressReferenceValueCacheManager>(); .AddSingleton<BloodPressReferenceValueCacheManager>();


#endregion #endregion


+ 166
- 17
HealthMonitor.WebApi/Worker.cs View File

@@ -4,6 +4,7 @@ using Google.Protobuf.WellKnownTypes;
using HealthMonitor.Common; using HealthMonitor.Common;
using HealthMonitor.Common.helper; using HealthMonitor.Common.helper;
using HealthMonitor.Core.Common.Extensions; using HealthMonitor.Core.Common.Extensions;
using HealthMonitor.Core.Pipeline;
using HealthMonitor.Model.Config; using HealthMonitor.Model.Config;
using HealthMonitor.Model.Service; using HealthMonitor.Model.Service;
using HealthMonitor.Model.Service.Mapper; using HealthMonitor.Model.Service.Mapper;
@@ -17,12 +18,16 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System;
using System.Reflection; using System.Reflection;
using System.Threading.Channels; using System.Threading.Channels;
using TDengineDriver; using TDengineDriver;
using TDengineTMQ; using TDengineTMQ;
using TelpoDataService.Util.Clients; using TelpoDataService.Util.Clients;
using TelpoDataService.Util.Entities.GpsCard;
using TelpoDataService.Util.Entities.GpsLocationHistory; using TelpoDataService.Util.Entities.GpsLocationHistory;
using TelpoDataService.Util.Models;
using TelpoDataService.Util.QueryObjects;


namespace HealthMonitor.WebApi namespace HealthMonitor.WebApi
{ {
@@ -40,6 +45,7 @@ namespace HealthMonitor.WebApi
private readonly BloodPressReferenceValueCacheManager _bpRefValCacheManager; private readonly BloodPressReferenceValueCacheManager _bpRefValCacheManager;
private readonly PersonCacheManager _personCacheMgr; private readonly PersonCacheManager _personCacheMgr;
private readonly DeviceCacheManager _deviceCacheMgr; private readonly DeviceCacheManager _deviceCacheMgr;
private readonly FetalMovementNormalValueRangeCacheManager _mgrFetalMovementNormalValueRangeCache;


private readonly GpsLocationHistoryAccessorClient<HisGpsFetalHeartRate> _hisFetalHeartApiClient; private readonly GpsLocationHistoryAccessorClient<HisGpsFetalHeartRate> _hisFetalHeartApiClient;


@@ -50,6 +56,7 @@ namespace HealthMonitor.WebApi
IOptions<BoodPressResolverConfig> optionBoodPressResolver, PackageProcess processor, IOptions<BoodPressResolverConfig> optionBoodPressResolver, PackageProcess processor,
TDengineDataSubcribe tdEngineDataSubcribe, TDengineService serviceDengine, TDengineDataSubcribe tdEngineDataSubcribe, TDengineService serviceDengine,
GpsLocationHistoryAccessorClient<HisGpsFetalHeartRate> hisFetalHeartApiClient, GpsLocationHistoryAccessorClient<HisGpsFetalHeartRate> hisFetalHeartApiClient,
FetalMovementNormalValueRangeCacheManager fetalMovementNormalValueRangeCacheMgr,
HttpHelper httpHelper, EtcdService serviceEtcd, DeviceCacheManager deviceCacheMgr) HttpHelper httpHelper, EtcdService serviceEtcd, DeviceCacheManager deviceCacheMgr)
{ {
_logger = logger; _logger = logger;
@@ -65,6 +72,7 @@ namespace HealthMonitor.WebApi
_personCacheMgr = personCacheMgr; _personCacheMgr = personCacheMgr;
_deviceCacheMgr = deviceCacheMgr; _deviceCacheMgr = deviceCacheMgr;
_hisFetalHeartApiClient = hisFetalHeartApiClient; _hisFetalHeartApiClient = hisFetalHeartApiClient;
_mgrFetalMovementNormalValueRangeCache = fetalMovementNormalValueRangeCacheMgr;
} }


public override Task StartAsync(CancellationToken cancellationToken) public override Task StartAsync(CancellationToken cancellationToken)
@@ -286,28 +294,133 @@ namespace HealthMonitor.WebApi


#region 注册定时计算胎心数据触发器 {interval} 秒后 #region 注册定时计算胎心数据触发器 {interval} 秒后
//var fetalKey = $"health_monitor/schedule_push/cal_fetal_heart_rate/imei/{imeiDel}"; //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);
}
} }
} }

Loading…
Cancel
Save