選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

PregnancyHeartRateResolver.cs 25KB

7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
7ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. using HealthMonitor.Common;
  2. using HealthMonitor.Common.helper;
  3. using HealthMonitor.Model.Service.Mapper;
  4. using HealthMonitor.Service.Biz;
  5. using HealthMonitor.Service.Biz.db;
  6. using HealthMonitor.Service.Cache;
  7. using HealthMonitor.Service.Etcd;
  8. using HealthMonitor.Service.Resolver.Interface;
  9. using HealthMonitor.Service.Sub;
  10. using HealthMonitor.Service.Sub.Topic.Model;
  11. using Microsoft.EntityFrameworkCore.Metadata;
  12. using Microsoft.Extensions.Logging;
  13. using Newtonsoft.Json;
  14. using SqlSugar;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. using TelpoDataService.Util.Clients;
  21. using TelpoDataService.Util.Entities.GpsLocationHistory;
  22. namespace HealthMonitor.Service.Resolver
  23. {
  24. public class PregnancyHeartRateResolver : IResolver
  25. {
  26. private readonly ILogger<PregnancyHeartRateResolver> _logger;
  27. private readonly TDengineService _serviceTDengine;
  28. private readonly DeviceCacheManager _deviceCacheMgr;
  29. private readonly IotApiService _serviceIotApi;
  30. private readonly AsyncLocal<string> _messageId = new();
  31. private readonly AsyncLocal<HisGpsHeartRate> _msgData = new();
  32. private readonly HttpHelper _httpHelper = default!;
  33. private readonly EtcdService _serviceEtcd;
  34. private readonly GpsLocationHistoryAccessorClient<HisGpsFetalHeartRate> _hisFetalHeartApiClient;
  35. public PregnancyHeartRateResolver(ILogger<PregnancyHeartRateResolver> logger,
  36. HttpHelper httpHelper, EtcdService serviceEtcd, DeviceCacheManager deviceCacheMgr,
  37. IotApiService iotApiService, TDengineService serviceDengine, GpsLocationHistoryAccessorClient<HisGpsFetalHeartRate> hisFetalHeartApiClient)
  38. {
  39. _logger = logger;
  40. _httpHelper = httpHelper;
  41. _serviceEtcd = serviceEtcd;
  42. _serviceTDengine = serviceDengine;
  43. _deviceCacheMgr = deviceCacheMgr;
  44. _serviceIotApi = iotApiService;
  45. _hisFetalHeartApiClient = hisFetalHeartApiClient;
  46. }
  47. public void SetResolveInfo(PackageMsgModel msg)
  48. {
  49. var topicHmPregnancyHeartRate = JsonConvert.DeserializeObject<TopicHmPregnancyHeartRate>(msg.DetailData.ToString()!);
  50. _messageId.Value = msg.MessageId;
  51. _msgData.Value = new HisGpsHeartRate()
  52. {
  53. HeartRateId = topicHmPregnancyHeartRate!.PregnancyHeartRateId,
  54. MessageId = topicHmPregnancyHeartRate!.MessageId,
  55. Serialno = topicHmPregnancyHeartRate!.Serialno,
  56. HeartRate= topicHmPregnancyHeartRate.PregnancyHeartRate,
  57. LastUpdate = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(SafeType.SafeInt64(topicHmPregnancyHeartRate.LastUpdate) / 1000000),
  58. CreateTime = DateTimeUtil.GetDateTimeFromUnixTimeMilliseconds(SafeType.SafeInt64(topicHmPregnancyHeartRate.CreateTime) / 1000000),
  59. Method = topicHmPregnancyHeartRate!.Method,
  60. IsDisplay = topicHmPregnancyHeartRate!.IsDisplay ? 1 : 0
  61. };
  62. }
  63. public override string ToString()
  64. {
  65. return $"{nameof(PregnancyHeartRateResolver)}[{_messageId.Value}]";
  66. }
  67. public async Task ExecuteMessageAsync()
  68. {
  69. //throw new NotImplementedException();
  70. var messageId = _messageId.Value;
  71. var heartRate = _msgData.Value!;
  72. var watchConfig = await _deviceCacheMgr.GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(heartRate.Serialno, "0067");
  73. var isFetalHeartEnable = watchConfig != null && (int)watchConfig["enabled"]! == 1;
  74. if (isFetalHeartEnable)
  75. {
  76. // 高频心率采样间隔
  77. var highFreqSampleInterval = (int)watchConfig!["highFreqSampleInterval"]!;
  78. // 触发高频监测的心率上限值
  79. var triggerHighFreqHigh = (int)watchConfig["triggerHighFreqHigh"]!;
  80. // 触发高频监测的心率下限值
  81. var triggerHighFreqLow = (int)watchConfig["triggerHighFreqLow"]!;
  82. //停止高频心率采样心率连续正常次数
  83. var stopHighFreqSampleCount = (int)watchConfig["stopHighFreqSampleCount"]!;
  84. // 高频心率采集时长 0 为持续采集,非零为高频心率的采集时长
  85. var highFreqSampleTimes = (int)watchConfig["stopHighFreqSampleCount"]!;
  86. // 告警上限阀值
  87. var upperAlarmThreshold = (int)watchConfig["upperAlarmThreshold"]!;
  88. // 告警下限阀值
  89. var lowerAlarmThreshold = (int)watchConfig["lowerAlarmThreshold"]!;
  90. var phr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(heartRate.Serialno, 7);
  91. if (phr.Count >= 30)
  92. {
  93. #region 高频心率计算
  94. // 获取最近的两个记录,并计算它们的 LastUpdate 时间差
  95. var firstTwoPhr = phr.OrderByDescending(i => i.LastUpdate).Take(2).Select(i => i.LastUpdate).ToList();
  96. var timeDiff = firstTwoPhr[0] - firstTwoPhr[1];
  97. // 如果需要,将时间差转换为秒
  98. var timeDiffInSeconds = timeDiff.TotalSeconds;
  99. // 高频心率启动
  100. if (timeDiffInSeconds<=highFreqSampleInterval)
  101. {
  102. var phrFreqstatus =await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);
  103. if (phrFreqstatus == null)
  104. {
  105. /// 设置高频状态
  106. _logger.LogInformation($"进入高频心率启动状态 timeDiffInSeconds {timeDiffInSeconds},highFreqSampleInterval:{highFreqSampleInterval}");
  107. // 设置高频状态
  108. var freqFirstPhr= phr.OrderByDescending(i => i.Timestamp).First();
  109. await _deviceCacheMgr.SetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno, freqFirstPhr);
  110. phrFreqstatus = await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);
  111. }
  112. /// phr PregnancyHeartRate 连续连续正常次数个值都是正常(大于等于triggerHighFreqLow,少于等于triggerHighFreqHig),
  113. /// 取连续正常次数正常值的平均值,推送到api/v1/open/OpenIot/SetFetalHeartRateConfig
  114. #region 检查是否连续12个值都是正常的
  115. // 获取最近连续正常次数个心率记录
  116. var lastPhr = phr.OrderByDescending(i => i.Timestamp).Take(stopHighFreqSampleCount).ToList();
  117. // 检查是否连续12个值都是正常的
  118. if (lastPhr.All(i => i.PregnancyHeartRate >= triggerHighFreqLow && i.PregnancyHeartRate <= triggerHighFreqHigh))
  119. {
  120. var avgPhr = lastPhr.Select(i => i.PregnancyHeartRate).Average();
  121. // 计算一般心率得到胎心系数
  122. await SaveAndPushFetalHeartRateAsync(heartRate, upperAlarmThreshold, lowerAlarmThreshold, avgPhr);
  123. }
  124. #endregion
  125. }
  126. // 高频心率结束
  127. else
  128. {
  129. var phrFreqstatus = await _deviceCacheMgr.GetPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);
  130. if (phrFreqstatus != null)
  131. {
  132. /// 在highFreqSampleTimes=0一直异常(大于等于triggerHighFreqLow,少于等于triggerHighFreqHig),
  133. /// 取所有值的平均值,推送胎心数据到api/v1/open/OpenIot/SetFetalHeartRateConfig
  134. if (highFreqSampleTimes==0)
  135. {
  136. // if (phr.OrderByDescending(i => i.Timestamp)
  137. //.Where(i => i.Timestamp >= phrFreqstatus?.Timestamp)
  138. //.Skip(1) // 去除首条
  139. //.All(i => i.PregnancyHeartRate < triggerHighFreqLow || i.PregnancyHeartRate > triggerHighFreqHig))
  140. // {
  141. // var avgPhr = phr.Select(i => i.PregnancyHeartRate).Average();
  142. // // 推送胎心数据到 api/v1/open/OpenIot/SetFetalHeartRateConfig
  143. // // 计算一般心率得到胎心系数
  144. // }
  145. var avgPhr = phr.OrderByDescending(i => i.Timestamp)
  146. .Where(i => i.Timestamp >= phrFreqstatus?.Timestamp)
  147. .Skip(1) // 去除首条
  148. .Where(i => i.PregnancyHeartRate < triggerHighFreqLow || i.PregnancyHeartRate > triggerHighFreqHigh)
  149. .Select(i => i.PregnancyHeartRate).Average();
  150. // 推送胎心数据到 api/v1/open/OpenIot/SetFetalHeartRateConfig
  151. // 计算一般心率得到胎心系数
  152. await SaveAndPushFetalHeartRateAsync(heartRate, upperAlarmThreshold, lowerAlarmThreshold, avgPhr);
  153. }
  154. /// 在highFreqSampleTimes>0一直异常(大于等于triggerHighFreqLow,少于等于triggerHighFreqHig),
  155. /// 取所有值的平均值,推送胎心数据到api/v1/open/OpenIot/SetFetalHeartRateConfig
  156. if (highFreqSampleTimes > 0 && heartRate.LastUpdate >= (phrFreqstatus?.LastUpdate + TimeSpan.FromSeconds(highFreqSampleTimes)))
  157. {
  158. var avgPhr = phr
  159. .Where(i => i.Timestamp >= phrFreqstatus?.Timestamp)
  160. .Skip(1) // 去除首条
  161. .Where(i => i.PregnancyHeartRate < triggerHighFreqLow || i.PregnancyHeartRate > triggerHighFreqHigh)
  162. .Select(i => i.PregnancyHeartRate).Average();
  163. // 推送胎心数据到 api/v1/open/OpenIot/SetFetalHeartRateConfig
  164. // 计算一般心率得到胎心系数
  165. await SaveAndPushFetalHeartRateAsync(heartRate, upperAlarmThreshold, lowerAlarmThreshold, avgPhr);
  166. }
  167. // 删除高频状态的首条记录
  168. await _deviceCacheMgr.DelPregnancyHeartRateFreqStatusAsync(heartRate.Serialno);
  169. /// 设置高频状态
  170. _logger.LogInformation($"结束高频心率状态 timeDiffInSeconds {timeDiffInSeconds},highFreqSampleInterval:{highFreqSampleInterval}");
  171. }
  172. }
  173. #endregion
  174. #region 计算胎心数据
  175. var commonPHR = await _serviceTDengine.GetLastAsync<PregnancyCommonHeartRateModel>(heartRate.Serialno);
  176. if (commonPHR != null)
  177. {
  178. #region 计算胎心数据
  179. // 上15分钟的数据
  180. // 获取当前时间
  181. DateTime nowQuarter = (DateTime)heartRate.LastUpdate!;
  182. // 计算last_update到上一刻钟的分钟数
  183. int minutesToSubtract = nowQuarter.Minute % 15;
  184. // 计算上一刻钟的时间
  185. DateTime previousQuarter = nowQuarter.AddMinutes(-minutesToSubtract).AddSeconds(-nowQuarter.Second).AddMilliseconds(-nowQuarter.Millisecond);
  186. // 使用 last_update 上一刻
  187. var sampleTime = DateTimeUtil.ConvertToTimeStamp(previousQuarter).ToString();
  188. // 计算last_update到下一刻钟的分钟数
  189. int minutesToAdd = 15 - (nowQuarter.Minute % 15);
  190. if (minutesToAdd == 15)
  191. {
  192. minutesToAdd = 0; // 如果已经是刻钟,则不需要增加分钟
  193. }
  194. // 计算下一刻钟的时间
  195. DateTime nextQuarter = nowQuarter.AddMinutes(minutesToAdd)
  196. .AddSeconds(-nowQuarter.Second)
  197. .AddMilliseconds(-nowQuarter.Millisecond);
  198. var daysPhr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(heartRate.Serialno, 7);
  199. var filteredPhr = daysPhr
  200. // 使用 last_update 下一刻
  201. .Where(i => i.LastUpdate <= nextQuarter && i.LastUpdate >= nextQuarter.AddMinutes(-15))
  202. .ToList();
  203. var qarterPhrValue = filteredPhr.Count == 1
  204. ? filteredPhr.First().PregnancyHeartRate
  205. : filteredPhr.Average(i => i.PregnancyHeartRate);
  206. var fetalHeartRate = SafeType.SafeInt(qarterPhrValue * commonPHR?.StatModeAvgFprCoefficient!);
  207. var isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0);
  208. HisGpsFetalHeartRate gpsFetalHeartRate = new()
  209. {
  210. FetalHeartRateId = Guid.NewGuid().ToString("D"),
  211. PersonId = commonPHR!.PersonId,
  212. Serialno = heartRate.Serialno,
  213. HeartRate = fetalHeartRate,
  214. SampleTime = sampleTime,
  215. IsAbnormal = isAbnormal,
  216. StatStartTime = filteredPhr.OrderBy(i => i.LastUpdate).First().LastUpdate,
  217. StatEndTime = filteredPhr.OrderBy(i => i.LastUpdate).Last().LastUpdate,
  218. CreateTime = DateTime.Now,
  219. Method = 1,
  220. IsDisplay = 1,
  221. DeviceKey = commonPHR!.DeviceKey
  222. };
  223. // 保存到 数据服务 MySQL 数据库
  224. await _hisFetalHeartApiClient.AddAsync(gpsFetalHeartRate).ConfigureAwait(false);
  225. // 推送到api/v1/open/OpenIot/SetFetalHeartRateConfig
  226. await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal);
  227. #endregion
  228. }
  229. #endregion
  230. #region 定时计算胎心数据触发器 {interval} 秒后
  231. //var fetalKey = $"health_monitor/schedule_push/cal_fetal_heart_rate/imei/{heartRate.Serialno}";
  232. //await SetIntervalTriggerAsync(fetalKey, heartRate.Serialno, 60 * 15);
  233. #endregion
  234. #region 定时计算胎心数据触发器下一刻钟后
  235. //// 获取当前时间
  236. //DateTime nowQuarter = DateTime.Now;
  237. //// 计算下一个15分钟的刻钟
  238. //int minutesToAdd = 15 - (nowQuarter.Minute % 15);
  239. //if (minutesToAdd == 15)
  240. //{
  241. // minutesToAdd = 0; // 如果已经是刻钟,则不需要增加分钟
  242. //}
  243. //// 计算下一刻钟的时间
  244. //DateTime nextQuarter = nowQuarter.AddMinutes(minutesToAdd)
  245. // .AddSeconds(-nowQuarter.Second)
  246. // .AddMilliseconds(-nowQuarter.Millisecond);
  247. //// 计算时间差
  248. //TimeSpan timeDifference = nextQuarter - nowQuarter;
  249. //var fetalKey = $"health_monitor/schedule_push/cal_fetal_heart_rate/imei/{heartRate.Serialno}";
  250. //await SetIntervalTriggerAsync(fetalKey, heartRate.Serialno, (long)timeDifference.TotalSeconds);
  251. #endregion
  252. #region 定时计算胎动数据触发器 0 点开始
  253. var fetalMovementKey = $"health_monitor/schedule_push/cal_fetal_movement/imei/{heartRate.Serialno}";
  254. /// 计算 0 点秒数
  255. DateTime now = DateTime.Now;
  256. var rand = new Random();
  257. var pushSec = rand.Next(59);
  258. int pushMin = int.TryParse(heartRate.Serialno.AsSpan(heartRate.Serialno.Length - 1), out pushMin) ? pushMin : 10;
  259. DateTime nextRunTime = new (now.Year, now.Month, now.Day, 0, pushMin, pushSec);
  260. TimeSpan timeUntilNextRun = nextRunTime - now;
  261. if (timeUntilNextRun < TimeSpan.Zero)
  262. {
  263. timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromDays(1));
  264. nextRunTime += timeUntilNextRun;
  265. }
  266. var ttl = (long)timeUntilNextRun.TotalSeconds;
  267. await SetIntervalTriggerAsync(fetalMovementKey, heartRate.Serialno, ttl);
  268. //var scheduleFetalMovementPush = await _serviceEtcd.GetValAsync(fetalMovementKey).ConfigureAwait(false);
  269. //if (string.IsNullOrWhiteSpace(scheduleFetalMovementPush))
  270. //{
  271. // var fetalMovementInterval = 60 * 15;
  272. // var fetalMovementNow = DateTime.Now;
  273. // var fetalMovementTimeNextRun = fetalMovementNow.Add(TimeSpan.FromSeconds(fetalMovementInterval));
  274. // var fetalMovementTTL = fetalMovementInterval;
  275. // var data = new
  276. // {
  277. // imei = heartRate.Serialno,
  278. // create_time = fetalMovementNow.ToString("yyyy-MM-dd HH:mm:ss"),
  279. // fetalMovementTTL,
  280. // next_run_time = fetalMovementTimeNextRun.ToString("yyyy-MM-dd HH:mm:ss")
  281. // };
  282. // var result = JsonConvert.SerializeObject(data);
  283. // await _serviceEtcd.PutValAsync(fetalKey, result, fetalMovementTTL, false).ConfigureAwait(false);
  284. //}
  285. #endregion
  286. }
  287. #region 定时下发触发器(定时建模)
  288. var key = $"health_monitor/schedule_push/pregnancy_heart_rate/imei/{heartRate.Serialno}";
  289. var schedule_push = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false);
  290. if (string.IsNullOrWhiteSpace(schedule_push))
  291. {
  292. // 注册首次下推
  293. #if DEBUG
  294. // await _serviceEtcd.PutValAsync(key, result, 60*1, false).ConfigureAwait(false);
  295. var interval = 0;
  296. // 获取当前时间
  297. DateTime now = DateTime.Now;
  298. // 计算距离下一个$interval天后的8点的时间间隔
  299. DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute + 1, 58).AddDays(interval);
  300. TimeSpan timeUntilNextRun = nextRunTime - now;
  301. // 如果当前时间已经超过了8点,将等待到明天后的8点
  302. if (timeUntilNextRun < TimeSpan.Zero)
  303. {
  304. timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromMinutes(1));
  305. nextRunTime += timeUntilNextRun;
  306. }
  307. var ttl = (long)timeUntilNextRun.TotalSeconds;
  308. var data = new
  309. {
  310. imei = heartRate.Serialno,
  311. create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  312. ttl,
  313. next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  314. };
  315. var result = JsonConvert.SerializeObject(data);
  316. await _serviceEtcd.PutValAsync(key, result, ttl, false).ConfigureAwait(false);
  317. #else
  318. var interval = 0;
  319. // 获取当前时间
  320. DateTime now = DateTime.Now;
  321. var rand=new Random();
  322. var pushSec = rand.Next(59);
  323. int pushMin= int.TryParse(heartRate.Serialno.AsSpan(heartRate.Serialno.Length - 1), out pushMin) ? pushMin : 10;
  324. // 计算距离下一个$interval天后的8点的时间间隔
  325. DateTime nextRunTime = new DateTime(now.Year, now.Month, now.Day, 18, pushMin, pushSec).AddDays(interval);
  326. TimeSpan timeUntilNextRun = nextRunTime - now;
  327. if (timeUntilNextRun < TimeSpan.Zero)
  328. {
  329. timeUntilNextRun = timeUntilNextRun.Add(TimeSpan.FromDays(1));
  330. nextRunTime += TimeSpan.FromDays(1);
  331. }
  332. var ttl =(long)timeUntilNextRun.TotalSeconds;
  333. var data = new
  334. {
  335. imei = heartRate.Serialno,
  336. create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  337. ttl,
  338. next_run_time = nextRunTime.ToString("yyyy-MM-dd HH:mm:ss")
  339. };
  340. var result = JsonConvert.SerializeObject(data);
  341. await _serviceEtcd.PutValAsync(key, result,ttl, false).ConfigureAwait(false);
  342. #endif
  343. }
  344. #endregion
  345. }
  346. }
  347. private async Task SaveAndPushFetalHeartRateAsync(HisGpsHeartRate heartRate, int upperAlarmThreshold, int lowerAlarmThreshold, double avgPhr)
  348. {
  349. var commonPHR = await _serviceTDengine.InitPregnancyCommonHeartRateModeAsync(heartRate.Serialno);
  350. if (commonPHR != null)
  351. {
  352. // 保存到TDengine数据库
  353. await _serviceTDengine.InsertAsync<PregnancyCommonHeartRateModel>("hm_pchr", commonPHR);
  354. // 计算胎心=孕妇心率*系数
  355. var fetalHeartRate = SafeType.SafeInt(avgPhr * commonPHR?.StatModeAvgFprCoefficient!);
  356. var sampleTime = DateTimeUtil.ConvertToTimeStamp(DateTime.Now).ToString();
  357. var isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0);
  358. // 保存到 数据服务 MySQL 数据库
  359. HisGpsFetalHeartRate gpsFetalHeartRate = new ()
  360. {
  361. FetalHeartRateId = Guid.NewGuid().ToString("D"),
  362. PersonId = commonPHR!.PersonId,
  363. Serialno = heartRate.Serialno,
  364. HeartRate = fetalHeartRate,
  365. SampleTime = sampleTime,
  366. IsAbnormal = isAbnormal,
  367. StatStartTime = commonPHR.StatStartTime,
  368. StatEndTime = commonPHR.StatEndTime,
  369. CreateTime = DateTime.Now,
  370. Method = 1,
  371. IsDisplay = 1,
  372. DeviceKey = commonPHR!.DeviceKey
  373. };
  374. await _hisFetalHeartApiClient.AddAsync(gpsFetalHeartRate).ConfigureAwait(false);
  375. // 推送到api/v1/open/OpenIot/SetFetalHeartRateConfig
  376. await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal);
  377. }
  378. }
  379. private async Task SetIntervalTriggerAsync(string key,string imei, long interval)
  380. {
  381. // var key = $"health_monitor/schedule_push/{type}/imei/{imei}";
  382. var schedulePush = await _serviceEtcd.GetValAsync(key).ConfigureAwait(false);
  383. if (string.IsNullOrWhiteSpace(schedulePush))
  384. {
  385. var now = DateTime.Now;
  386. var timeNextRun = now.Add(TimeSpan.FromSeconds(interval));
  387. var data = new
  388. {
  389. imei,
  390. create_time = now.ToString("yyyy-MM-dd HH:mm:ss"),
  391. ttl = interval,
  392. next_run_time = timeNextRun.ToString("yyyy-MM-dd HH:mm:ss")
  393. };
  394. var result = JsonConvert.SerializeObject(data);
  395. await _serviceEtcd.PutValAsync(key, result, interval, false).ConfigureAwait(false);
  396. }
  397. }
  398. }
  399. }