feat: add device relay and telemetry support

This commit is contained in:
2026-09-03 07:49:10 +03:30
parent 9eaa5b70d1
commit 6297df7dfd
18 changed files with 2077 additions and 20 deletions

View File

@@ -20,10 +20,17 @@ public sealed class DeviceSettingsService : IDeviceSettingsService
{
var settings = await _dbContext.DeviceSettings
.Include(x => x.Device)
.Include(x => x.Relays)
.ThenInclude(r => r.Rules)
.AsNoTracking()
.FirstOrDefaultAsync(x => x.DeviceId == deviceId, cancellationToken);
return settings != null ? _mapper.Map<DeviceSettingsDto>(settings) : null;
if (settings == null)
return null;
var dto = _mapper.Map<DeviceSettingsDto>(settings);
OrderRelays(dto);
return dto;
}
public async Task<int> CreateAsync(DeviceSettingsDto dto, CancellationToken cancellationToken)
@@ -32,6 +39,8 @@ public sealed class DeviceSettingsService : IDeviceSettingsService
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;
@@ -40,6 +49,8 @@ public sealed class DeviceSettingsService : IDeviceSettingsService
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)
@@ -48,6 +59,80 @@ public sealed class DeviceSettingsService : IDeviceSettingsService
_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
});
}
}
}