add smsRecievers field and send alert messages to user device
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
using GreenHome.Application;
|
||||
using GreenHome.Domain;
|
||||
using GreenHome.Sms.Ippanel;
|
||||
using GreenHome.VoiceCall.Avanak;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using static GreenHome.Sms.Ippanel.IppanelSmsService;
|
||||
|
||||
@@ -33,7 +36,7 @@ public sealed class AlertService : IAlertService
|
||||
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
|
||||
var device = await dbContext.Devices
|
||||
@@ -45,24 +48,34 @@ public sealed class AlertService : IAlertService
|
||||
if (device == null)
|
||||
{
|
||||
logger.LogWarning("Device not found: DeviceId={DeviceId}", deviceId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get device settings for location
|
||||
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
|
||||
var conditions = await dbContext.AlertConditions
|
||||
.Include(c => c.Rules)
|
||||
@@ -72,7 +85,7 @@ public sealed class AlertService : IAlertService
|
||||
if (!conditions.Any())
|
||||
{
|
||||
logger.LogDebug("No enabled alert conditions for device: DeviceId={DeviceId}", deviceId);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
List<string> messages = [];
|
||||
// Check each condition
|
||||
foreach (var condition in conditions)
|
||||
{
|
||||
@@ -101,9 +115,28 @@ public sealed class AlertService : IAlertService
|
||||
if (allRulesMatch && condition.Rules.Any())
|
||||
{
|
||||
// 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)
|
||||
@@ -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(
|
||||
Domain.AlertCondition condition,
|
||||
Domain.Device device,
|
||||
List<Domain.User> usersToAlert,
|
||||
List<User> usersToAlert,
|
||||
TelemetryDto telemetry,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user