Creado apartir del commit b888de6c92056de294456f581a56e25e734d4ab7 de develop
This commit is contained in:
@@ -0,0 +1,642 @@
|
||||
using System.Collections.Concurrent;
|
||||
using adas_core.Application.Exceptions;
|
||||
using adas_core.Application.Repositories.Interfaces;
|
||||
using adas_core.Application.Services.Interfaces;
|
||||
using adas_core.Domain.Enums;
|
||||
using adas_core.Domain.Models;
|
||||
using adas_core.Domain.Models.AppSettings;
|
||||
using adas_core.Domain.Models.DTO;
|
||||
using adas_core.Domain.Models.Filter;
|
||||
using adas_core.Domain.Models.GroupedObservations;
|
||||
using adas_core.Domain.Models.MongoModels;
|
||||
using adas_core.Domain.Models.Pumps;
|
||||
using adas_core.Domain.Models.Responses;
|
||||
using adas_core.Domain.Utils;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.CodeAnalysis.CSharp.Scripting;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Bson;
|
||||
|
||||
namespace adas_core.Application.Services;
|
||||
|
||||
public class ConfigObservationService : IConfigObservationService
|
||||
{
|
||||
private static readonly ConcurrentDictionary<ObjectId, ConfigObservationCached> CachedConfigObservations = new();
|
||||
|
||||
private static readonly ConcurrentDictionary<string, ConfigObservationKeyCached>
|
||||
CachedConfigObservationKeys = new();
|
||||
|
||||
private readonly IOptions<ApiSettings> _apiSettings;
|
||||
private readonly ILocalAuditService _auditService;
|
||||
private readonly IConfigObservationRepository _configObservationRepository;
|
||||
private readonly RetentionPolicy _defaultRetentionPolicy;
|
||||
private readonly int _defaultRetentionPolicyValue;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly bool _ignoreUnknownTreatment;
|
||||
private readonly ILogger<ConfigObservationService> _logger;
|
||||
private readonly int? _refreshTimeout;
|
||||
private readonly IUnitService _unitService;
|
||||
private readonly ICacheService _cacheService;
|
||||
private readonly CacheSettings? _cacheSettings;
|
||||
|
||||
private bool IgnoreUnknownObservation =>
|
||||
_apiSettings.Value.ConfigObservation?.IgnoreUnknownObservation ?? false;
|
||||
|
||||
public ConfigObservationService(
|
||||
IConfigObservationRepository configObservationRepository,
|
||||
IOptions<ApiSettings> apiSettings,
|
||||
IOptions<CacheSettings> cacheSettings,
|
||||
ILogger<ConfigObservationService> logger,
|
||||
IUnitService unitService,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
ILocalAuditService auditService,
|
||||
ICacheService cacheService
|
||||
)
|
||||
{
|
||||
_cacheService = cacheService;
|
||||
_cacheSettings = cacheSettings.Value;
|
||||
_configObservationRepository = configObservationRepository;
|
||||
_apiSettings = apiSettings;
|
||||
_logger = logger;
|
||||
_unitService = unitService;
|
||||
|
||||
_refreshTimeout = _apiSettings.Value.ConfigObservation?.Refresh;
|
||||
_ignoreUnknownTreatment = _apiSettings.Value.ConfigObservation?.IgnoreUnknownTreatment ?? false;
|
||||
|
||||
_defaultRetentionPolicyValue = _apiSettings.Value.RetentionPolicyValue;
|
||||
|
||||
_defaultRetentionPolicy = RetentionPolicy.NoDelete;
|
||||
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_auditService = auditService;
|
||||
}
|
||||
|
||||
public async Task<ICollection<ConfigObservation>> GetAllConfigs(CancellationToken ct = default)
|
||||
{
|
||||
|
||||
var (key, ttl) = CacheKeys.ConfigObservationsAllKeyWithTtl(_cacheSettings);
|
||||
|
||||
var result = await _cacheService.GetOrSetObjectAsync(
|
||||
key,
|
||||
async () => await _configObservationRepository.FindAll(),
|
||||
ttl,
|
||||
ct);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public async Task<ConfigObservationDto> GetAllCompact()
|
||||
{
|
||||
var count = await _configObservationRepository.Count();
|
||||
return new ConfigObservationDto { ItemCount = count };
|
||||
}
|
||||
|
||||
public async Task<PaginationResponse<ConfigObservation>> GetPaginatedItems(PaginationFilter filter)
|
||||
{
|
||||
var result = await _configObservationRepository.GetPaginatedItems(filter);
|
||||
var count = await _configObservationRepository.Count();
|
||||
return new PaginationResponse<ConfigObservation>(result.ToList(), filter.PageNumber, filter.PageSize,
|
||||
count);
|
||||
}
|
||||
|
||||
|
||||
public async Task<ConfigObservation?> GetConfigById(ObjectId id)
|
||||
{
|
||||
return await _configObservationRepository.FindById(id) ?? null;
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetConfigNames(string id)
|
||||
{
|
||||
return await _configObservationRepository.GetConfigNames(id);
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetConfigNames()
|
||||
{
|
||||
return await _configObservationRepository.GetConfigNames();
|
||||
}
|
||||
|
||||
|
||||
public async Task<ObservatitonRetentionResult?> RetentionActions<T>(T obs) where T : BasePatientObservation
|
||||
{
|
||||
var conf = await Get(obs);
|
||||
return conf is { RetentionPolicy: not null } ?
|
||||
new ObservatitonRetentionResult(conf.RetentionPolicy.Value, conf.RetentionPolicyValue) :
|
||||
new ObservatitonRetentionResult(RetentionPolicy.NoDelete, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<StatusEnum.Type> GroupedObservationStatus(GroupedField groupedField,
|
||||
GroupedObservationEnum.Result result,
|
||||
string name, object value, double? min, double? max)
|
||||
{
|
||||
var conf = await Get(name);
|
||||
if (conf == null) return StatusEnum.Type.Ok;
|
||||
PatientObservation? mapObs;
|
||||
if (conf.Grouped != null && groupedField.Group != null &&
|
||||
conf.Grouped.TryGetValue(groupedField.Group, out var grp))
|
||||
{
|
||||
mapObs = await MapConf(new PatientObservation { Name = name, Value = value, Min = min, Max = max }, grp);
|
||||
if (mapObs != null) return mapObs.Status;
|
||||
}
|
||||
|
||||
if (conf.Grouped != null && conf.Grouped.ContainsKey(result.ToString()))
|
||||
{
|
||||
mapObs = await MapConf(new PatientObservation { Name = name, Value = value, Min = min, Max = max },
|
||||
conf.Grouped[result.ToString()]);
|
||||
if (mapObs != null) return mapObs.Status;
|
||||
}
|
||||
|
||||
mapObs = await MapConf(new PatientObservation { Name = name, Value = value, Min = min, Max = max }, conf);
|
||||
if (mapObs != null) return mapObs.Status;
|
||||
|
||||
return StatusEnum.Type.Ok;
|
||||
}
|
||||
|
||||
public async Task<T?> Map<T>(T obs, bool onlyByName = false) where T : BasePatientObservation
|
||||
{
|
||||
var conf = onlyByName ? await Get(obs, onlyByName) : await Get(obs);
|
||||
if (conf == null)
|
||||
{
|
||||
_logger.LogDebug("Ignore Unknown Observation. {Name} {Code} {CodingSystem}", obs.Name, obs.Code,
|
||||
obs.CodingSystem);
|
||||
return IgnoreUnknownObservation ? null : obs;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(conf.Name))
|
||||
{
|
||||
_logger.LogError("Config Name is null or empty. {conf}", conf);
|
||||
return null;
|
||||
}
|
||||
|
||||
return await MapConf(obs, conf);
|
||||
}
|
||||
|
||||
public async Task<ConfigObservation?> RemoveConfigItem(ObjectId id)
|
||||
{
|
||||
var item = await _configObservationRepository.FindById(id);
|
||||
if (item == null) return null;
|
||||
|
||||
var deleted = await _configObservationRepository.Delete(id);
|
||||
|
||||
// Invalidar CACHE (colección completa)
|
||||
await _cacheService.DeleteByPatternAsync(CacheKeyPatterns.ForEntity(CacheEnum.EntityType.ConfigObservations));
|
||||
|
||||
return deleted;
|
||||
|
||||
}
|
||||
|
||||
public async Task<PatientTreatment?> Map(PatientTreatment treatment)
|
||||
{
|
||||
ConfigObservation? conf = null;
|
||||
|
||||
foreach (var requestGiveCode in treatment.RequestedGiveCodes)
|
||||
conf = string.IsNullOrEmpty(requestGiveCode.CodingSystem) &&
|
||||
string.IsNullOrEmpty(requestGiveCode.Identifier)
|
||||
? await Get(requestGiveCode.Text)
|
||||
: await GetByCodeSysAndCode(requestGiveCode.CodingSystem, requestGiveCode.Identifier);
|
||||
if (conf == null) return _ignoreUnknownTreatment ? null : treatment;
|
||||
|
||||
return conf.Name == null ? null : treatment;
|
||||
}
|
||||
|
||||
public async Task<ConfigObservation?> Get<T>(T obs, bool onlyByName = false)
|
||||
where T : BasePatientObservation
|
||||
{
|
||||
var items = await GetAllConfigs();
|
||||
if (items.Count == 0) return null;
|
||||
|
||||
if (onlyByName)
|
||||
{
|
||||
var configItem = items.FirstOrDefault(i => i.Name == obs.Name);
|
||||
if (configItem != null) return await Process(configItem);
|
||||
_logger.LogError("Error getting Config observation Item. Observation: {obs}", obs);
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
ConfigObservation? item = null;
|
||||
if ((!string.IsNullOrEmpty(obs.Code) && !string.IsNullOrEmpty(obs.CodingSystem)) ||
|
||||
obs.ParentData is { Code: not null, CodingSystem: not null })
|
||||
foreach (var obsConfig in items)
|
||||
{
|
||||
if (obs.Code != null && obs.Code != obsConfig.Code)
|
||||
continue;
|
||||
if (obsConfig.CodingSystem != null && obs.CodingSystem != obsConfig.CodingSystem)
|
||||
continue;
|
||||
if (obsConfig.OriginalName != null && obs.Name != obsConfig.OriginalName)
|
||||
continue;
|
||||
if (obsConfig.ParentCode != null && obs.ParentData?.Code != obsConfig.ParentCode)
|
||||
continue;
|
||||
if (obsConfig.ParentCodingSystem != null &&
|
||||
obs.ParentData?.CodingSystem != obsConfig.ParentCodingSystem)
|
||||
continue;
|
||||
if (obsConfig.ParentName != null && obs.ParentData?.Name != obsConfig.ParentName)
|
||||
continue;
|
||||
|
||||
if (obsConfig.OriginalName == null && obsConfig.Name != null && obs.Name != null &&
|
||||
obs.Name.Contains("Alarm") && obs.Name != obsConfig.Name)
|
||||
continue;
|
||||
|
||||
if (obsConfig.Code == null && obsConfig.CodingSystem == null && obsConfig.ParentCode == null &&
|
||||
obsConfig.ParentCodingSystem == null && obs.Name != null && !obs.Name.Contains("Alarm"))
|
||||
continue;
|
||||
if (obsConfig.Code == null &&
|
||||
obsConfig is { CodingSystem: not null, ParentCode: null, ParentCodingSystem: null } &&
|
||||
obs.Name != null && !obs.Name.Contains("Alarm"))
|
||||
continue;
|
||||
if (obsConfig.Code == null && obsConfig.CodingSystem == null && obsConfig.ParentCode == null &&
|
||||
obsConfig.ParentCodingSystem != null && obs.Name != null && !obs.Name.Contains("Alarm"))
|
||||
continue;
|
||||
if (obsConfig.Code == null &&
|
||||
obsConfig is { CodingSystem: not null, ParentCode: null, ParentCodingSystem: not null } &&
|
||||
obs.Name != null && !obs.Name.Contains("Alarm"))
|
||||
continue;
|
||||
|
||||
item = obsConfig;
|
||||
break;
|
||||
}
|
||||
else item = items.FirstOrDefault(i => i.Name == obs.Name);
|
||||
|
||||
return item != null ? await Process(item) : null;
|
||||
}
|
||||
|
||||
// public async Task<List<ConfigObservation>> GetAlarmWithRecordingConfig(ObjectId patientId)
|
||||
// {
|
||||
// var configObservationId = await GetConfigObservationKeyFromPatientId(patientId);
|
||||
// var configObservation = await GetConfig(configObservationId);
|
||||
// return configObservation?.Items
|
||||
// .Where(i => i is { CodingSystem: "ADAS_ALARM", Alarm.Recording.Enabled: true })
|
||||
// .ToList() ?? [];
|
||||
// }
|
||||
|
||||
public async Task<ConfigObservation?> GetByCodeSysAndCode(string? codingSystem, string? code)
|
||||
{
|
||||
var filteredResult = await _configObservationRepository.GetByCodeSysAndCode(codingSystem, code);
|
||||
if (filteredResult != null) return await Process(filteredResult);
|
||||
_logger.LogWarning("Config observation item not found. CodingSystem: {codingSystem} code: {code} ",
|
||||
codingSystem ?? "null", code ?? "null");
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public async Task<ConfigObservation?> Get(string? name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name)) return null;
|
||||
var result = await GetConfigByName(name);
|
||||
if (result == null)
|
||||
{
|
||||
// _logger.LogWarning(
|
||||
// "Config observation item not found. name: {name} configObservationId: {configObservationId} ",
|
||||
// name, name);
|
||||
return null;
|
||||
}
|
||||
|
||||
return await Process(result);
|
||||
}
|
||||
|
||||
public async Task<ConfigObservation?> UpdateConfig(ConfigObservation configObservationItem)
|
||||
{
|
||||
// if (!configObservationItem.Id.HasValue)
|
||||
// return await _configObservationRepository.InsertOneAsyncAndReturn(configObservationItem);
|
||||
var configObservation = await _configObservationRepository.FindById(configObservationItem.Id) ??
|
||||
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
||||
|
||||
var updatedConfig = await _configObservationRepository.Update(configObservation);
|
||||
|
||||
// Invalidar CACHE (colección completa)
|
||||
await _cacheService.DeleteByPatternAsync(CacheKeyPatterns.ForEntity(CacheEnum.EntityType.ConfigObservations));
|
||||
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, configObservation,
|
||||
updatedConfig!);
|
||||
return updatedConfig;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ConfigObservation>?> GetConfigObservationItem(string name)
|
||||
{
|
||||
var configObservationItems = await _configObservationRepository.FindAllByName(name);
|
||||
if (configObservationItems.Count != 0)
|
||||
return configObservationItems;
|
||||
_logger.LogWarning("Cant get config item, config not found, name: {name} ", name);
|
||||
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
||||
}
|
||||
|
||||
public async Task<ConfigObservation?> GetSingleConfigObservationItem(string? code, string? codingSystem,
|
||||
string? name, string? originalName)
|
||||
{
|
||||
var matchingItem =
|
||||
await _configObservationRepository.GetSingleConfigObservationItem(code, codingSystem, name, originalName);
|
||||
|
||||
if (matchingItem == null) throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundNoMatches);
|
||||
|
||||
return matchingItem;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteSingleConfigObservationItem(ConfigObservation configObservationItem)
|
||||
{
|
||||
var configObservation = await _configObservationRepository.FindById(configObservationItem.Id) ??
|
||||
throw new ConflictException(HttpEnum.ErrorMessage.ConflictDeleteFailed);
|
||||
|
||||
var auxConfigObservation = await _auditService.DeepCopyAsync(configObservation);
|
||||
|
||||
_ = await _configObservationRepository.DeleteAsync(configObservation.Id) ??
|
||||
throw new ConflictException(HttpEnum.ErrorMessage.ConflictDeleteFailed);
|
||||
|
||||
// Invalidar CACHE (colección completa)
|
||||
await _cacheService.DeleteByPatternAsync(CacheKeyPatterns.ForEntity(CacheEnum.EntityType.ConfigObservations));
|
||||
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, auxConfigObservation,
|
||||
configObservation);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ConfigObservation>> GetConfigObservationItemsByName(string name)
|
||||
{
|
||||
return await _configObservationRepository.FindAllByName(name);
|
||||
}
|
||||
|
||||
public async Task<ConfigObservation?> CreateConfig(ConfigObservation configObservation)
|
||||
{
|
||||
|
||||
var existing = await _configObservationRepository.FindById(configObservation.Id);
|
||||
if (existing != null)
|
||||
throw new BadRequestException(HttpEnum.ErrorMessage.ConflictCreationFailed);
|
||||
|
||||
await _configObservationRepository.InsertOneAsyncAndReturn(configObservation);
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, null, configObservation);
|
||||
return configObservation;
|
||||
}
|
||||
|
||||
|
||||
public async Task<ConfigObservation?> RemoveConfigItem(string itemName)
|
||||
{
|
||||
var configObservation = await GetConfigByName(itemName) ??
|
||||
throw new ConflictException(HttpEnum.ErrorMessage.ConflictDeleteFailed);
|
||||
var auxConfigObservation = await GetConfigByName(itemName) ??
|
||||
throw new ConflictException(HttpEnum.ErrorMessage.ConflictDeleteFailed);
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, auxConfigObservation,
|
||||
configObservation);
|
||||
|
||||
var result = await _configObservationRepository.Delete(configObservation.Id!);
|
||||
|
||||
// Invalidar CACHE (colección completa)
|
||||
await _cacheService.DeleteByPatternAsync(CacheKeyPatterns.ForEntity(CacheEnum.EntityType.ConfigObservations));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<ConfigObservation?> GetConfig(ObjectId configObservationId)
|
||||
{
|
||||
RefreshCachedConfigObservations();
|
||||
|
||||
if (CachedConfigObservations.TryGetValue(configObservationId, out var cached)
|
||||
&& DateTime.Now <= cached.NextRefresh)
|
||||
return cached.ConfigObservation;
|
||||
|
||||
var config = await _configObservationRepository.FindById(configObservationId);
|
||||
cached = new ConfigObservationCached
|
||||
{
|
||||
ConfigObservation = config ?? new ConfigObservation(),
|
||||
NextRefresh = _refreshTimeout.HasValue ? DateTime.Now.AddSeconds(_refreshTimeout.Value) : DateTime.MinValue
|
||||
};
|
||||
|
||||
CachedConfigObservations[configObservationId] = cached;
|
||||
|
||||
return cached.ConfigObservation;
|
||||
}
|
||||
|
||||
public async Task<ConfigObservation?> GetConfigByName(string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name)) return null;
|
||||
|
||||
RefreshCachedConfigObservations();
|
||||
|
||||
var cachedItem = CachedConfigObservations.Values
|
||||
.FirstOrDefault(cached =>
|
||||
DateTime.Now <= cached.NextRefresh &&
|
||||
cached.ConfigObservation is { Name: not null } &&
|
||||
cached.ConfigObservation.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (cachedItem != null) return cachedItem.ConfigObservation;
|
||||
var config = await _configObservationRepository.FindByName(name);
|
||||
if (config == null) return null;
|
||||
var newCachedItem = new ConfigObservationCached
|
||||
{
|
||||
ConfigObservation = config,
|
||||
NextRefresh = _refreshTimeout.HasValue
|
||||
? DateTime.Now.AddSeconds(_refreshTimeout.Value)
|
||||
: DateTime.MinValue
|
||||
};
|
||||
|
||||
CachedConfigObservations[config.Id!] = newCachedItem;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
private void RefreshCachedConfigObservations()
|
||||
{
|
||||
if (!_refreshTimeout.HasValue) return;
|
||||
|
||||
// Use ConcurrentDictionary's thread-safe features to identify and remove expired keys
|
||||
var keysToRemove = CachedConfigObservations
|
||||
.Where(k => DateTime.Now > k.Value.NextRefresh)
|
||||
.Select(k => k.Key)
|
||||
.ToList();
|
||||
|
||||
foreach (var key in keysToRemove) CachedConfigObservations.TryRemove(key, out _);
|
||||
}
|
||||
|
||||
private Task<ConfigObservation> Process(ConfigObservation confItem)
|
||||
{
|
||||
confItem.RetentionPolicy ??= _defaultRetentionPolicy;
|
||||
if (confItem.RetentionPolicy != RetentionPolicy.NoDelete && !confItem.RetentionPolicyValue.HasValue)
|
||||
{
|
||||
confItem.RetentionPolicyValue = _defaultRetentionPolicyValue;
|
||||
if (confItem.RetentionPolicyValue <= 0) confItem.RetentionPolicyValue = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
confItem.RetentionPolicyValue = null;
|
||||
}
|
||||
|
||||
return Task.FromResult(confItem);
|
||||
}
|
||||
|
||||
private void RefreshCachedConfigObservationKeys()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_refreshTimeout.HasValue) return;
|
||||
|
||||
// Use ConcurrentDictionary's thread-safe features to identify and remove expired keys
|
||||
var keysToRemove = CachedConfigObservationKeys
|
||||
.Where(k => DateTime.Now > k.Value.NextRefresh)
|
||||
.Select(k => k.Key)
|
||||
.ToList();
|
||||
|
||||
foreach (var key in keysToRemove) CachedConfigObservationKeys.TryRemove(key, out _);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("Error refreshing cached config observation keys. Exception: {ex}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<T?> MapConf<T>(T obs, ConfigObservation conf) where T : BasePatientObservation
|
||||
{
|
||||
_logger.LogTrace("Mapping observation: {obs}", obs);
|
||||
|
||||
obs.Name = conf.Name;
|
||||
if (obs is PatientObservation)
|
||||
{
|
||||
var noCalculateStatusWithCodingSystem = _apiSettings.Value.NoCalculateStatusWithCodingSystem;
|
||||
if (noCalculateStatusWithCodingSystem != null &&
|
||||
obs.CodingSystem == noCalculateStatusWithCodingSystem) return obs;
|
||||
if (obs is not PatientObservation pobs)
|
||||
return obs;
|
||||
|
||||
if (conf.MaxAlert != null && (conf.ForceAlert || !pobs.Max.HasValue)) pobs.Max = conf.MaxAlert;
|
||||
|
||||
if (conf.MinAlert.HasValue && (conf.ForceAlert || !pobs.Min.HasValue)) pobs.Min = conf.MinAlert;
|
||||
|
||||
if (conf.MaxWarn.HasValue && (conf.ForceWarn || !pobs.MaxWarn.HasValue)) pobs.MaxWarn = conf.MaxWarn;
|
||||
|
||||
if (conf.MinWarn.HasValue && (conf.ForceWarn || !pobs.MinWarn.HasValue)) pobs.MinWarn = conf.MinWarn;
|
||||
|
||||
if (conf.LevelCondition != null)
|
||||
try
|
||||
{
|
||||
var evalCondition = await CSharpScript.EvaluateAsync(conf.LevelCondition, globals: pobs);
|
||||
if (int.TryParse(evalCondition.ToString(), out var evalInt))
|
||||
pobs.Level = evalInt;
|
||||
else
|
||||
_logger.LogError("Error evaluating condition: {evalCondition} for obs: {pobs}",
|
||||
evalCondition, pobs);
|
||||
}
|
||||
catch (CompilationErrorException e)
|
||||
{
|
||||
_logger.LogError("Error evaluating expression for obs: {obs} error: {diagnostics}", obs,
|
||||
e.Diagnostics);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError("Error evaluating expression for obs: {obs} error: {e}", obs, e);
|
||||
}
|
||||
|
||||
pobs.Status = StatusEnum.Type.Ok;
|
||||
if (pobs.Value.IsNumber())
|
||||
{
|
||||
if (pobs.Min.HasValue && pobs.Min > pobs.Value.ToDouble() &&
|
||||
conf.Alert is null or '<')
|
||||
{
|
||||
pobs.Status = StatusEnum.Type.Alert;
|
||||
pobs.AlertColor = conf.AlertColor;
|
||||
}
|
||||
else if (pobs.Max.HasValue && pobs.Max < pobs.Value.ToDouble() &&
|
||||
conf.Alert is null or '>')
|
||||
{
|
||||
pobs.Status = StatusEnum.Type.Alert;
|
||||
pobs.AlertColor = conf.AlertColor;
|
||||
}
|
||||
else if (pobs.MinWarn.HasValue && pobs.MinWarn > pobs.Value.ToDouble() &&
|
||||
conf.Alert is null or '<')
|
||||
{
|
||||
pobs.Status = StatusEnum.Type.Warning;
|
||||
pobs.WarnColor = conf.WarnColor;
|
||||
}
|
||||
else if (pobs.MaxWarn.HasValue && pobs.MaxWarn < pobs.Value.ToDouble() &&
|
||||
conf.Alert is null or '>')
|
||||
{
|
||||
pobs.Status = StatusEnum.Type.Warning;
|
||||
pobs.WarnColor = conf.WarnColor;
|
||||
}
|
||||
}
|
||||
else if (pobs.Value is string)
|
||||
{
|
||||
if (conf.AlertValues != null && conf.AlertValues.Any() && conf.AlertValues.Contains(pobs.Value))
|
||||
pobs.Status = StatusEnum.Type.Alert;
|
||||
else if (conf.WarningValues != null && conf.WarningValues.Any() &&
|
||||
conf.WarningValues.Contains(pobs.Value)) pobs.Status = StatusEnum.Type.Warning;
|
||||
}
|
||||
|
||||
if (conf.Expires is > 0)
|
||||
{
|
||||
pobs.Expires = conf.Expires;
|
||||
//check if already is expired
|
||||
var expireTime = obs.Time.ToLocalTime().AddSeconds(Convert.ToDouble(conf.Expires));
|
||||
pobs.Expired = DateTime.Now.CompareTo(expireTime) > 0;
|
||||
}
|
||||
|
||||
pobs.ShowOnExpired = conf.ShowOnExpired;
|
||||
|
||||
if (conf.ColorOnExpired != null) pobs.ColorOnExpired = conf.ColorOnExpired;
|
||||
|
||||
if (conf.Persist != null)
|
||||
pobs.Persist = conf.Persist;
|
||||
|
||||
if (conf.UiConfiguration != null && conf.UiConfiguration.Any()) pobs.UiConfiguration = conf.UiConfiguration;
|
||||
|
||||
if (conf.Alarm != null) pobs.Alarm = conf.Alarm;
|
||||
|
||||
if (conf.TimeFromMessageTime)
|
||||
if (pobs.MessageTime.CompareTo(DateTime.MinValue) != 0)
|
||||
pobs.Time = pobs.MessageTime;
|
||||
|
||||
if (pobs.Units == null || conf.ForceUnits) pobs.Units = conf.Units;
|
||||
|
||||
if (conf.CreateObservation != null) pobs.CreateObservation = conf.CreateObservation;
|
||||
|
||||
pobs.CheckObservations = conf.CheckObservations;
|
||||
}
|
||||
|
||||
if (obs is PatientObservationAlarm)
|
||||
{
|
||||
if (obs is not PatientObservationAlarm pobs)
|
||||
return obs;
|
||||
|
||||
if (conf.Expires is > 0)
|
||||
{
|
||||
pobs.Expires = conf.Expires;
|
||||
//check if already is expired
|
||||
var expireTime = obs.Time.ToLocalTime().AddSeconds(Convert.ToDouble(conf.Expires));
|
||||
pobs.Expired = DateTime.Now.CompareTo(expireTime) > 0;
|
||||
}
|
||||
|
||||
if (conf.Persist != null)
|
||||
pobs.Persist = conf.Persist;
|
||||
|
||||
if (conf.Alarm != null) pobs.AlarmConfig = conf.Alarm;
|
||||
|
||||
if (conf.AlertColor != null) pobs.AlertColor = conf.AlertColor;
|
||||
|
||||
if (conf.TimeFromMessageTime)
|
||||
if (pobs.MessageTime.CompareTo(DateTime.MinValue) != 0)
|
||||
pobs.Time = pobs.MessageTime;
|
||||
|
||||
if (pobs.Units == null || conf.ForceUnits) pobs.Units = conf.Units;
|
||||
|
||||
if (conf.CreateObservation != null) pobs.CreateObservation = conf.CreateObservation;
|
||||
|
||||
pobs.CheckObservations = conf.CheckObservations;
|
||||
}
|
||||
|
||||
_logger.LogTrace("Observation mapped: {obs}", obs);
|
||||
|
||||
return obs;
|
||||
}
|
||||
|
||||
private class ConfigObservationCached
|
||||
{
|
||||
public DateTime NextRefresh { get; set; }
|
||||
public ConfigObservation? ConfigObservation { get; set; }
|
||||
}
|
||||
|
||||
private class ConfigObservationKeyCached
|
||||
{
|
||||
public DateTime NextRefresh { get; set; }
|
||||
public string? Key { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user