|
- using Google.Protobuf.WellKnownTypes;
- using Grpc.Core;
- using HealthMonitor.Common;
- using HealthMonitor.Common.helper;
- using HealthMonitor.Core.Dal;
- using HealthMonitor.Core.Pipeline;
- using HealthMonitor.Service.Biz.db;
- using HealthMonitor.Service.Cache;
- using HealthMonitor.Service.Etcd;
- using HealthMonitor.Service.Resolver;
- using HealthMonitor.Util.Entities.HealthMonitor;
- using HealthMonitor.WebApi.Configs;
- using HealthMonitor.WebApi.Model.Request;
- using Microsoft.AspNetCore.DataProtection.KeyManagement;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.AspNetCore.Mvc.ViewFeatures;
- using Microsoft.EntityFrameworkCore.Metadata;
- using Microsoft.EntityFrameworkCore.Metadata.Internal;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using TelpoDataService.Util.Entities.GpsCard;
- using TelpoDataService.Util.Clients;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel.DataAnnotations;
- using TelpoDataService.Util;
- using TelpoDataService.Util.Models;
- using TelpoDataService.Util.QueryObjects;
- using HealthMonitor.WebApi.Controllers.Api;
- using HealthMonitor.Service.Biz;
- using HealthMonitor.Model.Service;
- using HealthMonitor.Model.Service.Mapper;
- using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
-
- namespace HealthMonitor.WebApi.Controllers.HealthMonitor
- {
- [ApiExplorerSettings(GroupName = AppConsts.SWAGGER_DOC_HealthMonitor)]
- [Produces("application/json")]
- [Route("api/HealthMonitor/[controller]/[action]")]
- [ApiController]
- public class HmBloodPressConfigManualCalibrationController : ControllerBase
- {
- private readonly ILogger<HmBloodPressConfigManualCalibrationController> _logger;
- private readonly PersonCacheManager _personCacheMgr;
- private readonly TDengineService _serviceTDengine;
- private readonly HttpHelper _httpHelper = default!;
-
- private readonly IotWebApiService _serviceIotWebApi;
-
- private readonly GpsCardAccessorClient<GpsDevice> _deviceApiClient;
- private readonly GpsCardAccessorClient<GpsPerson> _gpsPersonApiClient;
-
- public HmBloodPressConfigManualCalibrationController
- (
- TDengineService serviceDengine,
- PersonCacheManager personCacheMgr, HttpHelper httpHelper,
- GpsCardAccessorClient<GpsPerson> gpsPersonApiClient,
- GpsCardAccessorClient<GpsDevice> deviceApiClient,
- ILogger<HmBloodPressConfigManualCalibrationController> logger,
- IotWebApiService iotWebApiService
- )
- {
-
-
- _serviceTDengine = serviceDengine;
- _logger = logger;
-
- _httpHelper = httpHelper;
- _gpsPersonApiClient = gpsPersonApiClient;
- _deviceApiClient = deviceApiClient;
- _personCacheMgr = personCacheMgr;
- _serviceIotWebApi = iotWebApiService;
-
- }
- [HttpPost]
- public async Task<ApiResponse<object>> Put([FromBody] BloodPressManualCalibration model, [FromHeader] string requestId)
- {
- try
- {
- var imei = model.Imei;
-
- #region 设备合法性
-
- #if DEBUG
-
- #else
- var param = new GeneralParam
- {
- Filters = new List<QueryFilterCondition>
- {
- new QueryFilterCondition
- {
- Key=nameof(GpsDevice.Serialno),
- Value=model.Imei,
- ValueType=QueryValueTypeEnum.String,
- Operator=QueryOperatorEnum.Equal
- }
- }
- };
-
- var device = await _deviceApiClient.GetFirstAsync(param, new RequestHeader { RequestId = requestId }).ConfigureAwait(false);
-
- if (device == null)
- {
-
- _logger.LogError($"非法设备:{model.Imei}");
- return ApiResponse<object>.Fail(500, $"非法设备:{model.Imei}");
- }
- #endif
-
- #endregion
-
- #region 重置设备
- if (model.ManualSystolicRefValue.Equals(0) && model.ManualDiastolicRefValue.Equals(0))
- {
- //return await IotSetBloodPressCalibrationConfigResponseAsync(model.Imei, 0, 0, 0, 0).ConfigureAwait(false);
- var statNow = DateTime.Now;
- _logger.LogInformation($"{imei} 重置设备");
- return await IotSetBloodPressCalibrationConfigResponseAsync(imei, 0, 0, 0, 0, 0, 0, 0, 0, statNow, statNow).ConfigureAwait(false);
-
- //return ApiResponse<object>.Success(new
- //{
- // imei = model.Imei,
- // systolicCalibrationValue = 0, //收缩压标定值,值为0 表示不生效
- // diastolicCalibrationValue = 0, //舒张压标定值,值为0表示不生效
- // systolicIncValue = 0, //收缩压显示增量,值为0 表示不生效
- // diastolicIncValue = 0 //舒张压显示增量,值为0 表示不生效
- //});
- }
-
- #endregion
-
- #region 只下发标定值,不计算增量值,保存数据库(修改个人信息)
- if (model.IsPushRefOnly)
- {
- var statNow = DateTime.Now;
- _logger.LogInformation($"{imei}:只下发标定值,不计算增量值,保存数据库(修改个人信息)");
- return await IotSetBloodPressCalibrationConfigResponseAsync(imei, model.ManualSystolicRefValue, model.ManualDiastolicRefValue, 0, 0, 0, 0, 0, 0, statNow, statNow).ConfigureAwait(false);
- }
-
- #endregion
-
- #region 数据合法性
- if (model.ManualSystolicRefValue.Equals(0) || model.ManualDiastolicRefValue.Equals(0))
- {
- return ApiResponse<object>.Fail(501, $"数据非法,{JsonConvert.SerializeObject(model)}");
- }
- #endregion
-
- #region 计算增量值
-
- // 计算增量值
- int systolicRefValue = model.ManualSystolicRefValue;//?
- int diastolicRefValue = model.ManualDiastolicRefValue;//?
- // 没有血压数据时增量值为0
- int systolicInc;
- int diastolicInc;
- decimal systolicAvg;
- decimal diastolicAvg;
-
- // 最后一次下发值
- int lastPushSystolicInc = 0;
- int lastPushDiastolicInc = 0;
-
- // 偏移参数
- var avgOffset = 0.25M;
- var systolicAvgOffset = avgOffset;
- var diastolicAvgOffset = avgOffset;
-
- //int duration = 7;
- long duration = 7 * 24 * 3600 * 1000;
- TimeSpan ts = TimeSpan.FromMilliseconds(duration);
- DateTime endTime = DateTime.Now; //测试
- DateTime startTime = endTime - ts;
-
- var lastPushResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bp_push_ref_inc_value", $"serialno='{imei}' order by ts desc", "last_row(*)");
- var lastPushParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressurePushRefIncModel>>(lastPushResponse!);
- var lastPush = lastPushParser!.Select().FirstOrDefault();
-
- // 上次下推增量
- lastPushSystolicInc = lastPush!.SystolicIncValue;
- lastPushDiastolicInc = lastPush!.DiastolicIncValue;
- startTime = lastPush!.Timestamp;
-
- var condition = $"ts between '{startTime:yyyy-MM-dd HH:mm:ss.fff}' and '{endTime:yyyy-MM-dd HH:mm:ss.fff}'" +
- $" and serialno='{imei}'" +
- $" and is_display = true";
- var hmBpResponse = await _serviceTDengine.ExecuteSelectRestResponseAsync("stb_hm_bloodpress", condition);
- var hmBpParser = JsonConvert.DeserializeObject<ParseTDengineRestResponse<BloodPressureModel>>(hmBpResponse!);
- if (hmBpParser!.Rows >= 5)
- {
- //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];
- // 平均值为0,说明数据不足,不能计算增量值
- // 数据不足等同进行初始化,只下发标定值,增量值为0;remarks恢复到未校准状态,需要基于第一个测量值生成增量值。
- if (systolicAvg.Equals(0))
- {
- _logger.LogInformation($"测量数据样本不足,将进行标定值初始,只下发标定值,增量值为0,更新remark (lastPushRefValue)");
- // 重置设备
- // var statNow = DateTime.Now;
- //await IotSetBloodPressCalibrationConfigResponseAsync(imei, 0, 0, 0, 0, 0, 0, 0, 0, statNow, statNow).ConfigureAwait(false);
- _logger.LogInformation($"1.测量数据样本不足,更新remark (lastPushRefValue)");
-
- var initRemarksFlag = await _serviceIotWebApi.UpdatePersonRemarksAsync(imei, 0, 0, 0, 0, "lastPushRefValue").ConfigureAwait(false);
- if (initRemarksFlag)
- {
- _logger.LogInformation($"2.测量数据样本不足,remarks恢复到未校准状态(remarks设置为空),成功");
- }
- else
- {
- _logger.LogInformation($"2.测量数据样本不足,remarks恢复到未校准状态(remarks设置为空),失败");
- }
- _logger.LogInformation($"2.测量数据样本不足,只下发手动标定值systolicRefValue:{systolicRefValue} -- diastolicRefValue:{diastolicRefValue},增量值为0");
- //statNow = statNow.AddSeconds(3);
- var statNow = DateTime.Now;
- return await IotSetBloodPressCalibrationConfigResponseAsync(imei, systolicRefValue, diastolicRefValue, 0, 0, 0, 0, 0, 0, statNow, statNow).ConfigureAwait(false);
- }
- // 除最大值和最小值后的平均值与标定值差值少于4后(当天计算出该结果则也不产生增量调整),就不再进行增量值调整了。
- //if (systolicRefValue-systolicAvg < 4)
- //{
- // _logger.LogInformation($"systolic 收缩压 {imei} 除最大值和最小值后的平均值:{systolicAvg}与标定值:{systolicRefValue}差值(标定值-平均值)少于4后,不再进行增量值调整");
- // return ApiResponse<object>.Fail(502, $"平均值与标定值差值少于4,不调整增量值");
- //}
-
- //if (diastolicRefValue - diastolicAvg < 4)
- //{
- // _logger.LogInformation($"diastolic 舒张压 {imei} 除最大值和最小值后的平均值:{diastolicAvg}与标定值:{diastolicRefValue}差值(标定值-平均值)少于4后,不再进行增量值调整");
- // return ApiResponse<object>.Fail(502, $"平均值与标定值差值少于4,不调整增量值");
- //}
-
- // 增量值=(标定值-平均值)* 0.25
- var currentSystolicInc = (int)((systolicRefValue - systolicAvg) * systolicAvgOffset)!;
- var currentDiastolicInc = (int)((diastolicRefValue - diastolicAvg) * diastolicAvgOffset)!;
-
- // 累计增量
- systolicInc = currentSystolicInc + lastPushSystolicInc;
- diastolicInc = currentDiastolicInc + lastPushDiastolicInc;
- _logger.LogInformation($"{imei}--{nameof(Put)}--计算增量值" +
- $"\n {imei}-- systolicAvg:{systolicAvg}--systolicInc:{systolicInc}-- currentSystolicInc:{currentSystolicInc} -- lastPushSystolicInc:{lastPushSystolicInc}" +
- $"\n {imei}-- diastolicAvg:{diastolicAvg}--diastolicInc:{diastolicInc} --currentDiastolicInc:{currentDiastolicInc} -- lastPushDiastolicInc:{lastPushDiastolicInc}");
- _logger.LogInformation($"{imei},手工校准,发给设备的绝对增量值=(上次绝对增量值+新数据的增量值)");
- return await IotSetBloodPressCalibrationConfigResponseAsync(imei, systolicRefValue, diastolicRefValue, systolicInc, diastolicInc, systolicAvg, diastolicAvg, systolicAvgOffset, diastolicAvgOffset, startTime, endTime).ConfigureAwait(false);
- }
- else
- {
- _logger.LogInformation($"没有符合条件的测试量数据(少于5条),将进行标定值初始,只下发标定值,增量值为0;更新remark (lastPushRefValue)");
- var statNow = DateTime.Now;
- // await IotSetBloodPressCalibrationConfigResponseAsync(imei, 0, 0, 0, 0, 0, 0, 0, 0, statNow, statNow).ConfigureAwait(false);
- _logger.LogInformation($"1.没有符合条件的测试量数据(少于5条),更新remark (lastPushRefValue)");
-
- var initRemarksFlag = await _serviceIotWebApi.UpdatePersonRemarksAsync(imei, 0, 0, 0, 0, "lastPushRefValue").ConfigureAwait(false);
- if (initRemarksFlag)
- {
- _logger.LogInformation($"2.没有符合条件的测试量数据(少于5条),remarks恢复到未校准状态(remarks设置为空),成功");
- }
- else
- {
- _logger.LogInformation($"2.没有符合条件的测试量数据(少于5条),remarks恢复到未校准状态(remarks设置为空),失败");
- }
- _logger.LogInformation($"2.没有符合条件的测试量数据(少于5条),只下发手动标定值systolicRefValue:{systolicRefValue} -- diastolicRefValue:{diastolicRefValue},增量值为0");
- statNow = statNow.AddSeconds(3);
- return await IotSetBloodPressCalibrationConfigResponseAsync(imei, systolicRefValue, diastolicRefValue, 0, 0, 0, 0, 0, 0, statNow, statNow).ConfigureAwait(false);
-
- }
- #endregion
-
- }
- catch
- ( Exception ex )
- {
-
- return ApiResponse<object>.Fail(500, $" 接口出错:{ex.Message}\n{ex.StackTrace}");
- }
- }
- private async Task<ApiResponse<object>> IotSetBloodPressCalibrationConfigResponseAsync(string imei, int systolicRefValue, int diastolicRefValue, int systolicInc, int diastolicInc)
- {
- BloodPressCalibrationConfigModel bpIncData = new()
- {
-
- Imei = imei,
- SystolicRefValue = systolicRefValue, //收缩压标定值,值为0 表示不生效
- DiastolicRefValue = diastolicRefValue, //舒张压标定值,值为0表示不生效
- SystolicIncValue = systolicInc, //收缩压显示增量,值为0 表示不生效
- DiastolicIncValue = diastolicInc //舒张压显示增量,值为0 表示不生效
- };
- // 下发 IOT 增量值
- // var flagIot = await _serviceIotWebApi.SetBloodPressCalibrationConfigAsync(bpIncData).ConfigureAwait(false);
- var response = await _serviceIotWebApi.SetBloodPressCalibrationConfig2Async(bpIncData).ConfigureAwait(false);
- var flagIot = response.Flag;
- if (flagIot)
- {
- #region 保存下推记录 stb_hm_bp_push_ref_inc_value
- var sql = $"INSERT INTO health_monitor.hm_bp_push_ref_inc_value_{imei.Substring(imei.Length - 2)} " +
- $"USING health_monitor.stb_hm_bp_push_ref_inc_value " +
- $"TAGS ('{imei.Substring(imei.Length - 2)}') " +
- $"VALUES(" +
- $"'{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}'," +
- $"'{imei}'," +
- $"{systolicRefValue}," +
- $"{diastolicRefValue}," +
- $"{systolicInc}," +
- $"{diastolicInc}," +
- $"{true})";
-
- _serviceTDengine.ExecuteInsertSQL(sql);
- #endregion
-
- // 返回结果
- return ApiResponse<object>.Success(bpIncData);
- }
- else
- {
- return ApiResponse<object>.Fail(500, $"业务出错!下发指令失败:{response.Message}");
- }
- }
-
- private async Task<ApiResponse<object>> IotSetBloodPressCalibrationConfigResponseAsync(string imei, int systolicRefValue, int diastolicRefValue, int systolicInc, int diastolicInc,decimal systolicAvgValue,decimal diastolicAvgValue,decimal systolicAvgOffset, decimal diastolicAvgOffset, DateTime statStartTime,DateTime statEndTime)
- {
- BloodPressCalibrationConfigModel bpIncData = new()
- {
-
- Imei = imei,
- SystolicRefValue = systolicRefValue, //收缩压标定值,值为0 表示不生效
- DiastolicRefValue = diastolicRefValue, //舒张压标定值,值为0表示不生效
- SystolicIncValue = systolicInc, //收缩压显示增量,值为0 表示不生效
- DiastolicIncValue = diastolicInc //舒张压显示增量,值为0 表示不生效
- };
- // 下发 IOT 增量值
- //var flagIot = await _serviceIotWebApi.SetBloodPressCalibrationConfigAsync(bpIncData).ConfigureAwait(false);
- var response = await _serviceIotWebApi.SetBloodPressCalibrationConfig2Async(bpIncData).ConfigureAwait(false);
- var flagIot = response.Flag;
- if (flagIot)
- {
- #region 保存下推记录 stb_hm_bp_push_ref_inc_value
- var sql = $"INSERT INTO health_monitor.hm_bp_push_ref_inc_value_{imei.Substring(imei.Length - 2)} " +
- $"USING health_monitor.stb_hm_bp_push_ref_inc_value " +
- $"TAGS ('{imei.Substring(imei.Length - 2)}') " +
- $"VALUES(" +
- $"'{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}'," +
- $"'{imei}'," +
- $"{systolicRefValue}," +
- $"{diastolicRefValue}," +
- $"{systolicInc}," +
- $"{diastolicInc}," +
- $"{true}," +
- $"{(float)systolicAvgValue}," +
- $"{(float)diastolicAvgValue}," +
- $"{systolicAvgOffset}," +
- $"{diastolicAvgOffset}," +
- $"'{statStartTime:yyyy-MM-dd HH:mm:ss.fff}'," +
- $"'{statEndTime:yyyy-MM-dd HH:mm:ss.fff}'" +
- $")";
-
- _serviceTDengine.ExecuteInsertSQL(sql);
- #endregion
-
- // 返回结果
- return ApiResponse<object>.Success(bpIncData);
- }
- else
- {
- return ApiResponse<object>.Fail(500, $"业务出错!下发指令失败:{response.Message}");
- }
- }
- }
- }
|