version 3

This commit is contained in:
2025-12-17 00:34:41 +03:30
parent 139924db94
commit 74e8480a68
38 changed files with 5399 additions and 70 deletions

View File

@@ -70,6 +70,10 @@ public class DailyReportService : IDailyReportService
throw new InvalidOperationException($"دستگاه با شناسه {request.DeviceId} یافت نشد");
}
// Get device settings (including ProductType if available)
var deviceSettings = await _context.DeviceSettings
.FirstOrDefaultAsync(ds => ds.DeviceId == request.DeviceId, cancellationToken);
// Query telemetry data for the specified date
var telemetryRecords = await _context.TelemetryRecords
.Where(t => t.DeviceId == request.DeviceId && t.PersianDate == request.PersianDate)
@@ -115,7 +119,15 @@ public class DailyReportService : IDailyReportService
}
// Prepare the question for AI
var question = $@"این داده‌های تلمتری یک روز ({request.PersianDate}) از یک گلخانه هوشمند هستند:
var productTypeInfo = !string.IsNullOrWhiteSpace(deviceSettings?.ProductType)
? $" محصول کشت شده: {deviceSettings.ProductType}."
: string.Empty;
var areaInfo = deviceSettings?.AreaSquareMeters != null
? $" مساحت گلخانه: {deviceSettings.AreaSquareMeters:F1} متر مربع."
: string.Empty;
var question = $@"این داده‌های تلمتری یک روز ({request.PersianDate}) از یک گلخانه هوشمند هستند.{productTypeInfo}{areaInfo}
{dataBuilder}
@@ -123,7 +135,7 @@ public class DailyReportService : IDailyReportService
1. وضعیت کلی دما، رطوبت، نور و کیفیت هوا
2. روندهای مشاهده شده در طول روز
3. هر گونه نکته یا هشدار مهم
4. پیشنهادات برای بهبود شرایط گلخانه
4. پیشنهادات برای بهبود شرایط گلخانه{(productTypeInfo != string.Empty ? " و رشد بهتر محصول" : string.Empty)}
خلاصه و مفید باش (حداکثر 300 کلمه).";
@@ -133,12 +145,16 @@ public class DailyReportService : IDailyReportService
try
{
var systemMessage = !string.IsNullOrWhiteSpace(deviceSettings?.ProductType)
? $"تو یک متخصص کشاورزی و گلخانه هستی که در کشت {deviceSettings.ProductType} تخصص داری و داده‌های تلمتری رو تحلیل می‌کنی."
: "تو یک متخصص کشاورزی و گلخانه هستی که داده‌های تلمتری رو تحلیل می‌کنی.";
var chatRequest = new ChatRequest
{
Model = "deepseek-chat",
Messages = new List<ChatMessage>
{
new() { Role = "system", Content = "تو یک متخصص کشاورزی و گلخانه هستی که داده‌های تلمتری رو تحلیل می‌کنی." },
new() { Role = "system", Content = systemMessage },
new() { Role = "user", Content = question }
},
Temperature = 0.7
@@ -225,5 +241,239 @@ public class DailyReportService : IDailyReportService
return true;
}
public async Task<DailyReportResponse> GetWeeklyAnalysisAsync(
WeeklyAnalysisRequest request,
CancellationToken cancellationToken)
{
// Get device info
var device = await _context.Devices
.FirstOrDefaultAsync(d => d.Id == request.DeviceId, cancellationToken);
if (device == null)
{
throw new InvalidOperationException($"دستگاه با شناسه {request.DeviceId} یافت نشد");
}
// Get device settings
var deviceSettings = await _context.DeviceSettings
.FirstOrDefaultAsync(ds => ds.DeviceId == request.DeviceId, cancellationToken);
// Query telemetry data for the week
var telemetryRecords = await _context.TelemetryRecords
.Where(t => t.DeviceId == request.DeviceId &&
string.Compare(t.PersianDate, request.StartDate) >= 0 &&
string.Compare(t.PersianDate, request.EndDate) <= 0)
.OrderBy(t => t.TimestampUtc)
.Select(t => new
{
t.TimestampUtc,
t.TemperatureC,
t.HumidityPercent,
t.Lux,
t.GasPPM,
t.PersianDate
})
.ToListAsync(cancellationToken);
if (telemetryRecords.Count == 0)
{
throw new InvalidOperationException(
$"هیچ رکوردی برای دستگاه {request.DeviceId} در بازه {request.StartDate} تا {request.EndDate} یافت نشد");
}
// Sample 1 per 100 records
var sampledRecords = telemetryRecords
.Select((record, index) => new { record, index })
.Where(x => x.index % 100 == 0)
.Select(x => x.record)
.ToList();
_logger.LogInformation(
"تعداد {TotalCount} رکورد یافت شد. نمونه‌برداری هفتگی: {SampledCount} رکورد",
telemetryRecords.Count, sampledRecords.Count);
// Build the data string
var dataBuilder = new StringBuilder();
dataBuilder.AppendLine("تاریخ | زمان | دما (°C) | رطوبت (%) | نور (Lux) | CO (PPM)");
dataBuilder.AppendLine("---------|----------|----------|-----------|-----------|----------");
foreach (var record in sampledRecords)
{
var localTime = record.TimestampUtc.AddHours(3.5);
dataBuilder.AppendLine(
$"{record.PersianDate} | {localTime:HH:mm} | {record.TemperatureC:F1} | {record.HumidityPercent:F1} | {record.Lux:F1} | {record.GasPPM}");
}
// Prepare AI prompt
var productTypeInfo = !string.IsNullOrWhiteSpace(deviceSettings?.ProductType)
? $" محصول کشت شده: {deviceSettings.ProductType}."
: string.Empty;
var areaInfo = deviceSettings?.AreaSquareMeters != null
? $" مساحت گلخانه: {deviceSettings.AreaSquareMeters:F1} متر مربع."
: string.Empty;
var question = $@"این داده‌های تلمتری یک هفته ({request.StartDate} تا {request.EndDate}) از یک گلخانه هوشمند هستند.{productTypeInfo}{areaInfo}
{dataBuilder}
لطفاً یک تحلیل جامع هفتگی بده که شامل:
1. خلاصه روند هفتگی دما، رطوبت، نور و کیفیت هوا
2. مقایسه شرایط در روزهای مختلف هفته
3. نکات و هشدارهای مهم
4. توصیه‌ها برای هفته آینده
خلاصه و کاربردی باش (حداکثر 500 کلمه).";
var systemMessage = !string.IsNullOrWhiteSpace(deviceSettings?.ProductType)
? $"تو یک متخصص کشاورزی و گلخانه هستی که در کشت {deviceSettings.ProductType} تخصص داری و داده‌های تلمتری رو تحلیل می‌کنی."
: "تو یک متخصص کشاورزی و گلخانه هستی که داده‌های تلمتری رو تحلیل می‌کنی.";
// Send to DeepSeek
var stopwatch = Stopwatch.StartNew();
var chatRequest = new ChatRequest
{
Model = "deepseek-chat",
Messages = new List<ChatMessage>
{
new() { Role = "system", Content = systemMessage },
new() { Role = "user", Content = question }
},
Temperature = 0.7
};
var aiResponse = await _deepSeekService.AskAsync(chatRequest, cancellationToken);
stopwatch.Stop();
if (aiResponse?.Choices == null || aiResponse.Choices.Count == 0 ||
string.IsNullOrWhiteSpace(aiResponse.Choices[0].Message?.Content))
{
throw new InvalidOperationException("پاسخ نامعتبر از سرویس هوش مصنوعی");
}
return new DailyReportResponse
{
Id = 0,
DeviceId = request.DeviceId,
DeviceName = device.DeviceName,
PersianDate = $"{request.StartDate} تا {request.EndDate}",
Analysis = aiResponse.Choices[0].Message!.Content,
RecordCount = telemetryRecords.Count,
SampledRecordCount = sampledRecords.Count,
TotalTokens = aiResponse.Usage?.TotalTokens ?? 0,
CreatedAt = DateTime.UtcNow,
FromCache = false
};
}
public async Task<DailyReportResponse> GetMonthlyAnalysisAsync(
MonthlyAnalysisRequest request,
CancellationToken cancellationToken)
{
// Get device info
var device = await _context.Devices
.FirstOrDefaultAsync(d => d.Id == request.DeviceId, cancellationToken);
if (device == null)
{
throw new InvalidOperationException($"دستگاه با شناسه {request.DeviceId} یافت نشد");
}
// Get device settings
var deviceSettings = await _context.DeviceSettings
.FirstOrDefaultAsync(ds => ds.DeviceId == request.DeviceId, cancellationToken);
// Get all daily reports for this month
var dailyReports = await _context.DailyReports
.Where(dr => dr.DeviceId == request.DeviceId &&
dr.PersianYear == request.Year &&
dr.PersianMonth == request.Month)
.OrderBy(dr => dr.PersianDay)
.Select(dr => new { dr.PersianDate, dr.Analysis })
.ToListAsync(cancellationToken);
if (dailyReports.Count == 0)
{
throw new InvalidOperationException(
$"هیچ تحلیل روزانه‌ای برای دستگاه {request.DeviceId} در ماه {request.Month} سال {request.Year} یافت نشد");
}
// Build summary of daily analyses
var summaryBuilder = new StringBuilder();
summaryBuilder.AppendLine($"تحلیل‌های روزانه ماه {request.Month} سال {request.Year}:");
summaryBuilder.AppendLine();
foreach (var report in dailyReports)
{
summaryBuilder.AppendLine($"📅 {report.PersianDate}:");
summaryBuilder.AppendLine(report.Analysis);
summaryBuilder.AppendLine();
summaryBuilder.AppendLine("---");
summaryBuilder.AppendLine();
}
// Prepare AI prompt
var productTypeInfo = !string.IsNullOrWhiteSpace(deviceSettings?.ProductType)
? $" محصول کشت شده: {deviceSettings.ProductType}."
: string.Empty;
var areaInfo = deviceSettings?.AreaSquareMeters != null
? $" مساحت گلخانه: {deviceSettings.AreaSquareMeters:F1} متر مربع."
: string.Empty;
var question = $@"این تحلیل‌های روزانه یک ماه ({request.Month}/{request.Year}) از یک گلخانه هوشمند هستند.{productTypeInfo}{areaInfo}
{summaryBuilder}
لطفاً یک تحلیل جامع ماهانه بده که شامل:
1. خلاصه کلی عملکرد ماه
2. روندهای اصلی و تغییرات مهم
3. نقاط قوت و ضعف
4. توصیه‌های کلیدی برای ماه آینده
5. نکات مهم برای بهبود بهره‌وری
جامع و کاربردی باش (حداکثر 800 کلمه).";
var systemMessage = !string.IsNullOrWhiteSpace(deviceSettings?.ProductType)
? $"تو یک متخصص کشاورزی و گلخانه هستی که در کشت {deviceSettings.ProductType} تخصص داری. تحلیل‌های روزانه رو بررسی کن و یک جمع‌بندی ماهانه جامع ارائه بده."
: "تو یک متخصص کشاورزی و گلخانه هستی. تحلیل‌های روزانه رو بررسی کن و یک جمع‌بندی ماهانه جامع ارائه بده.";
// Send to DeepSeek
var stopwatch = Stopwatch.StartNew();
var chatRequest = new ChatRequest
{
Model = "deepseek-chat",
Messages = new List<ChatMessage>
{
new() { Role = "system", Content = systemMessage },
new() { Role = "user", Content = question }
},
Temperature = 0.7
};
var aiResponse = await _deepSeekService.AskAsync(chatRequest, cancellationToken);
stopwatch.Stop();
if (aiResponse?.Choices == null || aiResponse.Choices.Count == 0 ||
string.IsNullOrWhiteSpace(aiResponse.Choices[0].Message?.Content))
{
throw new InvalidOperationException("پاسخ نامعتبر از سرویس هوش مصنوعی");
}
return new DailyReportResponse
{
Id = 0,
DeviceId = request.DeviceId,
DeviceName = device.DeviceName,
PersianDate = $"ماه {request.Month} سال {request.Year}",
Analysis = aiResponse.Choices[0].Message!.Content,
RecordCount = dailyReports.Count,
SampledRecordCount = dailyReports.Count,
TotalTokens = aiResponse.Usage?.TotalTokens ?? 0,
CreatedAt = DateTime.UtcNow,
FromCache = false
};
}
}