You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BloodpressResolver.cs 28KB

1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
11 kuukautta sitten
11 kuukautta sitten
1 vuosi sitten
1 vuosi sitten
4 kuukautta sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
4 kuukautta sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
8 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
11 kuukautta sitten
8 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
4 kuukautta sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
1 vuosi sitten
11 kuukautta sitten
1 vuosi sitten
1 vuosi sitten
1 vuosi sitten
11 kuukautta sitten
11 kuukautta sitten
11 kuukautta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. 
  2. using HealthMonitor.Common;
  3. using HealthMonitor.Common.helper;
  4. using HealthMonitor.Service.Biz.db;
  5. using HealthMonitor.Service.Cache;
  6. using HealthMonitor.Service.Etcd;
  7. using HealthMonitor.Service.Resolver.Interface;
  8. using HealthMonitor.Service.Sub;
  9. using HealthMonitor.Service.Sub.Topic.Model;
  10. using Microsoft.EntityFrameworkCore.Metadata;
  11. using Microsoft.Extensions.Logging;
  12. using Newtonsoft.Json;
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Data.Common;
  16. using System.Linq;
  17. using System.Text;
  18. using System.Text.Json.Serialization;
  19. using System.Threading.Tasks;
  20. using TDengineTMQ;
  21. using TelpoDataService.Util.Entities.GpsCard;
  22. using TelpoDataService.Util;
  23. using TelpoDataService.Util.Entities.GpsLocationHistory;
  24. using HealthMonitor.Service.Biz;
  25. using HealthMonitor.Model.Service;
  26. using Microsoft.Extensions.Options;
  27. using HealthMonitor.Model.Config;
  28. using HealthMonitor.Model.Service.Mapper;
  29. using Mvccpb;
  30. namespace HealthMonitor.Service.Resolver
  31. {
  32. public class BloodpressResolver: IResolver
  33. {
  34. private readonly ILogger<BloodpressResolver> _logger;
  35. private readonly BoodPressResolverConfig _configBoodPressResolver;
  36. private readonly PersonCacheManager _personCacheMgr;
  37. private readonly TDengineService _serviceTDengine;
  38. private readonly BloodPressReferenceValueCacheManager _bpRefValCacheManager;
  39. private readonly HttpHelper _httpHelper = default!;
  40. private readonly GpsCardAccessorClient<GpsPerson> _gpsPersonApiClient;
  41. private readonly IotApiService _serviceIotWebApi;
  42. private readonly AsyncLocal<string> _messageId = new();
  43. private readonly AsyncLocal<HisGpsBloodPress> _msgData = new();
  44. private readonly EtcdService _serviceEtcd;
  45. public BloodpressResolver(
  46. TDengineService serviceDengine,
  47. BloodPressReferenceValueCacheManager bpRefValCacheManager,
  48. PersonCacheManager personCacheMgr, HttpHelper httpHelper,
  49. GpsCardAccessorClient<GpsPerson> gpsPersonApiClient,
  50. IotApiService iotWebApiService,
  51. EtcdService serviceEtcd,
  52. IOptions<BoodPressResolverConfig> optionBoodPressResolver,
  53. ILogger<BloodpressResolver> logger)
  54. {
  55. _httpHelper = httpHelper;
  56. _serviceTDengine = serviceDengine;
  57. _bpRefValCacheManager = bpRefValCacheManager;
  58. _gpsPersonApiClient = gpsPersonApiClient;
  59. _serviceIotWebApi = iotWebApiService;
  60. _logger = logger;
  61. _personCacheMgr = personCacheMgr;
  62. _serviceEtcd = serviceEtcd;
  63. _configBoodPressResolver= optionBoodPressResolver.Value;
  64. }
  65. public void SetResolveInfo(PackageMsgModel msg)
  66. {
  67. var topicHmBloodPress = JsonConvert.DeserializeObject<TopicHmBloodPress>(msg.DetailData.ToString()!);
  68. _messageId.Value = msg.MessageId;
  69. _msgData.Value = new HisGpsBloodPress()
  70. {
  71. BloodPressId = topicHmBloodPress!.BloodPressId,
  72. MessageId = topicHmBloodPress!.MessageId,
  73. Serialno= topicHmBloodPress!.Serialno,
  74. SystolicValue = topicHmBloodPress!.SystolicValue,
  75. DiastolicValue= topicHmBloodPress!.DiastolicValue,
  76. LastUpdate= DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(SafeType.SafeInt64(topicHmBloodPress.LastUpdate) / 1000000),
  77. CreateTime= DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(SafeType.SafeInt64(topicHmBloodPress.CreateTime) / 1000000),
  78. Method= topicHmBloodPress!.Method,
  79. IsDisplay=topicHmBloodPress!.IsDisplay ? 1 : 0
  80. };
  81. }
  82. public override string ToString()
  83. {
  84. return $"{nameof(BloodpressResolver)}[{_messageId.Value}]";
  85. }
  86. public async Task ExecuteMessageAsync()
  87. {
  88. try
  89. {
  90. var messageId = _messageId.Value;
  91. var bp = _msgData.Value!;
  92. int systolicRefValue;
  93. int diastolicRefValue;
  94. int systolicInc;
  95. int diastolicInc;
  96. decimal systolicAvg;
  97. decimal diastolicAvg;
  98. int systolicMax = 0;
  99. int diastolicMax = 0;
  100. // 最小值
  101. int systolicMin = 0;
  102. int diastolicMin = 0;
  103. // 偏移参数
  104. var avgOffset = 0.25M;
  105. var systolicAvgOffset = avgOffset;
  106. var diastolicAvgOffset = avgOffset;
  107. // 统计时间
  108. DateTime endTime = DateTime.Now; //测试
  109. DateTime startTime = DateTime.Now;
  110. // 最后一次下发值
  111. //int lastPushSystolicInc = 0;
  112. //int lastPushDiastolicInc = 0;
  113. bool remarkFlag = false;
  114. //long duration = 7 * 24 * 3600 * 1000;
  115. string sql = string.Empty;
  116. #region 获取个人信息
  117. var person = await _personCacheMgr.GetDeviceGpsPersonCacheBySerialNoAsync(bp.MessageId, bp.Serialno).ConfigureAwait(false);
  118. //验证这个信息是否存在
  119. if (person == null || person?.Person.BornDate == null)
  120. {
  121. _logger.LogWarning($"{bp.Serialno}--{bp.MessageId} 验证个人信息,找不到个人信息,跳过此消息");
  122. return;
  123. }
  124. // 验证年龄是否在范围 (2 - 120)
  125. var age = SafeType.SafeInt(DateTime.Today.Year - person?.Person.BornDate!.Value.Year!);
  126. if (age < 2 || age > 120)
  127. {
  128. _logger.LogWarning($"{bp.Serialno}--{bp.MessageId} 验证年龄,不在范围 (2 - 120)岁,跳过此消息");
  129. return;
  130. }
  131. var gender = person?.Person.Gender == true ? 1 : 2;
  132. var isHypertension = SafeType.SafeBool(person?.Person.Ishypertension!);
  133. var height = SafeType.SafeDouble(person?.Person.Height!);
  134. var weight = SafeType.SafeDouble(person?.Person.Weight!);
  135. #endregion
  136. #region 初始化常规血压标定值标定值
  137. var bpRef = await _bpRefValCacheManager.GetBloodPressReferenceValueAsync(age, gender, isHypertension);
  138. systolicRefValue = bpRef!.Systolic;//?
  139. diastolicRefValue = bpRef!.Diastolic;//?
  140. #endregion
  141. _logger.LogInformation($"{bp.Serialno} -- Person 值:{JsonConvert.SerializeObject(person)}");
  142. _logger.LogInformation($"{bp.Serialno} -- Person Remarks 值:{person?.Person.Remarks}");
  143. if (string.IsNullOrWhiteSpace(person?.Person.Remarks))
  144. {
  145. _logger.LogInformation($"{bp.Serialno},设备解绑后绑定,首次手工测量了血压值,下发年龄标定值和增量值(测量值=平均值计算得出的)");
  146. #region 初始化计算增量值(个人血压信息)
  147. // 测量值当作平均值
  148. systolicAvg = bp.SystolicValue;
  149. diastolicAvg = bp.DiastolicValue;
  150. systolicInc = (int)((systolicRefValue - systolicAvg) * systolicAvgOffset)!;
  151. diastolicInc = (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!;
  152. #region 更新 gps_persoon remarks 下发增量值到iot
  153. // 更新
  154. remarkFlag = await _serviceIotWebApi.UpdatePersonRemarksAsync(bp.Serialno, (int)systolicRefValue!, (int)diastolicRefValue!, systolicInc, diastolicInc).ConfigureAwait(false);
  155. if (remarkFlag)
  156. {
  157. _logger.LogInformation($"{nameof(BloodpressResolver)} 开启血压标定值下发: {_configBoodPressResolver.EnableBPRefPush}");
  158. // 启血压标定值下发开关
  159. if (_configBoodPressResolver.EnableBPRefPush)
  160. {
  161. // 下推
  162. BloodPressCalibrationConfigModel bpIncData = new()
  163. {
  164. Imei = bp.Serialno,
  165. SystolicRefValue = (int)systolicRefValue!, //收缩压标定值,值为0 表示不生效
  166. DiastolicRefValue = (int)diastolicRefValue!, //舒张压标定值,值为0表示不生效
  167. SystolicIncValue = systolicInc, //收缩压显示增量,值为0 表示不生效
  168. DiastolicIncValue = diastolicInc //舒张压显示增量,值为0 表示不生效
  169. };
  170. // 下发 IOT 增量值
  171. //var flagIot = await _serviceIotWebApi.SetBloodPressCalibrationConfigAsync(bpIncData).ConfigureAwait(false);
  172. var response = await _serviceIotWebApi.SetBloodPressCalibrationConfig2Async(bpIncData).ConfigureAwait(false);
  173. var flagIot = response.Flag;
  174. if (flagIot)
  175. {
  176. startTime = (DateTime)bp.LastUpdate!;
  177. endTime = DateTime.Now;
  178. #region 保存下推记录 stb_hm_bp_push_ref_inc_value
  179. sql = $"INSERT INTO health_monitor.hm_bp_push_ref_inc_value_{bp.Serialno.Substring(bp.Serialno.Length - 2)} " +
  180. $"USING health_monitor.stb_hm_bp_push_ref_inc_value " +
  181. $"TAGS ('{bp.Serialno.Substring(bp.Serialno.Length - 2)}') " +
  182. $"VALUES(" +
  183. $"'{endTime:yyyy-MM-dd HH:mm:ss.fff}'," +
  184. $"'{bp.Serialno}'," +
  185. $"{systolicRefValue}," +
  186. $"{diastolicRefValue}," +
  187. $"{systolicInc}," +
  188. $"{diastolicInc}," +
  189. $"{true}," +
  190. $"{systolicAvg}," +
  191. $"{diastolicAvg}," +
  192. $"{systolicAvgOffset}," +
  193. $"{diastolicAvgOffset}," +
  194. $"'{startTime:yyyy-MM-dd HH:mm:ss.fff}'," +
  195. $"'{endTime:yyyy-MM-dd HH:mm:ss.fff}'" +
  196. $")";
  197. _serviceTDengine.ExecuteInsertSQL(sql);
  198. #endregion
  199. }
  200. }
  201. }
  202. #endregion
  203. #endregion
  204. }
  205. else if (person.Person.Remarks.Contains("lastPushRefValue"))
  206. {
  207. _logger.LogInformation($"{bp.Serialno},有新标定值(lastPushRefValue),使用最近一次下推的标定值和增量值(测量值=平均值计算得出的)");
  208. var lastPushResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bp_push_ref_inc_value", $"serialno='{bp.Serialno}' order by ts desc", "last_row(*)");
  209. var lastPushParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressurePushRefIncModel>>(lastPushResponse!);
  210. var lastPush = lastPushParser!.Select().FirstOrDefault();
  211. var lastPushSystolicRefValue = lastPush!.SystolicRefValue;
  212. var lastPushDiastolicRefValue = lastPush!.DiastolicRefValue;
  213. //使用最后一次设备下发校准值作为新的标定值
  214. systolicRefValue = lastPushSystolicRefValue;
  215. diastolicRefValue = lastPushDiastolicRefValue;
  216. // 测量值当作平均值
  217. systolicAvg = bp.SystolicValue;
  218. diastolicAvg = bp.DiastolicValue;
  219. systolicInc = (int)((systolicRefValue - systolicAvg) * systolicAvgOffset)!;
  220. diastolicInc = (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!;
  221. #region 更新 gps_persoon remarks 下发增量值到iot
  222. // 更新
  223. remarkFlag = await _serviceIotWebApi.UpdatePersonRemarksAsync(bp.Serialno, (int)systolicRefValue!, (int)diastolicRefValue!, systolicInc, diastolicInc).ConfigureAwait(false);
  224. if (remarkFlag)
  225. {
  226. _logger.LogInformation($"{nameof(BloodpressResolver)} 开启血压标定值下发: {_configBoodPressResolver.EnableBPRefPush}");
  227. // 启血压标定值下发开关
  228. if (_configBoodPressResolver.EnableBPRefPush)
  229. {
  230. // 下推
  231. BloodPressCalibrationConfigModel bpIncData = new()
  232. {
  233. Imei = bp.Serialno,
  234. SystolicRefValue = (int)systolicRefValue!, //收缩压标定值,值为0 表示不生效
  235. DiastolicRefValue = (int)diastolicRefValue!, //舒张压标定值,值为0表示不生效
  236. SystolicIncValue = systolicInc, //收缩压显示增量,值为0 表示不生效
  237. DiastolicIncValue = diastolicInc //舒张压显示增量,值为0 表示不生效
  238. };
  239. // 下发 IOT 增量值
  240. //var flagIot = await _serviceIotWebApi.SetBloodPressCalibrationConfigAsync(bpIncData).ConfigureAwait(false);
  241. var response = await _serviceIotWebApi.SetBloodPressCalibrationConfig2Async(bpIncData).ConfigureAwait(false);
  242. var flagIot = response.Flag;
  243. if (flagIot)
  244. {
  245. startTime = (DateTime)bp.LastUpdate!;
  246. endTime = DateTime.Now;
  247. #region 保存下推记录 stb_hm_bp_push_ref_inc_value
  248. sql = $"INSERT INTO health_monitor.hm_bp_push_ref_inc_value_{bp.Serialno.Substring(bp.Serialno.Length - 2)} " +
  249. $"USING health_monitor.stb_hm_bp_push_ref_inc_value " +
  250. $"TAGS ('{bp.Serialno.Substring(bp.Serialno.Length - 2)}') " +
  251. $"VALUES(" +
  252. $"'{endTime:yyyy-MM-dd HH:mm:ss.fff}'," +
  253. $"'{bp.Serialno}'," +
  254. $"{systolicRefValue}," +
  255. $"{diastolicRefValue}," +
  256. $"{systolicInc}," +
  257. $"{diastolicInc}," +
  258. $"{true}," +
  259. $"{systolicAvg}," +
  260. $"{diastolicAvg}," +
  261. $"{systolicAvgOffset}," +
  262. $"{diastolicAvgOffset}," +
  263. $"'{startTime:yyyy-MM-dd HH:mm:ss.fff}'," +
  264. $"'{endTime:yyyy-MM-dd HH:mm:ss.fff}'" +
  265. $")";
  266. _serviceTDengine.ExecuteInsertSQL(sql);
  267. #endregion
  268. }
  269. }
  270. }
  271. #endregion
  272. }
  273. else
  274. {
  275. #region (暂时取消)正常计算增量值
  276. /**
  277. // var lastPush = await _serviceTDengine.GetLastAsync("stb_hm_bp_push_ref_inc_value", $"serialno='{bp.Serialno}' order by ts desc");
  278. var lastPushResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bp_push_ref_inc_value", $"serialno='{bp.Serialno}' order by ts desc", "last_row(*)");
  279. if (lastPushResponse == null)
  280. {
  281. return;
  282. }
  283. var lastPushParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressurePushRefIncModel>>(lastPushResponse);
  284. var lastPush = lastPushParser!.Select().FirstOrDefault();
  285. //var ts = last?[0];
  286. // 曾经有下发记录
  287. if (lastPushParser?.Rows != 0)
  288. {
  289. // 重置设备,取正常值标定值
  290. if (
  291. lastPush!.SystolicRefValue == 0
  292. && lastPush!.DiastolicRefValue == 0
  293. && lastPush!.SystolicIncValue == 0
  294. && lastPush!.DiastolicIncValue == 0
  295. )
  296. {
  297. systolicRefValue = bpRef!.Systolic;//?
  298. diastolicRefValue = bpRef!.Diastolic;//?
  299. }
  300. // 取最后一条下推的标定值
  301. else
  302. {
  303. systolicRefValue = lastPush!.SystolicRefValue;
  304. diastolicRefValue = lastPush!.DiastolicRefValue;
  305. }
  306. duration = SafeType.SafeInt64(((DateTime)bp.LastUpdate! - lastPush!.Timestamp).TotalMilliseconds);
  307. lastPushSystolicInc = lastPush!.SystolicIncValue;
  308. lastPushDiastolicInc = lastPush!.DiastolicIncValue;
  309. }
  310. TimeSpan ts = TimeSpan.FromMilliseconds(duration);
  311. // 获取历史数据
  312. ////DateTime now = DateTime.Now;
  313. //DateTime now = (DateTime)bp.LastUpdate!; //测试
  314. //DateTime startTime = now.AddDays(-duration);
  315. //DateTime endTime = now;
  316. endTime = (DateTime)bp.LastUpdate!; //测试
  317. startTime = endTime - ts;
  318. var condition = $"ts between '{startTime:yyyy-MM-dd HH:mm:ss.fff}' and '{endTime:yyyy-MM-dd HH:mm:ss.fff}' and serialno='{bp.Serialno}'";
  319. var hmBpResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bloodpress", condition);
  320. var hmBpParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressureModel>>(hmBpResponse!);
  321. var hmBp = hmBpParser?.Select();
  322. if (hmBp?.ToList().Count < 2)
  323. {
  324. _logger.LogInformation($"{bp.Serialno} 数据值不足");
  325. return;
  326. }
  327. // 最大值
  328. systolicMax = (int)hmBpParser?.Select(i => i.SystolicValue).Max()!;
  329. diastolicMax = (int)hmBpParser?.Select(i => i.DiastolicValue).Max()!;
  330. // 最小值
  331. systolicMin = (int)hmBpParser?.Select(i => i.SystolicValue).Min()!;
  332. diastolicMin = (int)hmBpParser?.Select(i => i.DiastolicValue).Min()!;
  333. // 计算去除最大值和最小值和异常值的平均值
  334. //var systolicAvg = await _serviceTDengine.GetAvgExceptMaxMinValueAsync("systolic_value", "stb_hm_bloodpress", $"ts>='{startTime:yyyy-MM-dd HH:mm:ss.fff}' and ts <='{endTime:yyyy-MM-dd HH:mm:ss.fff}' and serialno='{bp.Serialno}' and systolic_value < {systolicRefValue} ");
  335. //var diastolicAvg = await _serviceTDengine.GetAvgExceptMaxMinValueAsync("diastolic_value", "stb_hm_bloodpress", $"ts>='{startTime:yyyy-MM-dd HH:mm:ss.fff}' and ts <='{endTime:yyyy-MM-dd HH:mm:ss.fff}' and serialno='{bp.Serialno}' and diastolic_value < {diastolicRefValue}");
  336. systolicAvg = (int)(hmBpParser?.AverageAfterRemovingOneMinMaxRef(i => i.SystolicValue, SafeType.SafeInt(systolicRefValue!)))!;
  337. diastolicAvg = (int)(hmBpParser?.AverageAfterRemovingOneMinMaxRef(i => i.DiastolicValue, SafeType.SafeInt(diastolicRefValue!)))!;
  338. if (systolicAvg.Equals(0) || diastolicAvg.Equals(0))
  339. {
  340. _logger.LogWarning($"{bp.Serialno} 历史数据{startTime}---{endTime}除最大值和最小值和异常值的平均值为0,使用测试量当做平均值");
  341. systolicAvg = bp.SystolicValue;
  342. diastolicAvg = bp.DiastolicValue;
  343. }
  344. //var systolicAvg = _serviceTDengine.GetAvgExceptMaxMinValue("systolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-dd HH:mm:ss.fff}' and ts <='{endTime:yyyy-MM-dd HH:mm:ss.fff}' and serialno='{bp.Serialno}' and systolic_value < {systolicRefValue} ");
  345. //var diastolicAvg = _serviceTDengine.GetAvgExceptMaxMinValue("diastolic_value", "hm_bloodpress", $"ts>='{startTime:yyyy-MM-dd HH:mm:ss.fff}' and ts <='{endTime:yyyy-MM-dd HH:mm:ss.fff}' and serialno='{bp.Serialno}' and diastolic_value < {diastolicRefValue}");
  346. // 增量值=(标定值-平均值)* 0.25
  347. var currentSystolicInc = (int)((systolicRefValue - systolicAvg) * systolicAvgOffset)!;
  348. var currentDiastolicInc = (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!;
  349. // 累计增量
  350. systolicInc = currentSystolicInc + lastPushSystolicInc;
  351. diastolicInc = currentDiastolicInc + lastPushDiastolicInc;
  352. */
  353. #endregion
  354. }
  355. #region (暂时取消)插入BP增量值 hm_bloodpress_stats_inc
  356. // 自动建表
  357. /** sql = $"INSERT INTO health_monitor.hm_bp_stats_inc_{bp.Serialno.Substring(bp.Serialno.Length - 2)} " +
  358. $"USING health_monitor.stb_hm_bloodpress_stats_inc " +
  359. $"TAGS ('{bp.Serialno.Substring(bp.Serialno.Length - 2)}') " +
  360. $"VALUES(" +
  361. $"'{bp.LastUpdate:yyyy-MM-dd HH:mm:ss.fff}'," +
  362. $"'{bp.BloodPressId}'," +
  363. $"'{bp.MessageId}'," +
  364. $"'{bp.Serialno}'," +
  365. $"{bp.SystolicValue}," +
  366. $"{systolicRefValue}," +
  367. $"{systolicAvg}," +
  368. $"{systolicMax}," +
  369. $"{systolicMin}," +
  370. $"{systolicAvgOffset}," +
  371. $"{systolicInc}," +
  372. $"{bp.DiastolicValue}," +
  373. $"{diastolicRefValue}," +
  374. $"{diastolicAvg}," +
  375. $"{diastolicMax}," +
  376. $"{diastolicMin}," +
  377. $"{diastolicAvgOffset}," +
  378. $"{diastolicInc}," +
  379. $"{gender}," +
  380. $"{age}," +
  381. $"{height}," +
  382. $"{weight}," +
  383. $"'{bp.LastUpdate:yyyy-MM-dd HH:mm:ss.fff}'," +
  384. $"{duration}," +
  385. $"'{startTime:yyyy-MM-dd HH:mm:ss.fff}'," +
  386. $"'{endTime:yyyy-MM-dd HH:mm:ss.fff}'," +
  387. $"'{string.Empty}'," +
  388. $"{isHypertension})";
  389. _serviceTDengine.ExecuteInsertSQL(sql);
  390. */
  391. // 发送到 设置设备血压标定参数
  392. #endregion
  393. #region 定时下发触发器
  394. var key = $"health_monitor/schedule_push/imei/{bp.Serialno}";
  395. var schedule_push = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false);
  396. if (string.IsNullOrWhiteSpace(schedule_push))
  397. {
  398. // 注册首次下推
  399. #if DEBUG
  400. // await _serviceEtcd.PutValAsync(key, result, 60*1, false).ConfigureAwait(false);
  401. var interval = 0;
  402. // 获取当前时间
  403. DateTime now = DateTime.Now;
  404. // 计算距离下一个$interval天后的8点的时间间隔
  405. DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute + 1, 58).AddDays(interval);
  406. TimeSpan timeUntilNextRun = nextRunTime - now;
  407. // 如果当前时间已经超过了8点,将等待到明天后的8点
  408. if (timeUntilNextRun < TimeSpan.Zero)
  409. {
  410. timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromMinutes(1));
  411. nextRunTime += timeUntilNextRun;
  412. }
  413. var ttl = (long)timeUntilNextRun.TotalSeconds;
  414. var data = new
  415. {
  416. imei = bp.Serialno,
  417. create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  418. ttl,
  419. next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  420. };
  421. var result = JsonConvert.SerializeObject(data);
  422. await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false);
  423. #else
  424. //DateTime sNow = DateTime.Now;
  425. //// 计算距离19:59:55点的时间间隔
  426. //TimeSpan timeUntil = new DateTime(sNow.Year, sNow.Month, sNow.Day, 19, 59, 55) - sNow;
  427. //// 如果当前时间已经超过了12点,将等待到明天
  428. //if (timeUntil < TimeSpan.Zero)
  429. //{
  430. // timeUntil = timeUntil.Add(TimeSpan.FromHours(24));
  431. //}
  432. //var ttl = (long)timeUntil.TotalSeconds;
  433. var interval = 0;
  434. // 获取当前时间
  435. DateTime now = DateTime.Now;
  436. // 计算距离下一个$interval天后的8点的时间间隔
  437. DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, 19, 59, 58).AddDays(interval);
  438. TimeSpan timeUntilNextRun = nextRunTime - now;
  439. // 如果当前时间已经超过了8点,将等待到明天后的8点
  440. if (timeUntilNextRun < TimeSpan.Zero)
  441. {
  442. timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromDays(1));
  443. // nextRunTime += timeUntilNextRun;
  444. nextRunTime += TimeSpan.FromDays(1);
  445. }
  446. var ttl =(long)timeUntilNextRun.TotalSeconds;
  447. var data = new
  448. {
  449. imei = bp.Serialno,
  450. create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  451. ttl,
  452. next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  453. };
  454. var result = JsonConvert.SerializeObject(data);
  455. await _serviceEtcd.PutValAsync(key, result,ttl, false).ConfigureAwait(false);
  456. #endif
  457. }
  458. #endregion
  459. }
  460. catch (Exception ex)
  461. {
  462. _logger.LogError($"解析血压出错, {ex.Message}\n{ex.StackTrace}");
  463. }
  464. }
  465. }
  466. }