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.

711 satır
42KB

  1. using dotnet_etcd;
  2. using Etcdserverpb;
  3. using Google.Protobuf.WellKnownTypes;
  4. using HealthMonitor.Common;
  5. using HealthMonitor.Common.helper;
  6. using HealthMonitor.Core.Common.Extensions;
  7. using HealthMonitor.Model.Config;
  8. using HealthMonitor.Model.Service;
  9. using HealthMonitor.Model.Service.Mapper;
  10. using HealthMonitor.Service.Biz;
  11. using HealthMonitor.Service.Biz.db;
  12. using HealthMonitor.Service.Etcd;
  13. using HealthMonitor.Service.Sub;
  14. using Microsoft.AspNetCore.Mvc.RazorPages;
  15. using Microsoft.EntityFrameworkCore.Metadata.Internal;
  16. using Microsoft.Extensions.Options;
  17. using Newtonsoft.Json;
  18. using Newtonsoft.Json.Linq;
  19. using System.Reflection;
  20. using System.Threading.Channels;
  21. using TDengineDriver;
  22. using TDengineTMQ;
  23. namespace HealthMonitor.WebApi
  24. {
  25. public class Worker : BackgroundService
  26. {
  27. private readonly ILogger<Worker> _logger;
  28. private readonly IServiceProvider _services;
  29. private readonly TDengineDataSubcribe _tdEngineDataSubcribe;
  30. private readonly PackageProcess _processor;
  31. private readonly TDengineService _serviceTDengine;
  32. private readonly EtcdService _serviceEtcd;
  33. private readonly HttpHelper _httpHelper = default!;
  34. private readonly IotWebApiService _serviceIotWebApi;
  35. private readonly BoodPressResolverConfig _configBoodPressResolver;
  36. private CancellationTokenSource _tokenSource=default!;
  37. public Worker(ILogger<Worker> logger, IServiceProvider services, IotWebApiService iotWebApiService, IOptions<BoodPressResolverConfig> optionBoodPressResolver, PackageProcess processor,TDengineDataSubcribe tdEngineDataSubcribe, TDengineService serviceDengine, HttpHelper httpHelper, EtcdService serviceEtcd)
  38. {
  39. _logger = logger;
  40. _tdEngineDataSubcribe = tdEngineDataSubcribe;
  41. _services = services;
  42. _serviceIotWebApi = iotWebApiService;
  43. _processor = processor;
  44. _serviceEtcd = serviceEtcd;
  45. _serviceTDengine = serviceDengine;
  46. _httpHelper = httpHelper;
  47. _configBoodPressResolver = optionBoodPressResolver.Value;
  48. }
  49. public override Task StartAsync(CancellationToken cancellationToken)
  50. {
  51. _logger.LogInformation("------StartAsync");
  52. _tokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
  53. // 创建消费者
  54. // _tdEngineDataSubcribe.CreateConsumer();
  55. return base.StartAsync(cancellationToken);
  56. }
  57. public override Task StopAsync(CancellationToken cancellationToken)
  58. {
  59. _logger.LogInformation("------StopAsync");
  60. _tokenSource.Cancel(); //停止工作线程
  61. // 关闭消费者
  62. // _tdEngineDataSubcribe.CloseConsumer();
  63. return base.StopAsync(cancellationToken);
  64. }
  65. protected override Task ExecuteAsync(CancellationToken stoppingToken)
  66. {
  67. // var processor = _services.GetService<PackageProcess>();
  68. TaskFactory factory = new(_tokenSource.Token);
  69. factory.StartNew(async () =>
  70. {
  71. if (_tokenSource.IsCancellationRequested)
  72. _logger.LogWarning("Worker exit");
  73. _logger.LogInformation("------ResolveAsync");
  74. while (!_tokenSource.IsCancellationRequested)
  75. {
  76. //
  77. await _processor.ResolveAsync().ConfigureAwait(false);
  78. // await _tdEngineDataSubcribe.ProcessMsg();
  79. }
  80. }, TaskCreationOptions.LongRunning);
  81. factory.StartNew(() =>
  82. {
  83. _logger.LogInformation("------_tdEngineDataSubcribe");
  84. while (!_tokenSource.IsCancellationRequested)
  85. {
  86. _tdEngineDataSubcribe.BeginListen(_tokenSource.Token);
  87. }
  88. }, TaskCreationOptions.LongRunning);
  89. Task.Run(() =>
  90. _serviceEtcd.WacthKeysWithPrefixResponseAsync($"health_moniter/schedule_push", WatchEvents)
  91. , stoppingToken);
  92. // watch
  93. //factory.StartNew(() =>
  94. //{
  95. // while (!_tokenSource.IsCancellationRequested)
  96. // {
  97. // //_serviceEtcd.WacthKeysWithPrefixAsync($"health_moniter/schedule_push", watchEvents => WatchEvents(watchEvents));
  98. // _serviceEtcd.WacthKeysWithPrefixResponseAsync($"health_moniter/schedule_push", WatchEvents);
  99. // }
  100. //}, TaskCreationOptions.LongRunning);
  101. // _serviceEtcd.WacthKeysWithPrefixResponseAsync($"health_moniter/schedule_push", WatchEvents);
  102. return Task.Delay(1000, _tokenSource.Token);
  103. }
  104. private void WatchEvents(WatchEvent[] response)
  105. {
  106. foreach (WatchEvent e1 in response)
  107. {
  108. // Console.WriteLine($"{nameof(WatchEventsAsync)} --- {e1.Key}:{e1.Value}:{e1.Type}");
  109. switch (e1.Type.ToString())
  110. {
  111. //case "Put":
  112. // // 获取时间点计算TTL
  113. // break;
  114. case "Delete":
  115. // TTL到了重新计算TTL,下发
  116. Console.WriteLine($"--- {e1.Key}:{e1.Value}:{e1.Type}");
  117. break;
  118. }
  119. }
  120. }
  121. private void WatchEvents(WatchResponse response)
  122. {
  123. response.Events.ToList<Mvccpb.Event>().ForEach(async e =>
  124. {
  125. switch (e.Type.ToString())
  126. {
  127. case "Put":
  128. // 获取时间点计算TTL
  129. Console.BackgroundColor = ConsoleColor.Blue;
  130. Console.WriteLine($"--- {e.Type}--{e.Kv.Key.ToStringUtf8()}--{e.Kv.Value.ToStringUtf8()}---{DateTime.Now}");
  131. Console.BackgroundColor = ConsoleColor.Black;
  132. break;
  133. case "Delete":
  134. // TTL到了重新计算TTL,下发
  135. Console.BackgroundColor = ConsoleColor.Green;
  136. Console.WriteLine($"--- {e.Type}--{e.Kv.Key.ToStringUtf8()}--{e.Kv.Value.ToStringUtf8()}---{DateTime.Now}");
  137. // var key = $"health_moniter/schedule_push/imei/{bp.Serialno}";
  138. var key = e.Kv.Key.ToStringUtf8();
  139. var imeiDel = key.Split('/')[3];
  140. var schedule_push = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false);
  141. if (string.IsNullOrWhiteSpace(schedule_push))
  142. {
  143. int systolicInc;
  144. int diastolicInc;
  145. int systolicRefValue;
  146. int diastolicRefValue;
  147. decimal systolicAvg;
  148. decimal diastolicAvg;
  149. int systolicMax = 0;
  150. int diastolicMax = 0;
  151. // 最小值
  152. int systolicMin = 0;
  153. int diastolicMin = 0;
  154. // 偏移参数
  155. var avgOffset = 0.25M;
  156. var systolicAvgOffset = avgOffset;
  157. var diastolicAvgOffset = avgOffset;
  158. // 最后一次下发值
  159. int lastPushSystolicInc = 0;
  160. int lastPushDiastolicInc = 0;
  161. var startTime = DateTime.Now;
  162. // 下发增量值
  163. #region 统计定时下发增量值
  164. //var last = await _serviceTDengine.GetLastAsync("stb_hm_bloodpress_stats_inc", $"serialno='{imeiDel}' order by last_update desc");
  165. //var ts = last?[0];
  166. // 最后一条血压数据
  167. var condition = $"serialno='{imeiDel}' order by last_update desc";
  168. var field = "last_row(*)";
  169. var lastHmBpResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bloodpress", condition, field);
  170. var lastHmBpParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressureModel>>(lastHmBpResponse!);
  171. var lastHmBp = lastHmBpParser?.Select().FirstOrDefault();
  172. //if (lastHmBpParser?.Select()?.ToList().Count < 2)
  173. //{
  174. // _logger.LogInformation($"{imeiDel} -- {nameof(Worker)} --{nameof(WatchEvents)} -- 血压数据条目不足");
  175. // break;
  176. //}
  177. // 7 天有效数据
  178. if (lastHmBp?.Timestamp.AddDays(7) > DateTime.Now)
  179. {
  180. // 计算增量值
  181. condition = $"serialno='{imeiDel}' order by ts desc";
  182. var lastPushResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bp_push_ref_inc_value", condition, field);
  183. if (lastPushResponse == null)
  184. {
  185. _logger.LogInformation($"{imeiDel}--没有下发记录");
  186. break;
  187. }
  188. var lastPushParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressurePushRefIncModel>>(lastPushResponse);
  189. var lastPush = lastPushParser!.Select().FirstOrDefault();
  190. systolicRefValue = lastPush!.SystolicRefValue;
  191. diastolicRefValue = lastPush!.DiastolicRefValue;
  192. lastPushSystolicInc = lastPush!.SystolicIncValue;
  193. lastPushDiastolicInc = lastPush!.DiastolicIncValue;
  194. condition = $"ts between '{lastPush?.Timestamp:yyyy-MM-dd HH:mm:ss.fff}' and '{startTime:yyyy-MM-dd HH:mm:ss.fff}' " +
  195. $"and serialno='{imeiDel}' " +
  196. $"and is_display = true";
  197. var hmBpResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bloodpress", condition);
  198. var hmBpParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressureModel>>(hmBpResponse!);
  199. var hmBp = hmBpParser?.Select();
  200. //if (hmBp?.ToList().Count < 2)
  201. // 1. 判断数据样本数量
  202. if (hmBpParser!.Rows < 5)
  203. {
  204. _logger.LogInformation($"{imeiDel} -- {nameof(Worker)} --{nameof(WatchEvents)} -- 统计定时下发,计算增量值的数据条目不足:{hmBpParser!.Rows} < 5");
  205. _logger.LogInformation($"{imeiDel} -- {nameof(Worker)} --{nameof(WatchEvents)} 没有足够的数据样本,不会定时下发");
  206. break;
  207. }
  208. // NewMethod(systolicRefValue, hmBpParser);
  209. // 最大值
  210. //systolicMax = (int)hmBpParser?.Select(i => i.SystolicValue).Max()!;
  211. //diastolicMax = (int)hmBpParser?.Select(i => i.DiastolicValue).Max()!;
  212. //// 最小值
  213. //systolicMin = (int)hmBpParser?.Select(i => i.SystolicValue).Min()!;
  214. //diastolicMin = (int)hmBpParser?.Select(i => i.DiastolicValue).Min()!;
  215. //systolicAvg = (int)(hmBpParser?.AverageAfterRemovingOneMinMaxRef(i => i.SystolicValue, SafeType.SafeInt(systolicRefValue!)))!;
  216. //diastolicAvg = (int)(hmBpParser?.AverageAfterRemovingOneMinMaxRef(i => i.DiastolicValue, SafeType.SafeInt(diastolicRefValue!)))!;
  217. var avgs = _serviceTDengine.AverageAfterRemovingOneMinMaxRef(SafeType.SafeInt(systolicRefValue!), hmBpParser!);
  218. systolicAvg = avgs[0];
  219. diastolicAvg = avgs[1];
  220. // 2. 判断能否计算增量值
  221. if (systolicAvg.Equals(0))
  222. {
  223. _logger.LogInformation($"{imeiDel}--{nameof(Worker)}--计算平均值" +
  224. $"\n currentSystolicAvg:{systolicAvg} -- lastPushSystolicInc:{lastPushSystolicInc}" +
  225. $"\n currentDiastolicInc:{diastolicAvg} -- lastPushDiastolicInc:{lastPushDiastolicInc}");
  226. _logger.LogInformation($"{imeiDel}--{nameof(Worker)} 没有足够的数据样本计算平均值,不会定时下发");
  227. break;
  228. }
  229. // 增量值=(标定值-平均值)* 0.25
  230. var currentSystolicInc = (int)((systolicRefValue - systolicAvg) * systolicAvgOffset)!;
  231. var currentDiastolicInc = (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!;
  232. // 累计增量
  233. systolicInc = currentSystolicInc + lastPushSystolicInc;
  234. diastolicInc = currentDiastolicInc + lastPushDiastolicInc;
  235. _logger.LogInformation($"{imeiDel}--{nameof(Worker)}--计算增量值" +
  236. $"\n {imeiDel} -- systolicAvg:{systolicAvg}-- systolicInc:{systolicInc}-- currentSystolicInc:{currentSystolicInc} -- lastPushSystolicInc:{lastPushSystolicInc}" +
  237. $"\n {imeiDel} -- diastolicAvg:{diastolicAvg}-- diastolicInc:{diastolicInc} --currentDiastolicInc:{currentDiastolicInc} -- lastPushDiastolicInc:{lastPushDiastolicInc}");
  238. _logger.LogInformation($"{imeiDel}--{nameof(Worker)}-- 定时校准,发给设备的绝对增量值=(上次绝对增量值+新数据的增量值)");
  239. _logger.LogInformation($"{nameof(Worker)} 开启血压标定值下发: {_configBoodPressResolver.EnableBPRefPush}");
  240. if (_configBoodPressResolver.EnableBPRefPush)
  241. // if (false) // 临时关闭
  242. {
  243. BloodPressCalibrationConfigModel bpIncData = new()
  244. {
  245. Imei = imeiDel,
  246. SystolicRefValue = SafeType.SafeInt(((int)systolicRefValue!)), //收缩压标定值,值为0 表示不生效
  247. DiastolicRefValue = SafeType.SafeInt(((int)diastolicRefValue!)), //舒张压标定值,值为0表示不生效
  248. SystolicIncValue = SafeType.SafeInt(((int)systolicInc!)), //收缩压显示增量,值为0 表示不生效
  249. DiastolicIncValue = SafeType.SafeInt(((int)diastolicInc!)) //舒张压显示增量,值为0 表示不生效
  250. };
  251. var pushedBP = await _serviceIotWebApi.SetBloodPressCalibrationConfigAsync(bpIncData).ConfigureAwait(false);
  252. if (pushedBP)
  253. {
  254. #region 保存下推记录 stb_hm_bp_push_ref_inc_value
  255. var sql = $"INSERT INTO health_monitor.hm_bp_push_ref_inc_value_{imeiDel.Substring(imeiDel.Length - 2)} " +
  256. $"USING health_monitor.stb_hm_bp_push_ref_inc_value " +
  257. $"TAGS ('{imeiDel.Substring(imeiDel.Length - 2)}') " +
  258. $"VALUES(" +
  259. $"'{startTime:yyyy-MM-dd HH:mm:ss.fff}'," +
  260. $"'{imeiDel}'," +
  261. $"{bpIncData.SystolicRefValue}," +
  262. $"{bpIncData.DiastolicRefValue}," +
  263. $"{bpIncData.SystolicIncValue}," +
  264. $"{bpIncData.DiastolicIncValue}," +
  265. $"{false}," +
  266. $"{systolicAvg}," +
  267. $"{diastolicAvg}," +
  268. $"{systolicAvgOffset}," +
  269. $"{diastolicAvgOffset}," +
  270. $"'{lastPush?.Timestamp:yyyy-MM-dd HH:mm:ss.fff}'," +
  271. $"'{startTime:yyyy-MM-dd HH:mm:ss.fff}'" +
  272. $")";
  273. _serviceTDengine.ExecuteInsertSQL(sql);
  274. #endregion
  275. #region 注册定时下发
  276. // 注册下次下推
  277. var endTime = DateTime.Now;
  278. #if DEBUG
  279. //long ttl = (long)((60 * 1000-(endTime-startTime).TotalMilliseconds)/1000);
  280. //await _serviceEtcd.PutValAsync(key, imeiDel,ttl, false).ConfigureAwait(false);
  281. var interval = 0;
  282. // 获取当前时间
  283. DateTime now = DateTime.Now;
  284. // 计算距离下一个$interval天后的8点的时间间隔
  285. DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute + 2, 0).AddDays(interval);
  286. TimeSpan timeUntilNextRun = nextRunTime - now;
  287. // 如果当前时间已经超过了8点,将等待到明天后的8点
  288. if (timeUntilNextRun < TimeSpan.Zero)
  289. {
  290. timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromMinutes(1));
  291. nextRunTime += timeUntilNextRun;
  292. }
  293. // var ttl = timeUntilNextRun.TotalMilliseconds;
  294. long ttl = (long)((timeUntilNextRun.TotalMilliseconds - (endTime - startTime).TotalMilliseconds) / 1000);
  295. var data = new
  296. {
  297. imei = imeiDel,
  298. create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  299. ttl,
  300. next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  301. };
  302. var result = JsonConvert.SerializeObject(data);
  303. await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false);
  304. #else
  305. // 每$interval天,晚上8点
  306. var interval = 1;
  307. // 获取当前时间
  308. DateTime now = DateTime.Now;
  309. // 计算距离下一个$interval天后的8点的时间间隔
  310. DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, 20, 0, 0).AddDays(interval);
  311. TimeSpan timeUntilNextRun = nextRunTime - now;
  312. // 如果当前时间已经超过了8点,将等待到明天后的8点
  313. if (timeUntilNextRun < TimeSpan.Zero)
  314. {
  315. timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromDays(1));
  316. nextRunTime += timeUntilNextRun;
  317. }
  318. // var ttl = timeUntilNextRun.TotalMilliseconds;
  319. long ttl = (long)((timeUntilNextRun.TotalMilliseconds-(endTime-startTime).TotalMilliseconds)/1000);
  320. var data = new
  321. {
  322. imei = imeiDel,
  323. create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  324. ttl,
  325. next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  326. };
  327. var result = JsonConvert.SerializeObject(data);
  328. await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false);
  329. #endif
  330. #endregion
  331. }
  332. else
  333. {
  334. _logger.LogInformation($"错误响应,没有下推数据");
  335. }
  336. }
  337. }
  338. else
  339. {
  340. _logger.LogInformation($"向{imeiDel}统计数据已经失效");
  341. }
  342. #endregion
  343. }
  344. break;
  345. }
  346. });
  347. }
  348. private static void NewMethod(int systolicRefValue, ParseTDengineRestResponse<BloodPressureModel>? hmBpParser)
  349. {
  350. var sortedList = hmBpParser?.Select(i => i)
  351. .Where(i => i.IsDisplay.Equals(true))
  352. .OrderByDescending(i => i.SystolicValue)
  353. .ThenByDescending(i => i.DiastolicValue)
  354. .ToList();
  355. // 去除最大值和最小值各一个(列表的头和尾)
  356. var trimmedList = sortedList?
  357. .Skip(1)
  358. .Take(sortedList.Count - 2)
  359. .ToList();
  360. // 去除异常值
  361. var filteredList = trimmedList?.Where(bp => bp.SystolicValue < SafeType.SafeInt(systolicRefValue!)).ToList();
  362. var systolicAvg1 = filteredList?.Select(bp => bp.SystolicValue).Average();
  363. var diastolicAvg1 = filteredList?.Select(bp => bp.DiastolicValue).Average();
  364. }
  365. // private void WatchEvents(WatchResponse response)
  366. // {
  367. // response.Events.ToList().ForEach(async e =>
  368. // {
  369. // switch (e.Type.ToString())
  370. // {
  371. // case "Put":
  372. // // 获取时间点计算TTL
  373. // Console.BackgroundColor = ConsoleColor.Blue;
  374. // Console.WriteLine($"--- {e.Type}--{e.Kv.Key.ToStringUtf8()}--{e.Kv.Value.ToStringUtf8()}---{DateTime.Now}");
  375. // Console.BackgroundColor = ConsoleColor.Black;
  376. // break;
  377. // case "Delete":
  378. // // TTL到了重新计算TTL,下发
  379. // Console.BackgroundColor = ConsoleColor.Green;
  380. // Console.WriteLine($"--- {e.Type}--{e.Kv.Key.ToStringUtf8()}--{e.Kv.Value.ToStringUtf8()}---{DateTime.Now}");
  381. // // var key = $"health_moniter/schedule_push/imei/{bp.Serialno}";
  382. // var key = e.Kv.Key.ToStringUtf8();
  383. // var imeiDel = key.Split('/')[3];
  384. // var schedule_push = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false);
  385. // if (string.IsNullOrWhiteSpace(schedule_push))
  386. // {
  387. // var startTime =DateTime.Now;
  388. // // 下发增量值
  389. // #region 定时下发增量值
  390. // var last= await _serviceTDengine.GetLastAsync("stb_hm_bloodpress_stats_inc", $"serialno='{imeiDel}' order by last_update desc");
  391. // var ts = last?[0];
  392. // if (DateTime.TryParse(ts?.ToString(),out DateTime newTs))
  393. // {
  394. // // 7 天有效数据
  395. // if (newTs.AddDays(7) > DateTime.Now)
  396. // {
  397. // Console.WriteLine(ts);
  398. // var systolic_ref_value = last?[5];
  399. // var diastolic_ref_value = last?[12];
  400. // var systolic_inc_value = last?[10];
  401. // var diastolic_inc_value = last?[17];
  402. // #region 判断是否初始化remark
  403. // // 判断是否初始化remark
  404. // /**
  405. // *
  406. // var imei = imeiDel;
  407. // var last_push = await _serviceTDengine.GetLastAsync("stb_hm_bp_push_ref_inc_value", $"serialno='{imei}' order by ts desc");
  408. // if (last_push?.Count == 0)
  409. // {
  410. // var dataServiceBaseUrl = $"https://id.ssjlai.com/data";
  411. // var DataServicePersionGet = $"{dataServiceBaseUrl}/api/GpsCard/GpsPerson/GetFirst";
  412. // List<KeyValuePair<string, string>> Dataheaders = new()
  413. // {
  414. // new KeyValuePair<string, string>("requestId", $"{imei}")
  415. // };
  416. // var dataPersion = new
  417. // {
  418. // filters = new List<object>() { new { key = "serialno", value = $"{imei}", valueType = "string", @operator = "Equal" } },
  419. // orderBys = new List<object>() { new { key = "serialno", isDesc = true } }
  420. // };
  421. // var resRef = await _httpHelper.HttpToPostAsync(DataServicePersionGet, dataPersion, Dataheaders).ConfigureAwait(false);
  422. // var resObj = JsonConvert.DeserializeObject(resRef!) as JToken;
  423. // var remark = resObj?["remarks"]?.ToString();
  424. // // 修改数据库
  425. // if (string.IsNullOrWhiteSpace(remark))
  426. // {
  427. // var newRemarkData = new
  428. // {
  429. // imei,
  430. // time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
  431. // commandValue = new
  432. // {
  433. // systolicCalibrationValue = systolic_ref_value, //收缩压标定值,值为0 表示不生效
  434. // diastolicCalibrationValue = diastolic_ref_value, //舒张压标定值,值为0表示不生效
  435. // systolicIncValue = 0, //收缩压显示增量,值为0 表示不生效
  436. // diastolicIncValue = 0 //舒张压显示增量,值为0 表示不生效
  437. // }
  438. // };
  439. // resObj!["remarks"] = $"is_blood_press:{JsonConvert.SerializeObject(newRemarkData)}|";
  440. // var DataServicePersionUpdate = $"{dataServiceBaseUrl}/api/GpsCard/GpsPerson/Update";
  441. // var resUpdate = await _httpHelper.HttpToPostAsync(DataServicePersionUpdate, resObj, Dataheaders).ConfigureAwait(false);
  442. // _logger.LogInformation($"更新Person数据库|{resUpdate}");
  443. // //更新缓存
  444. // List<KeyValuePair<string, string>> headersCache = new()
  445. // {
  446. // new KeyValuePair<string, string>("AuthKey", "key1")
  447. // };
  448. // var cacheUrl = $"http://id.ssjlai.com/webapi/api/Device/UpdatePersonInfoCache?imei={imei}";
  449. // var updateCache = await _httpHelper.HttpToGetAsync(cacheUrl, headersCache);
  450. // _logger.LogInformation($"更新Person缓存|{updateCache}");
  451. // }
  452. // }
  453. // */
  454. // #endregion
  455. // //var bpData = new
  456. // //{
  457. // // imei = imeiDel,
  458. // // //systolicCalibrationValue = last?[5], //收缩压标定值,值为0 表示不生效
  459. // // //diastolicCalibrationValue = last?[12], //舒张压标定值,值为0表示不生效
  460. // // //systolicIncValue = last?[10], //收缩压显示增量,值为0 表示不生效
  461. // // //diastolicIncValue = last?[17] //舒张压显示增量,值为0 表示不生效
  462. // // systolicCalibrationValue = systolic_ref_value, //收缩压标定值,值为0 表示不生效
  463. // // diastolicCalibrationValue = diastolic_ref_value, //舒张压标定值,值为0表示不生效
  464. // // systolicIncValue = systolic_inc_value, //收缩压显示增量,值为0 表示不生效
  465. // // diastolicIncValue = diastolic_inc_value //舒张压显示增量,值为0 表示不生效
  466. // //};
  467. // //var str = JsonConvert.SerializeObject(bpData);
  468. // //var url = $"http://id.ssjlai.com/webapi/api/Command/SetBloodPressCalibrationConfig";
  469. // //List<KeyValuePair<string, string>> headers = new()
  470. // //{
  471. // // new KeyValuePair<string, string>("AuthKey", "key1")
  472. // //};
  473. // //var res = await _httpHelper.HttpToPostAsync(url, bpData, headers).ConfigureAwait(false);
  474. // //_logger.LogInformation($"向{imeiDel}下发增量值数据:{str},响应:{res}");
  475. // //var resJToken = JsonConvert.DeserializeObject(res!) as JToken;
  476. // //if (resJToken!["message"]!.ToString().Equals("ok"))
  477. // Console.WriteLine($"{nameof(Worker)} 开启血压标定值下发: {_configBoodPressResolver.EnableBPRefPush}");
  478. // // if (_configBoodPressResolver.EnableBPRefPush)
  479. // if (false) // 临时关闭
  480. // {
  481. // BloodPressCalibrationConfigModel bpIncData = new()
  482. // {
  483. // Imei = imeiDel,
  484. // SystolicRefValue = SafeType.SafeInt(((int)systolic_ref_value!)), //收缩压标定值,值为0 表示不生效
  485. // DiastolicRefValue = SafeType.SafeInt(((int)diastolic_ref_value!)), //舒张压标定值,值为0表示不生效
  486. // SystolicIncValue = SafeType.SafeInt(((int)systolic_inc_value!)), //收缩压显示增量,值为0 表示不生效
  487. // DiastolicIncValue = SafeType.SafeInt(((int)diastolic_inc_value!)) //舒张压显示增量,值为0 表示不生效
  488. // };
  489. // var pushedBP = await _serviceIotWebApi.SetBloodPressCalibrationConfigAsync(bpIncData).ConfigureAwait(false);
  490. // if (pushedBP)
  491. // {
  492. // #region 保存下推记录 stb_hm_bp_push_ref_inc_value
  493. // var sql = $"INSERT INTO health_monitor.hm_bp_push_ref_inc_value_{imeiDel.Substring(imeiDel.Length - 2)} " +
  494. // $"USING health_monitor.stb_hm_bp_push_ref_inc_value " +
  495. // $"TAGS ('{imeiDel.Substring(imeiDel.Length - 2)}') " +
  496. // $"VALUES(" +
  497. // $"'{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}'," +
  498. // $"'{imeiDel}'," +
  499. // $"{systolic_ref_value}," +
  500. // $"{diastolic_ref_value}," +
  501. // $"{systolic_inc_value}," +
  502. // $"{diastolic_inc_value}," +
  503. // $"{false})";
  504. // _serviceTDengine.ExecuteInsertSQL(sql);
  505. // #endregion
  506. // // 注册下次下推
  507. // var endTime = DateTime.Now;
  508. //#if DEBUG
  509. // //long ttl = (long)((60 * 1000-(endTime-startTime).TotalMilliseconds)/1000);
  510. // //await _serviceEtcd.PutValAsync(key, imeiDel,ttl, false).ConfigureAwait(false);
  511. // var interval = 0;
  512. // // 获取当前时间
  513. // DateTime now = DateTime.Now;
  514. // // 计算距离下一个$interval天后的8点的时间间隔
  515. // DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute + 2, 0).AddDays(interval);
  516. // TimeSpan timeUntilNextRun = nextRunTime - now;
  517. // // 如果当前时间已经超过了8点,将等待到明天后的8点
  518. // if (timeUntilNextRun < TimeSpan.Zero)
  519. // {
  520. // timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromMinutes(1));
  521. // nextRunTime += timeUntilNextRun;
  522. // }
  523. // // var ttl = timeUntilNextRun.TotalMilliseconds;
  524. // long ttl = (long)((timeUntilNextRun.TotalMilliseconds - (endTime - startTime).TotalMilliseconds) / 1000);
  525. // var data = new
  526. // {
  527. // imei = imeiDel,
  528. // create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  529. // ttl,
  530. // next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  531. // };
  532. // var result = JsonConvert.SerializeObject(data);
  533. // await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false);
  534. //#else
  535. // // 每$interval天,晚上8点
  536. // var interval = 1;
  537. // // 获取当前时间
  538. // DateTime now = DateTime.Now;
  539. // // 计算距离下一个$interval天后的8点的时间间隔
  540. // DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, 20, 0, 0).AddDays(interval);
  541. // TimeSpan timeUntilNextRun = nextRunTime - now;
  542. // // 如果当前时间已经超过了8点,将等待到明天后的8点
  543. // if (timeUntilNextRun < TimeSpan.Zero)
  544. // {
  545. // timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromDays(1));
  546. // nextRunTime += timeUntilNextRun;
  547. // }
  548. // // var ttl = timeUntilNextRun.TotalMilliseconds;
  549. // long ttl = (long)((timeUntilNextRun.TotalMilliseconds-(endTime-startTime).TotalMilliseconds)/1000);
  550. // var data = new
  551. // {
  552. // imei = imeiDel,
  553. // create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  554. // ttl,
  555. // next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  556. // };
  557. // var result = JsonConvert.SerializeObject(data);
  558. // await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false);
  559. //#endif
  560. // }
  561. // else
  562. // {
  563. // _logger.LogInformation($"错误响应,没有下推数据");
  564. // }
  565. // }
  566. // }
  567. // }
  568. // else
  569. // {
  570. // _logger.LogInformation($"向{imeiDel}准备下推的数据已经失效ts,{ts}");
  571. // }
  572. // #endregion
  573. // //if (imeiDel.Equals("861281060086216"))
  574. // //{
  575. // // var result = await _httpHelper.HttpToPostAsync(url, data, headers).ConfigureAwait(false);
  576. // // _logger.LogInformation($"向{imeiDel}下发增量值数据:{str},响应:{result}");
  577. // // Console.WriteLine(str);
  578. // //}
  579. // //Console.BackgroundColor = ConsoleColor.Black;
  580. // }
  581. // break;
  582. // }
  583. // });
  584. // //if (response.Events.Count == 0)
  585. // //{
  586. // // Console.WriteLine(response);
  587. // //}
  588. // //else
  589. // //{
  590. // // Console.WriteLine($"{response.Events[0].Kv.Key.ToStringUtf8()}:{response.Events.Kv.Value.ToStringUtf8()}");
  591. // //}
  592. // }
  593. }
  594. }