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.DTO; using adas_core.Domain.Models.MongoModels; using Microsoft.Extensions.Logging; using MongoDB.Bson; namespace adas_core.Application.Services; public class DeviceService : IDeviceService { private readonly IDeviceRepository _deviceRepository; private readonly IObservationService _observationService; private readonly IAlarmService _alarmService; private readonly IConfigObservationService _configObservationService; private readonly IPointOfCareService _pointOfCareService; private readonly ILogger _logger; public DeviceService( IDeviceRepository deviceRepository, IPointOfCareService pointOfCareService, ILogger logger, IObservationService observationService, IConfigObservationService configObservationService, IAlarmService alarmService) { _deviceRepository = deviceRepository; _pointOfCareService = pointOfCareService; _logger = logger; _observationService = observationService; _configObservationService = configObservationService; _alarmService = alarmService; } public Device ToEntity(DeviceDto dto) { return new Device() { DeviceType = dto.DeviceType, MacAddr = dto.MacAddr, SerialNumber = dto.SerialNumber, Name = dto.Name, Battery = dto.Battery, Color = dto.Color, Connected = dto.Connected, Ready = dto.Ready, Uuid = dto.Uuid, Key = dto.Key, CreatedAt = dto.CreatedAt, UpdatedAt = dto.UpdatedAt, PointOfCareIds = dto.PointOfCareIds ?? new List(), Settings = dto.Settings ?? new DeviceSettings() }; } public async Task Create(DeviceDto deviceDto) { var device = ToEntity(deviceDto); device.CreatedAt = DateTime.UtcNow; device.UpdatedAt = DateTime.UtcNow; await _deviceRepository.InsertOneAsync(device); return device; } public async Task Delete(ObjectId objectId) { return await _deviceRepository.DeleteAsync(objectId) != null; } public async Task Update(DeviceDto deviceDto) { var device = ToEntity(deviceDto); device.UpdatedAt = DateTime.UtcNow; await _deviceRepository.UpdateOneAsync(device.Id, device); return device; } public async Task ReceiveEvent(DeviceDto deviceDto) { Device? deviceExist = null; if (!string.IsNullOrEmpty(deviceDto.MacAddr)) { deviceExist = await _deviceRepository.FindByMacAddr(deviceDto.MacAddr); } if (deviceExist == null && deviceDto.SerialNumber != null) { deviceExist = await _deviceRepository.FindBySerialNumber(deviceDto.SerialNumber); } if (deviceExist == null && deviceDto.Uuid != null) { deviceExist = await _deviceRepository.FindByUuid(deviceDto.Uuid); } if (deviceExist == null && deviceDto.Key != null) { deviceExist = await _deviceRepository.FindByKey(deviceDto.Key); } if (deviceExist == null) { deviceExist = ToEntity(deviceDto); deviceExist.CreatedAt = DateTime.UtcNow; deviceExist.UpdatedAt = DateTime.UtcNow; await _deviceRepository.InsertOneAsync(deviceExist); } else { await _deviceRepository.UpdateDeviceStats(deviceExist.Id, deviceDto); } switch (deviceDto.DeviceType) { case DeviceType.Unknown: break; case DeviceType.Button: await ManageDeviceButton(deviceExist, deviceDto); break; } return deviceExist; } private async Task ManageDeviceButton(Device deviceExist, DeviceDto deviceDto) { if (deviceExist.Settings?.Action?.Type != null && deviceDto.Event?.ClickType != null) { switch (deviceExist.Settings.Action.Type) { case DeviceActionType.SendObs: await SendObservationOnAction(deviceExist.Settings.Action, deviceDto.Event.ClickType.Value, deviceExist.PointOfCareIds); break; case DeviceActionType.SendAlarm: await SendAlarmOnAction(deviceExist.Settings.Action, deviceDto.Event.ClickType.Value, deviceExist.PointOfCareIds); break; } } } private async Task SendAlarmOnAction( DeviceAction settingsAction, ClickType eventClickType, List deviceExistPointOfCareIds) { var configObs = await _configObservationService.GetConfigById(settingsAction.ConfigObservationId); if(configObs == null) return; var obsData = new ObservationData { Code = configObs.Code, CodingSystem = configObs.CodingSystem, Time = DateTime.UtcNow, Text = configObs.Name, }; var obs = new PatientObservationAlarm { InactivationState = new InactivationState{ Visual = AlarmEnum.AudioVideoState.Enabled, Audio = AlarmEnum.AudioVideoState.Enabled}, MessageTime = DateTime.UtcNow, Persist = true, Code = obsData.Code, CodingSystem = obsData.CodingSystem, Name = configObs.Name, Time = DateTime.UtcNow }; foreach (var pocId in deviceExistPointOfCareIds) { var data = await _pointOfCareService.GetInfo(pocId, null, true); if (data != null && data.Patient?.Id != null) { obs.PatientId = data.Patient.Id; obs.Patient = data.Patient; switch (eventClickType) { case ClickType.SingleClick: if(settingsAction.ValueOnSingleClick == null) return; obs.Value = settingsAction.ValueOnSingleClick; break; case ClickType.DoubleClick: if(settingsAction.ValueOnDoubleClick == null) return; obs.Value = settingsAction.ValueOnDoubleClick; break; case ClickType.Hold: if(settingsAction.ValueOnHoldClick == null) return; obs.Value = settingsAction.ValueOnHoldClick; break; } // Process Obs on service await _alarmService.ProcessAlarmObservations(new List{obs},new List(){new (){Name = configObs.Name, Value = obs.Value, Code = obsData.Code, CodingSystem = obsData.CodingSystem}}, data.Patient, DateTime.UtcNow, obsData); } } } private async Task SendObservationOnAction( DeviceAction settingsAction, ClickType eventClickType, List deviceExistPointOfCareIds) { var configObs = await _configObservationService.GetConfigById(settingsAction.ConfigObservationId); if(configObs == null) return; var obsData = new ObservationData { Code = configObs.Code, CodingSystem = configObs.CodingSystem, Time = DateTime.UtcNow, Text = configObs.Name, }; var obs = new PatientObservation { MessageTime = DateTime.UtcNow, Persist = true, Code = obsData.Code, CodingSystem = obsData.CodingSystem, Name = configObs.Name, Time = DateTime.UtcNow }; foreach (var pocId in deviceExistPointOfCareIds) { var data = await _pointOfCareService.GetInfo(pocId, null, true); if (data != null && data.Patient?.Id != null) { obs.PatientId = data.Patient.Id; obs.Patient = data.Patient; switch (eventClickType) { case ClickType.SingleClick: if(settingsAction.ValueOnSingleClick == null) return; obs.Value = settingsAction.ValueOnSingleClick; break; case ClickType.DoubleClick: if(settingsAction.ValueOnDoubleClick == null) return; obs.Value = settingsAction.ValueOnDoubleClick; break; case ClickType.Hold: if(settingsAction.ValueOnHoldClick == null) return; obs.Value = settingsAction.ValueOnHoldClick; break; } // Process Obs on service _observationService.ProcessObservations(new List{obs}, data.Patient, DateTime.UtcNow, obsData); } } } }