add smsRecievers field and send alert messages to user device
This commit is contained in:
@@ -25,32 +25,44 @@ public class TelemetryController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("AddData")]
|
[HttpGet("AddData")]
|
||||||
public async Task<ActionResult<int>> Create([FromQuery] TelemetryDto telementry, CancellationToken cancellationToken)
|
public async Task<ActionResult<string>> Create([FromQuery] TelemetryDto telementry, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
||||||
telementry.TimestampUtc = DateTime.UtcNow;
|
telementry.TimestampUtc = DateTime.UtcNow;
|
||||||
var id = await telemetryService.AddAsync(telementry, cancellationToken);
|
var id = await telemetryService.AddAsync(telementry, cancellationToken);
|
||||||
|
|
||||||
// Check and send alerts if needed (fire and forget)
|
string? message;
|
||||||
_ = Task.Run(async () =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Get deviceId from the saved telemetry record
|
|
||||||
var deviceId = telementry.DeviceId;
|
|
||||||
if (deviceId > 0)
|
|
||||||
{
|
|
||||||
await alertService.CheckAndSendAlertsAsync(deviceId, telementry, cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// Log error but don't fail the request
|
|
||||||
// Errors are logged in AlertService
|
|
||||||
}
|
|
||||||
}, cancellationToken);
|
|
||||||
|
|
||||||
return Ok(id);
|
var deviceId = telementry.DeviceId;
|
||||||
|
if(deviceId > 0)
|
||||||
|
{
|
||||||
|
message = await alertService.CheckAndSendAlertsAsync(deviceId, telementry, cancellationToken);
|
||||||
|
if(!string.IsNullOrEmpty(message))
|
||||||
|
{
|
||||||
|
return Ok(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check and send alerts if needed (fire and forget)
|
||||||
|
// _ = Task.Run(async () =>
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // Get deviceId from the saved telemetry record
|
||||||
|
// var deviceId = telementry.DeviceId;
|
||||||
|
// if (deviceId > 0)
|
||||||
|
// {
|
||||||
|
// await alertService.CheckAndSendAlertsAsync(deviceId, telementry, cancellationToken);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch
|
||||||
|
// {
|
||||||
|
// // Log error but don't fail the request
|
||||||
|
// // Errors are logged in AlertService
|
||||||
|
// }
|
||||||
|
// }, cancellationToken);
|
||||||
|
|
||||||
|
return Ok(id + "");
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("minmax")]
|
[HttpGet("minmax")]
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public sealed class TelemetryDto
|
|||||||
public int GasPPM { get; set; }
|
public int GasPPM { get; set; }
|
||||||
public decimal? Voltage { get; set; }
|
public decimal? Voltage { get; set; }
|
||||||
public byte? Power { get; set; }
|
public byte? Power { get; set; }
|
||||||
|
public byte? OldPower { get; set; }
|
||||||
public decimal Lux { get; set; }
|
public decimal Lux { get; set; }
|
||||||
public int? PersianYear { get; set; }
|
public int? PersianYear { get; set; }
|
||||||
public int? PersianMonth { get; set; }
|
public int? PersianMonth { get; set; }
|
||||||
@@ -133,6 +134,7 @@ public sealed class DeviceSettingsDto
|
|||||||
public int UploadIntervalMin { get; set; } = 5;
|
public int UploadIntervalMin { get; set; } = 5;
|
||||||
public string DevicePhoneNumber { get; set; } = string.Empty;
|
public string DevicePhoneNumber { get; set; } = string.Empty;
|
||||||
public Domain.SimCardType? SimCardType { get; set; }
|
public Domain.SimCardType? SimCardType { get; set; }
|
||||||
|
public string SmsRecievers { get; set; } = string.Empty;
|
||||||
public string? TokenCode { get; set; }
|
public string? TokenCode { get; set; }
|
||||||
public string? VerificationCode { get; set; }
|
public string? VerificationCode { get; set; }
|
||||||
public DateTime? TokenExpiresAt { get; set; }
|
public DateTime? TokenExpiresAt { get; set; }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ namespace GreenHome.Application;
|
|||||||
|
|
||||||
public interface IAlertService
|
public interface IAlertService
|
||||||
{
|
{
|
||||||
Task CheckAndSendAlertsAsync(int deviceId, TelemetryDto telemetry, CancellationToken cancellationToken);
|
Task<string?> CheckAndSendAlertsAsync(int deviceId, TelemetryDto telemetry, CancellationToken cancellationToken);
|
||||||
Task SendPowerOutageAlertAsync(int deviceId, CancellationToken cancellationToken);
|
Task SendPowerOutageAlertAsync(int deviceId, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,6 @@ public sealed class Device
|
|||||||
public User User { get; set; } = null!;
|
public User User { get; set; } = null!;
|
||||||
public string Location { get; set; } = string.Empty; // varchar(250)
|
public string Location { get; set; } = string.Empty; // varchar(250)
|
||||||
public string NeshanLocation { get; set; } = string.Empty; // varchar(80)
|
public string NeshanLocation { get; set; } = string.Empty; // varchar(80)
|
||||||
public ICollection<DeviceUser> DeviceUsers { get; set; } = new List<DeviceUser>();
|
public ICollection<DeviceUser> DeviceUsers { get; set; } = [];
|
||||||
|
public ICollection<DeviceSettings> DeviceSettings { get; set; } = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace GreenHome.Domain;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace GreenHome.Domain;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// نوع سیم کارت
|
/// نوع سیم کارت
|
||||||
@@ -81,6 +83,9 @@ public sealed class DeviceSettings
|
|||||||
/// نوع سیم کارت
|
/// نوع سیم کارت
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SimCardType? SimCardType { get; set; }
|
public SimCardType? SimCardType { get; set; }
|
||||||
|
|
||||||
|
[StringLength(120)]
|
||||||
|
public string SmsRecievers { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// کد توکن (5 رقمی)
|
/// کد توکن (5 رقمی)
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
using GreenHome.Application;
|
using GreenHome.Application;
|
||||||
|
using GreenHome.Domain;
|
||||||
using GreenHome.Sms.Ippanel;
|
using GreenHome.Sms.Ippanel;
|
||||||
using GreenHome.VoiceCall.Avanak;
|
using GreenHome.VoiceCall.Avanak;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Globalization;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using static GreenHome.Sms.Ippanel.IppanelSmsService;
|
using static GreenHome.Sms.Ippanel.IppanelSmsService;
|
||||||
|
|
||||||
@@ -33,7 +36,7 @@ public sealed class AlertService : IAlertService
|
|||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CheckAndSendAlertsAsync(int deviceId, TelemetryDto telemetry, CancellationToken cancellationToken)
|
public async Task<string?> CheckAndSendAlertsAsync(int deviceId, TelemetryDto telemetry, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Get device with all users who should receive alerts
|
// Get device with all users who should receive alerts
|
||||||
var device = await dbContext.Devices
|
var device = await dbContext.Devices
|
||||||
@@ -45,24 +48,34 @@ public sealed class AlertService : IAlertService
|
|||||||
if (device == null)
|
if (device == null)
|
||||||
{
|
{
|
||||||
logger.LogWarning("Device not found: DeviceId={DeviceId}", deviceId);
|
logger.LogWarning("Device not found: DeviceId={DeviceId}", deviceId);
|
||||||
return;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
// Get all users who should receive alerts
|
|
||||||
var usersToAlert = device.DeviceUsers
|
|
||||||
.Where(du => du.ReceiveAlerts)
|
|
||||||
.Select(du => du.User)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (usersToAlert.Count == 0)
|
|
||||||
{
|
|
||||||
logger.LogInformation("No users with ReceiveAlerts enabled for device: DeviceId={DeviceId}", deviceId);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get device settings for location
|
// Get device settings for location
|
||||||
var settings = await deviceSettingsService.GetByDeviceIdAsync(deviceId, cancellationToken);
|
var settings = await deviceSettingsService.GetByDeviceIdAsync(deviceId, cancellationToken);
|
||||||
|
|
||||||
|
|
||||||
|
var recievers = device.User.Mobile;
|
||||||
|
recievers += "," + (settings?.SmsRecievers ?? "");
|
||||||
|
|
||||||
|
recievers = string.Join(",",
|
||||||
|
recievers
|
||||||
|
.Split(',')
|
||||||
|
.Select(x => x.Trim())
|
||||||
|
.Where(x => x.Length > 0)
|
||||||
|
);
|
||||||
|
// Get all users who should receive alerts
|
||||||
|
// var usersToAlert = device.DeviceUsers
|
||||||
|
// .Where(du => du.ReceiveAlerts)
|
||||||
|
// .Select(du => du.User)
|
||||||
|
// .ToList();
|
||||||
|
|
||||||
|
if (recievers.Length == 0)
|
||||||
|
{
|
||||||
|
logger.LogInformation("No users with ReceiveAlerts enabled for device: DeviceId={DeviceId}", deviceId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Get all enabled alert conditions for this device
|
// Get all enabled alert conditions for this device
|
||||||
var conditions = await dbContext.AlertConditions
|
var conditions = await dbContext.AlertConditions
|
||||||
.Include(c => c.Rules)
|
.Include(c => c.Rules)
|
||||||
@@ -72,7 +85,7 @@ public sealed class AlertService : IAlertService
|
|||||||
if (!conditions.Any())
|
if (!conditions.Any())
|
||||||
{
|
{
|
||||||
logger.LogDebug("No enabled alert conditions for device: DeviceId={DeviceId}", deviceId);
|
logger.LogDebug("No enabled alert conditions for device: DeviceId={DeviceId}", deviceId);
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if it's daytime or nighttime
|
// Determine if it's daytime or nighttime
|
||||||
@@ -82,6 +95,7 @@ public sealed class AlertService : IAlertService
|
|||||||
isDaytime = sunCalculatorService.IsDaytime(DateTime.UtcNow, settings.Latitude.Value, settings.Longitude.Value);
|
isDaytime = sunCalculatorService.IsDaytime(DateTime.UtcNow, settings.Latitude.Value, settings.Longitude.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<string> messages = [];
|
||||||
// Check each condition
|
// Check each condition
|
||||||
foreach (var condition in conditions)
|
foreach (var condition in conditions)
|
||||||
{
|
{
|
||||||
@@ -101,9 +115,28 @@ public sealed class AlertService : IAlertService
|
|||||||
if (allRulesMatch && condition.Rules.Any())
|
if (allRulesMatch && condition.Rules.Any())
|
||||||
{
|
{
|
||||||
// All rules passed, send alert if cooldown period has passed
|
// All rules passed, send alert if cooldown period has passed
|
||||||
await SendAlertForConditionAsync(condition, device, usersToAlert, telemetry, cancellationToken);
|
// await SendAlertForConditionAsync(condition, device, usersToAlert, telemetry, cancellationToken);
|
||||||
|
string? message = await GetAlertMessage(condition, device, device.User, telemetry, cancellationToken);
|
||||||
|
if(message != null && message.Length > 0)
|
||||||
|
messages.Add(message);
|
||||||
|
// return message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(telemetry.OldPower == 0 && telemetry.Power == 1)
|
||||||
|
{
|
||||||
|
messages.Add("برق دستگاه متصل شد");
|
||||||
|
}
|
||||||
|
else if(telemetry.OldPower == 1 && telemetry.Power == 0)
|
||||||
|
{
|
||||||
|
messages.Add("برق دستگاه قطع شد");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(messages.Any())
|
||||||
|
{
|
||||||
|
return $"tt{recievers}#{string.Join("@", messages)}";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckRule(Domain.AlertRule rule, TelemetryDto telemetry)
|
private bool CheckRule(Domain.AlertRule rule, TelemetryDto telemetry)
|
||||||
@@ -130,10 +163,59 @@ public sealed class AlertService : IAlertService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<string?> GetAlertMessage(
|
||||||
|
Domain.AlertCondition condition,
|
||||||
|
Domain.Device device,
|
||||||
|
User user,
|
||||||
|
TelemetryDto telemetry,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Determine cooldown based on notification type
|
||||||
|
var cooldownMinutes = condition.NotificationType == Domain.AlertNotificationType.Call
|
||||||
|
? condition.CallCooldownMinutes
|
||||||
|
: condition.SmsCooldownMinutes;
|
||||||
|
|
||||||
|
// Build alert message once
|
||||||
|
var message = BuildAlertMessage(condition, device.DeviceName, telemetry);
|
||||||
|
var sentAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
var cooldownTime = sentAt.AddMinutes(-cooldownMinutes);
|
||||||
|
var recentAlert = await dbContext.AlertNotifications
|
||||||
|
.Where(a => a.DeviceId == device.Id &&
|
||||||
|
a.UserId == user.Id &&
|
||||||
|
a.AlertConditionId == condition.Id &&
|
||||||
|
a.SentAt >= cooldownTime)
|
||||||
|
.FirstOrDefaultAsync(cancellationToken);
|
||||||
|
|
||||||
|
if (recentAlert != null)
|
||||||
|
{
|
||||||
|
logger.LogInformation("Alert skipped due to cooldown: DeviceId={DeviceId}, UserId={UserId}, ConditionId={ConditionId}",
|
||||||
|
device.Id, user.Id, condition.Id);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var notification = new Domain.AlertNotification
|
||||||
|
{
|
||||||
|
DeviceId = device.Id,
|
||||||
|
UserId = user.Id,
|
||||||
|
AlertConditionId = condition.Id,
|
||||||
|
NotificationType = condition.NotificationType,
|
||||||
|
Message = message,
|
||||||
|
//MessageOutboxIds = messageOutboxIds,
|
||||||
|
//ErrorMessage = errorMessage,
|
||||||
|
SentAt = sentAt,
|
||||||
|
IsSent = true
|
||||||
|
};
|
||||||
|
|
||||||
|
dbContext.AlertNotifications.Add(notification);
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SendAlertForConditionAsync(
|
private async Task SendAlertForConditionAsync(
|
||||||
Domain.AlertCondition condition,
|
Domain.AlertCondition condition,
|
||||||
Domain.Device device,
|
Domain.Device device,
|
||||||
List<Domain.User> usersToAlert,
|
List<User> usersToAlert,
|
||||||
TelemetryDto telemetry,
|
TelemetryDto telemetry,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public sealed class GreenHomeDbContext : DbContext
|
|||||||
b.Property(x => x.SoilPercent).HasColumnType("decimal(18,2)");
|
b.Property(x => x.SoilPercent).HasColumnType("decimal(18,2)");
|
||||||
b.Property(x => x.Lux).HasColumnType("decimal(18,2)");
|
b.Property(x => x.Lux).HasColumnType("decimal(18,2)");
|
||||||
b.Property(x => x.PersianDate).HasMaxLength(10);
|
b.Property(x => x.PersianDate).HasMaxLength(10);
|
||||||
|
b.Property(x => x.Voltage).HasColumnType("decimal(18,2)");
|
||||||
b.HasIndex(x => new { x.DeviceId, x.PersianYear, x.PersianMonth });
|
b.HasIndex(x => new { x.DeviceId, x.PersianYear, x.PersianMonth });
|
||||||
b.HasIndex(x => new { x.DeviceId, x.TimestampUtc });
|
b.HasIndex(x => new { x.DeviceId, x.TimestampUtc });
|
||||||
b.HasIndex(x => new { x.DeviceId, x.ServerTimestampUtc });
|
b.HasIndex(x => new { x.DeviceId, x.ServerTimestampUtc });
|
||||||
@@ -71,6 +72,7 @@ public sealed class GreenHomeDbContext : DbContext
|
|||||||
b.Property(x => x.MinimumSmsIntervalMinutes).HasDefaultValue(15);
|
b.Property(x => x.MinimumSmsIntervalMinutes).HasDefaultValue(15);
|
||||||
b.Property(x => x.MinimumCallIntervalMinutes).HasDefaultValue(60);
|
b.Property(x => x.MinimumCallIntervalMinutes).HasDefaultValue(60);
|
||||||
b.Property(x => x.AreaSquareMeters).HasColumnType("decimal(18,2)");
|
b.Property(x => x.AreaSquareMeters).HasColumnType("decimal(18,2)");
|
||||||
|
b.Property(x => x.SmsRecievers).HasMaxLength(120);
|
||||||
b.HasOne(x => x.Device)
|
b.HasOne(x => x.Device)
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey(x => x.DeviceId)
|
.HasForeignKey(x => x.DeviceId)
|
||||||
|
|||||||
1240
src/GreenHome.Infrastructure/Migrations/20260107144244_AddSmsRecievers.Designer.cs
generated
Normal file
1240
src/GreenHome.Infrastructure/Migrations/20260107144244_AddSmsRecievers.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,60 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace GreenHome.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddSmsRecievers : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "DeviceId1",
|
||||||
|
table: "DeviceSettings",
|
||||||
|
type: "int",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "SmsRecievers",
|
||||||
|
table: "DeviceSettings",
|
||||||
|
type: "nvarchar(120)",
|
||||||
|
maxLength: 120,
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_DeviceSettings_DeviceId1",
|
||||||
|
table: "DeviceSettings",
|
||||||
|
column: "DeviceId1");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_DeviceSettings_Devices_DeviceId1",
|
||||||
|
table: "DeviceSettings",
|
||||||
|
column: "DeviceId1",
|
||||||
|
principalTable: "Devices",
|
||||||
|
principalColumn: "Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_DeviceSettings_Devices_DeviceId1",
|
||||||
|
table: "DeviceSettings");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_DeviceSettings_DeviceId1",
|
||||||
|
table: "DeviceSettings");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "DeviceId1",
|
||||||
|
table: "DeviceSettings");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "SmsRecievers",
|
||||||
|
table: "DeviceSettings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -590,6 +590,9 @@ namespace GreenHome.Infrastructure.Migrations
|
|||||||
b.Property<int>("DeviceId")
|
b.Property<int>("DeviceId")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("DeviceId1")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("DevicePhoneNumber")
|
b.Property<string>("DevicePhoneNumber")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
@@ -623,6 +626,11 @@ namespace GreenHome.Infrastructure.Migrations
|
|||||||
b.Property<int?>("SimCardType")
|
b.Property<int?>("SimCardType")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("SmsRecievers")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(120)
|
||||||
|
.HasColumnType("nvarchar(120)");
|
||||||
|
|
||||||
b.Property<string>("TokenCode")
|
b.Property<string>("TokenCode")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
@@ -643,6 +651,8 @@ namespace GreenHome.Infrastructure.Migrations
|
|||||||
b.HasIndex("DeviceId")
|
b.HasIndex("DeviceId")
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("DeviceId1");
|
||||||
|
|
||||||
b.ToTable("DeviceSettings", (string)null);
|
b.ToTable("DeviceSettings", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1127,6 +1137,10 @@ namespace GreenHome.Infrastructure.Migrations
|
|||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("GreenHome.Domain.Device", null)
|
||||||
|
.WithMany("DeviceSettings")
|
||||||
|
.HasForeignKey("DeviceId1");
|
||||||
|
|
||||||
b.Navigation("Device");
|
b.Navigation("Device");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1198,6 +1212,8 @@ namespace GreenHome.Infrastructure.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("GreenHome.Domain.Device", b =>
|
modelBuilder.Entity("GreenHome.Domain.Device", b =>
|
||||||
{
|
{
|
||||||
|
b.Navigation("DeviceSettings");
|
||||||
|
|
||||||
b.Navigation("DeviceUsers");
|
b.Navigation("DeviceUsers");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user