139 lines
4.4 KiB
C#
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
|
|
});
|
|
}
|
|
}
|
|
}
|