ソースを参照

调整标定值缓存生命周期

td_orm
H Vs 1年前
コミット
fa6b89e66e
3個のファイルの変更247行の追加180行の削除
  1. +44
    -1
      HealthMonitor.Service/Cache/BloodPressReferenceValueCacheManager.cs
  2. +177
    -177
      HealthMonitor.WebApi/Controllers/HealthMonitor/HmBloodPressController.cs
  3. +26
    -2
      HealthMonitor.WebApi/Controllers/HealthMonitor/HmBloodPressReferenceValueController.cs

+ 44
- 1
HealthMonitor.Service/Cache/BloodPressReferenceValueCacheManager.cs ファイルの表示

@@ -5,6 +5,7 @@ using HealthMonitor.Util.Entities.HealthMonitor;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;

@@ -57,7 +58,7 @@ namespace HealthMonitor.Service.Cache
i.Age.Equals(age) &&
i.Gender.Equals(gender) &&
i.Hypertension.Equals(isHypertension)
);
).ConfigureAwait(false);
await RedisHelper.SetAsync(cacheKey, JsonConvert.SerializeObject(bpRef));
return bpRef;
}
@@ -76,6 +77,48 @@ namespace HealthMonitor.Service.Cache

}

public async Task UpdateBloodPressReferenceValueAsync(HmBloodPressReferenceValue bpRef)
{
try
{
var hashModel = new
{
Index = $"{bpRef.Age}-{bpRef.Gender}-{bpRef.Hypertension}"
};
var hash = ComputeHash(hashModel);
var cacheKey = CACHE_KEY_BP_REF_VALUE + $"{hash}";
await RedisHelper.SetAsync(cacheKey, JsonConvert.SerializeObject(bpRef));
}
catch (Exception ex)
{
_logger.LogError($"{nameof(UpdateBloodPressReferenceValueAsync)}发生异常:{ex.Message}, {ex.StackTrace}");
}
}

public async Task DeleteBloodPressReferenceValueAsync(HmBloodPressReferenceValue bpRef)
{
try
{

var hashModel = new
{
Index = $"{bpRef.Age}-{bpRef.Gender}-{bpRef.Hypertension}"
};
var hash = ComputeHash(hashModel);
var cacheKey = CACHE_KEY_BP_REF_VALUE + $"{hash}";
await RedisHelper.DelAsync(cacheKey);

}
catch (Exception ex)
{
_logger.LogError($"{nameof(DeleteBloodPressReferenceValueAsync)}发生异常:{ex.Message}, {ex.StackTrace}");

}
}

private string ComputeHash(object data)
{


+ 177
- 177
HealthMonitor.WebApi/Controllers/HealthMonitor/HmBloodPressController.cs ファイルの表示

@@ -18,187 +18,187 @@ using TelpoDataService.Util.Entities.GpsLocationHistory;

namespace HealthMonitor.WebApi.Controllers.HealthMonitor
{
[ApiExplorerSettings(GroupName = AppConsts.SWAGGER_DOC_HealthMonitor)]
[Produces("application/json")]
[Route("api/HealthMonitor/[controller]/[action]")]
[ApiController]
public class HmBloodPressController:ControllerBase
{
//[ApiExplorerSettings(GroupName = AppConsts.SWAGGER_DOC_HealthMonitor)]
//[Produces("application/json")]
//[Route("api/HealthMonitor/[controller]/[action]")]
//[ApiController]
//public class HmBloodPressController:ControllerBase
//{

protected readonly ILogger _logger;
private readonly TDengineService _serviceTDengine;
private readonly PersonCacheManager _personCacheMgr;
private readonly BloodPressReferenceValueCacheManager _bpRefValCacheManager;
protected readonly IHealthMonitorDataAccessor _dataAccessor;
// protected readonly ILogger _logger;
// private readonly TDengineService _serviceTDengine;
// private readonly PersonCacheManager _personCacheMgr;
// private readonly BloodPressReferenceValueCacheManager _bpRefValCacheManager;
// protected readonly IHealthMonitorDataAccessor _dataAccessor;


public HmBloodPressController
(
ILogger<HmBloodPressController> logger,
TDengineService serviceDengine,
PersonCacheManager personCacheMgr,
BloodPressReferenceValueCacheManager bpRefValCacheManager,
IHealthMonitorDataAccessor dataAccessor
)
{
_logger = logger;
_serviceTDengine = serviceDengine;
_personCacheMgr = personCacheMgr;
_dataAccessor = dataAccessor;
_bpRefValCacheManager = bpRefValCacheManager;
// public HmBloodPressController
// (
// ILogger<HmBloodPressController> logger,
// TDengineService serviceDengine,
// PersonCacheManager personCacheMgr,
// BloodPressReferenceValueCacheManager bpRefValCacheManager,
// IHealthMonitorDataAccessor dataAccessor
// )
// {
// _logger = logger;
// _serviceTDengine = serviceDengine;
// _personCacheMgr = personCacheMgr;
// _dataAccessor = dataAccessor;
// _bpRefValCacheManager = bpRefValCacheManager;
}
[HttpPost]
public async Task<IActionResult> AddAsync([FromHeader] string requestId,[FromBody] HisGpsBloodPress bp)
{
//
//HisGpsBloodPress bp = new()
//{
// BloodPressId = "261850cb-ce91-4003-8c63-a1f8f50d6495",
// MessageId = "1670682284342246914",
// Serialno = "861281060083627",
// SystolicValue = 114,
// DiastolicValue = 79,
// CreateTime = DateTime.Parse("2023-06-19 14:37:53"),
// LastUpdate = DateTime.Parse("2023-06-19 14:26:52"),
// Method = 1,
// IsDisplay = 1
//};
//
//861281060081969
//HisGpsBloodPress bp = new()
//{
// BloodPressId = "7df62202-8d49-4f91-90da-25a4036c26fb",
// MessageId = "1670992704491900929",
// Serialno = "861281060081969",
// SystolicValue = 110,
// DiastolicValue = 72,
// CreateTime = DateTime.Parse("2023-06-20 11:11:31"),
// LastUpdate = DateTime.Parse("2023-06-20 10:20:40"),
// Method = 1,
// IsDisplay = 1
//};
// 861281060086380
//var aggregate = await _serviceTDengine.GetAvgExceptMaxMinValueAsync("diastolic_value", "hm_bloodpress", $"ts>='{DateTime.Now.AddDays(-7):yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{DateTime.Now:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='861281060083627' and systolic_value < {120} and diastolic_value >{80}");
//+++++++++++++++++++++++++++++++
#region 获取个人信息
var person = await _personCacheMgr.GetDeviceGpsPersonCacheBySerialNoAsync(bp.MessageId, bp.Serialno).ConfigureAwait(false);
// 验证这个信息是否存在
if (person == null || person?.Person.BornDate == null) return Ok(false);
// 验证年龄是否在范围 (2 - 120)
var age = SafeType.SafeInt(DateTime.Today.Year - person?.Person.BornDate!.Value.Year!);
if (age < 1 || age > 120) return Ok(false);
var gender = person?.Person.Gender == true ? 1 : 2;
var isHypertension = SafeType.SafeBool(person?.Person.Ishypertension!);
var height = SafeType.SafeDouble(person?.Person.Height!);
var weight = SafeType.SafeDouble(person?.Person.Weight!);
#endregion
#region 插入当次BP数据
// 保存到TDengine
var bpSql = $"INSERT INTO health_monitor.hm_bloodpress VALUES(" +
$"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
$"'{bp.BloodPressId}'," +
$"'{bp.MessageId}'," +
$"'{bp.Serialno}'," +
$"{bp.SystolicValue}," +
$"{bp.DiastolicValue}," +
$"'{bp.CreateTime:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
$"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
$"{bp.Method}," +
$"{bp.IsDisplay == 1})";
await _serviceTDengine.GernalRestSql(bpSql);
#endregion
#region 计算增量值
var bpRef = await _bpRefValCacheManager.GetBloodPressReferenceValueAsync(age, gender, isHypertension);
var systolicRefValue = bpRef?.Systolic;//?
var diastolicRefValue = bpRef?.Diastolic;//?
int duration = 30;
// 获取历史数据
DateTime now = DateTime.Now;
DateTime startTime = now.AddDays(-duration);
DateTime endTime = now;
//
var systolicAggregate = await _serviceTDengine.GetAggregateValueAsync("systolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}'");
var diastolicAggregate = await _serviceTDengine.GetAggregateValueAsync("diastolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}'");
// 最大值
var systolicMax = systolicAggregate.Max;
var diastolicMax = diastolicAggregate.Max;
// 最小值
var systolicMin = systolicAggregate.Min;
var diastolicMin = diastolicAggregate.Min;
// 计算去除最大值和最小值和异常值的平均值
var systolicAvg = await _serviceTDengine.GetAvgExceptMaxMinValueAsync("systolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}' and systolic_value < {systolicRefValue} and diastolic_value >{diastolicRefValue}");
var diastolicAvg = await _serviceTDengine.GetAvgExceptMaxMinValueAsync("diastolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}' and systolic_value < {systolicRefValue} and diastolic_value >{diastolicRefValue}");
// 偏移参数
var avgOffset = 0.25M;
var systolicAvgOffset = avgOffset;
var diastolicAvgOffset = avgOffset;
// 增量值=(标定值-平均值)* 0.25
var systolicInc = systolicAvg.Equals(0M) ? 0: (int)((systolicRefValue - systolicAvg)* systolicAvgOffset)!;
var diastolicInc = diastolicAvg.Equals(0M) ? 0 : (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!;
#endregion
#region 插入BP增量值
var sql = $"INSERT INTO health_monitor.hm_bloodpress_stats_inc VALUES(" +
$"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
$"'{bp.BloodPressId}'," +
$"'{bp.MessageId}'," +
$"'{bp.Serialno}'," +
$"{bp.SystolicValue}," +
$"{systolicRefValue}," +
$"{systolicAvg}," +
$"{systolicMax}," +
$"{systolicMin}," +
$"{systolicAvgOffset}," +
$"{systolicInc}," +
$"{bp.DiastolicValue}," +
$"{diastolicRefValue}," +
$"{diastolicAvg}," +
$"{diastolicMax}," +
$"{diastolicMin}," +
$"{diastolicAvgOffset}," +
$"{diastolicInc}," +
$"{gender}," +
$"{age}," +
$"{height}," +
$"{weight}," +
$"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
$"{duration}," +
$"'{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
$"'{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
$"'{string.Empty}')";
var res = await _serviceTDengine.GernalRestSql(sql);
#endregion
return Ok(res);
}
}
// }
// [HttpPost]
// public async Task<IActionResult> AddAsync([FromHeader] string requestId,[FromBody] HisGpsBloodPress bp)
// {
// //
// //HisGpsBloodPress bp = new()
// //{
// // BloodPressId = "261850cb-ce91-4003-8c63-a1f8f50d6495",
// // MessageId = "1670682284342246914",
// // Serialno = "861281060083627",
// // SystolicValue = 114,
// // DiastolicValue = 79,
// // CreateTime = DateTime.Parse("2023-06-19 14:37:53"),
// // LastUpdate = DateTime.Parse("2023-06-19 14:26:52"),
// // Method = 1,
// // IsDisplay = 1
// //};
// //
// //861281060081969
// //HisGpsBloodPress bp = new()
// //{
// // BloodPressId = "7df62202-8d49-4f91-90da-25a4036c26fb",
// // MessageId = "1670992704491900929",
// // Serialno = "861281060081969",
// // SystolicValue = 110,
// // DiastolicValue = 72,
// // CreateTime = DateTime.Parse("2023-06-20 11:11:31"),
// // LastUpdate = DateTime.Parse("2023-06-20 10:20:40"),
// // Method = 1,
// // IsDisplay = 1
// //};
// // 861281060086380
// //var aggregate = await _serviceTDengine.GetAvgExceptMaxMinValueAsync("diastolic_value", "hm_bloodpress", $"ts>='{DateTime.Now.AddDays(-7):yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{DateTime.Now:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='861281060083627' and systolic_value < {120} and diastolic_value >{80}");
// //+++++++++++++++++++++++++++++++
// #region 获取个人信息
// var person = await _personCacheMgr.GetDeviceGpsPersonCacheBySerialNoAsync(bp.MessageId, bp.Serialno).ConfigureAwait(false);
// // 验证这个信息是否存在
// if (person == null || person?.Person.BornDate == null) return Ok(false);
// // 验证年龄是否在范围 (2 - 120)
// var age = SafeType.SafeInt(DateTime.Today.Year - person?.Person.BornDate!.Value.Year!);
// if (age < 1 || age > 120) return Ok(false);
// var gender = person?.Person.Gender == true ? 1 : 2;
// var isHypertension = SafeType.SafeBool(person?.Person.Ishypertension!);
// var height = SafeType.SafeDouble(person?.Person.Height!);
// var weight = SafeType.SafeDouble(person?.Person.Weight!);
// #endregion
// #region 插入当次BP数据
// // 保存到TDengine
// var bpSql = $"INSERT INTO health_monitor.hm_bloodpress VALUES(" +
// $"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
// $"'{bp.BloodPressId}'," +
// $"'{bp.MessageId}'," +
// $"'{bp.Serialno}'," +
// $"{bp.SystolicValue}," +
// $"{bp.DiastolicValue}," +
// $"'{bp.CreateTime:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
// $"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
// $"{bp.Method}," +
// $"{bp.IsDisplay == 1})";
// await _serviceTDengine.GernalRestSql(bpSql);
// #endregion
// #region 计算增量值
// var bpRef = await _bpRefValCacheManager.GetBloodPressReferenceValueAsync(age, gender, isHypertension);
// var systolicRefValue = bpRef?.Systolic;//?
// var diastolicRefValue = bpRef?.Diastolic;//?
// int duration = 30;
// // 获取历史数据
// DateTime now = DateTime.Now;
// DateTime startTime = now.AddDays(-duration);
// DateTime endTime = now;
// //
// var systolicAggregate = await _serviceTDengine.GetAggregateValueAsync("systolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}'");
// var diastolicAggregate = await _serviceTDengine.GetAggregateValueAsync("diastolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}'");
// // 最大值
// var systolicMax = systolicAggregate.Max;
// var diastolicMax = diastolicAggregate.Max;
// // 最小值
// var systolicMin = systolicAggregate.Min;
// var diastolicMin = diastolicAggregate.Min;
// // 计算去除最大值和最小值和异常值的平均值
// var systolicAvg = await _serviceTDengine.GetAvgExceptMaxMinValueAsync("systolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}' and systolic_value < {systolicRefValue} and diastolic_value >{diastolicRefValue}");
// var diastolicAvg = await _serviceTDengine.GetAvgExceptMaxMinValueAsync("diastolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and ts <='{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}' and serialno='{bp.Serialno}' and systolic_value < {systolicRefValue} and diastolic_value >{diastolicRefValue}");
// // 偏移参数
// var avgOffset = 0.25M;
// var systolicAvgOffset = avgOffset;
// var diastolicAvgOffset = avgOffset;
// // 增量值=(标定值-平均值)* 0.25
// var systolicInc = systolicAvg.Equals(0M) ? 0: (int)((systolicRefValue - systolicAvg)* systolicAvgOffset)!;
// var diastolicInc = diastolicAvg.Equals(0M) ? 0 : (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!;
// #endregion
// #region 插入BP增量值
// var sql = $"INSERT INTO health_monitor.hm_bloodpress_stats_inc VALUES(" +
// $"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
// $"'{bp.BloodPressId}'," +
// $"'{bp.MessageId}'," +
// $"'{bp.Serialno}'," +
// $"{bp.SystolicValue}," +
// $"{systolicRefValue}," +
// $"{systolicAvg}," +
// $"{systolicMax}," +
// $"{systolicMin}," +
// $"{systolicAvgOffset}," +
// $"{systolicInc}," +
// $"{bp.DiastolicValue}," +
// $"{diastolicRefValue}," +
// $"{diastolicAvg}," +
// $"{diastolicMax}," +
// $"{diastolicMin}," +
// $"{diastolicAvgOffset}," +
// $"{diastolicInc}," +
// $"{gender}," +
// $"{age}," +
// $"{height}," +
// $"{weight}," +
// $"'{bp.LastUpdate:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
// $"{duration}," +
// $"'{startTime:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
// $"'{endTime:yyyy-MM-ddTHH:mm:ss.fffZ}'," +
// $"'{string.Empty}')";
// var res = await _serviceTDengine.GernalRestSql(sql);
// #endregion
// return Ok(res);
// }
//}
}

+ 26
- 2
HealthMonitor.WebApi/Controllers/HealthMonitor/HmBloodPressReferenceValueController.cs ファイルの表示

@@ -1,6 +1,7 @@
using HealthMonitor.Core.Cache;
using HealthMonitor.Core.Dal;
using HealthMonitor.Core.Operator;
using HealthMonitor.Service.Cache;
using HealthMonitor.Util.Entities.HealthMonitor;
using HealthMonitor.WebApi.Configs;
using HealthMonitor.WebApi.Controllers.Base;
@@ -11,16 +12,39 @@ namespace HealthMonitor.WebApi.Controllers.HealthMonitor
[ApiExplorerSettings(GroupName = AppConsts.SWAGGER_DOC_HealthMonitor)]
public class HmBloodPressReferenceValueController : HealthMonitorControllerBase<HmBloodPressReferenceValue>
{
private readonly BloodPressReferenceValueCacheManager _bpRefValCacheManager;
public HmBloodPressReferenceValueController(
// IHealthMonitorDataAccessor dataAccessor,
IHealthMonitorDataAccessor dataAccessor,
IHealthMonitorOperatorManager operatorManager,
IDurableEntityManager durableManager,
ILogger<HmBloodPressReferenceValueController> logger)
ILogger<HmBloodPressReferenceValueController> logger,
BloodPressReferenceValueCacheManager bpRefValCacheManager
)
: base(dataAccessor, operatorManager, durableManager, logger)
{

_bpRefValCacheManager = bpRefValCacheManager;
}

[HttpPut]
//[UpdateCacheInterceptor]
public override async void Update([FromBody] HmBloodPressReferenceValue model, [FromHeader] string requestId)
{
AssertModelStateIsValid(model);
_dataAccessor.Update(model);
_dataAccessor.Save();
await _bpRefValCacheManager.UpdateBloodPressReferenceValueAsync(model);
}

[HttpDelete]

//[DeleteCacheInterceptor]
public override async void Delete([FromBody] HmBloodPressReferenceValue model, [FromHeader] string requestId)
{
_dataAccessor.Delete(model);
_dataAccessor.Save();
await _bpRefValCacheManager.DeleteBloodPressReferenceValueAsync(model).ConfigureAwait(false);
}
}
}

読み込み中…
キャンセル
保存