1. bug fix
2. 加入寄信背景服務
This commit is contained in:
parent
8c51ec5e04
commit
69007218b5
@ -169,6 +169,8 @@ namespace SolarPower.Controllers
|
|||||||
var XAxis = new List<string>();
|
var XAxis = new List<string>();
|
||||||
|
|
||||||
#region 電站資料
|
#region 電站資料
|
||||||
|
if (selected_powerStationIds.Count() > 0)
|
||||||
|
{
|
||||||
var powerStationHistories = await powerStationRepository.GetPowerStationHistory(post.SelectedDate, post.SearchType, selected_powerStationIds);
|
var powerStationHistories = await powerStationRepository.GetPowerStationHistory(post.SelectedDate, post.SearchType, selected_powerStationIds);
|
||||||
|
|
||||||
XAxis.AddRange(powerStationHistories.Select(x => x.Timestamp).Distinct().ToList());
|
XAxis.AddRange(powerStationHistories.Select(x => x.Timestamp).Distinct().ToList());
|
||||||
@ -283,9 +285,12 @@ namespace SolarPower.Controllers
|
|||||||
}
|
}
|
||||||
analysisDevice.Series.Add(modelTemperature);
|
analysisDevice.Series.Add(modelTemperature);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 電錶資料
|
#region 電錶資料
|
||||||
|
if (meterDic.Count() > 0)
|
||||||
|
{
|
||||||
var meterHistories = await powerStationRepository.GetMeterHistory(post.SelectedDate, post.SearchType, meterDic);
|
var meterHistories = await powerStationRepository.GetMeterHistory(post.SelectedDate, post.SearchType, meterDic);
|
||||||
|
|
||||||
XAxis.AddRange(meterHistories.Select(x => x.TIMESTAMP).Distinct().ToList());
|
XAxis.AddRange(meterHistories.Select(x => x.TIMESTAMP).Distinct().ToList());
|
||||||
@ -466,6 +471,8 @@ namespace SolarPower.Controllers
|
|||||||
}
|
}
|
||||||
analysisDevice.Series.Add(F);
|
analysisDevice.Series.Add(F);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
20
SolarPower/Models/NoticeSchedule.cs
Normal file
20
SolarPower/Models/NoticeSchedule.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
136
SolarPower/Quartz/Jobs/SendEmailJob.cs
Normal file
136
SolarPower/Quartz/Jobs/SendEmailJob.cs
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
68
SolarPower/Repository/Implement/NoticeScheduleRepository.cs
Normal file
68
SolarPower/Repository/Implement/NoticeScheduleRepository.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
14
SolarPower/Repository/Interface/INoticeScheduleRepository.cs
Normal file
14
SolarPower/Repository/Interface/INoticeScheduleRepository.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>'+
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user