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 _logger; private readonly PersonCacheManager _personCacheMgr; private readonly DeviceCacheManager _deviceCacheMgr; private readonly HttpHelper _httpHelper = default!; private readonly GpsCardAccessorClient _gpsPersonApiClient; public IotApiService(ILogger logger, HttpHelper httpHelper, DeviceCacheManager deviceCacheMgr, GpsCardAccessorClient gpsPersonApiClient, IOptions optConfigService, PersonCacheManager personCacheMgr) { _configService = optConfigService.Value; _httpHelper=httpHelper; _logger = logger; _personCacheMgr = personCacheMgr; _gpsPersonApiClient = gpsPersonApiClient; _deviceCacheMgr = deviceCacheMgr; } #region 平台下发血压标定参数 /// /// 平台下发血压标定参数 /// /// /// public async Task 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> headers = new() { new KeyValuePair("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 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> headers = new() { new KeyValuePair("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 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 { new QueryFilterCondition { Key=nameof(GpsDevice.Serialno), Value=imei, Operator= QueryOperatorEnum.Equal, ValueType=QueryValueTypeEnum.String } }, OrderBys = new List { 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 { // new QueryFilterCondition { // Key=nameof(GpsDevice.Serialno), // Value=imei, // Operator= QueryOperatorEnum.Equal, // ValueType=QueryValueTypeEnum.String // } // }, // OrderBys = new List { 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 SetFetalConfig(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 string tokenAuthData = await getAccessToken2(serialno).ConfigureAwait(false); if (tokenAuthData == null) { return false; } #endregion _logger.LogInformation($" SetFetalConfig Token TelpoManufactorId: {tokenAuthData}"); #region 发送到B端 List> headers = new() { new KeyValuePair("AccessToken", tokenAuthData) }; //var data = new //{ // imeis = new string[] { serialno }, // enabled = (int)watchConfig["enabled"]!, // interval= (int)watchConfig["interval"]!, // triggerHighFreqHigh = maxValue == 0 ? (int)watchConfig["triggerHighFreqHigh"]! : maxValue, // triggerHighFreqLow = minValue == 0 ? (int)watchConfig["triggerHighFreqLow"]! : minValue, // highFreqSampleTimes = (int)watchConfig["highFreqSampleTimes"]!, // highFreqSampleInterval = (int)watchConfig["highFreqSampleInterval"]!, // stopHighFreqSampleCount = (int)watchConfig["stopHighFreqSampleCount"]!, // mode = modeStatus, // edoc = watchConfig["EDOC"]!, // vibrateEnabled = (int)watchConfig["vibrateEnabled"]!, // lcdEnabled = (int)watchConfig["lcdEnabled"]!, // upperAlarmThreshold = (int)watchConfig["upperAlarmThreshold"]!, // lowerAlarmThreshold = (int)watchConfig["lowerAlarmThreshold"]! //}; watchConfig["mode"] = modeStatus; watchConfig["triggerHighFreqHigh"] = maxValue == 0 ? (int)watchConfig["triggerHighFreqHigh"]! : maxValue; watchConfig["triggerHighFreqLow"] = minValue == 0 ? (int)watchConfig["triggerHighFreqLow"]! : minValue; var data = watchConfig; var setUrl = $"{_configService.IotCore}/SetFetalConfig"; _logger.LogInformation($"{setUrl} 请求 {JsonConvert.SerializeObject(JsonConvert.SerializeObject(data))}"); var res = await _httpHelper.HttpToPostAsync(setUrl, data, headers).ConfigureAwait(false); _logger.LogInformation($"{setUrl} 响应 {res}"); 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(SetFetalConfig)} 下发胎心检测参数异常:{ex.Message}, {ex.StackTrace}"); return false; } } public async Task SetFetalConfigMockAsync(string serialno, int modeStatus = 0, int triggerHighFreqHigh = 0, int triggerHighFreqLow = 0, int highFreqSampleTimes=0,int highFreqSampleInterval=0,int stopHighFreqSampleCount=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 string tokenAuthData = await getAccessToken2(serialno).ConfigureAwait(false); if (tokenAuthData == null) { return false; } #endregion _logger.LogInformation($" SetFetalConfig Token TelpoManufactorId: {tokenAuthData}"); #region 发送到B端 List> headers = new() { new KeyValuePair("AccessToken", tokenAuthData) }; watchConfig["mode"] = modeStatus; watchConfig["highFreqSampleTimes"]= highFreqSampleTimes == 0 ? (int)watchConfig["highFreqSampleTimes"]! : highFreqSampleTimes; watchConfig["highFreqSampleInterval"] = highFreqSampleInterval == 0 ? (int)watchConfig["highFreqSampleInterval"]! : highFreqSampleInterval; watchConfig["stopHighFreqSampleCount"] = stopHighFreqSampleCount == 0 ? (int)watchConfig["stopHighFreqSampleCount"]! : stopHighFreqSampleCount; watchConfig["triggerHighFreqHigh"] = triggerHighFreqHigh == 0 ? (int)watchConfig["triggerHighFreqHigh"]! : triggerHighFreqHigh; watchConfig["triggerHighFreqLow"] = triggerHighFreqLow == 0 ? (int)watchConfig["triggerHighFreqLow"]! : triggerHighFreqLow; var data = watchConfig; var setUrl = $"{_configService.IotCore}/SetFetalConfig"; _logger.LogInformation($"{setUrl} 请求 {JsonConvert.SerializeObject(JsonConvert.SerializeObject(data))}"); var res = await _httpHelper.HttpToPostAsync(setUrl, data, headers).ConfigureAwait(false); _logger.LogInformation($"{setUrl} 响应 {res}"); 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(SetFetalConfig)} 下发胎心检测参数异常:{ex.Message}, {ex.StackTrace}"); return false; } } /// /// 下发胎心数据 /// /// /// 心率值 /// 检测时间(时间戳) /// 0 //是否异常 0 表示正常;1表示偏高;2表示偏低 /// public async Task SetFetalHeartRateConfig(string serialno, int fhr, string sampleTime, int isAbnormal) { 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 string tokenAuthData = await getAccessToken2(serialno).ConfigureAwait(false); if (tokenAuthData == null) { return false; } #endregion #region 下发数据 List> headers = new() { new KeyValuePair("AccessToken", tokenAuthData) }; _logger.LogInformation($" SetFetalHeartRateConfig Token TelpoManufactorId: {tokenAuthData}"); var data = new { imei = serialno, heartValue = fhr, sampleTime = sampleTime.Length > 10 ? sampleTime.Substring(0, 10) : sampleTime, isAbnormal }; var setUrl = $"{_configService.IotCore}/SetFetalHeartRateConfig"; _logger.LogInformation($"{setUrl} 请求 {JsonConvert.SerializeObject(JsonConvert.SerializeObject(data))}"); var res = await _httpHelper.HttpToPostAsync(setUrl, data, headers).ConfigureAwait(false); _logger.LogInformation($"{setUrl} 响应 {res}"); var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; return resJToken?["message"]?.ToString().Equals("ok") ?? false; #endregion } catch (Exception ex) { _logger.LogError($"{nameof(SetFetalHeartRateConfig)} 下发胎心数据异常:{ex.Message}, {ex.StackTrace}"); return false; } } public async Task SetFetalMovementConfig(string serialno,int fm, string sampleTime, int isAbnormal) { 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 string tokenAuthData = await getAccessToken2(serialno).ConfigureAwait(false); if (tokenAuthData == null) { return false; } #endregion #region 下发数据 List> headers = new() { new KeyValuePair("AccessToken", tokenAuthData) }; _logger.LogInformation($" SetFetalHeartRateConfig Token TelpoManufactorId: {tokenAuthData}"); var data = new { imei = serialno, movementValue = fm, sampleTime = sampleTime.Length > 10 ? sampleTime.Substring(0, 10) : sampleTime, isAbnormal }; var setUrl = $"{_configService.IotCore}/SetFetalMovementConfig"; _logger.LogInformation($"{setUrl} 请求 {JsonConvert.SerializeObject(JsonConvert.SerializeObject(data))}"); var res = await _httpHelper.HttpToPostAsync(setUrl, data, headers).ConfigureAwait(false); _logger.LogInformation($"{setUrl} 响应 {res}"); var resJToken = JsonConvert.DeserializeObject(res ?? string.Empty) as JToken; return resJToken?["message"]?.ToString().Equals("ok") ?? false; #endregion } catch (Exception ex) { _logger.LogError($"{nameof(SetFetalMovementConfig)} 下发胎动数据异常:{ex.Message}, {ex.StackTrace}"); return false; } } private async Task getAccessToken2(string serialno) { var getTokenUrl = $"{_configService.IotAuth}/getAccessToken2"; var tokenReq = new { manufactorId = "7c7c38cb-d045-41d8-b3d0-fcaaa84a8f02", imei = serialno }; _logger.LogInformation($"{getTokenUrl} 请求 {JsonConvert.SerializeObject(tokenReq)}"); var resToken = await _httpHelper.HttpToPostAsync(getTokenUrl, tokenReq).ConfigureAwait(false); _logger.LogInformation($"{getTokenUrl} 响应 {resToken}"); var tokenAuth = JsonConvert.DeserializeObject(resToken ?? string.Empty) as JToken; var tokenAuthData = tokenAuth?["data"]?.ToString() ?? string.Empty; return tokenAuthData; } #endregion } }