@@ -343,10 +343,10 @@ namespace HealthMonitor.Service.Biz | |||
/// </summary> | |||
/// <param name="serialno"></param> | |||
/// <param name="fhr">心率值</param> | |||
/// <param name="sampeTime">检测时间(时间戳)</param> | |||
/// <param name="sampleTime">检测时间(时间戳)</param> | |||
/// <param name="isAbnormal">0 //是否异常 0 表示正常;1表示偏高;2表示偏低</param> | |||
/// <returns></returns> | |||
public async Task<bool> SetFetalHeartRateConfig(string serialno, int fhr, string sampeTime, int isAbnormal) | |||
public async Task<bool> SetFetalHeartRateConfig(string serialno, int fhr, string sampleTime, int isAbnormal) | |||
{ | |||
try | |||
@@ -379,7 +379,7 @@ namespace HealthMonitor.Service.Biz | |||
{ | |||
imei = serialno, | |||
heartValue = fhr, | |||
sampeTime, | |||
sampleTime, | |||
isAbnormal | |||
}; | |||
@@ -739,6 +739,30 @@ namespace HealthMonitor.Service.Biz.db | |||
return first; | |||
} | |||
public Task<T> GetLastAsync<T>(string serialNo) where T : class | |||
{ | |||
var tableName = typeof(T) | |||
.GetCustomAttribute<STableAttribute>()? | |||
.STableName; | |||
// 创建表示 Timestamp 属性的表达式 | |||
var parameter = Expression.Parameter(typeof(T), "x"); | |||
var timestampProperty = Expression.Property(parameter, "Timestamp"); | |||
var timestampLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(timestampProperty, typeof(object)), parameter); | |||
// 创建表示 SerialNo 属性的表达式 | |||
var serialNoProperty = Expression.Property(parameter, "SerialNumber"); | |||
var serialNoConstant = Expression.Constant(serialNo); | |||
var equalExpression = Expression.Equal(serialNoProperty, serialNoConstant); | |||
var serialNoLambda = Expression.Lambda<Func<T, bool>>(equalExpression, parameter); | |||
var first = _clientSqlSugar | |||
.Queryable<T>() | |||
.AS(tableName) | |||
.Where(serialNoLambda) | |||
.OrderByDescending(timestampLambda).FirstAsync(); | |||
return first; | |||
} | |||
public async Task<List<T>> GetBySerialNoAsync<T>(string serialNo) where T : class | |||
{ | |||
var tableName = typeof(T) | |||
@@ -86,7 +86,22 @@ namespace HealthMonitor.Service.Resolver | |||
if (isFetalHeartEnable) | |||
{ | |||
// 高频心率采样间隔 | |||
var highFreqSampleInterval = (int)watchConfig!["highFreqSampleInterval"]!; | |||
// 触发高频监测的心率上限值 | |||
var triggerHighFreqHigh = (int)watchConfig["triggerHighFreqHigh"]!; | |||
// 触发高频监测的心率下限值 | |||
var triggerHighFreqLow = (int)watchConfig["triggerHighFreqLow"]!; | |||
//停止高频心率采样心率连续正常次数 | |||
var stopHighFreqSampleCount = (int)watchConfig["stopHighFreqSampleCount"]!; | |||
// 高频心率采集时长 0 为持续采集,非零为高频心率的采集时长 | |||
var highFreqSampleTimes = (int)watchConfig["stopHighFreqSampleCount"]!; | |||
// 告警上限阀值 | |||
var upperAlarmThreshold = (int)watchConfig["upperAlarmThreshold"]!; | |||
// 告警下限阀值 | |||
var lowerAlarmThreshold = (int)watchConfig["lowerAlarmThreshold"]!; | |||
var phr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(heartRate.Serialno, 7); | |||
if (phr.Count >= 30) | |||
{ | |||
@@ -97,20 +112,7 @@ namespace HealthMonitor.Service.Resolver | |||
// 如果需要,将时间差转换为秒 | |||
var timeDiffInSeconds = timeDiff.TotalSeconds; | |||
// 高频心率采样间隔 | |||
var highFreqSampleInterval = (int)watchConfig!["highFreqSampleInterval"]!; | |||
// 触发高频监测的心率上限值 | |||
var triggerHighFreqHigh = (int)watchConfig["triggerHighFreqHigh"]!; | |||
// 触发高频监测的心率下限值 | |||
var triggerHighFreqLow = (int)watchConfig["triggerHighFreqLow"]!; | |||
//停止高频心率采样心率连续正常次数 | |||
var stopHighFreqSampleCount = (int)watchConfig["stopHighFreqSampleCount"]!; | |||
// 高频心率采集时长 0 为持续采集,非零为高频心率的采集时长 | |||
var highFreqSampleTimes = (int)watchConfig["stopHighFreqSampleCount"]!; | |||
// 告警上限阀值 | |||
var upperAlarmThreshold = (int)watchConfig["upperAlarmThreshold"]!; | |||
// 告警下限阀值 | |||
var lowerAlarmThreshold= (int)watchConfig["lowerAlarmThreshold"]!; | |||
// 高频心率启动 | |||
if (timeDiffInSeconds<=highFreqSampleInterval) | |||
@@ -198,34 +200,108 @@ namespace HealthMonitor.Service.Resolver | |||
} | |||
#endregion | |||
#region 计算胎心数据 | |||
var commonPHR = await _serviceTDengine.GetLastAsync<PregnancyCommonHeartRateModel>(heartRate.Serialno); | |||
if (commonPHR != null) | |||
{ | |||
#region 计算胎心数据 | |||
// 上15分钟的数据 | |||
// 获取当前时间 | |||
DateTime nowQuarter = (DateTime)heartRate.LastUpdate!; | |||
// 计算last_update到上一刻钟的分钟数 | |||
int minutesToSubtract = nowQuarter.Minute % 15; | |||
// 计算上一刻钟的时间 | |||
DateTime previousQuarter = nowQuarter.AddMinutes(-minutesToSubtract).AddSeconds(-nowQuarter.Second).AddMilliseconds(-nowQuarter.Millisecond); | |||
// 使用 last_update 上一刻 | |||
var sampleTime = DateTimeUtil.ConvertToTimeStamp(previousQuarter).ToString(); | |||
// 计算last_update到下一刻钟的分钟数 | |||
int minutesToAdd = 15 - (nowQuarter.Minute % 15); | |||
if (minutesToAdd == 15) | |||
{ | |||
minutesToAdd = 0; // 如果已经是刻钟,则不需要增加分钟 | |||
} | |||
// 计算下一刻钟的时间 | |||
DateTime nextQuarter = nowQuarter.AddMinutes(minutesToAdd) | |||
.AddSeconds(-nowQuarter.Second) | |||
.AddMilliseconds(-nowQuarter.Millisecond); | |||
var daysPhr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(heartRate.Serialno, 7); | |||
var filteredPhr = daysPhr | |||
// 使用 last_update 下一刻 | |||
.Where(i => i.LastUpdate <= nextQuarter && i.LastUpdate >= nextQuarter.AddMinutes(-15)) | |||
.ToList(); | |||
var qarterPhrValue = filteredPhr.Count == 1 | |||
? filteredPhr.First().PregnancyHeartRate | |||
: filteredPhr.Average(i => i.PregnancyHeartRate); | |||
var fetalHeartRate = SafeType.SafeInt(qarterPhrValue * commonPHR?.StatModeAvgFprCoefficient!); | |||
var isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0); | |||
HisGpsFetalHeartRate gpsFetalHeartRate = new() | |||
{ | |||
FetalHeartRateId = Guid.NewGuid().ToString("D"), | |||
PersonId = commonPHR!.PersonId, | |||
Serialno = heartRate.Serialno, | |||
HeartRate = fetalHeartRate, | |||
SampleTime = sampleTime, | |||
IsAbnormal = isAbnormal, | |||
StatStartTime = filteredPhr.OrderByDescending(i => i.LastUpdate).First().LastUpdate, | |||
StatEndTime = filteredPhr.OrderByDescending(i => i.LastUpdate).Last().LastUpdate, | |||
CreateTime = DateTime.Now, | |||
Method = 1, | |||
IsDisplay = 1, | |||
DeviceKey = commonPHR!.DeviceKey | |||
}; | |||
// 保存到 数据服务 MySQL 数据库 | |||
await _hisFetalHeartApiClient.AddAsync(gpsFetalHeartRate).ConfigureAwait(false); | |||
// 推送到api/v1/open/OpenIot/SetFetalHeartRateConfig | |||
await _serviceIotApi.SetFetalHeartRateConfig(heartRate.Serialno, fetalHeartRate, sampleTime, isAbnormal); | |||
#endregion | |||
} | |||
#endregion | |||
#region 定时计算胎心数据触发器 {interval} 秒后 | |||
//var fetalKey = $"health_monitor/schedule_push/cal_fetal_heart_rate/imei/{heartRate.Serialno}"; | |||
//await SetIntervalTriggerAsync(fetalKey, heartRate.Serialno, 60 * 15); | |||
#endregion | |||
#region 定时计算胎心数据触发器下一刻钟后 | |||
// 获取当前时间 | |||
DateTime nowQuarter = DateTime.Now; | |||
//// 获取当前时间 | |||
//DateTime nowQuarter = DateTime.Now; | |||
// 计算下一个15分钟的刻钟 | |||
int minutesToAdd = 15 - (nowQuarter.Minute % 15); | |||
if (minutesToAdd == 15) | |||
{ | |||
minutesToAdd = 0; // 如果已经是刻钟,则不需要增加分钟 | |||
} | |||
// 计算下一刻钟的时间 | |||
DateTime nextQuarter = nowQuarter.AddMinutes(minutesToAdd) | |||
.AddSeconds(-nowQuarter.Second) | |||
.AddMilliseconds(-nowQuarter.Millisecond); | |||
//// 计算下一个15分钟的刻钟 | |||
//int minutesToAdd = 15 - (nowQuarter.Minute % 15); | |||
//if (minutesToAdd == 15) | |||
//{ | |||
// minutesToAdd = 0; // 如果已经是刻钟,则不需要增加分钟 | |||
//} | |||
//// 计算下一刻钟的时间 | |||
//DateTime nextQuarter = nowQuarter.AddMinutes(minutesToAdd) | |||
// .AddSeconds(-nowQuarter.Second) | |||
// .AddMilliseconds(-nowQuarter.Millisecond); | |||
// 计算时间差 | |||
TimeSpan timeDifference = nextQuarter - nowQuarter; | |||
//// 计算时间差 | |||
//TimeSpan timeDifference = nextQuarter - nowQuarter; | |||
var fetalKey = $"health_monitor/schedule_push/cal_fetal_heart_rate/imei/{heartRate.Serialno}"; | |||
await SetIntervalTriggerAsync(fetalKey, heartRate.Serialno, (long)timeDifference.TotalSeconds); | |||
//var fetalKey = $"health_monitor/schedule_push/cal_fetal_heart_rate/imei/{heartRate.Serialno}"; | |||
//await SetIntervalTriggerAsync(fetalKey, heartRate.Serialno, (long)timeDifference.TotalSeconds); | |||
#endregion | |||
#region 定时计算胎动数据触发器 0 点开始 | |||
var fetalMovementKey = $"health_monitor/schedule_push/cal_fetal_movement/imei/{heartRate.Serialno}"; | |||
/// 计算 0 点秒数 | |||
@@ -246,79 +246,79 @@ namespace HealthMonitor.WebApi | |||
// health_monitor/schedule_push/cal_fetal_heart_rate/imei/ | |||
else if (key.Contains("health_monitor/schedule_push/cal_fetal_heart_rate/imei/")) | |||
{ | |||
var watchConfig = await _deviceCacheMgr.GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(imeiDel, "0067"); | |||
var isFetalHeartEnable = watchConfig != null && (int)watchConfig["enabled"]! == 1; | |||
if (isFetalHeartEnable) | |||
{ | |||
// 处理胎心计算业务,计算一般心率获取胎心系数 | |||
var commonPHR = await _serviceTDengine.InitPregnancyCommonHeartRateModeAsync(imeiDel); | |||
if (commonPHR != null) | |||
{ | |||
# region 计算上刻钟的胎心数据 | |||
// 告警上限阀值 | |||
var upperAlarmThreshold = (int)watchConfig!["upperAlarmThreshold"]!; | |||
// 告警下限阀值 | |||
var lowerAlarmThreshold = (int)watchConfig["lowerAlarmThreshold"]!; | |||
//var lastPhr = await _serviceTDengine.GetLastAsync<PregnancyHeartRateModel>(); | |||
// 计算胎心=孕妇心率*系数 | |||
//var fetalHeartRate = SafeType.SafeInt(lastPhr.PregnancyHeartRate * commonPHR?.StatModeAvgFprCoefficient!); | |||
// 上15分钟的数据 | |||
// 获取当前时间 | |||
DateTime now = DateTime.Now; | |||
// 计算当前时间到上一刻钟的分钟数 | |||
int minutesToSubtract = now.Minute % 15; | |||
// 计算上一刻钟的时间 | |||
DateTime previousQuarter = now.AddMinutes(-minutesToSubtract).AddSeconds(-now.Second).AddMilliseconds(-now.Millisecond); | |||
var lastQuarterPhr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(imeiDel, 1); | |||
var filteredPhr = lastQuarterPhr | |||
.Where(i => i.LastUpdate <= previousQuarter && i.LastUpdate >= previousQuarter.AddMinutes(-15)) | |||
.ToList(); | |||
var lastQuarterPhrValue = filteredPhr.Count == 1 | |||
? filteredPhr.First().PregnancyHeartRate | |||
: filteredPhr.Average(i => i.PregnancyHeartRate); | |||
var fetalHeartRate = SafeType.SafeInt(lastQuarterPhrValue * commonPHR?.StatModeAvgFprCoefficient!); | |||
var sampleTime = DateTimeUtil.ConvertToTimeStamp(DateTime.Now).ToString(); | |||
var isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0); | |||
HisGpsFetalHeartRate gpsFetalHeartRate = new() | |||
{ | |||
FetalHeartRateId = Guid.NewGuid().ToString("D"), | |||
PersonId = commonPHR!.PersonId, | |||
Serialno = imeiDel, | |||
HeartRate = fetalHeartRate, | |||
SampleTime = sampleTime, | |||
IsAbnormal = isAbnormal, | |||
StatStartTime = filteredPhr.OrderByDescending(i=>i.LastUpdate).First().LastUpdate, | |||
StatEndTime = filteredPhr.OrderByDescending(i => i.LastUpdate).Last().LastUpdate, | |||
CreateTime = DateTime.Now, | |||
Method = 1, | |||
IsDisplay = 1, | |||
DeviceKey = commonPHR!.DeviceKey | |||
}; | |||
// 保存到 数据服务 MySQL 数据库 | |||
await _hisFetalHeartApiClient.AddAsync(gpsFetalHeartRate).ConfigureAwait(false); | |||
// 推送到api/v1/open/OpenIot/SetFetalHeartRateConfig | |||
await _serviceIotApi.SetFetalHeartRateConfig(imeiDel, fetalHeartRate, sampleTime, isAbnormal); | |||
#endregion | |||
#region 注册定时计算胎心数据触发器 {interval} 秒后 | |||
//await SetIntervalTriggerAsync(key, imeiDel, 60 * 15); | |||
#endregion | |||
} | |||
} | |||
/** | |||
var watchConfig = await _deviceCacheMgr.GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(imeiDel, "0067"); | |||
var isFetalHeartEnable = watchConfig != null && (int)watchConfig["enabled"]! == 1; | |||
if (isFetalHeartEnable) | |||
{ | |||
// 处理胎心计算业务,计算一般心率获取胎心系数 | |||
var commonPHR = await _serviceTDengine.InitPregnancyCommonHeartRateModeAsync(imeiDel); | |||
if (commonPHR != null) | |||
{ | |||
# region 计算上刻钟的胎心数据 | |||
// 告警上限阀值 | |||
var upperAlarmThreshold = (int)watchConfig!["upperAlarmThreshold"]!; | |||
// 告警下限阀值 | |||
var lowerAlarmThreshold = (int)watchConfig["lowerAlarmThreshold"]!; | |||
//var lastPhr = await _serviceTDengine.GetLastAsync<PregnancyHeartRateModel>(); | |||
// 计算胎心=孕妇心率*系数 | |||
//var fetalHeartRate = SafeType.SafeInt(lastPhr.PregnancyHeartRate * commonPHR?.StatModeAvgFprCoefficient!); | |||
// 上15分钟的数据 | |||
// 获取当前时间 | |||
DateTime now = DateTime.Now; | |||
// 计算当前时间到上一刻钟的分钟数 | |||
int minutesToSubtract = now.Minute % 15; | |||
// 计算上一刻钟的时间 | |||
DateTime previousQuarter = now.AddMinutes(-minutesToSubtract).AddSeconds(-now.Second).AddMilliseconds(-now.Millisecond); | |||
var lastQuarterPhr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(imeiDel, 1); | |||
var filteredPhr = lastQuarterPhr | |||
.Where(i => i.LastUpdate <= previousQuarter && i.LastUpdate >= previousQuarter.AddMinutes(-15)) | |||
.ToList(); | |||
var lastQuarterPhrValue = filteredPhr.Count == 1 | |||
? filteredPhr.First().PregnancyHeartRate | |||
: filteredPhr.Average(i => i.PregnancyHeartRate); | |||
var fetalHeartRate = SafeType.SafeInt(lastQuarterPhrValue * commonPHR?.StatModeAvgFprCoefficient!); | |||
var sampleTime = DateTimeUtil.ConvertToTimeStamp(DateTime.Now).ToString(); | |||
var isAbnormal = fetalHeartRate > upperAlarmThreshold ? 1 : (fetalHeartRate < lowerAlarmThreshold ? 2 : 0); | |||
HisGpsFetalHeartRate gpsFetalHeartRate = new() | |||
{ | |||
FetalHeartRateId = Guid.NewGuid().ToString("D"), | |||
PersonId = commonPHR!.PersonId, | |||
Serialno = imeiDel, | |||
HeartRate = fetalHeartRate, | |||
SampleTime = sampleTime, | |||
IsAbnormal = isAbnormal, | |||
StatStartTime = filteredPhr.OrderByDescending(i=>i.LastUpdate).First().LastUpdate, | |||
StatEndTime = filteredPhr.OrderByDescending(i => i.LastUpdate).Last().LastUpdate, | |||
CreateTime = DateTime.Now, | |||
Method = 1, | |||
IsDisplay = 1, | |||
DeviceKey = commonPHR!.DeviceKey | |||
}; | |||
// 保存到 数据服务 MySQL 数据库 | |||
await _hisFetalHeartApiClient.AddAsync(gpsFetalHeartRate).ConfigureAwait(false); | |||
// 推送到api/v1/open/OpenIot/SetFetalHeartRateConfig | |||
await _serviceIotApi.SetFetalHeartRateConfig(imeiDel, fetalHeartRate, sampleTime, isAbnormal); | |||
#endregion | |||
#region 注册定时计算胎心数据触发器 {interval} 秒后 | |||
//await SetIntervalTriggerAsync(key, imeiDel, 60 * 15); | |||
#endregion | |||
} | |||
} | |||
*/ | |||
} | |||
@@ -331,11 +331,11 @@ namespace HealthMonitor.WebApi | |||
if (isFetalHeartEnable) | |||
{ | |||
// 检查胎心建模 | |||
var fchr = await _serviceTDengine.GetLastAsync<PregnancyCommonHeartRateModel>(); | |||
var fchr = await _serviceTDengine.GetLastAsync<PregnancyCommonHeartRateModel>(imeiDel); | |||
if (fchr != null) | |||
{ | |||
// 获取孕妇心率数据接近最近2小时的数据 | |||
var phr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(imeiDel, 1); | |||
var phr = await _serviceTDengine.GetBySerialNoAsync<PregnancyHeartRateModel>(imeiDel, 7); | |||
var now = DateTime.Now; | |||
var ago2hrs = now.AddHours(-2); | |||
var phrRange = phr.Where(i => i.LastUpdate >= ago2hrs) | |||