Files
GreenHomeBack/src/GreenHome.Infrastructure/Services/Device/DeviceSettingsService.cs

139 lines
4.4 KiB
C#

using AutoMapper;
using GreenHome.Application;
using GreenHome.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
namespace GreenHome.Infrastructure.Services.Device;
public sealed class DeviceSettingsService : IDeviceSettingsService
{
private readonly GreenHomeDbContext _dbContext;
private readonly IMapper _mapper;
public DeviceSettingsService(GreenHomeDbContext dbContext, IMapper mapper)
{
_dbContext = dbContext;
_mapper = mapper;
}
public async Task<DeviceSettingsDto?> GetByDeviceIdAsync(int deviceId, CancellationToken cancellationToken)
{
var settings = await _dbContext.DeviceSettings
.Include(x => x.Device)
.Include(x => x.Relays)
.ThenInclude(r => r.Rules)
.AsNoTracking()
.FirstOrDefaultAsync(x => x.DeviceId == deviceId, cancellationToken);
if (settings == null)
return null;
var dto = _mapper.Map<DeviceSettingsDto>(settings);
OrderRelays(dto);
return dto;
}
public async Task<int> CreateAsync(DeviceSettingsDto dto, CancellationToken cancellationToken)
{
var entity = _mapper.Map<Domain.DeviceSettings>(dto);
entity.CreatedAt = DateTime.UtcNow;
entity.UpdatedAt = DateTime.UtcNow;
SyncRelays(entity, dto.Relays ?? new List<DeviceRelayDto>());
_dbContext.DeviceSettings.Add(entity);
await _dbContext.SaveChangesAsync(cancellationToken);
return entity.Id;
}
public async Task UpdateAsync(DeviceSettingsDto dto, CancellationToken cancellationToken)
{
var entity = await _dbContext.DeviceSettings
.Include(x => x.Relays)
.ThenInclude(r => r.Rules)
.FirstOrDefaultAsync(x => x.DeviceId == dto.DeviceId, cancellationToken);
if (entity == null)
throw new InvalidOperationException($"Device settings not found for device ID {dto.DeviceId}");
_mapper.Map(dto, entity);
entity.UpdatedAt = DateTime.UtcNow;
SyncRelays(entity, dto.Relays ?? new List<DeviceRelayDto>());
await _dbContext.SaveChangesAsync(cancellationToken);
}
private static void OrderRelays(DeviceSettingsDto dto)
{
if (dto.Relays == null)
return;
dto.Relays = dto.Relays
.OrderBy(r => r.RelayIndex)
.ToList();
foreach (var relay in dto.Relays)
{
relay.Rules = relay.Rules?
.OrderBy(r => r.Order)
.ToList() ?? new List<DeviceRelayRuleDto>();
}
}
private static void SyncRelays(Domain.DeviceSettings entity, List<DeviceRelayDto> relayDtos)
{
var now = DateTime.UtcNow;
var dtoIndexes = relayDtos.Select(r => r.RelayIndex).ToHashSet();
// حذف رله‌هایی که دیگر در لیست نیستند
foreach (var relay in entity.Relays.Where(r => !dtoIndexes.Contains(r.RelayIndex)).ToList())
{
entity.Relays.Remove(relay);
}
foreach (var dto in relayDtos)
{
var relay = entity.Relays.FirstOrDefault(r => r.RelayIndex == dto.RelayIndex);
if (relay == null)
{
relay = new Domain.DeviceRelay
{
RelayIndex = dto.RelayIndex,
CreatedAt = now
};
entity.Relays.Add(relay);
}
relay.Name = dto.Name ?? string.Empty;
relay.IsEnabled = dto.IsEnabled;
relay.RelayKind = dto.RelayKind;
relay.Mode = dto.Mode;
relay.MinOnMinutes = dto.MinOnMinutes;
relay.MinOffMinutes = dto.MinOffMinutes;
relay.UpdatedAt = now;
SyncRules(relay, dto.Rules ?? new List<DeviceRelayRuleDto>());
}
}
private static void SyncRules(Domain.DeviceRelay relay, List<DeviceRelayRuleDto> ruleDtos)
{
relay.Rules.Clear();
foreach (var dto in ruleDtos.OrderBy(r => r.Order))
{
relay.Rules.Add(new Domain.RelayRule
{
SensorType = dto.SensorType,
ComparisonType = dto.ComparisonType,
Value1 = dto.Value1,
Value2 = dto.Value2,
Action = dto.Action,
TimeType = dto.TimeType,
Order = dto.Order
});
}
}
}