@@ -10,17 +10,9 @@ | |||
public string EtcdServerAddress { get; set; } = default!; | |||
public string IotWebApiUrl { get; set; } = default!; | |||
///// <summary> | |||
///// Kafka服务地址 | |||
///// </summary> | |||
//public string MqServerAddress { get; set; } | |||
///// <summary> | |||
///// 服务守护消息kafka服务地址 | |||
///// </summary> | |||
//public string ServiceGuardMqAddress { get; set; } | |||
///// <summary> | |||
///// 服务守护消息主题 | |||
///// </summary> | |||
//public string ServiceGuardMqTopic { get; set; } | |||
public string IotAuth { get; set; } = default!; | |||
public string IotCore { get; set; } = default!; | |||
} | |||
} |
@@ -0,0 +1,79 @@ | |||
using Newtonsoft.Json; | |||
using SqlSugar; | |||
using SqlSugar.TDengine; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace HealthMonitor.Model.Service.Mapper | |||
{ | |||
[STableAttribute(STableName = "stb_hm_pregnancy_common_heart_rate")] | |||
public class PregnancyCommonHeartRateModel | |||
{ | |||
[JsonProperty("ts")] | |||
[SqlSugar.SugarColumn(IsPrimaryKey = true, ColumnName = "ts", SqlParameterDbType = typeof(DateTime19))] | |||
public DateTime Timestamp { get; set; } | |||
[JsonProperty("person_id")] | |||
[SqlSugar.SugarColumn(ColumnName = "person_id")] | |||
public string PersonId { get; set; } = default!; | |||
[JsonProperty("device_key")] | |||
[SqlSugar.SugarColumn(ColumnName = "device_key")] | |||
public string DeviceKey { get; set; } = default!; | |||
[JsonProperty("serialno")] | |||
[SqlSugar.SugarColumn(ColumnName = "serialno")] | |||
public string SerialNumber { get; set; } = default!; | |||
[JsonProperty("mode")] | |||
[SqlSugar.SugarColumn(ColumnName = "mode")] | |||
public float Mode { get; set; } | |||
[JsonProperty("percentage")] | |||
[SqlSugar.SugarColumn(ColumnName = "percentage")] | |||
public int Percentage { get; set; } | |||
[JsonProperty("max_value")] | |||
[SqlSugar.SugarColumn(ColumnName = "max_value")] | |||
public int MaxValue { get; set; } | |||
[JsonProperty("min_value")] | |||
[SqlSugar.SugarColumn(ColumnName = "min_value")] | |||
public int MinValue { get; set; } | |||
[JsonProperty("original_max_value")] | |||
[SqlSugar.SugarColumn(ColumnName = "original_max_value")] | |||
public int OriginalMaxValue { get; set; } | |||
[JsonProperty("original_min_value")] | |||
[SqlSugar.SugarColumn(ColumnName = "original_min_value")] | |||
public int OriginalMinValue { get; set; } | |||
[JsonProperty("create_time")] | |||
[SqlSugar.SugarColumn(ColumnName = "create_time")] | |||
public DateTime CreateTime { get; set; } | |||
[JsonProperty("stat_start_time")] | |||
[SqlSugar.SugarColumn(ColumnName = "stat_start_time")] | |||
public DateTime StatStartTime { get; set; } | |||
[JsonProperty("stat_end_time")] | |||
[SqlSugar.SugarColumn(ColumnName = "stat_end_time")] | |||
public DateTime StatEndTime { get; set; } | |||
[JsonProperty("remark")] | |||
[SqlSugar.SugarColumn(ColumnName = "remark")] | |||
public string Remark { get; set; } = default!; | |||
[JsonProperty("serial_tail_no")] | |||
[SqlSugar.SugarColumn(IsIgnore = true, ColumnName = "serial_tail_no")] | |||
public string SerialTailNumber { get; set; } = default!; | |||
} | |||
} |
@@ -0,0 +1,328 @@ | |||
using HealthMonitor.Common.helper; | |||
using HealthMonitor.Model.Config; | |||
using HealthMonitor.Service.Resolver; | |||
using Microsoft.Extensions.Logging; | |||
using Microsoft.Extensions.Options; | |||
using Newtonsoft.Json.Linq; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using HealthMonitor.Model.Service; | |||
using TelpoDataService.Util.Entities.GpsCard; | |||
using TelpoDataService.Util; | |||
using TelpoDataService.Util.Clients; | |||
using TelpoDataService.Util.Models; | |||
using TelpoDataService.Util.QueryObjects; | |||
using HealthMonitor.Service.Cache; | |||
using HealthMonitor.Model.Cache; | |||
using Etcdserverpb; | |||
namespace HealthMonitor.Service.Biz | |||
{ | |||
public class IotApiService | |||
{ | |||
private readonly ServiceConfig _configService; | |||
private readonly ILogger<IotApiService> _logger; | |||
private readonly PersonCacheManager _personCacheMgr; | |||
private readonly DeviceCacheManager _deviceCacheMgr; | |||
private readonly HttpHelper _httpHelper = default!; | |||
private readonly GpsCardAccessorClient<GpsPerson> _gpsPersonApiClient; | |||
public IotApiService(ILogger<IotApiService> logger, HttpHelper httpHelper, DeviceCacheManager deviceCacheMgr, GpsCardAccessorClient<GpsPerson> gpsPersonApiClient, IOptions<ServiceConfig> optConfigService, PersonCacheManager personCacheMgr) | |||
{ | |||
_configService = optConfigService.Value; | |||
_httpHelper=httpHelper; | |||
_logger = logger; | |||
_personCacheMgr = personCacheMgr; | |||
_gpsPersonApiClient = gpsPersonApiClient; | |||
_deviceCacheMgr = deviceCacheMgr; | |||
} | |||
#region 平台下发血压标定参数 | |||
/// <summary> | |||
/// 平台下发血压标定参数 | |||
/// </summary> | |||
/// <param name="bpsCalibrationConfig"></param> | |||
/// <returns></returns> | |||
public async Task<bool> SetBloodPressCalibrationConfigAsync(BloodPressCalibrationConfigModel bpsCalibrationConfig) | |||
{ | |||
#if DEBUG | |||
var flag = true; | |||
#else | |||
//systolicCalibrationValue = 0, //收缩压标定值,值为0 表示不生效 | |||
//diastolicCalibrationValue 0, //舒张压标定值,值为0表示不生效 | |||
//systolicIncValue = 0, //收缩压显示增量,值为0 表示不生效 | |||
//diastolicIncValue = 0 //舒张压显示增量,值为0 表示不生效 | |||
var flag = false; | |||
try | |||
{ | |||
var url = $"{_configService.IotWebApiUrl}Command/SetBloodPressCalibrationConfig"; | |||
List<KeyValuePair<string, string>> headers = new() | |||
{ | |||
new KeyValuePair<string, string>("AuthKey", "key1") | |||
}; | |||
var res = await _httpHelper.HttpToPostAsync(url, bpsCalibrationConfig, headers).ConfigureAwait(false); | |||
_logger.LogInformation($"向{bpsCalibrationConfig.Imei}下发增量值数据:{JsonConvert.SerializeObject(bpsCalibrationConfig)},响应:{res}"); | |||
var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; | |||
flag= resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(SetBloodPressCalibrationConfigAsync)} 下发血压增量值异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
#endif | |||
return flag; | |||
} | |||
public async Task<BloodPressCalibrationConfigModelReponse> SetBloodPressCalibrationConfig2Async(BloodPressCalibrationConfigModel bpsCalibrationConfig) | |||
{ | |||
BloodPressCalibrationConfigModelReponse response = new BloodPressCalibrationConfigModelReponse(); | |||
response.Flag = false; | |||
response.Message = string.Empty; | |||
#if DEBUG | |||
//var flag = true; | |||
response.Flag=true; | |||
#else | |||
//systolicCalibrationValue = 0, //收缩压标定值,值为0 表示不生效 | |||
//diastolicCalibrationValue 0, //舒张压标定值,值为0表示不生效 | |||
//systolicIncValue = 0, //收缩压显示增量,值为0 表示不生效 | |||
//diastolicIncValue = 0 //舒张压显示增量,值为0 表示不生效 | |||
// var flag = false; | |||
try | |||
{ | |||
var url = $"{_configService.IotWebApiUrl}Command/SetBloodPressCalibrationConfig"; | |||
List<KeyValuePair<string, string>> headers = new() | |||
{ | |||
new KeyValuePair<string, string>("AuthKey", "key1") | |||
}; | |||
var res = await _httpHelper.HttpToPostAsync(url, bpsCalibrationConfig, headers).ConfigureAwait(false); | |||
_logger.LogInformation($"向{bpsCalibrationConfig.Imei}下发增量值数据:{JsonConvert.SerializeObject(bpsCalibrationConfig)},响应:{res}"); | |||
var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; | |||
//response.Flag= resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
response.Flag = Convert.ToBoolean(resJToken?["succeed"]?.ToString()); | |||
if (!response.Flag) | |||
{ | |||
response.Message = resJToken?["message"]?.ToString()!; | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(SetBloodPressCalibrationConfigAsync)} 下发血压增量值异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
#endif | |||
return response; | |||
} | |||
public async Task<bool> UpdatePersonRemarksAsync(string imei, int systolicRefValue, int diastolicRefValue, int systolicIncValue, int diastolicIncValue, string remarks = "is_blood_press") | |||
{ | |||
var flag = false; | |||
try | |||
{ | |||
// 保证实时性,先更新缓存,再更新数据库 | |||
var personCache = await _personCacheMgr.GetDeviceGpsPersonCacheObjectBySerialNoAsync(new Guid().ToString(), imei).ConfigureAwait(false); | |||
if (personCache == null) | |||
{ | |||
_logger.LogInformation($"{imei} -- Person remarks数据异常,检查缓存和数据库"); | |||
} | |||
else | |||
{ | |||
var newRemarkData = new | |||
{ | |||
imei, | |||
time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
commandValue = new | |||
{ | |||
systolicCalibrationValue = systolicRefValue, //收缩压标定值,值为0 表示不生效 | |||
diastolicCalibrationValue = diastolicRefValue, //舒张压标定值,值为0表示不生效 | |||
systolicIncValue, //收缩压显示增量,值为0 表示不生效 | |||
diastolicIncValue //舒张压显示增量,值为0 表示不生效 | |||
} | |||
}; | |||
var newRemarkStr = $"{remarks}:{JsonConvert.SerializeObject(newRemarkData)}|"; | |||
personCache["person"]!["remarks"] = newRemarkStr; | |||
bool cacheFlag = await _personCacheMgr.UpdateDeviceGpsPersonCacheObjectBySerialNoAsync(personCache, imei); | |||
if (cacheFlag) | |||
{ | |||
GeneralParam condition = new() | |||
{ | |||
Filters = new List<QueryFilterCondition> { | |||
new QueryFilterCondition { | |||
Key=nameof(GpsDevice.Serialno), | |||
Value=imei, | |||
Operator= QueryOperatorEnum.Equal, | |||
ValueType=QueryValueTypeEnum.String | |||
} | |||
}, | |||
OrderBys = new List<OrderByCondition> { new OrderByCondition { Key = "serialno", IsDesc = true } } | |||
}; | |||
_logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)}成功,{JsonConvert.SerializeObject(personCache)}"); | |||
// 读取数据库 | |||
var person = await _gpsPersonApiClient.GetFirstAsync(condition, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// 更新字段 | |||
person!.Remarks = newRemarkStr; | |||
await _gpsPersonApiClient.UpdateAsync(person, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
_logger.LogInformation($"{imei} 更新Person remarks字段|{person.Remarks}"); | |||
} | |||
else | |||
{ | |||
_logger.LogInformation($"{imei} 更新缓存和数据库{nameof(UpdatePersonRemarksAsync)}失败,{JsonConvert.SerializeObject(personCache)}"); | |||
} | |||
flag = cacheFlag; | |||
} | |||
// else if (string.IsNullOrWhiteSpace(personCache["person"]!["remarks"]!.ToString())) | |||
//else if (personCache?["person"]!["remarks"]!.ToString()!=null) | |||
//{ | |||
// var newRemarkData = new | |||
// { | |||
// imei, | |||
// time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
// commandValue = new | |||
// { | |||
// systolicCalibrationValue = systolicRefValue, //收缩压标定值,值为0 表示不生效 | |||
// diastolicCalibrationValue = diastolicRefValue, //舒张压标定值,值为0表示不生效 | |||
// systolicIncValue, //收缩压显示增量,值为0 表示不生效 | |||
// diastolicIncValue //舒张压显示增量,值为0 表示不生效 | |||
// } | |||
// }; | |||
// var newRemarkStr = $"{remarks}:{JsonConvert.SerializeObject(newRemarkData)}|"; | |||
// personCache["person"]!["remarks"] = newRemarkStr; | |||
// bool cacheFlag = await _personCacheMgr.UpdateDeviceGpsPersonCacheObjectBySerialNoAsync(personCache, imei); | |||
// if (cacheFlag) | |||
// { | |||
// GeneralParam condition = new() | |||
// { | |||
// Filters = new List<QueryFilterCondition> { | |||
// new QueryFilterCondition { | |||
// Key=nameof(GpsDevice.Serialno), | |||
// Value=imei, | |||
// Operator= QueryOperatorEnum.Equal, | |||
// ValueType=QueryValueTypeEnum.String | |||
// } | |||
// }, | |||
// OrderBys = new List<OrderByCondition> { new OrderByCondition { Key = "serialno", IsDesc = true } } | |||
// }; | |||
// _logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)}成功,{JsonConvert.SerializeObject(personCache)}"); | |||
// // 读取数据库 | |||
// var person = await _gpsPersonApiClient.GetFirstAsync(condition, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// // 更新字段 | |||
// person!.Remarks = newRemarkStr; | |||
// await _gpsPersonApiClient.UpdateAsync(person, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// _logger.LogInformation($"{imei} 更新Person remarks字段|{person.Remarks}"); | |||
// } | |||
// else | |||
// { | |||
// _logger.LogInformation($"{imei} 更新缓存和数据库{nameof(UpdatePersonRemarksAsync)}失败,{JsonConvert.SerializeObject(personCache)}"); | |||
// } | |||
// flag = cacheFlag; | |||
//} | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(UpdatePersonRemarksAsync)} {imei}--更新个人信息异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
return flag; | |||
} | |||
#endregion | |||
#region 平台下发胎心监测参数 | |||
public async Task<bool> SetFetalHeartRateConfig(string serialno, int modeStatus=0, int maxValue=0, int minValue = 0) | |||
{ | |||
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 | |||
var getTokenUrl = $"{_configService.IotAuth}/getAccessToken2"; | |||
var tokenReq = new | |||
{ | |||
manufactorId= "7c7c38cb-d045-41d8-b3d0-fcaaa84a8f02", | |||
imei= serialno | |||
}; | |||
var resToken = await _httpHelper.HttpToPostAsync(getTokenUrl, tokenReq).ConfigureAwait(false); | |||
var tokenAuth= JsonConvert.DeserializeObject(resToken ?? string.Empty) as JToken; | |||
var tokenAuthData = tokenAuth?["data"]?.ToString()??string.Empty; | |||
if (tokenAuthData == null) | |||
{ | |||
return false; | |||
} | |||
#endregion | |||
#region 发送到B端 | |||
List<KeyValuePair<string, string>> headers = new() | |||
{ | |||
new KeyValuePair<string, string>("TelpoManufactorId", tokenAuthData) | |||
}; | |||
var data = new | |||
{ | |||
imeis = new string[] { serialno }, | |||
enabled = (int)watchConfig["fetalParamters"]!["enabled"]!, | |||
triggerHighFreqHigh = maxValue == 0 ? (int)watchConfig["fetalParamters"]!["triggerHighFreqHigh"]!:maxValue, | |||
triggerLowFreqLow = minValue == 0 ? (int)watchConfig["fetalParamters"]!["triggerHighFreqLow"]! : minValue, | |||
highFreqSampleTimes = (int)watchConfig["fetalParamters"]!["highFreqSampleTimes"]!, | |||
highFreqSampleInterval = (int)watchConfig["fetalParamters"]!["highFreqSampleInterval"]!, | |||
stopHighFreqSampleCount = (int)watchConfig["fetalParamters"]!["stopHighFreqSampleCount"]!, | |||
mode = modeStatus, | |||
edoc = watchConfig["fetalParamters"]!["EDOC"]!, | |||
vibrateEnabled = (int)watchConfig["fetalParamters"]!["vibrateEnabled"]!, | |||
lcdEnabled= (int)watchConfig["fetalParamters"]!["lcdEnabled"]! | |||
}; | |||
var setUrl = $"{_configService.IotCore}/api/v1/open/OpenIot/SetFetalConfig"; | |||
var res = await _httpHelper.HttpToPostAsync(setUrl, data, headers).ConfigureAwait(false); | |||
var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; | |||
return resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
//response.Flag = resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
//response.Flag = Convert.ToBoolean(resJToken?["succeed"]?.ToString()); | |||
//if (!response.Flag) | |||
//{ | |||
// response.Message = resJToken?["message"]?.ToString()!; | |||
//} | |||
#endregion | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(SetFetalHeartRateConfig)} 下发胎心检测参数异常:{ex.Message}, {ex.StackTrace}"); | |||
return false; | |||
} | |||
} | |||
#endregion | |||
} | |||
} |
@@ -1,626 +0,0 @@ | |||
using HealthMonitor.Common.helper; | |||
using HealthMonitor.Model.Config; | |||
using HealthMonitor.Service.Resolver; | |||
using Microsoft.Extensions.Logging; | |||
using Microsoft.Extensions.Options; | |||
using Newtonsoft.Json.Linq; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using HealthMonitor.Model.Service; | |||
using TelpoDataService.Util.Entities.GpsCard; | |||
using TelpoDataService.Util; | |||
using TelpoDataService.Util.Clients; | |||
using TelpoDataService.Util.Models; | |||
using TelpoDataService.Util.QueryObjects; | |||
using HealthMonitor.Service.Cache; | |||
using HealthMonitor.Model.Cache; | |||
namespace HealthMonitor.Service.Biz | |||
{ | |||
public class IotWebApiService | |||
{ | |||
private readonly ServiceConfig _configService; | |||
private readonly ILogger<IotWebApiService> _logger; | |||
private readonly PersonCacheManager _personCacheMgr; | |||
private readonly HttpHelper _httpHelper = default!; | |||
private readonly GpsCardAccessorClient<GpsPerson> _gpsPersonApiClient; | |||
public IotWebApiService(ILogger<IotWebApiService> logger, HttpHelper httpHelper, GpsCardAccessorClient<GpsPerson> gpsPersonApiClient, IOptions<ServiceConfig> optConfigService, PersonCacheManager personCacheMgr) | |||
{ | |||
_configService = optConfigService.Value; | |||
_httpHelper=httpHelper; | |||
_logger = logger; | |||
_personCacheMgr = personCacheMgr; | |||
_gpsPersonApiClient = gpsPersonApiClient; | |||
} | |||
/// <summary> | |||
/// 平台下发血压标定参数 | |||
/// </summary> | |||
/// <param name="bpsCalibrationConfig"></param> | |||
/// <returns></returns> | |||
public async Task<bool> SetBloodPressCalibrationConfigAsync(BloodPressCalibrationConfigModel bpsCalibrationConfig) | |||
{ | |||
#if DEBUG | |||
var flag = true; | |||
#else | |||
//systolicCalibrationValue = 0, //收缩压标定值,值为0 表示不生效 | |||
//diastolicCalibrationValue 0, //舒张压标定值,值为0表示不生效 | |||
//systolicIncValue = 0, //收缩压显示增量,值为0 表示不生效 | |||
//diastolicIncValue = 0 //舒张压显示增量,值为0 表示不生效 | |||
var flag = false; | |||
try | |||
{ | |||
var url = $"{_configService.IotWebApiUrl}Command/SetBloodPressCalibrationConfig"; | |||
List<KeyValuePair<string, string>> headers = new() | |||
{ | |||
new KeyValuePair<string, string>("AuthKey", "key1") | |||
}; | |||
var res = await _httpHelper.HttpToPostAsync(url, bpsCalibrationConfig, headers).ConfigureAwait(false); | |||
_logger.LogInformation($"向{bpsCalibrationConfig.Imei}下发增量值数据:{JsonConvert.SerializeObject(bpsCalibrationConfig)},响应:{res}"); | |||
var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; | |||
flag= resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(SetBloodPressCalibrationConfigAsync)} 下发血压增量值异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
#endif | |||
return flag; | |||
} | |||
public async Task<BloodPressCalibrationConfigModelReponse> SetBloodPressCalibrationConfig2Async(BloodPressCalibrationConfigModel bpsCalibrationConfig) | |||
{ | |||
BloodPressCalibrationConfigModelReponse response = new BloodPressCalibrationConfigModelReponse(); | |||
response.Flag = false; | |||
response.Message = string.Empty; | |||
#if DEBUG | |||
//var flag = true; | |||
response.Flag=true; | |||
#else | |||
//systolicCalibrationValue = 0, //收缩压标定值,值为0 表示不生效 | |||
//diastolicCalibrationValue 0, //舒张压标定值,值为0表示不生效 | |||
//systolicIncValue = 0, //收缩压显示增量,值为0 表示不生效 | |||
//diastolicIncValue = 0 //舒张压显示增量,值为0 表示不生效 | |||
// var flag = false; | |||
try | |||
{ | |||
var url = $"{_configService.IotWebApiUrl}Command/SetBloodPressCalibrationConfig"; | |||
List<KeyValuePair<string, string>> headers = new() | |||
{ | |||
new KeyValuePair<string, string>("AuthKey", "key1") | |||
}; | |||
var res = await _httpHelper.HttpToPostAsync(url, bpsCalibrationConfig, headers).ConfigureAwait(false); | |||
_logger.LogInformation($"向{bpsCalibrationConfig.Imei}下发增量值数据:{JsonConvert.SerializeObject(bpsCalibrationConfig)},响应:{res}"); | |||
var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; | |||
//response.Flag= resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
response.Flag = Convert.ToBoolean(resJToken?["succeed"]?.ToString()); | |||
if (!response.Flag) | |||
{ | |||
response.Message = resJToken?["message"]?.ToString()!; | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(SetBloodPressCalibrationConfigAsync)} 下发血压增量值异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
#endif | |||
return response; | |||
} | |||
/** 取消 | |||
/// <summary> | |||
/// 更新 gps_person remark和缓存 | |||
/// </summary> | |||
/// <param name="imei"></param> | |||
/// <param name="systolicRefValue"></param> | |||
/// <param name="diastolicRefValue"></param> | |||
/// <returns></returns> | |||
public async Task<bool> UpdatePersonRemarksAsync(string imei,int systolicRefValue,int diastolicRefValue) | |||
{ | |||
var flag = false; | |||
try | |||
{ | |||
GeneralParam condition = new () | |||
{ | |||
Filters = new List<QueryFilterCondition> { | |||
new QueryFilterCondition { | |||
Key=nameof(GpsDevice.Serialno), | |||
Value=imei, | |||
Operator= QueryOperatorEnum.Equal, | |||
ValueType=QueryValueTypeEnum.String | |||
} | |||
}, | |||
OrderBys = new List<OrderByCondition> { new OrderByCondition { Key = "serialno", IsDesc = true } } | |||
}; | |||
var person = await _gpsPersonApiClient.GetFirstAsync(condition, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
//// 若remark为空,更新person remark字段 | |||
//if (string.IsNullOrWhiteSpace(person?.Remarks)) | |||
//{ | |||
// var newRemarkData = new | |||
// { | |||
// imei, | |||
// time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
// commandValue = new | |||
// { | |||
// systolicCalibrationValue = systolicRefValue, //收缩压标定值,值为0 表示不生效 | |||
// diastolicCalibrationValue = diastolicRefValue, //舒张压标定值,值为0表示不生效 | |||
// systolicIncValue = 0, //收缩压显示增量,值为0 表示不生效 | |||
// diastolicIncValue = 0 //舒张压显示增量,值为0 表示不生效 | |||
// } | |||
// }; | |||
// person!.Remarks = $"is_blood_press:{JsonConvert.SerializeObject(newRemarkData)}|"; | |||
// await _gpsPersonApiClient.UpdateAsync(person, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// _logger.LogInformation($"更新Person remarks字段|{person.Remarks}"); | |||
// // 更新缓存 | |||
// var url = $"{_configService.IotWebApiUrl}Device/UpdatePersonInfoCache?imei={imei}"; | |||
// List<KeyValuePair<string, string>> headers = new() | |||
// { | |||
// new KeyValuePair<string, string>("AuthKey", "key1") | |||
// }; | |||
// var res = await _httpHelper.HttpToGetAsync(url, headers).ConfigureAwait(false); | |||
// _logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)},响应:{res}"); | |||
// var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; | |||
// flag = resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
//} | |||
var newRemarkData = new | |||
{ | |||
imei, | |||
time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
commandValue = new | |||
{ | |||
systolicCalibrationValue = systolicRefValue, //收缩压标定值,值为0 表示不生效 | |||
diastolicCalibrationValue = diastolicRefValue, //舒张压标定值,值为0表示不生效 | |||
systolicIncValue = 0, //收缩压显示增量,值为0 表示不生效 | |||
diastolicIncValue = 0 //舒张压显示增量,值为0 表示不生效 | |||
} | |||
}; | |||
person!.Remarks = $"is_blood_press:{JsonConvert.SerializeObject(newRemarkData)}|"; | |||
await _gpsPersonApiClient.UpdateAsync(person, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
_logger.LogInformation($"更新Person remarks字段|{person.Remarks}"); | |||
// 更新缓存 | |||
var url = $"{_configService.IotWebApiUrl}Device/UpdatePersonInfoCache?imei={imei}"; | |||
List<KeyValuePair<string, string>> headers = new() | |||
{ | |||
new KeyValuePair<string, string>("AuthKey", "key1") | |||
}; | |||
var res = await _httpHelper.HttpToGetAsync(url, headers).ConfigureAwait(false); | |||
_logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)},响应:{res}"); | |||
var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; | |||
flag = resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(UpdatePersonRemarksAsync)} 更新个人信息异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
return flag; | |||
} | |||
*/ | |||
///// <summary> | |||
///// 初次开通更新 gps_person remark和对应的缓存 | |||
///// </summary> | |||
///// <param name="imei"></param> | |||
///// <param name="systolicRefValue"></param> | |||
///// <param name="diastolicRefValue"></param> | |||
///// <param name="systolicIncValue"></param> | |||
///// <param name="diastolicIncValue"></param> | |||
///// <returns></returns> | |||
//public async Task<bool> UpdatePersonRemarksAsync0(string imei, int systolicRefValue, int diastolicRefValue,int systolicIncValue,int diastolicIncValue) | |||
//{ | |||
// var flag = false; | |||
// try | |||
// { | |||
// GeneralParam condition = new() | |||
// { | |||
// Filters = new List<QueryFilterCondition> { | |||
// new QueryFilterCondition { | |||
// Key=nameof(GpsDevice.Serialno), | |||
// Value=imei, | |||
// Operator= QueryOperatorEnum.Equal, | |||
// ValueType=QueryValueTypeEnum.String | |||
// } | |||
// }, | |||
// OrderBys = new List<OrderByCondition> { new OrderByCondition { Key = "serialno", IsDesc = true } } | |||
// }; | |||
// var person = await _gpsPersonApiClient.GetFirstAsync(condition, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// // 若remark为空,更新person remark字段 | |||
// if (string.IsNullOrWhiteSpace(person?.Remarks)) | |||
// { | |||
// var newRemarkData = new | |||
// { | |||
// imei, | |||
// time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
// commandValue = new | |||
// { | |||
// systolicCalibrationValue = systolicRefValue, //收缩压标定值,值为0 表示不生效 | |||
// diastolicCalibrationValue = diastolicRefValue, //舒张压标定值,值为0表示不生效 | |||
// systolicIncValue, //收缩压显示增量,值为0 表示不生效 | |||
// diastolicIncValue //舒张压显示增量,值为0 表示不生效 | |||
// } | |||
// }; | |||
// person!.Remarks = $"is_blood_press:{JsonConvert.SerializeObject(newRemarkData)}|"; | |||
// await _gpsPersonApiClient.UpdateAsync(person, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// _logger.LogInformation($"更新Person remarks字段|{person.Remarks}"); | |||
// // 更新缓存 | |||
// var personCache = await _personCacheMgr.GetDeviceGpsPersonCacheObjectBySerialNoAsync(new Guid().ToString(), imei).ConfigureAwait(false); | |||
// if (personCache != null) | |||
// { | |||
// //personCache.Person.Remarks = person!.Remarks; | |||
// personCache["person"]!["remarks"] = person!.Remarks; | |||
// bool cacheFlag= await _personCacheMgr.UpdateDeviceGpsPersonCacheObjectBySerialNoAsync(personCache, imei); | |||
// // flag = true; | |||
// if (cacheFlag) | |||
// { | |||
// flag = true; | |||
// _logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)}成功,{JsonConvert.SerializeObject(personCache)}"); | |||
// } | |||
// else | |||
// { | |||
// flag = false; | |||
// _logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)}失败,{JsonConvert.SerializeObject(personCache)}"); | |||
// } | |||
// } | |||
// //var url = $"{_configService.IotWebApiUrl}Device/UpdatePersonInfoCache?imei={imei}"; | |||
// //List<KeyValuePair<string, string>> headers = new() | |||
// //{ | |||
// // new KeyValuePair<string, string>("AuthKey", "key1") | |||
// //}; | |||
// //var res = await _httpHelper.HttpToGetAsync(url, headers).ConfigureAwait(false); | |||
// //_logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)},响应:{res}"); | |||
// //var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; | |||
// //flag = resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
// } | |||
// } | |||
// catch (Exception ex) | |||
// { | |||
// _logger.LogError($"{nameof(UpdatePersonRemarksAsync)} 更新个人信息异常:{ex.Message}, {ex.StackTrace}"); | |||
// } | |||
// return flag; | |||
//} | |||
/** | |||
/// <summary> | |||
/// 更新 gps_person remark缓存和数据库 | |||
/// </summary> | |||
/// <param name="imei"></param> | |||
/// <param name="systolicRefValue"></param> | |||
/// <param name="diastolicRefValue"></param> | |||
/// <param name="systolicIncValue"></param> | |||
/// <param name="diastolicIncValue"></param> | |||
/// <param name="isInitRemakers">是否初始化,即清空remakers</param> | |||
/// <returns></returns> | |||
public async Task<bool> UpdatePersonRemarksAsync(string imei, int systolicRefValue, int diastolicRefValue, int systolicIncValue, int diastolicIncValue, bool isInitRemakers=false) | |||
{ | |||
var flag = false; | |||
try | |||
{ | |||
// 保证实时性,先更新缓存,再更新数据库 | |||
var personCache = await _personCacheMgr.GetDeviceGpsPersonCacheObjectBySerialNoAsync(new Guid().ToString(), imei).ConfigureAwait(false); | |||
if (personCache == null) | |||
{ | |||
_logger.LogInformation($"{imei} -- Person remarks数据异常,检查缓存和数据库"); | |||
} | |||
else if (string.IsNullOrWhiteSpace(personCache["person"]!["remarks"]!.ToString())) | |||
{ | |||
var newRemarkData = new | |||
{ | |||
imei, | |||
time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
commandValue = new | |||
{ | |||
systolicCalibrationValue = systolicRefValue, //收缩压标定值,值为0 表示不生效 | |||
diastolicCalibrationValue = diastolicRefValue, //舒张压标定值,值为0表示不生效 | |||
systolicIncValue, //收缩压显示增量,值为0 表示不生效 | |||
diastolicIncValue //舒张压显示增量,值为0 表示不生效 | |||
} | |||
}; | |||
var newRemarkStr = isInitRemakers ? string.Empty:$"is_blood_press:{JsonConvert.SerializeObject(newRemarkData)}|"; | |||
personCache["person"]!["remarks"] = newRemarkStr; | |||
bool cacheFlag = await _personCacheMgr.UpdateDeviceGpsPersonCacheObjectBySerialNoAsync(personCache, imei); | |||
if (cacheFlag) | |||
{ | |||
GeneralParam condition = new() | |||
{ | |||
Filters = new List<QueryFilterCondition> { | |||
new QueryFilterCondition { | |||
Key=nameof(GpsDevice.Serialno), | |||
Value=imei, | |||
Operator= QueryOperatorEnum.Equal, | |||
ValueType=QueryValueTypeEnum.String | |||
} | |||
}, | |||
OrderBys = new List<OrderByCondition> { new OrderByCondition { Key = "serialno", IsDesc = true } } | |||
}; | |||
_logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)}成功,{JsonConvert.SerializeObject(personCache)}"); | |||
// 读取数据库 | |||
var person = await _gpsPersonApiClient.GetFirstAsync(condition, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// 更新字段 | |||
person!.Remarks = newRemarkStr; | |||
await _gpsPersonApiClient.UpdateAsync(person, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
_logger.LogInformation($"{imei} 更新Person remarks字段|{person.Remarks}"); | |||
} | |||
else | |||
{ | |||
_logger.LogInformation($"{imei} 更新缓存和数据库{nameof(UpdatePersonRemarksAsync)}失败,{JsonConvert.SerializeObject(personCache)}"); | |||
} | |||
flag = cacheFlag; | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(UpdatePersonRemarksAsync)} {imei}--更新个人信息异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
return flag; | |||
} | |||
*/ | |||
/// <summary> | |||
///// 更新 gps_person remark缓存和数据库 | |||
///// </summary> | |||
///// <param name="imei"></param> | |||
///// <param name="systolicRefValue"></param> | |||
///// <param name="diastolicRefValue"></param> | |||
///// <param name="systolicIncValue"></param> | |||
///// <param name="diastolicIncValue"></param> | |||
///// <param name="remarks"></param> | |||
///// <returns></returns> | |||
//public async Task<bool> UpdatePersonRemarksAsync(string imei, int systolicRefValue, int diastolicRefValue, int systolicIncValue, int diastolicIncValue, string remarks= "is_blood_press") | |||
//{ | |||
// var flag = false; | |||
// try | |||
// { | |||
// // 保证实时性,先更新缓存,再更新数据库 | |||
// var personCache = await _personCacheMgr.GetDeviceGpsPersonCacheObjectBySerialNoAsync(new Guid().ToString(), imei).ConfigureAwait(false); | |||
// if (personCache == null) | |||
// { | |||
// _logger.LogInformation($"{imei} -- Person remarks数据异常,检查缓存和数据库"); | |||
// } | |||
// else if (string.IsNullOrWhiteSpace(personCache["person"]!["remarks"]!.ToString())) | |||
// { | |||
// var newRemarkData = new | |||
// { | |||
// imei, | |||
// time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
// commandValue = new | |||
// { | |||
// systolicCalibrationValue = systolicRefValue, //收缩压标定值,值为0 表示不生效 | |||
// diastolicCalibrationValue = diastolicRefValue, //舒张压标定值,值为0表示不生效 | |||
// systolicIncValue, //收缩压显示增量,值为0 表示不生效 | |||
// diastolicIncValue //舒张压显示增量,值为0 表示不生效 | |||
// } | |||
// }; | |||
// var newRemarkStr = $"{remarks}:{JsonConvert.SerializeObject(newRemarkData)}|"; | |||
// personCache["person"]!["remarks"] = newRemarkStr; | |||
// bool cacheFlag = await _personCacheMgr.UpdateDeviceGpsPersonCacheObjectBySerialNoAsync(personCache, imei); | |||
// if (cacheFlag) | |||
// { | |||
// GeneralParam condition = new() | |||
// { | |||
// Filters = new List<QueryFilterCondition> { | |||
// new QueryFilterCondition { | |||
// Key=nameof(GpsDevice.Serialno), | |||
// Value=imei, | |||
// Operator= QueryOperatorEnum.Equal, | |||
// ValueType=QueryValueTypeEnum.String | |||
// } | |||
// }, | |||
// OrderBys = new List<OrderByCondition> { new OrderByCondition { Key = "serialno", IsDesc = true } } | |||
// }; | |||
// _logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)}成功,{JsonConvert.SerializeObject(personCache)}"); | |||
// // 读取数据库 | |||
// var person = await _gpsPersonApiClient.GetFirstAsync(condition, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// // 更新字段 | |||
// person!.Remarks = newRemarkStr; | |||
// await _gpsPersonApiClient.UpdateAsync(person, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// _logger.LogInformation($"{imei} 更新Person remarks字段|{person.Remarks}"); | |||
// } | |||
// else | |||
// { | |||
// _logger.LogInformation($"{imei} 更新缓存和数据库{nameof(UpdatePersonRemarksAsync)}失败,{JsonConvert.SerializeObject(personCache)}"); | |||
// } | |||
// flag = cacheFlag; | |||
// } | |||
// } | |||
// catch (Exception ex) | |||
// { | |||
// _logger.LogError($"{nameof(UpdatePersonRemarksAsync)} {imei}--更新个人信息异常:{ex.Message}, {ex.StackTrace}"); | |||
// } | |||
// return flag; | |||
//} | |||
/// 更新 gps_person remark缓存和数据库 | |||
/// </summary> | |||
/// <param name="imei"></param> | |||
/// <param name="systolicRefValue"></param> | |||
/// <param name="diastolicRefValue"></param> | |||
/// <param name="systolicIncValue"></param> | |||
/// <param name="diastolicIncValue"></param> | |||
/// <param name="remarks"></param> | |||
/// <returns></returns> | |||
public async Task<bool> UpdatePersonRemarksAsync(string imei, int systolicRefValue, int diastolicRefValue, int systolicIncValue, int diastolicIncValue, string remarks = "is_blood_press") | |||
{ | |||
var flag = false; | |||
try | |||
{ | |||
// 保证实时性,先更新缓存,再更新数据库 | |||
var personCache = await _personCacheMgr.GetDeviceGpsPersonCacheObjectBySerialNoAsync(new Guid().ToString(), imei).ConfigureAwait(false); | |||
if (personCache == null) | |||
{ | |||
_logger.LogInformation($"{imei} -- Person remarks数据异常,检查缓存和数据库"); | |||
} | |||
else | |||
{ | |||
var newRemarkData = new | |||
{ | |||
imei, | |||
time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
commandValue = new | |||
{ | |||
systolicCalibrationValue = systolicRefValue, //收缩压标定值,值为0 表示不生效 | |||
diastolicCalibrationValue = diastolicRefValue, //舒张压标定值,值为0表示不生效 | |||
systolicIncValue, //收缩压显示增量,值为0 表示不生效 | |||
diastolicIncValue //舒张压显示增量,值为0 表示不生效 | |||
} | |||
}; | |||
var newRemarkStr = $"{remarks}:{JsonConvert.SerializeObject(newRemarkData)}|"; | |||
personCache["person"]!["remarks"] = newRemarkStr; | |||
bool cacheFlag = await _personCacheMgr.UpdateDeviceGpsPersonCacheObjectBySerialNoAsync(personCache, imei); | |||
if (cacheFlag) | |||
{ | |||
GeneralParam condition = new() | |||
{ | |||
Filters = new List<QueryFilterCondition> { | |||
new QueryFilterCondition { | |||
Key=nameof(GpsDevice.Serialno), | |||
Value=imei, | |||
Operator= QueryOperatorEnum.Equal, | |||
ValueType=QueryValueTypeEnum.String | |||
} | |||
}, | |||
OrderBys = new List<OrderByCondition> { new OrderByCondition { Key = "serialno", IsDesc = true } } | |||
}; | |||
_logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)}成功,{JsonConvert.SerializeObject(personCache)}"); | |||
// 读取数据库 | |||
var person = await _gpsPersonApiClient.GetFirstAsync(condition, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// 更新字段 | |||
person!.Remarks = newRemarkStr; | |||
await _gpsPersonApiClient.UpdateAsync(person, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
_logger.LogInformation($"{imei} 更新Person remarks字段|{person.Remarks}"); | |||
} | |||
else | |||
{ | |||
_logger.LogInformation($"{imei} 更新缓存和数据库{nameof(UpdatePersonRemarksAsync)}失败,{JsonConvert.SerializeObject(personCache)}"); | |||
} | |||
flag = cacheFlag; | |||
} | |||
// else if (string.IsNullOrWhiteSpace(personCache["person"]!["remarks"]!.ToString())) | |||
//else if (personCache?["person"]!["remarks"]!.ToString()!=null) | |||
//{ | |||
// var newRemarkData = new | |||
// { | |||
// imei, | |||
// time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
// commandValue = new | |||
// { | |||
// systolicCalibrationValue = systolicRefValue, //收缩压标定值,值为0 表示不生效 | |||
// diastolicCalibrationValue = diastolicRefValue, //舒张压标定值,值为0表示不生效 | |||
// systolicIncValue, //收缩压显示增量,值为0 表示不生效 | |||
// diastolicIncValue //舒张压显示增量,值为0 表示不生效 | |||
// } | |||
// }; | |||
// var newRemarkStr = $"{remarks}:{JsonConvert.SerializeObject(newRemarkData)}|"; | |||
// personCache["person"]!["remarks"] = newRemarkStr; | |||
// bool cacheFlag = await _personCacheMgr.UpdateDeviceGpsPersonCacheObjectBySerialNoAsync(personCache, imei); | |||
// if (cacheFlag) | |||
// { | |||
// GeneralParam condition = new() | |||
// { | |||
// Filters = new List<QueryFilterCondition> { | |||
// new QueryFilterCondition { | |||
// Key=nameof(GpsDevice.Serialno), | |||
// Value=imei, | |||
// Operator= QueryOperatorEnum.Equal, | |||
// ValueType=QueryValueTypeEnum.String | |||
// } | |||
// }, | |||
// OrderBys = new List<OrderByCondition> { new OrderByCondition { Key = "serialno", IsDesc = true } } | |||
// }; | |||
// _logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonRemarksAsync)}成功,{JsonConvert.SerializeObject(personCache)}"); | |||
// // 读取数据库 | |||
// var person = await _gpsPersonApiClient.GetFirstAsync(condition, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// // 更新字段 | |||
// person!.Remarks = newRemarkStr; | |||
// await _gpsPersonApiClient.UpdateAsync(person, new RequestHeader() { RequestId = $"{imei}" }).ConfigureAwait(false); | |||
// _logger.LogInformation($"{imei} 更新Person remarks字段|{person.Remarks}"); | |||
// } | |||
// else | |||
// { | |||
// _logger.LogInformation($"{imei} 更新缓存和数据库{nameof(UpdatePersonRemarksAsync)}失败,{JsonConvert.SerializeObject(personCache)}"); | |||
// } | |||
// flag = cacheFlag; | |||
//} | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(UpdatePersonRemarksAsync)} {imei}--更新个人信息异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
return flag; | |||
} | |||
/** 取消 | |||
public async Task<bool> UpdatePersonInfoCacheAsync(string imei) | |||
{ | |||
var flag = false; | |||
try | |||
{ | |||
var url = $"{_configService.IotWebApiUrl}Device/UpdatePersonInfoCache?imei={imei}"; | |||
List<KeyValuePair<string, string>> headers = new() | |||
{ | |||
new KeyValuePair<string, string>("AuthKey", "key1") | |||
}; | |||
var res = await _httpHelper.HttpToGetAsync(url, headers).ConfigureAwait(false); | |||
_logger.LogInformation($"{imei} 更新缓存{nameof(UpdatePersonInfoCacheAsync)},响应:{res}"); | |||
var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; | |||
flag = resJToken?["message"]?.ToString().Equals("ok") ?? false; | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogError($"{nameof(UpdatePersonInfoCacheAsync)} 更新缓存异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
return flag; | |||
} | |||
*/ | |||
} | |||
} |
@@ -637,6 +637,7 @@ namespace HealthMonitor.Service.Biz.db | |||
} | |||
#region SqlSugarClient | |||
/** | |||
public async Task InsertFetalHeartRateAsync() | |||
{ | |||
var tableName = typeof(FetalHeartRateModel) | |||
@@ -680,61 +681,9 @@ namespace HealthMonitor.Service.Biz.db | |||
.OrderByDescending(x => x.Timestamp).FirstAsync(); | |||
return first; | |||
} | |||
public void InsertFetalHeartRate2() | |||
{ | |||
//var insrtSql = ""; | |||
//_clientSqlSugar.Ado.ExecuteCommand(insrtSql); | |||
// 通过反射获取STableAttribute的STableName值 | |||
var tableName = typeof(FetalHeartRateModel) | |||
.GetCustomAttribute<STableAttribute>()? | |||
.STableName; | |||
if (tableName == null) | |||
{ | |||
throw new InvalidOperationException("STableAttribute not found on FetalHeartRateModel class."); | |||
} | |||
_clientSqlSugar.Ado.ExecuteCommand($"create table IF NOT EXISTS hm_fhr_00 using {tableName} tags('00')"); | |||
//_clientSqlSugar.Ado.ExecuteCommand($"create table IF NOT EXISTS hm_fhr_00 using `stb_hm_fetal_heart_rate_test` tags('00')"); | |||
_clientSqlSugar.Insertable(new FetalHeartRateModel() | |||
{ | |||
Timestamp = DateTime.Now, | |||
CreateTime = DateTime.Now, | |||
FetalHeartRate = 90, | |||
FetalHeartRateId = Guid.NewGuid().ToString("D"), | |||
IsDisplay = false, | |||
Method = 1, | |||
PersonId = Guid.NewGuid().ToString("D"), | |||
MessageId = Guid.NewGuid().ToString("D"), | |||
SerialNumber = Guid.NewGuid().ToString("D"), | |||
DeviceKey = Guid.NewGuid().ToString("D"), | |||
SerialTailNumber = "00", | |||
LastUpdate = DateTime.Now, | |||
}).AS("hm_fhr_00").ExecuteCommand(); | |||
//List<FetalHeartRateModel> rows = new(); | |||
//rows.Add(new FetalHeartRateModel() { | |||
// Timestamp = new DateTime(2024, 1, 1), | |||
// CreateTime = DateTime.Now, | |||
// FetalHeartRate = 90, | |||
// FetalHeartRateId = Guid.NewGuid().ToString("D"), | |||
// IsDisplay = false, | |||
// Method = 1, | |||
// PersonId = Guid.NewGuid().ToString("D"), | |||
// MessageId = Guid.NewGuid().ToString("D"), | |||
// SerialNumber = Guid.NewGuid().ToString("D"), | |||
// DeviceKey = Guid.NewGuid().ToString("D"), | |||
// SerialTailNumber = "00", | |||
// LastUpdate = DateTime.Now, | |||
//}); | |||
//_clientSqlSugar.Insertable(rows).AS("hm_fhr_00").ExecuteCommand(); | |||
} | |||
*/ | |||
/// <summary> | |||
/// 插入记录 | |||
/// </summary> | |||
@@ -808,5 +757,192 @@ namespace HealthMonitor.Service.Biz.db | |||
return res; | |||
} | |||
#endregion | |||
#region 胎心算法 | |||
/// <summary> | |||
/// 获取孕妇心率众数 | |||
/// </summary> | |||
/// <param name="serialNo"></param> | |||
/// <param name="days"></param> | |||
/// <returns></returns> | |||
public async Task<int> GetPregnancyHeartRateModeAsync(string serialNo,int days=7) | |||
{ | |||
var tableName = typeof(PregnancyHeartRateModel) | |||
.GetCustomAttribute<STableAttribute>()? | |||
.STableName; | |||
var res = await _clientSqlSugar | |||
.Queryable<PregnancyHeartRateModel>() | |||
.AS(tableName) | |||
.Where(i=>i.SerialNumber.Equals(serialNo)) | |||
.Where(i => i.Timestamp > DateTime.Now.AddDays(-days)) | |||
//.OrderByDescending(i => i.PregnancyHeartRate) | |||
.Select(i =>i.PregnancyHeartRate) | |||
.ToListAsync(); | |||
// 心率数据量必须30个以上才进行计算 | |||
if (res.Count < 30) return 0; | |||
// 计算众数 | |||
var mode = res.GroupBy(n => n) | |||
.OrderByDescending(g => g.Count()) | |||
.First() | |||
.Key; | |||
Console.WriteLine("众数是: " + mode); | |||
// 如果有多个众数的情况 | |||
var maxCount = res.GroupBy(n => n) | |||
.Max(g => g.Count()); | |||
var modes = res.GroupBy(n => n) | |||
.Where(g => g.Count() == maxCount) | |||
.Select(g => g.Key) | |||
.ToList(); | |||
// 多个众数,选择最接近平均数或中位数的众数 | |||
if (modes.Count>1) | |||
{ | |||
// 计算平均值 | |||
double average = res.Average(); | |||
Console.WriteLine("平均值是: " + average); | |||
// 计算中位数 | |||
double median; | |||
int count = res.Count; | |||
var sortedRes = res.OrderBy(n => n).ToList(); | |||
if (count % 2 == 0) | |||
{ | |||
// 偶数个元素,取中间两个数的平均值 | |||
median = (sortedRes[count / 2 - 1] + sortedRes[count / 2]) / 2.0; | |||
} | |||
else | |||
{ | |||
// 奇数个元素,取中间的数 | |||
median = sortedRes[count / 2]; | |||
} | |||
Console.WriteLine("中位数是: " + median); | |||
// 找出最接近平均值的众数 | |||
//var closestToAverage = modes.OrderBy(m => Math.Abs(m - average)).First(); | |||
//Console.WriteLine("最接近平均值的众数是: " + closestToAverage); | |||
// 找出最接近中位数的众数 | |||
var closestToMedian = modes.OrderBy(m => Math.Abs(m - median)).First(); | |||
Console.WriteLine("最接近中位数的众数是: " + closestToMedian); | |||
mode = closestToMedian; | |||
} | |||
return mode; | |||
} | |||
/// <summary> | |||
/// 计算个人一般心率 | |||
/// </summary> | |||
/// <param name="serialNo"></param> | |||
/// <param name="days"></param> | |||
/// <param name="percentage"></param> | |||
/// <returns></returns> | |||
public async Task<PregnancyCommonHeartRateModel?> InitPregnancyCommonHeartRateModeAsync(string serialNo, int days = 7,int percentage=90) | |||
{ | |||
var tableName = typeof(PregnancyHeartRateModel) | |||
.GetCustomAttribute<STableAttribute>()? | |||
.STableName; | |||
var collection = await _clientSqlSugar | |||
.Queryable<PregnancyHeartRateModel>() | |||
.AS(tableName) | |||
.Where(i => i.SerialNumber.Equals(serialNo)) | |||
.Where(i => i.Timestamp > DateTime.Now.AddDays(-days)) | |||
.OrderByDescending(i => i.Timestamp) | |||
.ToArrayAsync(); | |||
var res = collection | |||
.Select(i => i.PregnancyHeartRate).ToList(); | |||
// 心率数据量必须30个以上才进行计算 | |||
if (res.Count < 30) | |||
{ | |||
_logger.LogInformation($"{serialNo} 心率数据不足,无法计算其众数"); | |||
return null; | |||
} | |||
#region 计算众数 | |||
var mode = res.GroupBy(n => n) | |||
.OrderByDescending(g => g.Count()) | |||
.First() | |||
.Key; | |||
Console.WriteLine("众数是: " + mode); | |||
// 如果有多个众数的情况 | |||
var maxCount = res.GroupBy(n => n) | |||
.Max(g => g.Count()); | |||
var modes = res.GroupBy(n => n) | |||
.Where(g => g.Count() == maxCount) | |||
.Select(g => g.Key) | |||
.ToList(); | |||
// 多个众数,选择最接近平均数或中位数的众数 | |||
if (modes.Count > 1) | |||
{ | |||
// 计算平均值 | |||
double average = res.Average(); | |||
Console.WriteLine("平均值是: " + average); | |||
// 计算中位数 | |||
double median; | |||
int count = res.Count; | |||
var sortedRes = res.OrderBy(n => n).ToList(); | |||
if (count % 2 == 0) | |||
{ | |||
// 偶数个元素,取中间两个数的平均值 | |||
median = (sortedRes[count / 2 - 1] + sortedRes[count / 2]) / 2.0; | |||
} | |||
else | |||
{ | |||
// 奇数个元素,取中间的数 | |||
median = sortedRes[count / 2]; | |||
} | |||
Console.WriteLine("中位数是: " + median); | |||
// 找出最接近平均值的众数 | |||
//var closestToAverage = modes.OrderBy(m => Math.Abs(m - average)).First(); | |||
//Console.WriteLine("最接近平均值的众数是: " + closestToAverage); | |||
// 找出最接近中位数的众数 | |||
var closestToMedian = modes.OrderBy(m => Math.Abs(m - median)).First(); | |||
Console.WriteLine("最接近中位数的众数是: " + closestToMedian); | |||
mode = closestToMedian; | |||
} | |||
#endregion | |||
// 计算需要的数量 | |||
int requiredCount = (int)(res.Count * 0.8); | |||
// 从原始数据集中获取最接近众数的元素 | |||
var closestToModeData = res.OrderBy(n => Math.Abs(n - mode)) | |||
.Take(requiredCount) | |||
.ToList(); | |||
// 输出新数据集 | |||
Console.WriteLine("新数据集: " + string.Join(", ", closestToModeData)); | |||
Console.WriteLine("新数据集的数量: " + closestToModeData.Count); | |||
return new PregnancyCommonHeartRateModel() | |||
{ | |||
Timestamp = DateTime.Now, | |||
PersonId = collection.First().DeviceKey, | |||
DeviceKey = collection.First().DeviceKey, | |||
SerialNumber = collection.First().SerialNumber, | |||
Mode = mode, | |||
Percentage= percentage, | |||
MaxValue= closestToModeData.Max(), | |||
MinValue= closestToModeData.Min(), | |||
OriginalMaxValue=res.Max(), | |||
OriginalMinValue= res.Min(), | |||
CreateTime = DateTime.Now, | |||
StatStartTime = collection.OrderBy(i=>i.Timestamp).Select(i=>i.Timestamp).First(), | |||
StatEndTime= collection.OrderBy(i => i.Timestamp).Select(i => i.Timestamp).Last(), | |||
}; | |||
} | |||
#endregion | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
using Microsoft.Extensions.Logging; | |||
using Newtonsoft.Json.Linq; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace HealthMonitor.Service.Cache | |||
{ | |||
public class DeviceCacheManager | |||
{ | |||
private readonly ILogger<DeviceCacheManager> _logger; | |||
private const string CACHE_KEY_GPSDEVICE_WATCH_CONFIG = "#GPSDEVICE_WATCH_CONFIG_HASH"; | |||
public DeviceCacheManager(ILogger<DeviceCacheManager> logger) | |||
{ | |||
_logger = logger; | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
/// <param name="sn"></param> | |||
/// <param name="bizCode"> | |||
/// 业务码 | |||
/// 0067 胎心启动配置 | |||
/// </param> | |||
/// <returns></returns> | |||
public async Task<JObject?> GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(string sn, string bizCode) | |||
{ | |||
if (string.IsNullOrWhiteSpace(sn)) return null; | |||
try | |||
{ | |||
var config = await RedisHelperDb7.HGetAsync(CACHE_KEY_GPSDEVICE_WATCH_CONFIG, $"{sn}_{bizCode}").ConfigureAwait(false); | |||
if (config == null) return null; | |||
return (JObject)JsonConvert.DeserializeObject(config)!; | |||
} | |||
catch (Exception ex) | |||
{ | |||
_logger.LogWarning($"Redis DB7发生异常:{ex.Message}, {ex.StackTrace}"); | |||
} | |||
return null; | |||
} | |||
} | |||
} |
@@ -42,7 +42,7 @@ namespace HealthMonitor.Service.Resolver | |||
private readonly HttpHelper _httpHelper = default!; | |||
private readonly GpsCardAccessorClient<GpsPerson> _gpsPersonApiClient; | |||
private readonly IotWebApiService _serviceIotWebApi; | |||
private readonly IotApiService _serviceIotWebApi; | |||
private readonly AsyncLocal<string> _messageId = new(); | |||
private readonly AsyncLocal<HisGpsBloodPress> _msgData = new(); | |||
@@ -54,7 +54,7 @@ namespace HealthMonitor.Service.Resolver | |||
BloodPressReferenceValueCacheManager bpRefValCacheManager, | |||
PersonCacheManager personCacheMgr, HttpHelper httpHelper, | |||
GpsCardAccessorClient<GpsPerson> gpsPersonApiClient, | |||
IotWebApiService iotWebApiService, | |||
IotApiService iotWebApiService, | |||
EtcdService serviceEtcd, | |||
IOptions<BoodPressResolverConfig> optionBoodPressResolver, | |||
ILogger<BloodpressResolver> logger) | |||
@@ -55,7 +55,6 @@ namespace HealthMonitor.Service.Resolver.Factory | |||
MessageId = msg.MessageId, | |||
Topic = msg.Topic, | |||
DetailData = msg.Body, | |||
}; | |||
} | |||
} | |||
@@ -0,0 +1,134 @@ | |||
using HealthMonitor.Common; | |||
using HealthMonitor.Common.helper; | |||
using HealthMonitor.Service.Etcd; | |||
using HealthMonitor.Service.Resolver.Interface; | |||
using HealthMonitor.Service.Sub; | |||
using HealthMonitor.Service.Sub.Topic.Model; | |||
using Microsoft.Extensions.Logging; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using TelpoDataService.Util.Entities.GpsLocationHistory; | |||
namespace HealthMonitor.Service.Resolver | |||
{ | |||
public class PregnancyHeartRateResolver : IResolver | |||
{ | |||
private readonly ILogger<PregnancyHeartRateResolver> _logger; | |||
private readonly AsyncLocal<string> _messageId = new(); | |||
private readonly AsyncLocal<HisGpsHeartRate> _msgData = new(); | |||
private readonly HttpHelper _httpHelper = default!; | |||
private readonly EtcdService _serviceEtcd; | |||
public PregnancyHeartRateResolver(ILogger<PregnancyHeartRateResolver> logger, HttpHelper httpHelper, EtcdService serviceEtcd) | |||
{ | |||
_logger = logger; | |||
_httpHelper = httpHelper; | |||
_serviceEtcd = serviceEtcd; | |||
} | |||
public void SetResolveInfo(PackageMsgModel msg) | |||
{ | |||
var topicHmPregnancyHeartRate = JsonConvert.DeserializeObject<TopicHmPregnancyHeartRate>(msg.DetailData.ToString()!); | |||
_messageId.Value = msg.MessageId; | |||
_msgData.Value = new HisGpsHeartRate() | |||
{ | |||
HeartRateId = topicHmPregnancyHeartRate!.PregnancyHeartRateId, | |||
MessageId = topicHmPregnancyHeartRate!.MessageId, | |||
Serialno = topicHmPregnancyHeartRate!.Serialno, | |||
HeartRate= topicHmPregnancyHeartRate.PregnancyHeartRate, | |||
LastUpdate = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(SafeType.SafeInt64(topicHmPregnancyHeartRate.LastUpdate) / 1000000), | |||
CreateTime = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(SafeType.SafeInt64(topicHmPregnancyHeartRate.CreateTime) / 1000000), | |||
Method = topicHmPregnancyHeartRate!.Method, | |||
IsDisplay = topicHmPregnancyHeartRate!.IsDisplay ? 1 : 0 | |||
}; | |||
} | |||
public override string ToString() | |||
{ | |||
return $"{nameof(PregnancyHeartRateResolver)}[{_messageId.Value}]"; | |||
} | |||
public async Task ExecuteMessageAsync() | |||
{ | |||
//throw new NotImplementedException(); | |||
var messageId = _messageId.Value; | |||
var phr = _msgData.Value!; | |||
#region 定时下发触发器 | |||
var key = $"health_moniter/schedule_push/pregnancy_heart_rate/imei/{phr.Serialno}"; | |||
var schedule_push = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false); | |||
if (string.IsNullOrWhiteSpace(schedule_push)) | |||
{ | |||
// 注册首次下推 | |||
#if DEBUG | |||
// await _serviceEtcd.PutValAsync(key, result, 60*1, false).ConfigureAwait(false); | |||
var interval = 0; | |||
// 获取当前时间 | |||
DateTime now = DateTime.Now; | |||
// 计算距离下一个$interval天后的8点的时间间隔 | |||
DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute + 1, 58).AddDays(interval); | |||
TimeSpan timeUntilNextRun = nextRunTime - now; | |||
// 如果当前时间已经超过了8点,将等待到明天后的8点 | |||
if (timeUntilNextRun < TimeSpan.Zero) | |||
{ | |||
timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromMinutes(1)); | |||
nextRunTime += timeUntilNextRun; | |||
} | |||
var ttl = (long)timeUntilNextRun.TotalSeconds; | |||
var data = new | |||
{ | |||
imei = phr.Serialno, | |||
create_time = now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
ttl, | |||
next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss") | |||
}; | |||
var result = JsonConvert.SerializeObject(data); | |||
await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false); | |||
#else | |||
var interval = 0; | |||
// 获取当前时间 | |||
DateTime now = DateTime.Now; | |||
var rand=new Random(); | |||
var pushSec = rand.Next(59); | |||
int pushMin= int.TryParse(phr.Serialno.AsSpan(phr.Serialno.Length - 1), out pushMin) ? pushMin : 10; | |||
// 计算距离下一个$interval天后的8点的时间间隔 | |||
DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, 18, pushMin, pushSec).AddDays(interval); | |||
TimeSpan timeUntilNextRun = nextRunTime - now; | |||
if (timeUntilNextRun < TimeSpan.Zero) | |||
{ | |||
timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromDays(1)); | |||
nextRunTime += TimeSpan.FromDays(1); | |||
} | |||
var ttl =(long)timeUntilNextRun.TotalSeconds; | |||
var data = new | |||
{ | |||
imei = phr.Serialno, | |||
create_time = now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
ttl, | |||
next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss") | |||
}; | |||
var result = JsonConvert.SerializeObject(data); | |||
await _serviceEtcd.PutValAsync(key, result,ttl, false).ConfigureAwait(false); | |||
#endif | |||
} | |||
#endregion | |||
} | |||
} | |||
} |
@@ -15,15 +15,19 @@ namespace HealthMonitor.Service.Sub | |||
{ | |||
private readonly ILogger<MsgQueueManager> _logger; | |||
private readonly BloodpressResolver _resolverBloodpress; | |||
private readonly PregnancyHeartRateResolver _resolverPregnacyHeartRate; | |||
//private const string BP = nameof(TopicHmBloodPress).ToLower(); | |||
public MsgQueueManager(ILogger<MsgQueueManager> logger, BloodpressResolver resolverBloodpress) | |||
public MsgQueueManager(ILogger<MsgQueueManager> logger, | |||
BloodpressResolver resolverBloodpress, | |||
PregnancyHeartRateResolver pregnacyHeartRateResolver) | |||
{ | |||
_logger = logger; | |||
_resolverBloodpress = resolverBloodpress; | |||
_resolverPregnacyHeartRate = pregnacyHeartRateResolver; | |||
} | |||
//public IResolver? GetMsgResolver() | |||
@@ -55,6 +59,12 @@ namespace HealthMonitor.Service.Sub | |||
_resolverBloodpress.SetResolveInfo(msg); | |||
return _resolverBloodpress; | |||
} | |||
if (msg.Topic.Equals(nameof(TopicHmPregnancyHeartRate).ToLower())) | |||
{ | |||
_resolverPregnacyHeartRate.SetResolveInfo(msg); | |||
return _resolverPregnacyHeartRate; | |||
} | |||
return null; | |||
@@ -20,6 +20,7 @@ using System.Threading.Tasks; | |||
using TDengineDriver; | |||
using TDengineTMQ; | |||
using TelpoDataService.Util.Entities.GpsLocationHistory; | |||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; | |||
namespace HealthMonitor.Service.Sub | |||
{ | |||
@@ -69,40 +70,80 @@ namespace HealthMonitor.Service.Sub | |||
DoReceive(conn); | |||
} | |||
public void DoReceive(IntPtr Connection) | |||
public void DoReceive(IntPtr connection) | |||
{ | |||
#region topichmbpstats 订阅 | |||
#region topic 订阅 | |||
// string topic = "topichmbpstats"; | |||
string topic = nameof(TopicHmBloodPress).ToLower(); | |||
TopicHmBloodPress fields = new(); | |||
PropertyInfo[] props = fields.GetType().GetProperties(); | |||
// 获取 fields | |||
string attributes = ""; | |||
foreach (PropertyInfo prop in props) | |||
//string bloodPressTopic = nameof(TopicHmBloodPress).ToLower(); | |||
//TopicHmBloodPress fields = new(); | |||
//PropertyInfo[] props = fields.GetType().GetProperties(); | |||
//// 获取 fields | |||
//string attributes = ""; | |||
//foreach (PropertyInfo prop in props) | |||
//{ | |||
// JsonPropertyAttribute attr = prop.GetCustomAttribute<JsonPropertyAttribute>()!; | |||
// if (attr != null) | |||
// { | |||
// attributes += attr.PropertyName + ","; | |||
// } | |||
//} | |||
//attributes = attributes.TrimEnd(','); | |||
////创建 topichmbpstats | |||
//IntPtr res = TDengine.Query(Connection, $"create topic if not exists {bloodPressTopic} as select {attributes} from health_monitor.stb_hm_bloodpress"); | |||
////创建 topichmpregnancyheartrate | |||
//var pregnancyHeartRateTopic = nameof(TopicHmPregnancyHeartRate).ToLower(); | |||
//var pregnancyHeartateAttributes = typeof(TopicHmPregnancyHeartRate).GetType().GetProperties().Select(prop => prop.GetCustomAttribute<JsonPropertyAttribute>()); | |||
//var pregnancyHeartateAttributesStr = string.Join(", ", pregnancyHeartateAttributes); | |||
//res = TDengine.Query(Connection, $"create topic if not exists {pregnancyHeartRateTopic} as select {pregnancyHeartateAttributesStr} from {_configTDengineService.DB}.stb_hm_pregnancy_heart_rate"); | |||
//if (TDengine.ErrorNo(res) != 0) | |||
//{ | |||
// _logger.LogError($"create topic failed, reason:{TDengine.Error(res)}"); | |||
// throw new Exception($"create topic failed, reason:{TDengine.Error(res)}"); | |||
//} | |||
// 获取字段属性 | |||
string GetAttributes(Type type) | |||
{ | |||
JsonPropertyAttribute attr = prop.GetCustomAttribute<JsonPropertyAttribute>()!; | |||
if (attr != null) | |||
var props = type.GetProperties(); | |||
var attributeNames = props | |||
.Select(prop => prop.GetCustomAttribute<JsonPropertyAttribute>()?.PropertyName) | |||
.Where(attr => !string.IsNullOrEmpty(attr)); | |||
return string.Join(",", attributeNames); | |||
} | |||
// 创建 topic | |||
void CreateTopic(IntPtr conn, string topicName, string attributes, string tableName) | |||
{ | |||
string query = $"create topic if not exists {topicName} as select {attributes} from {tableName}"; | |||
IntPtr res = TDengine.Query(conn, query); | |||
if (TDengine.ErrorNo(res) != 0) | |||
{ | |||
attributes += attr.PropertyName + ","; | |||
string error = TDengine.Error(res); | |||
_logger.LogError($"Create topic {topicName} failed, reason: {error}"); | |||
throw new Exception($"Create topic {topicName} failed, reason: {error}"); | |||
} | |||
} | |||
attributes = attributes.TrimEnd(','); | |||
//创建 topichmbpstats | |||
IntPtr res = TDengine.Query(Connection, $"create topic if not exists {topic} as select {attributes} from health_monitor.stb_hm_bloodpress"); | |||
// 血压 topic | |||
string bloodPressTopic = nameof(TopicHmBloodPress).ToLower(); | |||
string bloodPressAttributes = GetAttributes(typeof(TopicHmBloodPress)); | |||
CreateTopic(connection, bloodPressTopic, bloodPressAttributes, $"{_configTDengineService.DB}.stb_hm_bloodpress"); | |||
// 孕期心率 topic | |||
string pregnancyHeartRateTopic = nameof(TopicHmPregnancyHeartRate).ToLower(); | |||
string pregnancyHeartRateAttributes = GetAttributes(typeof(TopicHmPregnancyHeartRate)); | |||
CreateTopic(connection, pregnancyHeartRateTopic, pregnancyHeartRateAttributes, $"{_configTDengineService.DB}.stb_hm_pregnancy_heart_rate"); | |||
//创建 topichmfetalheartrate | |||
//var fetalHeartRateTopic = "topichmfetalheartrate"; | |||
//var fetalHeartRateFields = "ts,fetal_heart_rate_id,message_id,person_id,serialno,fetal_heart_rate,create_time,method,last_update,is_display,device_key"; | |||
//res = TDengine.Query(Connection, $"create topic if not exists {fetalHeartRateTopic} as select {fetalHeartRateFields} from health_monitor.stb_hm_fetal_heart_rate_test"); | |||
#endregion | |||
if (TDengine.ErrorNo(res) != 0) | |||
{ | |||
_logger.LogError($"create topic failed, reason:{TDengine.Error(res)}"); | |||
throw new Exception($"create topic failed, reason:{TDengine.Error(res)}"); | |||
} | |||
var cfg = new ConsumerConfig | |||
{ | |||
GourpId = "group_1", | |||
@@ -112,12 +153,13 @@ namespace HealthMonitor.Service.Sub | |||
TDConnectIp = _configTDengineService.Host, | |||
}; | |||
// create consumer | |||
var consumer = new ConsumerBuilder(cfg) | |||
.Build(); | |||
var consumer = new ConsumerBuilder(cfg).Build(); | |||
var topics = new string[] { bloodPressTopic, pregnancyHeartRateTopic }; | |||
// subscribe | |||
consumer.Subscribe(topic); | |||
consumer.Subscribe(topics); | |||
while (!_tokenSource!.IsCancellationRequested) | |||
{ | |||
var consumeRes = consumer.Consume(300); | |||
@@ -154,14 +196,11 @@ namespace HealthMonitor.Service.Sub | |||
} | |||
} | |||
consumer.Commit(consumeRes); | |||
//_logger.LogInformation("监听中...."); | |||
// Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff},监听中...."); | |||
} | |||
// close consumer after use.Otherwise will lead memory leak. | |||
consumer.Close(); | |||
TDengine.Close(Connection); | |||
TDengine.Close(connection); | |||
} | |||
public void ParsePackage(ReceiveMessageModel model) | |||
@@ -0,0 +1,44 @@ | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace HealthMonitor.Service.Sub.Topic.Model | |||
{ | |||
public class TopicHmPregnancyHeartRate | |||
{ | |||
[JsonProperty("ts")] | |||
public long Ts { get; set; } = default!; | |||
[JsonProperty("pregnancy_heart_rate_id")] | |||
public string PregnancyHeartRateId { get; set; } = default!; | |||
[JsonProperty("message_id")] | |||
public string MessageId { get; set; } = default!; | |||
[JsonProperty("person_id")] | |||
public string PersonId { get; set; } = default!; | |||
[JsonProperty("serialno")] | |||
public string Serialno { get; set; } = default!; | |||
[JsonProperty("pregnancy_heart_rate")] | |||
public int PregnancyHeartRate { get; set; } | |||
[JsonProperty("last_update")] | |||
public long LastUpdate { get; set; } | |||
[JsonProperty("create_time")] | |||
public long CreateTime { get; set; } | |||
[JsonProperty("method")] | |||
public int Method { get; set; } | |||
[JsonProperty("is_display")] | |||
public bool IsDisplay { get; set; } | |||
[JsonProperty("device_key")] | |||
public string DeviceKey { get; set; } = default!; | |||
} | |||
} |
@@ -46,7 +46,7 @@ namespace HealthMonitor.WebApi.Controllers.HealthMonitor | |||
private readonly TDengineService _serviceTDengine; | |||
private readonly HttpHelper _httpHelper = default!; | |||
private readonly IotWebApiService _serviceIotWebApi; | |||
private readonly IotApiService _serviceIotWebApi; | |||
private readonly GpsCardAccessorClient<GpsDevice> _deviceApiClient; | |||
private readonly GpsCardAccessorClient<GpsPerson> _gpsPersonApiClient; | |||
@@ -58,7 +58,7 @@ namespace HealthMonitor.WebApi.Controllers.HealthMonitor | |||
GpsCardAccessorClient<GpsPerson> gpsPersonApiClient, | |||
GpsCardAccessorClient<GpsDevice> deviceApiClient, | |||
ILogger<HmBloodPressConfigManualCalibrationController> logger, | |||
IotWebApiService iotWebApiService | |||
IotApiService iotWebApiService | |||
) | |||
{ | |||
@@ -97,7 +97,24 @@ namespace HealthMonitor.WebApi.Controllers.HealthMonitor | |||
//await _serviceTDengine.InsertAsync<FetalHeartRateModel>("hm_fhr", test); | |||
//var first = _serviceTDengine.GetFirst(); | |||
var first = await _serviceTDengine.GetBySerialNoAsync<FetalHeartRateModel>("864144050568123"); | |||
var test2 = new PregnancyHeartRateModel() | |||
{ | |||
Timestamp = DateTime.Now, | |||
CreateTime = DateTime.Now, | |||
PregnancyHeartRate = 120, | |||
PregnancyHeartRateId= Guid.NewGuid().ToString("D"), | |||
IsDisplay = false, | |||
Method = 1, | |||
PersonId = Guid.NewGuid().ToString("D"), | |||
MessageId = Guid.NewGuid().ToString("D"), | |||
SerialNumber = "864144050568123", | |||
DeviceKey = Guid.NewGuid().ToString("D"), | |||
SerialTailNumber = "23", | |||
LastUpdate = DateTime.Now, | |||
}; | |||
await _serviceTDengine.InsertAsync<PregnancyHeartRateModel>("hm_phr", test2); | |||
var first = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>("864144050568123"); | |||
return Ok(first); | |||
} | |||
} | |||
@@ -93,7 +93,7 @@ namespace HealthMonitor.WebApi | |||
var serverVersion = ServerVersion.AutoDetect(mySqlCon); | |||
options.UseMySql(mySqlCon, serverVersion) | |||
.UseLoggerFactory(loggerFactory); | |||
}, poolSize: 64); ; | |||
}, poolSize: 64); | |||
builder.Services | |||
.AddScoped<IGpsCardDataAccessor, EfCoreDataAccessor>(sp => | |||
@@ -172,6 +172,7 @@ namespace HealthMonitor.WebApi | |||
#region Cache | |||
builder.Services | |||
.AddSingleton<PersonCacheManager>() | |||
.AddSingleton<DeviceCacheManager>() | |||
.AddSingleton<BloodPressReferenceValueCacheManager>(); | |||
#endregion | |||
@@ -189,11 +190,12 @@ namespace HealthMonitor.WebApi | |||
builder.Services.AddSingleton<MsgQueueManager>(); | |||
builder.Services.AddSingleton<IResolverFactory, ResolverFactory>(); | |||
builder.Services.AddSingleton<BloodpressResolver>(); | |||
builder.Services.AddSingleton<PregnancyHeartRateResolver>(); | |||
builder.Services.AddSingleton<PackageProcess>(); | |||
builder.Services | |||
.AddSingleton<TDengineDataSubcribe>() | |||
.AddSingleton<IotWebApiService>() | |||
.AddSingleton<IotApiService>() | |||
.AddSingleton<EtcdService>() | |||
.AddHostedService<Worker>(); | |||
#endregion | |||
@@ -33,19 +33,19 @@ namespace HealthMonitor.WebApi | |||
private readonly TDengineService _serviceTDengine; | |||
private readonly EtcdService _serviceEtcd; | |||
private readonly HttpHelper _httpHelper = default!; | |||
private readonly IotWebApiService _serviceIotWebApi; | |||
private readonly IotApiService _serviceIotApi; | |||
private readonly BoodPressResolverConfig _configBoodPressResolver; | |||
private readonly BloodPressReferenceValueCacheManager _bpRefValCacheManager; | |||
private readonly PersonCacheManager _personCacheMgr; | |||
private CancellationTokenSource _tokenSource = default!; | |||
public Worker(ILogger<Worker> logger, IServiceProvider services, PersonCacheManager personCacheMgr, BloodPressReferenceValueCacheManager bpRefValCacheManager, IotWebApiService iotWebApiService, IOptions<BoodPressResolverConfig> optionBoodPressResolver, PackageProcess processor, TDengineDataSubcribe tdEngineDataSubcribe, TDengineService serviceDengine, HttpHelper httpHelper, EtcdService serviceEtcd) | |||
public Worker(ILogger<Worker> logger, IServiceProvider services, PersonCacheManager personCacheMgr, BloodPressReferenceValueCacheManager bpRefValCacheManager, IotApiService IotApiService, IOptions<BoodPressResolverConfig> optionBoodPressResolver, PackageProcess processor, TDengineDataSubcribe tdEngineDataSubcribe, TDengineService serviceDengine, HttpHelper httpHelper, EtcdService serviceEtcd) | |||
{ | |||
_logger = logger; | |||
_tdEngineDataSubcribe = tdEngineDataSubcribe; | |||
_services = services; | |||
_serviceIotWebApi = iotWebApiService; | |||
_serviceIotApi = IotApiService; | |||
_processor = processor; | |||
_serviceEtcd = serviceEtcd; | |||
_serviceTDengine = serviceDengine; | |||
@@ -116,283 +116,382 @@ namespace HealthMonitor.WebApi | |||
case "Delete": | |||
// TTL到了重新计算TTL,下发 | |||
Console.BackgroundColor = ConsoleColor.Green; | |||
Console.WriteLine($"--- {e.Type}--{e.Kv.Key.ToStringUtf8()}--{e.Kv.Value.ToStringUtf8()}---{DateTime.Now}"); | |||
//Console.BackgroundColor = ConsoleColor.Green; | |||
//Console.WriteLine($"--- {e.Type}--{e.Kv.Key.ToStringUtf8()}--{e.Kv.Value.ToStringUtf8()}---{DateTime.Now}"); | |||
// var key = $"health_moniter/schedule_push/imei/{bp.Serialno}"; | |||
var key = e.Kv.Key.ToStringUtf8(); | |||
var imeiDel = key.Split('/')[3]; | |||
var imeiDel = key.Split('/')[^1]; | |||
var schedule_push = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false); | |||
if (string.IsNullOrWhiteSpace(schedule_push)) | |||
{ | |||
int systolicInc; | |||
int diastolicInc; | |||
if (key.Contains("pregnancy_heart_rate")) | |||
{ | |||
// 处理孕妇业务,计算一般心率并下发 | |||
var commonPHR= await _serviceTDengine.InitPregnancyCommonHeartRateModeAsync(imeiDel); | |||
// 设置胎心监测参数 | |||
int systolicRefValue; | |||
int diastolicRefValue; | |||
if (commonPHR == null) | |||
{ | |||
// 建模中 | |||
var flag= await _serviceIotApi.SetFetalHeartRateConfig(imeiDel); | |||
_logger.LogInformation($"{imeiDel} 建模建模中"); | |||
} | |||
else | |||
{ | |||
// 建模完成 | |||
var flag = await _serviceIotApi.SetFetalHeartRateConfig(imeiDel,1,commonPHR.MaxValue,commonPHR.MinValue); | |||
_logger.LogInformation($"{imeiDel} 建模完成"); | |||
// 保存到TDengine数据库 | |||
await _serviceTDengine.InsertAsync<PregnancyCommonHeartRateModel>("hm_pchr", commonPHR); | |||
_logger.LogInformation($"保存TDengine完成"); | |||
} | |||
decimal systolicAvg; | |||
decimal diastolicAvg; | |||
#region 注册定时下发 | |||
var startTime = DateTime.Now; | |||
// 注册下次下推 | |||
var endTime = DateTime.Now; | |||
int systolicMax = 0; | |||
int diastolicMax = 0; | |||
#if DEBUG | |||
// 统计时间 | |||
//DateTime endTime = DateTime.Now; //测试 | |||
DateTime statStartTime = DateTime.Now; | |||
//long ttl = (long)((60 * 1000-(endTime-startTime).TotalMilliseconds)/1000); | |||
//await _serviceEtcd.PutValAsync(key, imeiDel,ttl, false).ConfigureAwait(false); | |||
// 最小值 | |||
int systolicMin = 0; | |||
int diastolicMin = 0; | |||
var interval = 0; | |||
// 获取当前时间 | |||
DateTime now = DateTime.Now; | |||
// 偏移参数 | |||
var avgOffset = 0.25M; | |||
var systolicAvgOffset = avgOffset; | |||
var diastolicAvgOffset = avgOffset; | |||
// 计算距离下一个$interval天后的8点的时间间隔 | |||
DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute + 2, 0).AddDays(interval); | |||
TimeSpan timeUntilNextRun = nextRunTime - now; | |||
// 最后一次下发值 | |||
int lastPushSystolicInc = 0; | |||
int lastPushDiastolicInc = 0; | |||
// 如果当前时间已经超过了8点,将等待到明天后的8点 | |||
if (timeUntilNextRun < TimeSpan.Zero) | |||
{ | |||
timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromMinutes(1)); | |||
nextRunTime += timeUntilNextRun; | |||
} | |||
//long ttl = timeUntilNextRun.Milliseconds/1000; | |||
long ttl = (long)((timeUntilNextRun.TotalMilliseconds - (endTime - startTime).TotalMilliseconds) / 1000); | |||
var data = new | |||
{ | |||
imei = imeiDel, | |||
create_time = now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
ttl, | |||
next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss") | |||
}; | |||
var result = JsonConvert.SerializeObject(data); | |||
await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false); | |||
var startTime = DateTime.Now; | |||
// 下发增量值 | |||
#region 统计定时下发增量值 | |||
//var last = await _serviceTDengine.GetLastAsync("stb_hm_bloodpress_stats_inc", $"serialno='{imeiDel}' order by last_update desc"); | |||
//var ts = last?[0]; | |||
// 最后一条血压数据 | |||
var condition = $"serialno='{imeiDel}' order by last_update desc"; | |||
var field = "last_row(*)"; | |||
var lastHmBpResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bloodpress", condition, field); | |||
var lastHmBpParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressureModel>>(lastHmBpResponse!); | |||
var lastHmBp = lastHmBpParser?.Select().FirstOrDefault(); | |||
//if (lastHmBpParser?.Select()?.ToList().Count < 2) | |||
//{ | |||
// _logger.LogInformation($"{imeiDel} -- {nameof(Worker)} --{nameof(WatchEvents)} -- 血压数据条目不足"); | |||
// break; | |||
//} | |||
#else | |||
// 每$interval天,晚上8点 | |||
var interval = 1; | |||
// 获取当前时间 | |||
DateTime now = DateTime.Now; | |||
var rand = new Random(); | |||
// 7 天有效数据 | |||
if (lastHmBp?.Timestamp.AddDays(7) > DateTime.Now) | |||
var pushSec = rand.Next(59); | |||
int pushMin = int.TryParse(imeiDel.AsSpan(imeiDel.Length - 1), out pushMin) ? pushMin : 10; | |||
// 计算距离下一个$interval天后的8点的时间间隔 | |||
DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, 18, pushMin, pushSec).AddDays(interval); | |||
TimeSpan timeUntilNextRun = nextRunTime - now; | |||
// 如果当前时间已经超过了8点,将等待到明天后的8点 | |||
if (timeUntilNextRun < TimeSpan.Zero) | |||
{ | |||
timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromDays(1)); | |||
nextRunTime += timeUntilNextRun; | |||
} | |||
// var ttl = timeUntilNextRun.TotalMilliseconds; | |||
long ttl = (long)((timeUntilNextRun.TotalMilliseconds-(endTime-startTime).TotalMilliseconds)/1000); | |||
var data = new | |||
{ | |||
imei = imeiDel, | |||
create_time = now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
ttl, | |||
next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss") | |||
}; | |||
var result = JsonConvert.SerializeObject(data); | |||
await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false); | |||
#endif | |||
#endregion | |||
} | |||
else | |||
{ | |||
// 计算增量值 | |||
condition = $"serialno='{imeiDel}' order by ts desc"; | |||
var lastPushResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bp_push_ref_inc_value", condition, field); | |||
if (lastPushResponse == null) | |||
// 处理血压业务 | |||
int systolicInc; | |||
int diastolicInc; | |||
int systolicRefValue; | |||
int diastolicRefValue; | |||
decimal systolicAvg; | |||
decimal diastolicAvg; | |||
int systolicMax = 0; | |||
int diastolicMax = 0; | |||
// 统计时间 | |||
//DateTime endTime = DateTime.Now; //测试 | |||
DateTime statStartTime = DateTime.Now; | |||
// 最小值 | |||
int systolicMin = 0; | |||
int diastolicMin = 0; | |||
// 偏移参数 | |||
var avgOffset = 0.25M; | |||
var systolicAvgOffset = avgOffset; | |||
var diastolicAvgOffset = avgOffset; | |||
// 最后一次下发值 | |||
int lastPushSystolicInc = 0; | |||
int lastPushDiastolicInc = 0; | |||
var startTime = DateTime.Now; | |||
// 下发增量值 | |||
#region 统计定时下发增量值 | |||
//var last = await _serviceTDengine.GetLastAsync("stb_hm_bloodpress_stats_inc", $"serialno='{imeiDel}' order by last_update desc"); | |||
//var ts = last?[0]; | |||
// 最后一条血压数据 | |||
var condition = $"serialno='{imeiDel}' order by last_update desc"; | |||
var field = "last_row(*)"; | |||
var lastHmBpResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bloodpress", condition, field); | |||
var lastHmBpParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressureModel>>(lastHmBpResponse!); | |||
var lastHmBp = lastHmBpParser?.Select().FirstOrDefault(); | |||
//if (lastHmBpParser?.Select()?.ToList().Count < 2) | |||
//{ | |||
// _logger.LogInformation($"{imeiDel} -- {nameof(Worker)} --{nameof(WatchEvents)} -- 血压数据条目不足"); | |||
// break; | |||
//} | |||
// 7 天有效数据 | |||
if (lastHmBp?.Timestamp.AddDays(7) > DateTime.Now) | |||
{ | |||
_logger.LogInformation($"{imeiDel}--没有下发记录"); | |||
break; | |||
} | |||
var lastPushParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressurePushRefIncModel>>(lastPushResponse); | |||
var lastPush = lastPushParser!.Select().FirstOrDefault(); | |||
// 有下推记录 | |||
if (lastPush != null) | |||
{ | |||
systolicRefValue = lastPush!.SystolicRefValue; | |||
diastolicRefValue = lastPush!.DiastolicRefValue; | |||
lastPushSystolicInc = lastPush!.SystolicIncValue; | |||
lastPushDiastolicInc = lastPush!.DiastolicIncValue; | |||
condition = $"ts between '{lastPush?.Timestamp:yyyy-MM-dd HH:mm:ss.fff}' and '{startTime:yyyy-MM-dd HH:mm:ss.fff}' " + | |||
$"and serialno='{imeiDel}' " + | |||
$"and is_display = true"; | |||
// 使用最近一次的下推时间作为统计的开始时间 | |||
statStartTime = lastPush!.Timestamp; | |||
} | |||
// 没有下推记录(历史遗留数据),没有初始的测量值产生的平均值(测量值=平均值) | |||
else | |||
{ | |||
#region 获取个人信息 | |||
var person = await _personCacheMgr.GetDeviceGpsPersonCacheBySerialNoAsync(Guid.NewGuid().ToString(), imeiDel).ConfigureAwait(false); | |||
//验证这个信息是否存在 | |||
if (person == null || person?.Person.BornDate == null) | |||
// 计算增量值 | |||
condition = $"serialno='{imeiDel}' order by ts desc"; | |||
var lastPushResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bp_push_ref_inc_value", condition, field); | |||
if (lastPushResponse == null) | |||
{ | |||
_logger.LogWarning($"{nameof(Worker)}--{imeiDel} 验证个人信息,找不到个人信息,跳过此消息"); | |||
_logger.LogInformation($"{imeiDel}--没有下发记录"); | |||
break; | |||
} | |||
// 验证年龄是否在范围 (2 - 120) | |||
var age = SafeType.SafeInt(DateTime.Today.Year - person?.Person.BornDate!.Value.Year!); | |||
if (age < 2 || age > 120) | |||
var lastPushParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressurePushRefIncModel>>(lastPushResponse); | |||
var lastPush = lastPushParser!.Select().FirstOrDefault(); | |||
// 有下推记录 | |||
if (lastPush != null) | |||
{ | |||
_logger.LogWarning($"{nameof(Worker)}--{imeiDel} 验证年龄,不在范围 (2 - 120)岁,跳过此消息"); | |||
break; | |||
systolicRefValue = lastPush!.SystolicRefValue; | |||
diastolicRefValue = lastPush!.DiastolicRefValue; | |||
lastPushSystolicInc = lastPush!.SystolicIncValue; | |||
lastPushDiastolicInc = lastPush!.DiastolicIncValue; | |||
condition = $"ts between '{lastPush?.Timestamp:yyyy-MM-dd HH:mm:ss.fff}' and '{startTime:yyyy-MM-dd HH:mm:ss.fff}' " + | |||
$"and serialno='{imeiDel}' " + | |||
$"and is_display = true"; | |||
// 使用最近一次的下推时间作为统计的开始时间 | |||
statStartTime = lastPush!.Timestamp; | |||
} | |||
// 没有下推记录(历史遗留数据),没有初始的测量值产生的平均值(测量值=平均值) | |||
else | |||
{ | |||
#region 获取个人信息 | |||
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 初始化常规血压标定值标定值 | |||
var bpRef = await _bpRefValCacheManager.GetBloodPressReferenceValueAsync(age, gender, isHypertension); | |||
//systolicRefValue = bpRef!.Systolic;//? | |||
//diastolicRefValue = bpRef!.Diastolic;//? | |||
#endregion | |||
systolicRefValue = bpRef!.Systolic; | |||
diastolicRefValue = bpRef!.Diastolic; | |||
lastPushSystolicInc = 0; | |||
lastPushDiastolicInc = 0; | |||
condition = $"ts <= '{startTime:yyyy-MM-dd HH:mm:ss.fff}' " + | |||
$"and serialno='{imeiDel}' " + | |||
$"and is_display = true"; | |||
} | |||
var person = await _personCacheMgr.GetDeviceGpsPersonCacheBySerialNoAsync(Guid.NewGuid().ToString(), imeiDel).ConfigureAwait(false); | |||
//验证这个信息是否存在 | |||
if (person == null || person?.Person.BornDate == null) | |||
{ | |||
_logger.LogWarning($"{nameof(Worker)}--{imeiDel} 验证个人信息,找不到个人信息,跳过此消息"); | |||
break; | |||
} | |||
// 验证年龄是否在范围 (2 - 120) | |||
var age = SafeType.SafeInt(DateTime.Today.Year - person?.Person.BornDate!.Value.Year!); | |||
if (age < 2 || age > 120) | |||
{ | |||
_logger.LogWarning($"{nameof(Worker)}--{imeiDel} 验证年龄,不在范围 (2 - 120)岁,跳过此消息"); | |||
break; | |||
} | |||
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 | |||
var hmBpResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bloodpress", condition); | |||
var hmBpParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressureModel>>(hmBpResponse!); | |||
var hmBp = hmBpParser?.Select(); | |||
//if (hmBp?.ToList().Count < 2) | |||
// 1. 判断数据样本数量 | |||
if (hmBpParser!.Rows < 5) | |||
{ | |||
_logger.LogInformation($"{imeiDel} -- {nameof(Worker)} --{nameof(WatchEvents)} -- 统计定时下发,计算增量值的数据条目不足:{hmBpParser!.Rows} < 5"); | |||
_logger.LogInformation($"{imeiDel} -- {nameof(Worker)} --{nameof(WatchEvents)} 没有足够的数据样本,不会定时下发"); | |||
break; | |||
} | |||
// 没有下推记录重新计算统计时间 | |||
if (lastPush == null) | |||
{ | |||
var firstHmBp = hmBpParser?.Select(i => i).OrderBy(i => i.Timestamp).FirstOrDefault(); | |||
statStartTime = firstHmBp!.Timestamp; | |||
} | |||
#region 初始化常规血压标定值标定值 | |||
var bpRef = await _bpRefValCacheManager.GetBloodPressReferenceValueAsync(age, gender, isHypertension); | |||
//systolicRefValue = bpRef!.Systolic;//? | |||
//diastolicRefValue = bpRef!.Diastolic;//? | |||
#endregion | |||
// NewMethod(systolicRefValue, hmBpParser); | |||
systolicRefValue = bpRef!.Systolic; | |||
diastolicRefValue = bpRef!.Diastolic; | |||
lastPushSystolicInc = 0; | |||
lastPushDiastolicInc = 0; | |||
condition = $"ts <= '{startTime:yyyy-MM-dd HH:mm:ss.fff}' " + | |||
$"and serialno='{imeiDel}' " + | |||
$"and is_display = true"; | |||
} | |||
// 最大值 | |||
//systolicMax = (int)hmBpParser?.Select(i => i.SystolicValue).Max()!; | |||
//diastolicMax = (int)hmBpParser?.Select(i => i.DiastolicValue).Max()!; | |||
//// 最小值 | |||
//systolicMin = (int)hmBpParser?.Select(i => i.SystolicValue).Min()!; | |||
//diastolicMin = (int)hmBpParser?.Select(i => i.DiastolicValue).Min()!; | |||
//systolicAvg = (int)(hmBpParser?.AverageAfterRemovingOneMinMaxRef(i => i.SystolicValue, SafeType.SafeInt(systolicRefValue!)))!; | |||
//diastolicAvg = (int)(hmBpParser?.AverageAfterRemovingOneMinMaxRef(i => i.DiastolicValue, SafeType.SafeInt(diastolicRefValue!)))!; | |||
var avgs = _serviceTDengine.AverageAfterRemovingOneMinMaxRef(hmBpParser!); | |||
systolicAvg = avgs[0]; | |||
diastolicAvg = avgs[1]; | |||
var hmBpResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bloodpress", condition); | |||
var hmBpParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressureModel>>(hmBpResponse!); | |||
var hmBp = hmBpParser?.Select(); | |||
//if (hmBp?.ToList().Count < 2) | |||
// 1. 判断数据样本数量 | |||
if (hmBpParser!.Rows < 5) | |||
{ | |||
_logger.LogInformation($"{imeiDel} -- {nameof(Worker)} --{nameof(WatchEvents)} -- 统计定时下发,计算增量值的数据条目不足:{hmBpParser!.Rows} < 5"); | |||
_logger.LogInformation($"{imeiDel} -- {nameof(Worker)} --{nameof(WatchEvents)} 没有足够的数据样本,不会定时下发"); | |||
break; | |||
} | |||
// 没有下推记录重新计算统计时间 | |||
if (lastPush == null) | |||
{ | |||
var firstHmBp = hmBpParser?.Select(i => i).OrderBy(i => i.Timestamp).FirstOrDefault(); | |||
statStartTime = firstHmBp!.Timestamp; | |||
} | |||
// NewMethod(systolicRefValue, hmBpParser); | |||
// 2. 判断能否计算增量值 | |||
if (systolicAvg.Equals(0)) | |||
{ | |||
_logger.LogInformation($"{imeiDel}--{nameof(Worker)}--计算平均值" + | |||
$"\n currentSystolicAvg:{systolicAvg} -- lastPushSystolicInc:{lastPushSystolicInc}" + | |||
$"\n currentDiastolicInc:{diastolicAvg} -- lastPushDiastolicInc:{lastPushDiastolicInc}"); | |||
_logger.LogInformation($"{imeiDel}--{nameof(Worker)} 没有足够的数据样本计算平均值,不会定时下发"); | |||
break; | |||
} | |||
// 除最大值和最小值后的平均值与标定值差值少于4后(当天计算出该结果则也不产生增量调整),就不再进行增量值调整了。 | |||
if (systolicRefValue - systolicAvg < 4) | |||
{ | |||
_logger.LogInformation($"diastolic 舒张压 {imeiDel}除最大值和最小值后的平均值:{diastolicAvg}与标定值:{diastolicRefValue}\n systolic 收缩压 {imeiDel}除最大值和最小值后的平均值:{systolicAvg}与标定值:{systolicRefValue}的差值(标定值-平均值)少于4后,systolic 收缩压 不再进行增量值调整"); | |||
break; | |||
} | |||
// 最大值 | |||
//systolicMax = (int)hmBpParser?.Select(i => i.SystolicValue).Max()!; | |||
//diastolicMax = (int)hmBpParser?.Select(i => i.DiastolicValue).Max()!; | |||
//// 最小值 | |||
//systolicMin = (int)hmBpParser?.Select(i => i.SystolicValue).Min()!; | |||
//diastolicMin = (int)hmBpParser?.Select(i => i.DiastolicValue).Min()!; | |||
if (diastolicRefValue - diastolicAvg < 4) | |||
{ | |||
_logger.LogInformation($"systolic 收缩压 {imeiDel}除最大值和最小值后的平均值:{systolicAvg}与标定值:{systolicRefValue}\n diastolic 舒张压 {imeiDel}除最大值和最小值后的平均值:{diastolicAvg}与标定值:{diastolicRefValue}的差值(标定值-平均值)少于4后,diastolic 舒张压 不再进行增量值调整"); | |||
break; | |||
} | |||
//systolicAvg = (int)(hmBpParser?.AverageAfterRemovingOneMinMaxRef(i => i.SystolicValue, SafeType.SafeInt(systolicRefValue!)))!; | |||
//diastolicAvg = (int)(hmBpParser?.AverageAfterRemovingOneMinMaxRef(i => i.DiastolicValue, SafeType.SafeInt(diastolicRefValue!)))!; | |||
// 增量值=(标定值-平均值)* 0.25 | |||
var currentSystolicInc = (int)((systolicRefValue - systolicAvg) * systolicAvgOffset)!; | |||
var currentDiastolicInc = (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!; | |||
var avgs = _serviceTDengine.AverageAfterRemovingOneMinMaxRef(hmBpParser!); | |||
systolicAvg = avgs[0]; | |||
diastolicAvg = avgs[1]; | |||
// 累计增量 | |||
systolicInc = currentSystolicInc + lastPushSystolicInc; | |||
diastolicInc = currentDiastolicInc + lastPushDiastolicInc; | |||
// 2. 判断能否计算增量值 | |||
if (systolicAvg.Equals(0)) | |||
{ | |||
_logger.LogInformation($"{imeiDel}--{nameof(Worker)}--计算平均值" + | |||
$"\n currentSystolicAvg:{systolicAvg} -- lastPushSystolicInc:{lastPushSystolicInc}" + | |||
$"\n currentDiastolicInc:{diastolicAvg} -- lastPushDiastolicInc:{lastPushDiastolicInc}"); | |||
_logger.LogInformation($"{imeiDel}--{nameof(Worker)} 没有足够的数据样本计算平均值,不会定时下发"); | |||
break; | |||
} | |||
// 除最大值和最小值后的平均值与标定值差值少于4后(当天计算出该结果则也不产生增量调整),就不再进行增量值调整了。 | |||
if (systolicRefValue - systolicAvg < 4) | |||
{ | |||
_logger.LogInformation($"diastolic 舒张压 {imeiDel}除最大值和最小值后的平均值:{diastolicAvg}与标定值:{diastolicRefValue}\n systolic 收缩压 {imeiDel}除最大值和最小值后的平均值:{systolicAvg}与标定值:{systolicRefValue}的差值(标定值-平均值)少于4后,systolic 收缩压 不再进行增量值调整"); | |||
break; | |||
} | |||
_logger.LogInformation($"{imeiDel}--{nameof(Worker)}--计算增量值" + | |||
$"\n {imeiDel} -- systolicAvg:{systolicAvg}-- systolicInc:{systolicInc}-- currentSystolicInc:{currentSystolicInc} -- lastPushSystolicInc:{lastPushSystolicInc}" + | |||
$"\n {imeiDel} -- diastolicAvg:{diastolicAvg}-- diastolicInc:{diastolicInc} --currentDiastolicInc:{currentDiastolicInc} -- lastPushDiastolicInc:{lastPushDiastolicInc}"); | |||
_logger.LogInformation($"{imeiDel}--{nameof(Worker)}-- 定时校准,发给设备的绝对增量值=(上次绝对增量值+新数据的增量值)"); | |||
if (diastolicRefValue - diastolicAvg < 4) | |||
{ | |||
_logger.LogInformation($"systolic 收缩压 {imeiDel}除最大值和最小值后的平均值:{systolicAvg}与标定值:{systolicRefValue}\n diastolic 舒张压 {imeiDel}除最大值和最小值后的平均值:{diastolicAvg}与标定值:{diastolicRefValue}的差值(标定值-平均值)少于4后,diastolic 舒张压 不再进行增量值调整"); | |||
break; | |||
} | |||
// 增量值=(标定值-平均值)* 0.25 | |||
var currentSystolicInc = (int)((systolicRefValue - systolicAvg) * systolicAvgOffset)!; | |||
var currentDiastolicInc = (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!; | |||
_logger.LogInformation($"{nameof(Worker)} 开启血压标定值下发: {_configBoodPressResolver.EnableBPRefPush}"); | |||
if (_configBoodPressResolver.EnableBPRefPush) | |||
// if (false) // 临时关闭 | |||
{ | |||
BloodPressCalibrationConfigModel bpIncData = new() | |||
{ | |||
Imei = imeiDel, | |||
SystolicRefValue = SafeType.SafeInt(((int)systolicRefValue!)), //收缩压标定值,值为0 表示不生效 | |||
DiastolicRefValue = SafeType.SafeInt(((int)diastolicRefValue!)), //舒张压标定值,值为0表示不生效 | |||
SystolicIncValue = SafeType.SafeInt(((int)systolicInc!)), //收缩压显示增量,值为0 表示不生效 | |||
DiastolicIncValue = SafeType.SafeInt(((int)diastolicInc!)) //舒张压显示增量,值为0 表示不生效 | |||
}; | |||
//var pushedBP = await _serviceIotWebApi.SetBloodPressCalibrationConfigAsync(bpIncData).ConfigureAwait(false); | |||
var response = await _serviceIotWebApi.SetBloodPressCalibrationConfig2Async(bpIncData).ConfigureAwait(false); | |||
var pushedBP = response.Flag; | |||
if (pushedBP) | |||
// 累计增量 | |||
systolicInc = currentSystolicInc + lastPushSystolicInc; | |||
diastolicInc = currentDiastolicInc + lastPushDiastolicInc; | |||
_logger.LogInformation($"{imeiDel}--{nameof(Worker)}--计算增量值" + | |||
$"\n {imeiDel} -- systolicAvg:{systolicAvg}-- systolicInc:{systolicInc}-- currentSystolicInc:{currentSystolicInc} -- lastPushSystolicInc:{lastPushSystolicInc}" + | |||
$"\n {imeiDel} -- diastolicAvg:{diastolicAvg}-- diastolicInc:{diastolicInc} --currentDiastolicInc:{currentDiastolicInc} -- lastPushDiastolicInc:{lastPushDiastolicInc}"); | |||
_logger.LogInformation($"{imeiDel}--{nameof(Worker)}-- 定时校准,发给设备的绝对增量值=(上次绝对增量值+新数据的增量值)"); | |||
_logger.LogInformation($"{nameof(Worker)} 开启血压标定值下发: {_configBoodPressResolver.EnableBPRefPush}"); | |||
if (_configBoodPressResolver.EnableBPRefPush) | |||
// if (false) // 临时关闭 | |||
{ | |||
#region 保存下推记录 stb_hm_bp_push_ref_inc_value | |||
var sql = $"INSERT INTO health_monitor.hm_bp_push_ref_inc_value_{imeiDel.Substring(imeiDel.Length - 2)} " + | |||
$"USING health_monitor.stb_hm_bp_push_ref_inc_value " + | |||
$"TAGS ('{imeiDel.Substring(imeiDel.Length - 2)}') " + | |||
$"VALUES(" + | |||
$"'{startTime:yyyy-MM-dd HH:mm:ss.fff}'," + | |||
$"'{imeiDel}'," + | |||
$"{bpIncData.SystolicRefValue}," + | |||
$"{bpIncData.DiastolicRefValue}," + | |||
$"{bpIncData.SystolicIncValue}," + | |||
$"{bpIncData.DiastolicIncValue}," + | |||
$"{false}," + | |||
$"{systolicAvg}," + | |||
$"{diastolicAvg}," + | |||
$"{systolicAvgOffset}," + | |||
$"{diastolicAvgOffset}," + | |||
$"'{statStartTime:yyyy-MM-dd HH:mm:ss.fff}'," + | |||
$"'{startTime:yyyy-MM-dd HH:mm:ss.fff}'" + | |||
$")"; | |||
_serviceTDengine.ExecuteInsertSQL(sql); | |||
#endregion | |||
BloodPressCalibrationConfigModel bpIncData = new() | |||
{ | |||
#region 注册定时下发 | |||
// 注册下次下推 | |||
var endTime = DateTime.Now; | |||
Imei = imeiDel, | |||
SystolicRefValue = SafeType.SafeInt(((int)systolicRefValue!)), //收缩压标定值,值为0 表示不生效 | |||
DiastolicRefValue = SafeType.SafeInt(((int)diastolicRefValue!)), //舒张压标定值,值为0表示不生效 | |||
SystolicIncValue = SafeType.SafeInt(((int)systolicInc!)), //收缩压显示增量,值为0 表示不生效 | |||
DiastolicIncValue = SafeType.SafeInt(((int)diastolicInc!)) //舒张压显示增量,值为0 表示不生效 | |||
}; | |||
//var pushedBP = await _serviceIotApi.SetBloodPressCalibrationConfigAsync(bpIncData).ConfigureAwait(false); | |||
var response = await _serviceIotApi.SetBloodPressCalibrationConfig2Async(bpIncData).ConfigureAwait(false); | |||
var pushedBP = response.Flag; | |||
if (pushedBP) | |||
{ | |||
#region 保存下推记录 stb_hm_bp_push_ref_inc_value | |||
var sql = $"INSERT INTO health_monitor.hm_bp_push_ref_inc_value_{imeiDel.Substring(imeiDel.Length - 2)} " + | |||
$"USING health_monitor.stb_hm_bp_push_ref_inc_value " + | |||
$"TAGS ('{imeiDel.Substring(imeiDel.Length - 2)}') " + | |||
$"VALUES(" + | |||
$"'{startTime:yyyy-MM-dd HH:mm:ss.fff}'," + | |||
$"'{imeiDel}'," + | |||
$"{bpIncData.SystolicRefValue}," + | |||
$"{bpIncData.DiastolicRefValue}," + | |||
$"{bpIncData.SystolicIncValue}," + | |||
$"{bpIncData.DiastolicIncValue}," + | |||
$"{false}," + | |||
$"{systolicAvg}," + | |||
$"{diastolicAvg}," + | |||
$"{systolicAvgOffset}," + | |||
$"{diastolicAvgOffset}," + | |||
$"'{statStartTime:yyyy-MM-dd HH:mm:ss.fff}'," + | |||
$"'{startTime:yyyy-MM-dd HH:mm:ss.fff}'" + | |||
$")"; | |||
_serviceTDengine.ExecuteInsertSQL(sql); | |||
#endregion | |||
#region 注册定时下发 | |||
// 注册下次下推 | |||
var endTime = DateTime.Now; | |||
#if DEBUG | |||
//long ttl = (long)((60 * 1000-(endTime-startTime).TotalMilliseconds)/1000); | |||
//await _serviceEtcd.PutValAsync(key, imeiDel,ttl, false).ConfigureAwait(false); | |||
//long ttl = (long)((60 * 1000-(endTime-startTime).TotalMilliseconds)/1000); | |||
//await _serviceEtcd.PutValAsync(key, imeiDel,ttl, false).ConfigureAwait(false); | |||
var interval = 0; | |||
// 获取当前时间 | |||
DateTime now = DateTime.Now; | |||
var interval = 0; | |||
// 获取当前时间 | |||
DateTime now = DateTime.Now; | |||
// 计算距离下一个$interval天后的8点的时间间隔 | |||
DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute + 2, 0).AddDays(interval); | |||
TimeSpan timeUntilNextRun = nextRunTime - now; | |||
// 计算距离下一个$interval天后的8点的时间间隔 | |||
DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute + 2, 0).AddDays(interval); | |||
TimeSpan timeUntilNextRun = nextRunTime - now; | |||
// 如果当前时间已经超过了8点,将等待到明天后的8点 | |||
if (timeUntilNextRun < TimeSpan.Zero) | |||
{ | |||
timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromMinutes(1)); | |||
nextRunTime += timeUntilNextRun; | |||
} | |||
// 如果当前时间已经超过了8点,将等待到明天后的8点 | |||
if (timeUntilNextRun < TimeSpan.Zero) | |||
{ | |||
timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromMinutes(1)); | |||
nextRunTime += timeUntilNextRun; | |||
} | |||
// var ttl = timeUntilNextRun.TotalMilliseconds; | |||
long ttl = (long)((timeUntilNextRun.TotalMilliseconds - (endTime - startTime).TotalMilliseconds) / 1000); | |||
var data = new | |||
{ | |||
imei = imeiDel, | |||
create_time = now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
ttl, | |||
next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss") | |||
}; | |||
var result = JsonConvert.SerializeObject(data); | |||
// var ttl = timeUntilNextRun.TotalMilliseconds; | |||
long ttl = (long)((timeUntilNextRun.TotalMilliseconds - (endTime - startTime).TotalMilliseconds) / 1000); | |||
var data = new | |||
{ | |||
imei = imeiDel, | |||
create_time = now.ToString("yyyy-MM-dd HH:mm:ss"), | |||
ttl, | |||
next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss") | |||
}; | |||
var result = JsonConvert.SerializeObject(data); | |||
await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false); | |||
await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false); | |||
#else | |||
@@ -424,24 +523,24 @@ namespace HealthMonitor.WebApi | |||
var result = JsonConvert.SerializeObject(data); | |||
await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false); | |||
#endif | |||
#endregion | |||
#endregion | |||
} | |||
else | |||
{ | |||
_logger.LogInformation($"错误响应,没有下推数据:{response.Message}"); | |||
} | |||
else | |||
{ | |||
_logger.LogInformation($"错误响应,没有下推数据:{response.Message}"); | |||
} | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
_logger.LogInformation($"向{imeiDel}统计数据已经失效"); | |||
} | |||
#endregion | |||
else | |||
{ | |||
_logger.LogInformation($"向{imeiDel}统计数据已经失效"); | |||
} | |||
#endregion | |||
} | |||
} | |||
break; | |||
} | |||
} | |||
@@ -454,62 +553,6 @@ namespace HealthMonitor.WebApi | |||
}); | |||
} | |||
/** | |||
protected override Task ExecuteAsync(CancellationToken stoppingToken) | |||
{ | |||
TaskFactory factory = new(_tokenSource.Token); | |||
factory.StartNew(async () => | |||
{ | |||
if (_tokenSource.IsCancellationRequested) | |||
_logger.LogWarning("Worker exit"); | |||
_logger.LogInformation("------ResolveAsync"); | |||
while (!_tokenSource.IsCancellationRequested) | |||
{ | |||
await _processor.ResolveAsync().ConfigureAwait(false); | |||
} | |||
}, TaskCreationOptions.LongRunning); | |||
factory.StartNew(() => | |||
{ | |||
_logger.LogInformation("------_tdEngineDataSubcribe"); | |||
while (!_tokenSource.IsCancellationRequested) | |||
{ | |||
_tdEngineDataSubcribe.BeginListen(_tokenSource.Token); | |||
} | |||
}, TaskCreationOptions.LongRunning); | |||
Task.Run(() => | |||
_serviceEtcd.WacthKeysWithPrefixResponseAsync($"health_moniter/schedule_push", WatchEvents) | |||
, stoppingToken); | |||
return Task.Delay(1000, _tokenSource.Token); | |||
} | |||
**/ | |||
/** | |||
private void WatchEvents(WatchEvent[] response) | |||
{ | |||
foreach (WatchEvent e1 in response) | |||
{ | |||
// Console.WriteLine($"{nameof(WatchEventsAsync)} --- {e1.Key}:{e1.Value}:{e1.Type}"); | |||
switch (e1.Type.ToString()) | |||
{ | |||
//case "Put": | |||
// // 获取时间点计算TTL | |||
// break; | |||
case "Delete": | |||
// TTL到了重新计算TTL,下发 | |||
Console.WriteLine($"--- {e1.Key}:{e1.Value}:{e1.Type}"); | |||
break; | |||
} | |||
} | |||
} | |||
*/ | |||
} | |||
@@ -27,7 +27,9 @@ | |||
"ServiceConfig": { | |||
"TelpoDataUrl": "https://id.gdssjl.com/data/", | |||
"EtcdServerAddress": "http://192.168.2.121:2379", | |||
"IotWebApiUrl": "http://id.gdssjl.com/webapi/api/" | |||
"IotWebApiUrl": "http://id.gdssjl.com/webapi/api/", | |||
"IotAuth": "http://id.ssjlai.com/auth/identityController", | |||
"IotCore": "https://id.ssjlai.com/gateway/core/api/v1/open/OpenIot" | |||
}, | |||
"BoodPressResolverConfig": { | |||
"EnableBPRefPush": true | |||
@@ -24,7 +24,9 @@ | |||
"ServiceConfig": { | |||
"TelpoDataUrl": "https://ai.gdssjl.com/data/", | |||
"EtcdServerAddress": "http://172.19.42.40:2379", | |||
"IotWebApiUrl": "http://ai.gdssjl.com/webapi/api/" | |||
"IotWebApiUrl": "http://ai.gdssjl.com/webapi/api/", | |||
"IotAuth": "http://ai.ssjlai.com/auth/identityController", | |||
"IotCore": "https://ai.ssjlai.com/gateway/core/api/v1/open/OpenIot" | |||
}, | |||
"BoodPressResolverConfig": { | |||
"EnableBPRefPush": true | |||
@@ -32,7 +32,9 @@ | |||
"ServiceConfig": { | |||
"TelpoDataUrl": "https://id.gdssjl.com/data/", | |||
"EtcdServerAddress": "http://172.19.42.44:2379", | |||
"IotWebApiUrl": "http://id.gdssjl.com/webapi/api/" | |||
"IotWebApiUrl": "http://id.gdssjl.com/webapi/api/", | |||
"IotAuth": "http://id.ssjlai.com/auth/identityController", | |||
"IotCore": "https://id.ssjlai.com/gateway/core/api/v1/open/OpenIot" | |||
}, | |||
"BoodPressResolverConfig": { | |||
"EnableBPRefPush": true | |||