1. bug fix

2. 加入寄信背景服務
This commit is contained in:
Kai 2021-08-02 13:47:15 +08:00
parent 8c51ec5e04
commit 69007218b5
10 changed files with 519 additions and 264 deletions

View File

@ -169,304 +169,311 @@ namespace SolarPower.Controllers
var XAxis = new List<string>(); var XAxis = new List<string>();
#region #region
var powerStationHistories = await powerStationRepository.GetPowerStationHistory(post.SelectedDate, post.SearchType, selected_powerStationIds); if (selected_powerStationIds.Count() > 0)
XAxis.AddRange(powerStationHistories.Select(x => x.Timestamp).Distinct().ToList());
var powerStationHistories_Id_Group = powerStationHistories.GroupBy(x => x.PowerStationId).ToList();
foreach (var item in powerStationHistories_Id_Group)
{ {
var powerStation = await powerStationRepository.GetOneAsync(item.Key); var powerStationHistories = await powerStationRepository.GetPowerStationHistory(post.SelectedDate, post.SearchType, selected_powerStationIds);
var temp_item = item.OrderBy(x => x.Timestamp).ToList(); XAxis.AddRange(powerStationHistories.Select(x => x.Timestamp).Distinct().ToList());
DeviceHistoryInfo Irradiance = new DeviceHistoryInfo(); var powerStationHistories_Id_Group = powerStationHistories.GroupBy(x => x.PowerStationId).ToList();
Irradiance.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["Irradiance"]);
Irradiance.YaxesKey = "Irradiance"; foreach (var item in powerStationHistories_Id_Group)
Irradiance.Values = new List<double>();
foreach (var history in temp_item)
{ {
if (XAxis.IndexOf(history.Timestamp) > -1) var powerStation = await powerStationRepository.GetOneAsync(item.Key);
{
Irradiance.Values.Add(history.Irradiance);
}
else
{
Irradiance.Values.Add(0);
}
}
analysisDevice.Series.Add(Irradiance);
DeviceHistoryInfo KWH = new DeviceHistoryInfo(); var temp_item = item.OrderBy(x => x.Timestamp).ToList();
KWH.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["KWH"]);
KWH.YaxesKey = "KWH";
KWH.Values = new List<double>();
foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.Timestamp) > -1)
{
KWH.Values.Add(Math.Round(history.KWH, 2));
}
else
{
KWH.Values.Add(0);
}
}
analysisDevice.Series.Add(KWH);
DeviceHistoryInfo solarHour = new DeviceHistoryInfo(); DeviceHistoryInfo Irradiance = new DeviceHistoryInfo();
solarHour.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["SolarHour"]); Irradiance.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["Irradiance"]);
solarHour.YaxesKey = "SolarHour"; Irradiance.YaxesKey = "Irradiance";
solarHour.Values = new List<double>(); Irradiance.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.Timestamp) > -1)
{ {
solarHour.Values.Add(Math.Round(history.SolarHour, 2)); if (XAxis.IndexOf(history.Timestamp) > -1)
{
Irradiance.Values.Add(history.Irradiance);
}
else
{
Irradiance.Values.Add(0);
}
} }
else analysisDevice.Series.Add(Irradiance);
{
solarHour.Values.Add(0);
}
}
analysisDevice.Series.Add(solarHour);
DeviceHistoryInfo KWHKWP = new DeviceHistoryInfo(); DeviceHistoryInfo KWH = new DeviceHistoryInfo();
KWHKWP.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["KWHKWP"]); KWH.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["KWH"]);
KWHKWP.YaxesKey = "KWHKWP"; KWH.YaxesKey = "KWH";
KWHKWP.Values = new List<double>(); KWH.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.Timestamp) > -1)
{ {
KWHKWP.Values.Add(Math.Round(history.KWHKWP, 2)); if (XAxis.IndexOf(history.Timestamp) > -1)
{
KWH.Values.Add(Math.Round(history.KWH, 2));
}
else
{
KWH.Values.Add(0);
}
} }
else analysisDevice.Series.Add(KWH);
{
KWHKWP.Values.Add(0);
}
}
analysisDevice.Series.Add(KWHKWP);
DeviceHistoryInfo PR = new DeviceHistoryInfo(); DeviceHistoryInfo solarHour = new DeviceHistoryInfo();
PR.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["PR"]); solarHour.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["SolarHour"]);
PR.YaxesKey = "PR"; solarHour.YaxesKey = "SolarHour";
PR.Values = new List<double>(); solarHour.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.Timestamp) > -1)
{ {
PR.Values.Add(Math.Round(history.PR, 2)); if (XAxis.IndexOf(history.Timestamp) > -1)
{
solarHour.Values.Add(Math.Round(history.SolarHour, 2));
}
else
{
solarHour.Values.Add(0);
}
} }
else analysisDevice.Series.Add(solarHour);
{
PR.Values.Add(0);
}
}
analysisDevice.Series.Add(PR);
DeviceHistoryInfo modelTemperature = new DeviceHistoryInfo(); DeviceHistoryInfo KWHKWP = new DeviceHistoryInfo();
modelTemperature.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["ModelTemperature"]); KWHKWP.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["KWHKWP"]);
modelTemperature.YaxesKey = "ModelTemperature"; KWHKWP.YaxesKey = "KWHKWP";
modelTemperature.Values = new List<double>(); KWHKWP.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.Timestamp) > -1)
{ {
modelTemperature.Values.Add(Math.Round(history.Temperature, 2)); if (XAxis.IndexOf(history.Timestamp) > -1)
{
KWHKWP.Values.Add(Math.Round(history.KWHKWP, 2));
}
else
{
KWHKWP.Values.Add(0);
}
} }
else analysisDevice.Series.Add(KWHKWP);
DeviceHistoryInfo PR = new DeviceHistoryInfo();
PR.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["PR"]);
PR.YaxesKey = "PR";
PR.Values = new List<double>();
foreach (var history in temp_item)
{ {
modelTemperature.Values.Add(0); if (XAxis.IndexOf(history.Timestamp) > -1)
{
PR.Values.Add(Math.Round(history.PR, 2));
}
else
{
PR.Values.Add(0);
}
} }
analysisDevice.Series.Add(PR);
DeviceHistoryInfo modelTemperature = new DeviceHistoryInfo();
modelTemperature.Name = string.Format("{0}:{1}", powerStation.Name, analysisDevice.MultipleYaxes["ModelTemperature"]);
modelTemperature.YaxesKey = "ModelTemperature";
modelTemperature.Values = new List<double>();
foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.Timestamp) > -1)
{
modelTemperature.Values.Add(Math.Round(history.Temperature, 2));
}
else
{
modelTemperature.Values.Add(0);
}
}
analysisDevice.Series.Add(modelTemperature);
} }
analysisDevice.Series.Add(modelTemperature);
} }
#endregion #endregion
#region #region
var meterHistories = await powerStationRepository.GetMeterHistory(post.SelectedDate, post.SearchType, meterDic); if (meterDic.Count() > 0)
XAxis.AddRange(meterHistories.Select(x => x.TIMESTAMP).Distinct().ToList());
var meterHistories_Id_Group = meterHistories.GroupBy(x => x.METERID).ToList();
foreach (var item in meterHistories_Id_Group)
{ {
var temp_item = item.OrderBy(x => x.TIMESTAMP).ToList(); var meterHistories = await powerStationRepository.GetMeterHistory(post.SelectedDate, post.SearchType, meterDic);
DeviceHistoryInfo OUTPUT_KWH = new DeviceHistoryInfo(); XAxis.AddRange(meterHistories.Select(x => x.TIMESTAMP).Distinct().ToList());
OUTPUT_KWH.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["OUTPUT_KWH"]);
OUTPUT_KWH.YaxesKey = "OUTPUT_KWH";
OUTPUT_KWH.Values = new List<double>();
foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
OUTPUT_KWH.Values.Add(Math.Round(history.OUTPUT_KWH, 2));
}
else
{
OUTPUT_KWH.Values.Add(0);
}
}
analysisDevice.Series.Add(OUTPUT_KWH);
DeviceHistoryInfo INPUT_KWH = new DeviceHistoryInfo(); var meterHistories_Id_Group = meterHistories.GroupBy(x => x.METERID).ToList();
INPUT_KWH.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["INPUT_KWH"]);
INPUT_KWH.YaxesKey = "INPUT_KWH";
INPUT_KWH.Values = new List<double>();
foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
INPUT_KWH.Values.Add(Math.Round(history.INPUT_KWH, 2));
}
else
{
INPUT_KWH.Values.Add(0);
}
}
analysisDevice.Series.Add(INPUT_KWH);
DeviceHistoryInfo V_AB = new DeviceHistoryInfo(); foreach (var item in meterHistories_Id_Group)
V_AB.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["V_AB"]);
V_AB.YaxesKey = "V_AB";
V_AB.Values = new List<double>();
foreach (var history in temp_item)
{ {
if (XAxis.IndexOf(history.TIMESTAMP) > -1) var temp_item = item.OrderBy(x => x.TIMESTAMP).ToList();
{
V_AB.Values.Add(Math.Round(history.V_AB, 2));
}
else
{
V_AB.Values.Add(0);
}
}
analysisDevice.Series.Add(V_AB);
DeviceHistoryInfo V_BC = new DeviceHistoryInfo(); DeviceHistoryInfo OUTPUT_KWH = new DeviceHistoryInfo();
V_BC.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["V_BC"]); OUTPUT_KWH.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["OUTPUT_KWH"]);
V_BC.YaxesKey = "V_BC"; OUTPUT_KWH.YaxesKey = "OUTPUT_KWH";
V_BC.Values = new List<double>(); OUTPUT_KWH.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{ {
V_BC.Values.Add(Math.Round(history.V_BC, 2)); if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
OUTPUT_KWH.Values.Add(Math.Round(history.OUTPUT_KWH, 2));
}
else
{
OUTPUT_KWH.Values.Add(0);
}
} }
else analysisDevice.Series.Add(OUTPUT_KWH);
{
V_BC.Values.Add(0);
}
}
analysisDevice.Series.Add(V_BC);
DeviceHistoryInfo V_CA = new DeviceHistoryInfo(); DeviceHistoryInfo INPUT_KWH = new DeviceHistoryInfo();
V_CA.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["V_BC"]); INPUT_KWH.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["INPUT_KWH"]);
V_CA.YaxesKey = "V_CA"; INPUT_KWH.YaxesKey = "INPUT_KWH";
V_CA.Values = new List<double>(); INPUT_KWH.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{ {
V_CA.Values.Add(Math.Round(history.V_CA, 2)); if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
INPUT_KWH.Values.Add(Math.Round(history.INPUT_KWH, 2));
}
else
{
INPUT_KWH.Values.Add(0);
}
} }
else analysisDevice.Series.Add(INPUT_KWH);
{
V_CA.Values.Add(0);
}
}
analysisDevice.Series.Add(V_CA);
DeviceHistoryInfo I_A = new DeviceHistoryInfo(); DeviceHistoryInfo V_AB = new DeviceHistoryInfo();
I_A.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["I_A"]); V_AB.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["V_AB"]);
I_A.YaxesKey = "I_A"; V_AB.YaxesKey = "V_AB";
I_A.Values = new List<double>(); V_AB.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{ {
I_A.Values.Add(Math.Round(history.I_A, 2)); if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
V_AB.Values.Add(Math.Round(history.V_AB, 2));
}
else
{
V_AB.Values.Add(0);
}
} }
else analysisDevice.Series.Add(V_AB);
{
I_A.Values.Add(0);
}
}
analysisDevice.Series.Add(I_A);
DeviceHistoryInfo I_B = new DeviceHistoryInfo(); DeviceHistoryInfo V_BC = new DeviceHistoryInfo();
I_B.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["I_B"]); V_BC.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["V_BC"]);
I_B.YaxesKey = "I_B"; V_BC.YaxesKey = "V_BC";
I_B.Values = new List<double>(); V_BC.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{ {
I_B.Values.Add(Math.Round(history.I_B, 2)); if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
V_BC.Values.Add(Math.Round(history.V_BC, 2));
}
else
{
V_BC.Values.Add(0);
}
} }
else analysisDevice.Series.Add(V_BC);
{
I_B.Values.Add(0);
}
}
analysisDevice.Series.Add(I_B);
DeviceHistoryInfo I_C = new DeviceHistoryInfo(); DeviceHistoryInfo V_CA = new DeviceHistoryInfo();
I_C.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["I_C"]); V_CA.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["V_BC"]);
I_C.YaxesKey = "I_C"; V_CA.YaxesKey = "V_CA";
I_C.Values = new List<double>(); V_CA.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{ {
I_C.Values.Add(Math.Round(history.I_C, 2)); if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
V_CA.Values.Add(Math.Round(history.V_CA, 2));
}
else
{
V_CA.Values.Add(0);
}
} }
else analysisDevice.Series.Add(V_CA);
{
I_C.Values.Add(0);
}
}
analysisDevice.Series.Add(I_C);
DeviceHistoryInfo P = new DeviceHistoryInfo(); DeviceHistoryInfo I_A = new DeviceHistoryInfo();
P.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["P"]); I_A.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["I_A"]);
P.YaxesKey = "P"; I_A.YaxesKey = "I_A";
P.Values = new List<double>(); I_A.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{ {
P.Values.Add(Math.Round(history.P, 2)); if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
I_A.Values.Add(Math.Round(history.I_A, 2));
}
else
{
I_A.Values.Add(0);
}
} }
else analysisDevice.Series.Add(I_A);
{
P.Values.Add(0);
}
}
analysisDevice.Series.Add(P);
DeviceHistoryInfo F = new DeviceHistoryInfo(); DeviceHistoryInfo I_B = new DeviceHistoryInfo();
F.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["F"]); I_B.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["I_B"]);
F.YaxesKey = "F"; I_B.YaxesKey = "I_B";
F.Values = new List<double>(); I_B.Values = new List<double>();
foreach (var history in temp_item) foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{ {
F.Values.Add(Math.Round(history.F, 2)); if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
I_B.Values.Add(Math.Round(history.I_B, 2));
}
else
{
I_B.Values.Add(0);
}
} }
else analysisDevice.Series.Add(I_B);
DeviceHistoryInfo I_C = new DeviceHistoryInfo();
I_C.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["I_C"]);
I_C.YaxesKey = "I_C";
I_C.Values = new List<double>();
foreach (var history in temp_item)
{ {
F.Values.Add(0); if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
I_C.Values.Add(Math.Round(history.I_C, 2));
}
else
{
I_C.Values.Add(0);
}
} }
analysisDevice.Series.Add(I_C);
DeviceHistoryInfo P = new DeviceHistoryInfo();
P.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["P"]);
P.YaxesKey = "P";
P.Values = new List<double>();
foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
P.Values.Add(Math.Round(history.P, 2));
}
else
{
P.Values.Add(0);
}
}
analysisDevice.Series.Add(P);
DeviceHistoryInfo F = new DeviceHistoryInfo();
F.Name = string.Format("{0}:{1}", item.Key, analysisDevice.MultipleYaxes["F"]);
F.YaxesKey = "F";
F.Values = new List<double>();
foreach (var history in temp_item)
{
if (XAxis.IndexOf(history.TIMESTAMP) > -1)
{
F.Values.Add(Math.Round(history.F, 2));
}
else
{
F.Values.Add(0);
}
}
analysisDevice.Series.Add(F);
} }
analysisDevice.Series.Add(F);
} }
#endregion #endregion
#region #region

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SolarPower.Models
{
public class NoticeSchedule
{
public int Id { get; set; }
public byte Type { get; set; }
public string RecipientName { get; set; }
public string RecipientEmail { get; set; }
public string Subject { get; set; }
public string Content { get; set; }
public string Attachment { get; set; }
public byte IsDelivery { get; set; }
public string DeliveryAt { get; set; }
}
}

View File

@ -0,0 +1,136 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Quartz;
using SolarPower.Models;
using SolarPower.Repository.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Threading.Tasks;
namespace SolarPower.Quartz.Jobs
{
[DisallowConcurrentExecution]
public class SendEmailJob : IJob
{
private readonly ILogger<SendEmailJob> logger;
private readonly IOptions<SMTPConfig> _options;
private readonly INoticeScheduleRepository noticeScheduleRepository;
private SMTPConfig smtp;
public SendEmailJob(
ILogger<SendEmailJob> logger,
IOptions<SMTPConfig> options,
INoticeScheduleRepository noticeScheduleRepository)
{
this.logger = logger;
this.smtp = options.Value;
this.noticeScheduleRepository = noticeScheduleRepository;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
//取得要寄信的列表
logger.LogInformation("【SendEmailJob】【任務開始】");
var noticeSchedules = await noticeScheduleRepository.GetNotYetDelivery();
var updateNoticeSchedules = new List<NoticeSchedule>();
foreach (var notice in noticeSchedules)
{
var attachments = new List<string>();
var recipientEmails = new List<string>()
{
notice.RecipientEmail
};
if (!string.IsNullOrEmpty(notice.Attachment))
{
attachments = notice.Attachment.Split(',').ToList();
}
var result = Send(recipientEmails, notice.Subject, notice.Content, attachments);
if(result)
{
NoticeSchedule noticeSchedule = new NoticeSchedule();
noticeSchedule.Id = notice.Id;
noticeSchedule.IsDelivery = 1;
noticeSchedule.DeliveryAt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
updateNoticeSchedules.Add(noticeSchedule);
}
List<string> properties = new List<string>()
{
"Id",
"IsDelivery",
"DeliveryAt"
};
await noticeScheduleRepository.UpdateList(updateNoticeSchedules, properties);
}
logger.LogInformation("【SendEmailJob】【任務完成】");
}
catch (Exception exception)
{
logger.LogError("【{0}】{1}", "SendEmailJob", exception.Message);
}
}
private bool Send(List<string> recipientEmails, string subject, string content, List<string> attachments)
{
MailMessage MyMail = new MailMessage();
MyMail.SubjectEncoding = System.Text.Encoding.UTF8;//郵件標題編碼
MyMail.BodyEncoding = System.Text.Encoding.UTF8; //郵件內容編碼
MyMail.IsBodyHtml = true; //是否使用html格式
MyMail.From = new System.Net.Mail.MailAddress(smtp.UserName); //寄件人
foreach (var email in recipientEmails)
{
MyMail.To.Add(email); //設定收件者Email
}
MyMail.Subject = subject; //主題
MyMail.Body = content; //設定信件內容
foreach(var attachment in attachments)
{
var directoryBase = Directory.GetCurrentDirectory();
var filePath = @$"{directoryBase}/wwwroot{attachment}";
var data = new Attachment(filePath);
MyMail.Attachments.Add(data);
}
//讀取 SMTP Config
SmtpClient MySMTP = new SmtpClient(smtp.Host, smtp.Port);
MySMTP.EnableSsl = smtp.EnableSsl;
MySMTP.Credentials = new System.Net.NetworkCredential(smtp.UserName, smtp.Password);
try
{
MySMTP.Send(MyMail);
MySMTP.Dispose();
MyMail.Dispose(); //釋放資源
return true;
}
catch (Exception ex)
{
string json = System.Text.Json.JsonSerializer.Serialize(recipientEmails);
logger.LogError("【SendEmailJob】 " + "寄送信件失敗");
logger.LogError("【SendEmailJob】 - Emails:" + json);
logger.LogError("【SendEmailJob】 - Exception:" + ex.Message);
return false;
}
}
}
}

View File

@ -0,0 +1,68 @@
using Dapper;
using SolarPower.Helper;
using SolarPower.Models;
using SolarPower.Repository.Interface;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
namespace SolarPower.Repository.Implement
{
public class NoticeScheduleRepository : RepositoryBase<NoticeSchedule>, INoticeScheduleRepository
{
public NoticeScheduleRepository(IDatabaseHelper databaseHelper) : base(databaseHelper)
{
tableName = "notice_schedule";
}
public async Task<List<NoticeSchedule>> GetNotYetDelivery()
{
List<NoticeSchedule> result;
using (IDbConnection conn = this._databaseHelper.GetConnection())
{
try
{
var sql = $"SELECT * FROM {tableName} WHERE IsDelivery = 0";
result = (await conn.QueryAsync<NoticeSchedule>(sql)).ToList();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
public async Task UpdateList(List<NoticeSchedule> noticeSchedules, List<string> properties)
{
using (IDbConnection conn = this._databaseHelper.GetConnection())
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
try
{
var sql = GenerateUpdateQuery(properties);
await conn.ExecuteAsync(sql, noticeSchedules, trans);
trans.Commit();
}
catch (Exception exception)
{
trans.Rollback();
throw exception;
}
finally
{
conn.Close();
}
}
}
}
}
}

View File

@ -0,0 +1,14 @@
using SolarPower.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SolarPower.Repository.Interface
{
public interface INoticeScheduleRepository : IRepositoryBase<NoticeSchedule>
{
Task<List<NoticeSchedule>> GetNotYetDelivery();
Task UpdateList(List<NoticeSchedule> noticeSchedules, List<string> properties);
}
}

View File

@ -78,6 +78,7 @@ namespace SolarPower
services.AddTransient<IOverviewRepository, OverviewRepository>(); services.AddTransient<IOverviewRepository, OverviewRepository>();
services.AddTransient<IAnalysisStationCombineRepository,AnalysisStationCombineRepository>(); services.AddTransient<IAnalysisStationCombineRepository,AnalysisStationCombineRepository>();
services.AddTransient<IStationReportRepository, StationReportRepository>(); services.AddTransient<IStationReportRepository, StationReportRepository>();
services.AddTransient<INoticeScheduleRepository, NoticeScheduleRepository>();
#endregion #endregion
double loginExpireMinute = this.Configuration.GetValue<double>("LoginExpireMinute"); double loginExpireMinute = this.Configuration.GetValue<double>("LoginExpireMinute");
@ -122,6 +123,14 @@ namespace SolarPower
//new JobSchedule(jobType: typeof(CalcAvgPowerStationJob), cronExpression: "0/10 * * * * ?") //new JobSchedule(jobType: typeof(CalcAvgPowerStationJob), cronExpression: "0/10 * * * * ?")
); );
#endregion #endregion
#region Email(2)
services.AddSingleton<SendEmailJob>();
services.AddSingleton(
new JobSchedule(jobType: typeof(SendEmailJob), cronExpression: Configuration.GetValue<string>("BackgroundServiceCron:SendEmailJob"))
);
#endregion
services.AddHostedService<QuartzHostedService>(); services.AddHostedService<QuartzHostedService>();
#endregion #endregion
} }

View File

@ -16,11 +16,11 @@
<div class="card"> <div class="card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap"> <div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap">
<h4 class="mb-0 font-weight-bold"><span class="fal fa-bolt mr-1"></span> 發電量</h4> <h4 class="mb-0 font-weight-bold"><span class="fal fa-bolt mr-1"></span> 發電量</h4>
<div class="ml-auto">kwh</div> <div class="ml-auto">kW h</div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<p>總發電量</p> <p>即時總發電量</p>
<p><span class="color-info-700 fs-xl font-weight-bold" id="today_kwh">126,161.72</span></p> <p><span class="color-info-700 fs-xl font-weight-bold" id="today_kwh">126,161.72</span></p>
</div> </div>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -32,7 +32,7 @@
<div class="card"> <div class="card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap"> <div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap">
<h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span> 日照度</h4> <h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span> 日照度</h4>
<div class="ml-auto">kw/m<sup>2</sup></div> <div class="ml-auto">k W/m<sup>2</sup></div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -63,17 +63,17 @@
</div> </div>
<div class="card"> <div class="card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap"> <div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap">
<h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span> kWh / kWp</h4> <h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span>有效日照時數</h4>
<div class="ml-auto">hr</div> <div class="ml-auto">hr</div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<p>即時平均 kWh / kWp</p> <p>即時平均有效日照時數</p>
<p><span class="color-info-700 fs-xl font-weight-bold" id="today_kwhkwp">140.39</span> kW/m2</p> <p><span class="color-info-700 fs-xl font-weight-bold" id="today_kwhkwp">140.39</span></p>
</div> </div>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<p>平均 kWh / kWp (30天)</p> <p>平均有效日照時數 (30天)</p>
<p><span class="color-info-700 fs-xl font-weight-bold" id="avg_kwhkwp">4.53</span> kW/m2</p> <p><span class="color-info-700 fs-xl font-weight-bold" id="avg_kwhkwp">4.53</span></p>
</div> </div>
</div> </div>
</div> </div>
@ -264,8 +264,8 @@
'<div id="bodyContent">' + '<div id="bodyContent">' +
'<div class="row">' + '<div class="row">' +
'<div class="col-12">' + '<div class="col-12">' +
'<div>發電量:' + item.today_kWh + '</div>'+ '<div>即時總發電量:' + item.today_kWh + '</div>'+
'<div>日照度:' + item.today_irradiance + '</div>'+ '<div>即時平均日照度:' + item.today_irradiance + '</div>'+
'<div>發電小時:' + item.solarHour + '</div>' + '<div>發電小時:' + item.solarHour + '</div>' +
'<div>裝置容量:' + item.generatingCapacity + '</div>' + '<div>裝置容量:' + item.generatingCapacity + '</div>' +
'<div>天氣:' + + '</div>'+ '<div>天氣:' + + '</div>'+

View File

@ -80,7 +80,7 @@
<div class="card"> <div class="card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap"> <div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap">
<h4 class="mb-0 font-weight-bold"><span class="fal fa-bolt mr-1"></span> 發電量</h4> <h4 class="mb-0 font-weight-bold"><span class="fal fa-bolt mr-1"></span> 發電量</h4>
<div class="ml-auto">kWh</div> <div class="ml-auto">kW h</div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -96,7 +96,7 @@
<div class="card"> <div class="card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap"> <div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap">
<h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span> 日照度</h4> <h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span> 日照度</h4>
<div class="ml-auto">kW/m<sup>2</sup></div> <div class="ml-auto">k W/m<sup>2</sup></div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -127,16 +127,16 @@
</div> </div>
<div class="card"> <div class="card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap"> <div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap">
<h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span> kWh / kWp</h4> <h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span>有效日照時數</h4>
<div class="ml-auto">hr</div> <div class="ml-auto">hr</div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<p>即時平均 kWh / kWp</p> <p>即時平均有效日照時數</p>
<p><span class="color-info-700" id="today_kwhkwp">140.39</span></p> <p><span class="color-info-700" id="today_kwhkwp">140.39</span></p>
</div> </div>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<p>平均 kWh / kWp (30天)</p> <p>平均有效日照時數(30天)</p>
<p><span class="color-info-700" id="avg_kwhkwp">4.53</span></p> <p><span class="color-info-700" id="avg_kwhkwp">4.53</span></p>
</div> </div>
</div> </div>

View File

@ -3,7 +3,7 @@
<div class="card"> <div class="card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap"> <div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap">
<h4 class="mb-0 font-weight-bold"><span class="fal fa-bolt mr-1"></span> 發電量</h4> <h4 class="mb-0 font-weight-bold"><span class="fal fa-bolt mr-1"></span> 發電量</h4>
<div class="ml-auto">kwh</div> <div class="ml-auto">kW h</div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -35,7 +35,7 @@
<div class="card irradiance-card"> <div class="card irradiance-card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap"> <div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap">
<h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span> 日照度</h4> <h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span> 日照度</h4>
<div class="ml-auto">kw/m<sup>2</sup></div> <div class="ml-auto">k W/m<sup>2</sup></div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -66,16 +66,16 @@
</div> </div>
<div class="card"> <div class="card">
<div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap"> <div class="card-header bg-fusion-25 py-2 pr-3 d-flex align-items-center flex-wrap">
<h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span> kWh / kWp</h4> <h4 class="mb-0 font-weight-bold"><span class="fal fa-sun mr-1"></span>有效日照時數</h4>
<div class="ml-auto">hr</div> <div class="ml-auto">hr</div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<p>即時平均 kWh / kWp</p> <p>即時平均有效日照時數</p>
<p><span class="color-info-700" id="today_kwhkwp">140.39</span></p> <p><span class="color-info-700" id="today_kwhkwp">140.39</span></p>
</div> </div>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<p>平均 kWh / kWp (30天)</p> <p>平均有效日照時數(30天)</p>
<p><span class="color-info-700" id="avg_kwhkwp">4.53</span></p> <p><span class="color-info-700" id="avg_kwhkwp">4.53</span></p>
</div> </div>
</div> </div>

View File

@ -25,7 +25,8 @@
"CalcPowerStationJob": "0 5 * * * ?", "CalcPowerStationJob": "0 5 * * * ?",
"CalcAvgPowerStationJob": "0 0 2 * * ?", "CalcAvgPowerStationJob": "0 0 2 * * ?",
"OperationScheduleJob": "0 0 2 * * ?", "OperationScheduleJob": "0 0 2 * * ?",
"CalcInverter15minJob": "0 2/15 * * * ?" "CalcInverter15minJob": "0 2/15 * * * ?",
"SendEmailJob": "0/10 * * * * ?"
}, },
"SMTPConfig": { "SMTPConfig": {
"Host": "smtp.gmail.com", "Host": "smtp.gmail.com",