This commit is contained in:
JiaHao Liu 2021-08-17 12:52:31 +08:00
commit 57ccee0c09
13 changed files with 1287 additions and 354 deletions

View File

@ -38,7 +38,8 @@ namespace SolarPower.Controllers
0 => "日報表", 0 => "日報表",
1 => "月報表", 1 => "月報表",
2 => "綜合報表", 2 => "綜合報表",
3 => "運維", 3 => "運維通知",
4 => "異常通知",
_ => "" _ => ""
}; };
a.IsDeliveryName = a.IsDelivery switch a.IsDeliveryName = a.IsDelivery switch

View File

@ -2775,5 +2775,76 @@ namespace SolarPower.Controllers
apiResult.Msg = errorCode.GetString(apiResult.Code); apiResult.Msg = errorCode.GetString(apiResult.Code);
return apiResult; return apiResult;
} }
public async Task<ApiResult<List<InverterInfoList>>> GetInverterInfoList (IdAndDB post)
{
List<InverterInfoList> list = new List<InverterInfoList>();
ApiResult<List<InverterInfoList>> apiResult = new ApiResult<List<InverterInfoList>>();
try
{
var controllers = await powerStationRepository.GetAllDeviceControllerId(post.Id, post.SiteDB);
if(controllers.Count == 0)
{
apiResult.Code = "0001";
apiResult.Msg = "該電站沒有控制器";
return apiResult;
}
var inverters = await powerStationRepository.InverterTable(controllers, post.SiteDB);
if (inverters.Count == 0)
{
apiResult.Code = "0001";
apiResult.Msg = "該電站沒有啟用的逆變器";
return apiResult;
}
var inverterIds = inverters.Where(x => x.Enabled == 1 && x.Status == 1).Select(x => x.InverterId).ToList();
if(inverterIds.Count > 0)
{
var site = "s" + inverterIds[0].Substring(0, 11) + "_inv";
var inverterss = await powerStationRepository.GetAllInverterInfo(inverterIds, site, post.SiteDB);
foreach(var inverter in inverterss)
{
var info = new InverterInfoList
{
Input = (inverter.DC1W + inverter.DC2W + inverter.DC3W + inverter.DC4W + inverter.DC5W)/1000,
Output = (inverter.AC1W + inverter.AC2W + inverter.AC3W)/1000,
PR = inverter.PR,
TODAYKWH = inverter.TODAYKWH,
Name = inverter.INVERTERName,
ID = inverter.ID,
Type = 1
};
list.Add(info);
}
}
var inverterIdsdd = inverters.Where(x => x.Enabled == 1 && x.Status == 2).Select(x => new { name = x.InverterName , id = x.Id } ).ToList();
foreach (var inverter in inverterIdsdd)
{
var info = new InverterInfoList
{
Input = 0,
Output = 0,
PR = 0,
TODAYKWH = 0,
Name = inverter.name,
ID = inverter.id,
Type = 2
};
list.Add(info);
}
apiResult.Code = "0000";
apiResult.Data = list;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = errorCode.GetString(apiResult.Code);
string json = System.Text.Json.JsonSerializer.Serialize(post);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + json);
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
}
return apiResult;
}
} }
} }

View File

@ -687,6 +687,7 @@ namespace SolarPower.Models.PowerStation
public string TIMESTAMP { get; set; } public string TIMESTAMP { get; set; }
public int PowerStationId { get; set; } public int PowerStationId { get; set; }
public string INVERTERID { get; set; } public string INVERTERID { get; set; }
public string INVERTERName { get; set; }
public double Irradiance { get; set; } public double Irradiance { get; set; }
public double AC1V { get; set; } public double AC1V { get; set; }
public double AC1A { get; set; } public double AC1A { get; set; }
@ -740,6 +741,7 @@ namespace SolarPower.Models.PowerStation
public double TODAYKWH { get; set; } public double TODAYKWH { get; set; }
public double TOTALKWH { get; set; } public double TOTALKWH { get; set; }
public double KWHKWP { get; set; } public double KWHKWP { get; set; }
public int ID { get; set; }
} }
#region #region
public class FieldsItem public class FieldsItem
@ -929,5 +931,23 @@ namespace SolarPower.Models.PowerStation
public double INPUT_KWH { get; set; } public double INPUT_KWH { get; set; }
} }
public class InverterInfoList
{
public double Input { get; set; }
public double Output { get; set; }
public double PR { get; set; }
public double TODAYKWH { get; set; }
public string Name { get; set; }
public int ID { get; set; }
public int Type { get; set; }
}
public class IdAndDB
{
public int Id { get; set; }
public string SiteDB { get; set; }
}
} }

View File

@ -212,77 +212,92 @@ namespace SolarPower.Quartz.Jobs
var dateNowDay = DateTimeNow.AddDays(-1).ToString("yyyy-MM-dd"); var dateNowDay = DateTimeNow.AddDays(-1).ToString("yyyy-MM-dd");
var dateNowMonth = DateTimeNow.AddDays(-1).ToString("yyyy-MM"); var dateNowMonth = DateTimeNow.AddDays(-1).ToString("yyyy-MM");
Root2 observation = null;
#region () #region ()
logger.LogInformation("【CalcAvgPowerStationJob】【開始取得氣象觀測】"); try
var client = new HttpClient();
var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=Wx,PoP&sort=time";
HttpResponseMessage response = client.GetAsync(UVUri).Result;
String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
Root2 observation = JsonConvert.DeserializeObject<Root2>(jsonUVs);
logger.LogInformation("【CalcAvgPowerStationJob】【取得成功氣象觀測】");
#endregion
foreach (var location in observation.Records.Location)
{ {
WeatherForecast weatherForecast = new WeatherForecast(); logger.LogInformation("【CalcAvgPowerStationJob】【開始取得氣象觀測】");
weatherForecast.LocationName = location.LocationName; var client = new HttpClient();
var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=Wx,PoP&sort=time";
HttpResponseMessage response = client.GetAsync(UVUri).Result;
String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
observation = JsonConvert.DeserializeObject<Root2>(jsonUVs);
logger.LogInformation("【CalcAvgPowerStationJob】【取得成功氣象觀測】");
}
catch (Exception ex)
{
logger.LogError("【CalcAvgPowerStationJob】【取得失敗氣象觀測】");
logger.LogError("【{0}】{1}", "CalcPowerStationJob", ex.Message);
observation = null;
}
List<WeatherForecast> SubweatherForecasts = new List<WeatherForecast>(); #endregion
if (observation != null)
foreach (var a in location.WeatherElement) {
foreach (var location in observation.Records.Location)
{ {
if (a.ElementName == "Wx") WeatherForecast weatherForecast = new WeatherForecast();
weatherForecast.LocationName = location.LocationName;
List<WeatherForecast> SubweatherForecasts = new List<WeatherForecast>();
foreach (var a in location.WeatherElement)
{ {
foreach (var time in a.Time) if (a.ElementName == "Wx")
{
foreach (var time in a.Time)
{
int index = 0;
if (location.WeatherElement[0].ElementName == "Wx")
{
weatherForecast = new WeatherForecast();
weatherForecast.LocationName = location.LocationName;
weatherForecast.StartTime = time.StartTime.ToString();
weatherForecast.EndTime = time.EndTime.ToString();
weatherForecast.Wx = time.Parameter.ParameterName;
weatherForecast.WxValue = time.Parameter.ParameterValue;
SubweatherForecasts.Add(weatherForecast);
}
else
{
SubweatherForecasts[index].StartTime = time.StartTime.ToString();
SubweatherForecasts[index].EndTime = time.EndTime.ToString();
SubweatherForecasts[index].Wx = time.Parameter.ParameterName;
SubweatherForecasts[index].WxValue = time.Parameter.ParameterValue;
//SubweatherForecasts.Add(weatherForecast);
index++;
}
//weatherForecasts.Add(weatherForecast);
}
}
if (a.ElementName == "PoP")
{ {
int index = 0; int index = 0;
if (location.WeatherElement[0].ElementName == "Wx") foreach (var time in a.Time)
{ {
weatherForecast = new WeatherForecast(); if (location.WeatherElement[0].ElementName == "PoP")
weatherForecast.LocationName = location.LocationName; {
weatherForecast.StartTime = time.StartTime.ToString(); weatherForecast = new WeatherForecast();
weatherForecast.EndTime = time.EndTime.ToString(); weatherForecast.LocationName = location.LocationName;
weatherForecast.Wx = time.Parameter.ParameterName; weatherForecast.PoP = time.Parameter.ParameterName;
weatherForecast.WxValue = time.Parameter.ParameterValue; SubweatherForecasts.Add(weatherForecast);
SubweatherForecasts.Add(weatherForecast); }
else
{
SubweatherForecasts[index].PoP = time.Parameter.ParameterName;
} //SubweatherForecasts.Add(weatherForecast);
else index++;
{ }
SubweatherForecasts[index].StartTime = time.StartTime.ToString();
SubweatherForecasts[index].EndTime = time.EndTime.ToString();
SubweatherForecasts[index].Wx = time.Parameter.ParameterName;
SubweatherForecasts[index].WxValue = time.Parameter.ParameterValue;
//SubweatherForecasts.Add(weatherForecast);
index++;
}
//weatherForecasts.Add(weatherForecast);
}
}
if (a.ElementName == "PoP")
{
int index = 0;
foreach (var time in a.Time)
{
if (location.WeatherElement[0].ElementName == "PoP")
{
weatherForecast = new WeatherForecast();
weatherForecast.LocationName = location.LocationName;
weatherForecast.PoP = time.Parameter.ParameterName;
SubweatherForecasts.Add(weatherForecast);
}
else
{
SubweatherForecasts[index].PoP = time.Parameter.ParameterName;
//SubweatherForecasts.Add(weatherForecast);
index++;
} }
} }
} }
weatherForecasts.AddRange(SubweatherForecasts);
} }
weatherForecasts.AddRange(SubweatherForecasts);
} }
List<string> weather_forecast_properties = new List<string>() List<string> weather_forecast_properties = new List<string>()
{ {
"LocationName", "LocationName",

View File

@ -40,9 +40,13 @@ namespace SolarPower.Quartz.Jobs
var DateTimeNow = DateTime.Now; var DateTimeNow = DateTime.Now;
var dateTime = DateTimeNow.AddHours(-1).ToString("yyyy-MM-dd HH"); var dateTime = DateTimeNow.AddHours(-1).ToString("yyyy-MM-dd HH");
var hasException = false;
Root2 observation = null;
if (this.environment.IsDevelopment()) if (this.environment.IsDevelopment())
{ {
dateTime = "2021-08-09 10"; dateTime = "2021-08-16 09";
} }
logger.LogInformation("【CalcPowerStationJob】【任務開始】"); logger.LogInformation("【CalcPowerStationJob】【任務開始】");
@ -64,324 +68,338 @@ namespace SolarPower.Quartz.Jobs
List<WeatherObservation> weatherObservations = new List<WeatherObservation>(); List<WeatherObservation> weatherObservations = new List<WeatherObservation>();
#region () #region ()
logger.LogInformation("【CalcPowerStationJob】【開始取得氣象觀測】"); try
var client = new HttpClient(); {
var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0003-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=TIME,TEMP"; logger.LogInformation("【CalcPowerStationJob】【開始取得氣象觀測】");
HttpResponseMessage response = client.GetAsync(UVUri).Result; var client = new HttpClient();
String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString(); var UVUri = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0003-001?Authorization=CWB-EA24220B-DDCC-4188-84E5-AD37A0E03F80&elementName=TIME,TEMP";
Root2 observation = JsonConvert.DeserializeObject<Root2>(jsonUVs); HttpResponseMessage response = client.GetAsync(UVUri).Result;
logger.LogInformation("【CalcPowerStationJob】【取得成功氣象觀測】"); String jsonUVs = response.Content.ReadAsStringAsync().Result.ToString();
observation = JsonConvert.DeserializeObject<Root2>(jsonUVs);
logger.LogInformation("【CalcPowerStationJob】【取得成功氣象觀測】");
}
catch (Exception ex)
{
logger.LogError("【CalcPowerStationJob】【取得失敗氣象觀測】");
logger.LogError("【{0}】{1}", "CalcPowerStationJob", ex.Message);
observation = null;
}
#endregion #endregion
#region step2. DB及電站編號找出該電站的控制器 #region step2. DB及電站編號找出該電站的控制器
foreach (var powerStation in powerStations) foreach (var powerStation in powerStations)
{ {
var calcPowerStation = new PowerStation(); try
calcPowerStation.Id = powerStation.Id;
#region step2-1.
var table_name = String.Format("s{1}01_station", powerStation.SiteDB, powerStation.Code);
var full_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, table_name);
var exist = await powerStationRepository.ExistTable(powerStation.SiteDB, table_name);
if (!string.IsNullOrEmpty(exist))
{ {
logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); var calcPowerStation = new PowerStation();
var history = await powerStationRepository.GetPowerStationHistoryPerHour(dateTime, full_table_name); calcPowerStation.Id = powerStation.Id;
logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的每小時歷史資料】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(history));
var lastmoneyhistorybyhour = await powerStationRepository.GetLastMoneyAndCarbonInHour(powerStation.Id, 0, dateTime);
if (history != null) #region step2-1.
var table_name = String.Format("s{1}01_station", powerStation.SiteDB, powerStation.Code);
var full_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, table_name);
var exist = await powerStationRepository.ExistTable(powerStation.SiteDB, table_name);
if (!string.IsNullOrEmpty(exist))
{ {
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime); logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
history.PowerStationId = powerStation.Id; var history = await powerStationRepository.GetPowerStationHistoryPerHour(dateTime, full_table_name);
history.Timestamp = Convert.ToDateTime(history.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss"); logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的每小時歷史資料】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(history));
var lastmoneyhistorybyhour = await powerStationRepository.GetLastMoneyAndCarbonInHour(powerStation.Id, 0, dateTime);
#region if (history != null)
#region
//每小時發電量(直接填寫
calcPowerStation.kwh = history.KWH;
//今日發電量(直接填寫
calcPowerStation.Today_kWh = history.TodayKWh;
//總發電量(直接填寫
calcPowerStation.Total_kWh = history.TotalKWH;
#endregion
#region
//發電金額
switch (powerStation.SolarType)
{ {
case (int)SolarTypeEnum.SelfSold: //自建躉售 logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
//今日發電金額 計算方式todaykWh * 授電費率 history.PowerStationId = powerStation.Id;
calcPowerStation.Today_Money = history.TodayKWh * powerStation.PowerRate; history.Timestamp = Convert.ToDateTime(history.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
history.MONEY = history.KWH * powerStation.PowerRate;
//總發電金額 計算方式totalkWh * 授電費率 #region
calcPowerStation.Total_Money = history.TotalKWH * powerStation.PowerRate;
break;
case (int)SolarTypeEnum.HireSold: //租建躉售
//找出該電站的所有土地房屋資訊
var landBuildings = await powerStationRepository.GetAllLandBuildingInfoByPowerStationId(powerStation.Id, powerStation.SiteDB);
var sumLeaseRate = 0.00;
var avgLeaseRate = 0.00;
foreach (var landBuilding in landBuildings) #region
{ //每小時發電量(直接填寫
sumLeaseRate += landBuilding.LeaseRate; calcPowerStation.kwh = history.KWH;
} //今日發電量(直接填寫
//avgLeaseRate = sumLeaseRate / landBuildings.Count(); calcPowerStation.Today_kWh = history.TodayKWh;
//總發電量(直接填寫
calcPowerStation.Total_kWh = history.TotalKWH;
#endregion
//今日發電金額計算方式todaykWh * 出借費率(各個土地房屋租借比率平均) #region
calcPowerStation.Today_Money = history.TodayKWh * sumLeaseRate; //發電金額
switch (powerStation.SolarType)
history.MONEY = history.KWH * sumLeaseRate;
//總發電金額 計算方式totalkWh * 授電費率
calcPowerStation.Total_Money = history.TotalKWH * sumLeaseRate;
break;
case (int)SolarTypeEnum.SelfUse: //自建自用
//今日發電金額 計算方式todaykWh * 授電費率
calcPowerStation.Today_Money = history.TodayKWh * powerStation.PowerRate;
history.MONEY = history.KWH * powerStation.PowerRate;
//總發電金額 計算方式totalkWh * 授電費率
calcPowerStation.Total_Money = history.TotalKWH * powerStation.PowerRate;
break;
}
#endregion
#region kWh/kWp
//直接填寫
calcPowerStation.Today_kwhkwp = history.KWHKWP;
#endregion
#region PR
//直接填寫
calcPowerStation.Today_PR = history.PR;
#endregion
#region
carbonRate = Convert.ToDouble(await powerStationRepository.GetOneVariableByName("CarbonRate"));
//今日減碳量( 今日發電量 * (0.554/1000)[抓資料庫值]
calcPowerStation.Today_Carbon = history.TodayKWh * carbonRate;
history.CARBON = history.KWH * carbonRate;
//總減碳量(總發電量 * (0.554/1000)[抓資料庫值]
calcPowerStation.Total_Carbon = history.TotalKWH * carbonRate;
if (lastmoneyhistorybyhour != null)
{
history.TODAYCARBON = lastmoneyhistorybyhour.TODAYCARBON + history.KWH * carbonRate;
history.TOTALCARBON = lastmoneyhistorybyhour.TOTALCARBON + history.KWH * carbonRate;
history.TODAYMONEY = lastmoneyhistorybyhour.TODAYMONEY + history.KWH * powerStation.PowerRate;
history.TOTALMONEY = lastmoneyhistorybyhour.TOTALMONEY + history.KWH * powerStation.PowerRate;
}
else
{
history.TODAYCARBON = history.KWH * carbonRate;
history.TOTALCARBON = history.KWH * carbonRate;
history.TODAYMONEY = history.KWH * powerStation.PowerRate;
history.TOTALMONEY = history.KWH * powerStation.PowerRate;
}
#endregion
#region
calcPowerStation.SolarHour = history.SolarHour;
#endregion
#endregion
powerStationHistoriesHour.Add(history);
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
}
#endregion
#region step2-2.
//1. 找出該電站所有日照計設備(包含共享
logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime);
var deviceInfos = await powerStationRepository.GetListPyrheliometerByPowerStationId(powerStation.Id, powerStation.SiteDB);
logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime);
logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的日照計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(deviceInfos));
if (deviceInfos != null && deviceInfos.Count() > 0)
{
//2. 計算該電站所有日照計設的每小時的平均在依照日照計數量平均
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的日照計的日照度】", powerStation.Code, dateTime);
var pyrheliometerHistory = await powerStationRepository.GetPyrheliometerHistoryPerHour(dateTime, deviceInfos, 0);
if (pyrheliometerHistory != null)
{
calcPowerStation.Today_irradiance = pyrheliometerHistory.Irradiance;
pyrheliometerHistory.Timestamp = Convert.ToDateTime(pyrheliometerHistory.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
pyrheliometerHistory.PowerStationId = powerStation.Id;
pyrheliometerHistoriesHour.Add(pyrheliometerHistory);
}
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的日照計的日照度】", powerStation.Code, dateTime);
}
//2. 計算該電站所有溫度計設的每小時的平均在依照溫度計數量平均
// 找出該電站所有溫度計設備(包含共享
logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的溫度計設備資訊】", powerStation.Code, dateTime);
var tempdeviceInfos = await powerStationRepository.GetListTempByPowerStationId(powerStation.Id, powerStation.SiteDB);
logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的溫度計設備資訊】", powerStation.Code, dateTime);
logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的溫度計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(tempdeviceInfos));
if (tempdeviceInfos != null && tempdeviceInfos.Count() > 0)
{
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的溫度計的平均溫度】", powerStation.Code, dateTime);
var tempHistory = await powerStationRepository.GetPyrheliometerHistoryPerHour(dateTime, tempdeviceInfos, 1);
if (tempHistory != null)
{
tempHistory.Timestamp = Convert.ToDateTime(tempHistory.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
tempHistory.PowerStationId = powerStation.Id;
TempHistoriesHour.Add(tempHistory);
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的溫度計的平均溫度】", powerStation.Code, dateTime);
}
}
#endregion
calcPowerStations.Add(calcPowerStation);
}
#region step2-3.
logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime);
var controllers = await powerStationRepository.GetAllDeviceControllerId(powerStation.Id, powerStation.SiteDB);
var inverters = await powerStationRepository.InverterTable(controllers, powerStation.SiteDB);
var inverterIds = inverters.Where(x => x.Enabled == 1 && x.Status != 0).Select(x => x.InverterId).ToList();
logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime);
logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的逆變器設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(inverterIds));
var inverter_table_name = String.Format("s{0}01_inv", powerStation.Code);
var full_inverter_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, inverter_table_name);
var exist_inverter_table = await powerStationRepository.ExistTable(powerStation.SiteDB, inverter_table_name);
if (!string.IsNullOrEmpty(exist_inverter_table) && inverterIds != null && inverterIds.Count() > 0)
{
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime);
var inverterHistories = await powerStationRepository.CalcInverterHisyortHourData(dateTime, powerStation.SiteDB, full_inverter_table_name, inverterIds);
//取得日照計要找的欄位資訊
var pyrheliometer = await powerStationRepository.GetFirstPyrheliometerInfo(powerStation.Id, powerStation.SiteDB);
var pyrheliometerValue = await powerStationRepository.GetFirstPyrheliometerValue(dateTime, pyrheliometer.DBName, pyrheliometer.TableName, pyrheliometer.ColName);
foreach (var inverterHistory in inverterHistories)
{
inverterHistory.Irradiance = pyrheliometerValue;
inverterHistory.DC1KW = inverterHistory.DC1W / 1000;
inverterHistory.DC2KW = inverterHistory.DC2W / 1000;
inverterHistory.DC3KW = inverterHistory.DC3W / 1000;
inverterHistory.DC4KW = inverterHistory.DC4W / 1000;
inverterHistory.DC5KW = inverterHistory.DC5W / 1000;
inverterHistory.DCKW = (inverterHistory.DC1W + inverterHistory.DC2W + inverterHistory.DC3W + inverterHistory.DC4W + inverterHistory.DC5W) / 1000;
inverterHistory.ACKW = (inverterHistory.AC1W + inverterHistory.AC2W + inverterHistory.AC3W) / 1000;
inverterHistory.TIMESTAMP = Convert.ToDateTime(inverterHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
inverterHistory.PowerStationId = powerStation.Id;
inverterHistoriesHour.Add(inverterHistory);
}
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime);
}
#endregion
#region step2-4. sensoravg
var seneoravg_table_name = String.Format("s{0}01_sensoravg", powerStation.Code);
var full_seneoravg_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, seneoravg_table_name);
var exist_seneoravg_table = await powerStationRepository.ExistTable(powerStation.SiteDB, seneoravg_table_name);
if (!string.IsNullOrEmpty(exist_seneoravg_table))
{
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime);
var sensorAvgHistory = await powerStationRepository.CalcSensorAvgHistory(dateTime, full_seneoravg_table_name);
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime);
if (sensorAvgHistory != null)
{
sensorAvgHistory.PowerStationId = powerStation.Id;
sensorAvgHistory.TIMESTAMP = Convert.ToDateTime(sensorAvgHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
sensorAvgHistoryHour.Add(sensorAvgHistory);
}
}
#endregion
#region step2-5. meter
var meter_table_name = String.Format("s{0}01_meter", powerStation.Code);
var full_meter_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, meter_table_name);
var exist_meter_table = await powerStationRepository.ExistTable(powerStation.SiteDB, meter_table_name);
if (!string.IsNullOrEmpty(exist_meter_table))
{
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime);
var meterHistory = await powerStationRepository.CalcMeterHistory(dateTime, full_meter_table_name);
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime);
if (meterHistory != null)
{
meterHistory.PowerStationId = powerStation.Id;
meterHistory.TIMESTAMP = Convert.ToDateTime(meterHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
meterHistoriesHour.Add(meterHistory);
}
}
#endregion
#region ()
if (powerStation.WeathersStationId == null)
{
var weatherStationId = "";
double shortLocation = 9999;
foreach (var Location in observation.Records.Location)
{
if (powerStation.Coordinate != null)
{
var powerLocation = powerStation.Coordinate.Split(',');
var nowLocation = Math.Sqrt(Math.Pow(Convert.ToDouble(powerLocation[0]) - Convert.ToDouble(Location.Lat), 2) + Math.Pow(Convert.ToDouble(powerLocation[1]) - Convert.ToDouble(Location.Lon), 2));
if (nowLocation < shortLocation)
{ {
shortLocation = nowLocation; case (int)SolarTypeEnum.SelfSold: //自建躉售
weatherStationId = Location.StationId; //今日發電金額 計算方式todaykWh * 授電費率
calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue); calcPowerStation.Today_Money = history.TodayKWh * powerStation.PowerRate;
history.MONEY = history.KWH * powerStation.PowerRate;
//總發電金額 計算方式totalkWh * 授電費率
calcPowerStation.Total_Money = history.TotalKWH * powerStation.PowerRate;
break;
case (int)SolarTypeEnum.HireSold: //租建躉售
//找出該電站的所有土地房屋資訊
var landBuildings = await powerStationRepository.GetAllLandBuildingInfoByPowerStationId(powerStation.Id, powerStation.SiteDB);
var sumLeaseRate = 0.00;
var avgLeaseRate = 0.00;
foreach (var landBuilding in landBuildings)
{
sumLeaseRate += landBuilding.LeaseRate;
}
//avgLeaseRate = sumLeaseRate / landBuildings.Count();
//今日發電金額計算方式todaykWh * 出借費率(各個土地房屋租借比率平均)
calcPowerStation.Today_Money = history.TodayKWh * sumLeaseRate;
history.MONEY = history.KWH * sumLeaseRate;
//總發電金額 計算方式totalkWh * 授電費率
calcPowerStation.Total_Money = history.TotalKWH * sumLeaseRate;
break;
case (int)SolarTypeEnum.SelfUse: //自建自用
//今日發電金額 計算方式todaykWh * 授電費率
calcPowerStation.Today_Money = history.TodayKWh * powerStation.PowerRate;
history.MONEY = history.KWH * powerStation.PowerRate;
//總發電金額 計算方式totalkWh * 授電費率
calcPowerStation.Total_Money = history.TotalKWH * powerStation.PowerRate;
break;
}
#endregion
#region kWh/kWp
//直接填寫
calcPowerStation.Today_kwhkwp = history.KWHKWP;
#endregion
#region PR
//直接填寫
calcPowerStation.Today_PR = history.PR;
#endregion
#region
carbonRate = Convert.ToDouble(await powerStationRepository.GetOneVariableByName("CarbonRate"));
//今日減碳量( 今日發電量 * (0.554/1000)[抓資料庫值]
calcPowerStation.Today_Carbon = history.TodayKWh * carbonRate;
history.CARBON = history.KWH * carbonRate;
//總減碳量(總發電量 * (0.554/1000)[抓資料庫值]
calcPowerStation.Total_Carbon = history.TotalKWH * carbonRate;
if (lastmoneyhistorybyhour != null)
{
history.TODAYCARBON = lastmoneyhistorybyhour.TODAYCARBON + history.KWH * carbonRate;
history.TOTALCARBON = lastmoneyhistorybyhour.TOTALCARBON + history.KWH * carbonRate;
history.TODAYMONEY = lastmoneyhistorybyhour.TODAYMONEY + history.KWH * powerStation.PowerRate;
history.TOTALMONEY = lastmoneyhistorybyhour.TOTALMONEY + history.KWH * powerStation.PowerRate;
}
else
{
history.TODAYCARBON = history.KWH * carbonRate;
history.TOTALCARBON = history.KWH * carbonRate;
history.TODAYMONEY = history.KWH * powerStation.PowerRate;
history.TOTALMONEY = history.KWH * powerStation.PowerRate;
}
#endregion
#region
calcPowerStation.SolarHour = history.SolarHour;
#endregion
#endregion
powerStationHistoriesHour.Add(history);
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的每小時歷史資料】", powerStation.Code, dateTime);
}
#endregion
#region step2-2.
//1. 找出該電站所有日照計設備(包含共享
logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime);
var deviceInfos = await powerStationRepository.GetListPyrheliometerByPowerStationId(powerStation.Id, powerStation.SiteDB);
logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的日照計設備資訊】", powerStation.Code, dateTime);
logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的日照計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(deviceInfos));
if (deviceInfos != null && deviceInfos.Count() > 0)
{
//2. 計算該電站所有日照計設的每小時的平均在依照日照計數量平均
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的日照計的日照度】", powerStation.Code, dateTime);
var pyrheliometerHistory = await powerStationRepository.GetPyrheliometerHistoryPerHour(dateTime, deviceInfos, 0);
if (pyrheliometerHistory != null)
{
calcPowerStation.Today_irradiance = pyrheliometerHistory.Irradiance;
pyrheliometerHistory.Timestamp = Convert.ToDateTime(pyrheliometerHistory.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
pyrheliometerHistory.PowerStationId = powerStation.Id;
pyrheliometerHistoriesHour.Add(pyrheliometerHistory);
}
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的日照計的日照度】", powerStation.Code, dateTime);
}
//2. 計算該電站所有溫度計設的每小時的平均在依照溫度計數量平均
// 找出該電站所有溫度計設備(包含共享
logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的溫度計設備資訊】", powerStation.Code, dateTime);
var tempdeviceInfos = await powerStationRepository.GetListTempByPowerStationId(powerStation.Id, powerStation.SiteDB);
logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的溫度計設備資訊】", powerStation.Code, dateTime);
logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的溫度計設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(tempdeviceInfos));
if (tempdeviceInfos != null && tempdeviceInfos.Count() > 0)
{
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的溫度計的平均溫度】", powerStation.Code, dateTime);
var tempHistory = await powerStationRepository.GetPyrheliometerHistoryPerHour(dateTime, tempdeviceInfos, 1);
if (tempHistory != null)
{
tempHistory.Timestamp = Convert.ToDateTime(tempHistory.Timestamp + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
tempHistory.PowerStationId = powerStation.Id;
TempHistoriesHour.Add(tempHistory);
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的溫度計的平均溫度】", powerStation.Code, dateTime);
} }
} }
#endregion
calcPowerStations.Add(calcPowerStation);
} }
calcPowerStation.WeathersStationId = weatherStationId; #region step2-3.
} logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime);
#endregion var controllers = await powerStationRepository.GetAllDeviceControllerId(powerStation.Id, powerStation.SiteDB);
var inverters = await powerStationRepository.InverterTable(controllers, powerStation.SiteDB);
var inverterIds = inverters.Where(x => x.Enabled == 1 && x.Status != 0).Select(x => x.InverterId).ToList();
logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的逆變器設備資訊】", powerStation.Code, dateTime);
logger.LogInformation("【CalcPowerStationJob】【電站[{0}]在{1}的逆變器設備資訊】 - {2}", powerStation.Code, dateTime, System.Text.Json.JsonSerializer.Serialize(inverterIds));
WeatherObservation weatherObservation = new WeatherObservation(); var inverter_table_name = String.Format("s{0}01_inv", powerStation.Code);
if (powerStation.WeathersStationId != null) var full_inverter_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, inverter_table_name);
{ var exist_inverter_table = await powerStationRepository.ExistTable(powerStation.SiteDB, inverter_table_name);
foreach (var Location in observation.Records.Location)
if (!string.IsNullOrEmpty(exist_inverter_table) && inverterIds != null && inverterIds.Count() > 0)
{ {
if (Location.StationId == powerStation.WeathersStationId) logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime);
var inverterHistories = await powerStationRepository.CalcInverterHisyortHourData(dateTime, powerStation.SiteDB, full_inverter_table_name, inverterIds);
//取得日照計要找的欄位資訊
var pyrheliometer = await powerStationRepository.GetFirstPyrheliometerInfo(powerStation.Id, powerStation.SiteDB);
var pyrheliometerValue = await powerStationRepository.GetFirstPyrheliometerValue(dateTime, pyrheliometer.DBName, pyrheliometer.TableName, pyrheliometer.ColName);
foreach (var inverterHistory in inverterHistories)
{ {
inverterHistory.Irradiance = pyrheliometerValue;
inverterHistory.DC1KW = inverterHistory.DC1W / 1000;
inverterHistory.DC2KW = inverterHistory.DC2W / 1000;
inverterHistory.DC3KW = inverterHistory.DC3W / 1000;
inverterHistory.DC4KW = inverterHistory.DC4W / 1000;
inverterHistory.DC5KW = inverterHistory.DC5W / 1000;
calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue); inverterHistory.DCKW = (inverterHistory.DC1W + inverterHistory.DC2W + inverterHistory.DC3W + inverterHistory.DC4W + inverterHistory.DC5W) / 1000;
weatherObservation.PowerStationId = powerStation.Id; inverterHistory.ACKW = (inverterHistory.AC1W + inverterHistory.AC2W + inverterHistory.AC3W) / 1000;
weatherObservation.Temp = Convert.ToDouble(Location.WeatherElement[0].ElementValue);
weatherObservation.ObsTime = !string.IsNullOrEmpty(Location.Time.ObsTime)? Convert.ToInt32(Location.Time.ObsTime.Substring(0, 4)) >= 1971 ? Location.Time.ObsTime : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); inverterHistory.TIMESTAMP = Convert.ToDateTime(inverterHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
calcPowerStation.WeathersStationId = powerStation.WeathersStationId; inverterHistory.PowerStationId = powerStation.Id;
break;
inverterHistoriesHour.Add(inverterHistory);
}
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的逆變器的資訊】", powerStation.Code, dateTime);
}
#endregion
#region step2-4. sensoravg
var seneoravg_table_name = String.Format("s{0}01_sensoravg", powerStation.Code);
var full_seneoravg_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, seneoravg_table_name);
var exist_seneoravg_table = await powerStationRepository.ExistTable(powerStation.SiteDB, seneoravg_table_name);
if (!string.IsNullOrEmpty(exist_seneoravg_table))
{
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime);
var sensorAvgHistory = await powerStationRepository.CalcSensorAvgHistory(dateTime, full_seneoravg_table_name);
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的sensor avg的資訊】", powerStation.Code, dateTime);
if (sensorAvgHistory != null)
{
sensorAvgHistory.PowerStationId = powerStation.Id;
sensorAvgHistory.TIMESTAMP = Convert.ToDateTime(sensorAvgHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
sensorAvgHistoryHour.Add(sensorAvgHistory);
} }
} }
weatherObservations.Add(weatherObservation); #endregion
}
logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime); #region step2-5. meter
var weather = await powerStationRepository.SelectNowWeather(powerStation.CityId); var meter_table_name = String.Format("s{0}01_meter", powerStation.Code);
logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime); var full_meter_table_name = String.Format("`{0}`.`{1}`", powerStation.SiteDB, meter_table_name);
if (weather != null) var exist_meter_table = await powerStationRepository.ExistTable(powerStation.SiteDB, meter_table_name);
if (!string.IsNullOrEmpty(exist_meter_table))
{
logger.LogInformation("【CalcPowerStationJob】【開始計算電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime);
var meterHistory = await powerStationRepository.CalcMeterHistory(dateTime, full_meter_table_name);
logger.LogInformation("【CalcPowerStationJob】【計算完成電站[{0}]在{1}的meter的資訊】", powerStation.Code, dateTime);
if (meterHistory != null)
{
meterHistory.PowerStationId = powerStation.Id;
meterHistory.TIMESTAMP = Convert.ToDateTime(meterHistory.TIMESTAMP + ":00:00").ToString("yyyy-MM-dd HH:mm:ss");
meterHistoriesHour.Add(meterHistory);
}
}
#endregion
#region ()
if (powerStation.WeathersStationId == null)
{
var weatherStationId = "";
double shortLocation = 9999;
foreach (var Location in observation.Records.Location)
{
if (powerStation.Coordinate != null)
{
var powerLocation = powerStation.Coordinate.Split(',');
var nowLocation = Math.Sqrt(Math.Pow(Convert.ToDouble(powerLocation[0]) - Convert.ToDouble(Location.Lat), 2) + Math.Pow(Convert.ToDouble(powerLocation[1]) - Convert.ToDouble(Location.Lon), 2));
if (nowLocation < shortLocation)
{
shortLocation = nowLocation;
weatherStationId = Location.StationId;
calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue);
}
}
}
calcPowerStation.WeathersStationId = weatherStationId;
}
#endregion
WeatherObservation weatherObservation = new WeatherObservation();
if (powerStation.WeathersStationId != null && observation != null)
{
foreach (var Location in observation.Records.Location)
{
if (Location.StationId == powerStation.WeathersStationId)
{
calcPowerStation.TodayWeatherTemp = Convert.ToDouble(Location.WeatherElement[0].ElementValue);
weatherObservation.PowerStationId = powerStation.Id;
weatherObservation.Temp = Convert.ToDouble(Location.WeatherElement[0].ElementValue);
weatherObservation.ObsTime = !string.IsNullOrEmpty(Location.Time.ObsTime) ? Convert.ToInt32(Location.Time.ObsTime.Substring(0, 4)) >= 1971 ? Location.Time.ObsTime : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") : DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
calcPowerStation.WeathersStationId = powerStation.WeathersStationId;
break;
}
}
weatherObservations.Add(weatherObservation);
}
logger.LogInformation("【CalcPowerStationJob】【開始取得電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime);
var weather = await powerStationRepository.SelectNowWeather(powerStation.CityId);
logger.LogInformation("【CalcPowerStationJob】【取得成功電站[{0}]在{1}的天氣預報的資訊】", powerStation.Code, dateTime);
if (weather != null)
{
calcPowerStation.TodayWeather = weather.WeatherKey;
calcPowerStation.RateOfRain = weather.PoP;
}
}
catch (Exception exception)
{ {
calcPowerStation.TodayWeather = weather.WeatherKey; logger.LogError("【{0}】{1}", "CalcPowerStationJob", exception.Message);
calcPowerStation.RateOfRain = weather.PoP;
} }
} }
#endregion #endregion

View File

@ -486,6 +486,7 @@ namespace SolarPower.Repository.Implement
`InverterId` varchar(50) DEFAULT NULL COMMENT 'UID', `InverterId` varchar(50) DEFAULT NULL COMMENT 'UID',
`ControllerId` int(10) DEFAULT NULL COMMENT '', `ControllerId` int(10) DEFAULT NULL COMMENT '',
`Brand` varchar(50) DEFAULT NULL COMMENT '', `Brand` varchar(50) DEFAULT NULL COMMENT '',
`BrandNum` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '',
`Model` varchar(50) DEFAULT NULL COMMENT '', `Model` varchar(50) DEFAULT NULL COMMENT '',
`Capacity` double(10,3) DEFAULT NULL COMMENT ' kWp', `Capacity` double(10,3) DEFAULT NULL COMMENT ' kWp',
`Pyrheliometer` int(10) DEFAULT NULL COMMENT '', `Pyrheliometer` int(10) DEFAULT NULL COMMENT '',

View File

@ -5037,5 +5037,32 @@ namespace SolarPower.Repository.Implement
return result; return result;
} }
} }
public async Task<List<InverterHistory>> GetAllInverterInfo(List<string> post,string site_table, string site_db)
{
List<InverterHistory> result;
using (IDbConnection conn = this._databaseHelper.GetConnection())
{
try
{
var sql = @$"SELECT b.*,c.InverterName as INVERTERName,c.ID as ID FROM
(
SELECT MAX(aa.TIMESTAMP) AS maxtime ,aa.INVERTERID from (SELECT * from {site_db}.{site_table} ORDER BY ID desc LIMIT 1000) aa GROUP BY INVERTERID
) a
LEFT JOIN
(SELECT * from {site_db}.{site_table} ORDER BY ID desc LIMIT 1000) b ON a.maxtime = b.TIMESTAMP AND a.INVERTERID = b.INVERTERID
LEFT JOIN {site_db}.inverter c ON b.INVERTERID = c.InverterId
WHERE b.INVERTERID in @ids
";
result = (await conn.QueryAsync<InverterHistory>(sql, new { ids = post })).ToList();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
} }
} }

View File

@ -587,5 +587,7 @@ namespace SolarPower.Repository.Interface
Task AddAfterPurgeSensorAvgHistory(string startDate, string endDate, byte type, List<SensorAvgHistory> entity, List<string> properties); Task AddAfterPurgeSensorAvgHistory(string startDate, string endDate, byte type, List<SensorAvgHistory> entity, List<string> properties);
Task<bool> CheckShowMoney(int userid); Task<bool> CheckShowMoney(int userid);
Task<List<InverterHistory>> GetAllInverterRowData(string date, string table_name); Task<List<InverterHistory>> GetAllInverterRowData(string date, string table_name);
Task<List<InverterHistory>> GetAllInverterInfo(List<string> post, string site_table, string site_db);
} }
} }

View File

@ -43,6 +43,11 @@
<i class="fal fa-list-alt text-success"></i> <span class="hidden-sm-down ml-1">裝置列表</span> <i class="fal fa-list-alt text-success"></i> <span class="hidden-sm-down ml-1">裝置列表</span>
</a> </a>
</li> </li>
<li class="nav-item">
<a class="nav-link fs-lg px-4" data-toggle="tab" href="#tab-inverter" role="tab">
<i class="fal fa-sensor-alert text-success"></i> <span class="hidden-sm-down ml-1">逆變器監控</span>
</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link fs-lg px-4" data-toggle="tab" href="#tab-operation-firm" role="tab"> <a class="nav-link fs-lg px-4" data-toggle="tab" href="#tab-operation-firm" role="tab">
<i class="fal fa-hands-helping text-success"></i> <span class="hidden-sm-down ml-1">維運廠商</span> <i class="fal fa-hands-helping text-success"></i> <span class="hidden-sm-down ml-1">維運廠商</span>
@ -58,6 +63,7 @@
<i class="fal fa-sensor-alert text-success"></i> <span class="hidden-sm-down ml-1">異常設定</span> <i class="fal fa-sensor-alert text-success"></i> <span class="hidden-sm-down ml-1">異常設定</span>
</a> </a>
</li> </li>
</ul> </ul>
<div class="tab-content p-3"> <div class="tab-content p-3">
<div class="tab-pane fade show active" id="tab-station-info" role="tabpanel" aria-labelledby="tab-station-info"> <div class="tab-pane fade show active" id="tab-station-info" role="tabpanel" aria-labelledby="tab-station-info">
@ -68,6 +74,10 @@
@Html.Partial("_DeviceSetting") @Html.Partial("_DeviceSetting")
</div> </div>
<div class="tab-pane fade" id="tab-inverter" role="tabpanel" aria-labelledby="tab-inverter">
@Html.Partial("_Inverter")
</div>
<div class="tab-pane fade" id="tab-operation-firm" role="tabpanel" aria-labelledby="tab-operation-firm"> <div class="tab-pane fade" id="tab-operation-firm" role="tabpanel" aria-labelledby="tab-operation-firm">
@Html.Partial("_Operation") @Html.Partial("_Operation")
</div> </div>
@ -79,6 +89,8 @@
<div class="tab-pane fade" id="tab-exception" role="tabpanel" aria-labelledby="tab-exception"> <div class="tab-pane fade" id="tab-exception" role="tabpanel" aria-labelledby="tab-exception">
@Html.Partial("_Exception") @Html.Partial("_Exception")
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -86,6 +98,8 @@
</div> </div>
</div> </div>
<div class="page-content-overlay" data-action="toggle" data-class="mobile-nav-on"></div>
@section Scripts{ @section Scripts{
<script> <script>
var stationId; var stationId;
@ -95,6 +109,7 @@
var selected_id = 0; var selected_id = 0;
var countPowerStationImage = 0; var countPowerStationSingleLine = 0; var countPowerStationImage = 0; var countPowerStationSingleLine = 0;
var upper = 0; var upper = 0;
var stationDB = "";
$(function () { $(function () {
var url = new URL(location.href); var url = new URL(location.href);
stationId = url.searchParams.get('stationId'); stationId = url.searchParams.get('stationId');
@ -883,6 +898,17 @@
}); });
}); });
//#endregion //#endregion
GetInverterCard(stationId);
if (typeof (Worker) !== "undefined") {
var worker = new Worker('../js/workers/workers.js');
worker.onmessage = function (event) {
if (event.data == "ok") {
GetInverterCard(stationId);
}
}
}
}); });
//#region 代管切換 //#region 代管切換
@ -2849,5 +2875,200 @@
} }
}); });
function GetInverterCard(stationId)
{
var url = "/PowerStation/GetOnePowerStation/";
var send_data = {
id: stationId
}
$.post(url, send_data, function (rel) {
if (rel.code != "0000") {
toast_error(rel.msg);
return;
}
$("#Invertercard-Name").html(rel.data.name);
$("#Invertercard-kwh").html(rel.data.kwh);
$("#Invertercard-money").html(rel.data.today_Money);
$("#Invertercard-pr").html(rel.data.today_PR);
var str = "<div class='progress progress-sm ' id='prbar'>" +
"<div class='progress-bar bg-info' role = 'progressbar' style = 'width: " + rel.data.today_PR + "%;' aria - valuenow='" + rel.data.today_PR +"' aria - valuemin='0' aria - valuemax='100' ></div > </div >"
$('#prbar').remove();
$("#Invertercard").append(str);
var TypeName = "";
switch (rel.data.solarType) {
case 0:
TypeName = "自建躉售";
break;
case 1:
TypeName = "租建躉售";
break;
case 2:
TypeName = "自建自用";
break;
}
$("#Invertercard-type").html(TypeName);
var time = new Date(rel.data.createdAt);
$("#Invertercard-date").html(time.getMonth() + "/" + time.getDate() + " " + time.getHours() + ":" + time.getMinutes())
$("#Invertercard").find('.card-img-top').attr('src', "../upload/power_station/" + rel.data.id + "/" + rel.data.mainDisplay);
$('#Invertercard-Temp').html(rel.data.todayWeatherTemp + '°C');
$('#Invertercard-weathericon').attr("class", 'fal fa-' + rel.data.todayWeather + ' fa-2x');
stationDB = rel.data.siteDB;
InverterInfoList();
}, 'json');
};
function InverterInfoList()
{
var url = "/PowerStation/GetInverterInfoList/";
var send_data = {
id: stationId,
siteDB: stationDB
}
$.post(url, send_data, function (rel) {
if (rel.code == "9999") {
toast_error(rel.msg);
return;
}
if (rel.code == "0001") {
toast_warning(rel.msg);
return;
}
$("#ullist").empty();
var long = rel.data.length <= 4 ? rel.data.length : 4;
for (var a = 0; a < long; a++)
{
var str = "<li class='col-xl-3' id='li_" + a + "'>";
str += '<div class="card border m-auto m-lg-0">';
str += '<div class="card-body d-flex justify-content-between pb-0 px-2 bg-fusion-25">';
str += '<p class="font-weight-bold"> <i class="fal fa-ballot-check"></i> ' + rel.data[a].name + '</p>';
str += '</div>';
str += '<div class="list-group list-group-flush">';
str += '<div class="list-group-item px-2">';
str += '<div class=" d-flex justify-content-between">';
str += '<p class="mb-0">設備狀態</p>';
if (rel.data[a].type == 1) {
str += '<p class="mb-0"><span class="color-info-700 font-weight-bold">正常</span></p>';
}
else {
str += '<p class="mb-0"><span class="color-info-700 font-weight-bold">異常</span></p>';
}
str += '<p class="mb-0"><span class="color-info-700 font-weight-bold"><a href="javascript:;" OnClick="InverterInfoDetail(' + rel.data[a].id + ')">詳細資料</a></span></p>';
str += '</div>';
str += '</div>';
str += '<div class="list-group-item px-2 bg-info-20">';
str += '<div class=" d-flex justify-content-between">';
str += '<p class="mb-0">輸出功率</p>';
str += '<p class="mb-0">' + rel.data[a].output.toFixed(2) + '</p>';
str += '<p class="mb-0">kw</p>';
str += '</div>';
str += '</div>';
str += '<div class="list-group-item px-2">';
str += '<div class=" d-flex justify-content-between">';
str += '<p class="mb-0">輸入功率</p>';
str += '<p class="mb-0">' + rel.data[a].input.toFixed(2) + '</p>';
str += '<p class="mb-0">kw</p>';
str += '</div>';
str += '</div>';
str += '<div class="list-group-item px-2 bg-info-20">';
str += '<div class="d-flex">';
str += 'PR <span class="d-inline-block ml-auto">' + rel.data[a].pr.toFixed(2) + '%</span>';
str += '</div>';
str += '<div class="progress progress-sm mb-3">';
str += '<div class="progress-bar bg-info-400" role="progressbar" style="width: ' + rel.data[a].pr.toFixed(2) + '%;" aria-valuenow="' + rel.data[a].pr.toFixed(2) + '" aria-valuemin="0" aria-valuemax="100"></div>';
str += '</div>';
str += '</div>';
str += '<div class="list-group-item px-2">';
str += '<div class=" d-flex justify-content-between">';
str += '<p class="mb-0">日發電量</p>';
str += '<p class="mb-0">' + rel.data[a].todaykwh.toFixed(2) + '</p>';
str += '<p class="mb-0">kWh</p>';
str += '</div>';
str += '</div>';
str += '</div>';
str += '</div>';
str += '</li>';
$("#ullist").append(str);
}
if (rel.data.length >= 4)
{
for (var a = 4; a < rel.data.length; a++)
{
var str = '<ul>';
str += '<div class="card border m-auto m-lg-0">';
str += '<div class="card-body d-flex justify-content-between pb-0 px-2 bg-fusion-25">';
str += '<p class="font-weight-bold"> <i class="fal fa-ballot-check"></i> ' + rel.data[a].name + '</p>';
str += '</div>';
str += '<div class="list-group list-group-flush">';
str += '<div class="list-group-item px-2">';
str += '<div class=" d-flex justify-content-between">';
str += '<p class="mb-0">設備狀態</p>';
if (rel.data[a].type == 1) {
str += '<p class="mb-0"><span class="color-info-700 font-weight-bold">正常</span></p>';
}
else {
str += '<p class="mb-0"><span class="color-info-700 font-weight-bold">異常</span></p>';
}
str += '<p class="mb-0"><span class="color-info-700 font-weight-bold"><a href="javascript:;" OnClick="InverterInfoDetail(' + rel.data[a].id + ')">詳細資料</a></span></p>';
str += '</div>';
str += '</div>';
str += '<div class="list-group-item px-2 bg-info-20">';
str += '<div class=" d-flex justify-content-between">';
str += '<p class="mb-0">輸出功率</p>';
str += '<p class="mb-0">' + rel.data[a].output.toFixed(2) + '</p>';
str += '<p class="mb-0">kw</p>';
str += '</div>';
str += '</div>';
str += '<div class="list-group-item px-2">';
str += '<div class=" d-flex justify-content-between">';
str += '<p class="mb-0">輸入功率</p>';
str += '<p class="mb-0">' + rel.data[a].input.toFixed(2) + '</p>';
str += '<p class="mb-0">kw</p>';
str += '</div>';
str += '</div>';
str += '<div class="list-group-item px-2 bg-info-20">';
str += '<div class="d-flex">';
str += 'PR <span class="d-inline-block ml-auto">' + rel.data[a].pr.toFixed(2) + '%</span>';
str += '</div>';
str += '<div class="progress progress-sm mb-3">';
str += '<div class="progress-bar bg-info-400" role="progressbar" style="width: ' + rel.data[a].pr.toFixed(2) + '%;" aria-valuenow="' + rel.data[a].pr.toFixed(2) + '" aria-valuemin="0" aria-valuemax="100"></div>';
str += '</div>';
str += '</div>';
str += '<div class="list-group-item px-2">';
str += '<div class=" d-flex justify-content-between">';
str += '<p class="mb-0">日發電量</p>';
str += '<p class="mb-0">' + rel.data[a].todaykwh.toFixed(2) + '</p>';
str += '<p class="mb-0">kWh</p>';
str += '</div>';
str += '</div>';
str += '</div>';
str += '</div>';
str += '</ul>';
$("#li_" + a % 4).append(str);
}
};
});
}
function InverterInfoDetail(id) {
$("#inverterdetailmodal").modal();
}
</script> </script>
} }

View File

@ -0,0 +1,546 @@
<div class="row my-5">
<div class="tree w-100">
<ul>
<li class=" w-100">
<div class="mx-auto" style="width: 20%;">
<div class="card border m-auto m-lg-0" id="Invertercard">
<a href="0station.html"> <img src="img/card-backgrounds/cover-3-lg.png" class="card-img-top" alt="..."> </a>
<div class="card-body d-flex justify-content-between pb-0 px-2">
<h4 class="font-weight-bold" style="line-height: 27px;" id="Invertercard-Name"> <a href="javascript:void(0);" class="btn btn-success btn-sm btn-icon rounded-circle waves-effect waves-themed"> <i class="fal fa-check"></i> </a> 新竹巨城站</h4>
<p class="card-text"><i class="fal fa-cloud-sun-rain fa-2x" id="Invertercard-weathericon"></i></p>
</div>
<div class="list-group list-group-flush">
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p>發電量</p>
<p><span class="color-info-700 font-weight-bold" id="Invertercard-kwh">185</span> kWh</p>
<p id="Invertercard-Temp">27°C</p>
</div>
<div class=" d-flex justify-content-between">
<p>發電金額</p>
<p><span class="color-info-700 font-weight-bold" id="Invertercard-money">2,5840</span> NT</p>
<p class="color-info-700 font-weight-bold" id="Invertercard-type">自建躉售</p>
</div>
<div class=" d-flex justify-content-between">
<p>Pr值</p>
<p><span class="color-info-700 font-weight-bold" id="Invertercard-pr">90</span> %</p>
<p class="small" id="Invertercard-date">17:50:36</p>
</div>
</div>
</div>
</div>
</div>
<ul id="ullist">
<li class="col-xl-3">
<div class="card border m-auto m-lg-0">
<div class="card-body d-flex justify-content-between pb-0 px-2 bg-fusion-25">
<p class="font-weight-bold"> <i class="fal fa-ballot-check"></i> 逆變器 022020001010001 (96.6kWp)</p>
<p class="card-text">4分鐘前</p>
</div>
<div class="list-group list-group-flush">
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">設備狀態</p>
<p class="mb-0"><span class="color-info-700 font-weight-bold">正常</span></p>
<p class="mb-0"><span class="color-info-700 font-weight-bold"><a href="javascript:;" data-toggle="modal" data-target="#default-example-modal-center">詳細資料</a></span></p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸出功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸入功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class="d-flex">
PR
<span class="d-inline-block ml-auto">36.3%</span>
</div>
<div class="progress progress-sm mb-3">
<div class="progress-bar bg-info-400" role="progressbar" style="width: 36.3%;" aria-valuenow="36" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">日發電量</p>
<p class="mb-0">83.1</p>
<p class="mb-0">kWh</p>
</div>
</div>
</div>
</div>
<ul>
<li class="w-100 px-0">
<div class="card border m-auto m-lg-0">
<div class="card-body d-flex justify-content-between pb-0 px-2 bg-fusion-25">
<p class="font-weight-bold"> <i class="fal fa-ballot-check"></i> 逆變器 022020001010001 (96.6kWp)</p>
<p class="card-text">4分鐘前</p>
</div>
<div class="list-group list-group-flush">
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">設備狀態</p>
<p class="mb-0"><span class="color-info-700 font-weight-bold">正常</span></p>
<p class="mb-0"><span class="color-info-700 font-weight-bold"><a href="javascript:;" OnClick='InverterInfoDetail()'>詳細資料</a></span></p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸出功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸入功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class="d-flex">
PR
<span class="d-inline-block ml-auto">36.3%</span>
</div>
<div class="progress progress-sm mb-3">
<div class="progress-bar bg-info-400" role="progressbar" style="width: 36.3%;" aria-valuenow="36" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">日發電量</p>
<p class="mb-0">83.1</p>
<p class="mb-0">kWh</p>
</div>
</div>
</div>
</div>
</li>
</ul>
</li>
<li class="col-xl-3">
<div class="card border m-auto m-lg-0">
<div class="card-body d-flex justify-content-between pb-0 px-2 bg-fusion-25">
<p class="font-weight-bold"> <i class="fal fa-ballot-check"></i> 逆變器 022020001010001 (96.6kWp)</p>
<p class="card-text">4分鐘前</p>
</div>
<div class="list-group list-group-flush">
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">設備狀態</p>
<p class="mb-0"><span class="color-info-700 font-weight-bold">正常</span></p>
<p class="mb-0"><span class="color-info-700 font-weight-bold"><a href="javascript:;" data-toggle="modal" data-target="#default-example-modal-center">詳細資料</a></span></p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸出功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸入功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class="d-flex">
PR
<span class="d-inline-block ml-auto">36.3%</span>
</div>
<div class="progress progress-sm mb-3">
<div class="progress-bar bg-info-400" role="progressbar" style="width: 36.3%;" aria-valuenow="36" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">日發電量</p>
<p class="mb-0">83.1</p>
<p class="mb-0">kWh</p>
</div>
</div>
</div>
</div>
<ul>
<li class="w-100 px-0">
<div class="card border m-auto m-lg-0">
<div class="card-body d-flex justify-content-between pb-0 px-2 bg-fusion-25">
<p class="font-weight-bold"> <i class="fal fa-ballot-check"></i> 逆變器 022020001010001 (96.6kWp)</p>
<p class="card-text">4分鐘前</p>
</div>
<div class="list-group list-group-flush">
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">設備狀態</p>
<p class="mb-0"><span class="color-info-700 font-weight-bold">正常</span></p>
<p class="mb-0"><span class="color-info-700 font-weight-bold"><a href="javascript:;" data-toggle="modal" data-target="#default-example-modal-center">詳細資料</a></span></p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸出功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸入功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class="d-flex">
PR
<span class="d-inline-block ml-auto">36.3%</span>
</div>
<div class="progress progress-sm mb-3">
<div class="progress-bar bg-info-400" role="progressbar" style="width: 36.3%;" aria-valuenow="36" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">日發電量</p>
<p class="mb-0">83.1</p>
<p class="mb-0">kWh</p>
</div>
</div>
</div>
</div>
</li>
</ul>
</li>
<li class="col-xl-3">
<div class="card border m-auto m-lg-0">
<div class="card-body d-flex justify-content-between pb-0 px-2 bg-fusion-25">
<p class="font-weight-bold"> <i class="fal fa-ballot-check"></i> 逆變器 022020001010001 (96.6kWp)</p>
<p class="card-text">4分鐘前</p>
</div>
<div class="list-group list-group-flush">
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">設備狀態</p>
<p class="mb-0"><span class="color-info-700 font-weight-bold">正常</span></p>
<p class="mb-0"><span class="color-info-700 font-weight-bold"><a href="javascript:;" data-toggle="modal" data-target="#default-example-modal-center">詳細資料</a></span></p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸出功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸入功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class="d-flex">
PR
<span class="d-inline-block ml-auto">36.3%</span>
</div>
<div class="progress progress-sm mb-3">
<div class="progress-bar bg-info-400" role="progressbar" style="width: 36.3%;" aria-valuenow="36" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">日發電量</p>
<p class="mb-0">83.1</p>
<p class="mb-0">kWh</p>
</div>
</div>
</div>
</div>
</li>
<li class="col-xl-3">
<div class="card border m-auto m-lg-0">
<div class="card-body d-flex justify-content-between pb-0 px-2 bg-fusion-25">
<p class="font-weight-bold"> <i class="fal fa-ballot-check"></i> 逆變器 022020001010001 (96.6kWp)</p>
<p class="card-text">4分鐘前</p>
</div>
<div class="list-group list-group-flush">
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">設備狀態</p>
<p class="mb-0"><span class="color-info-700 font-weight-bold">正常</span></p>
<p class="mb-0"><span class="color-info-700 font-weight-bold"><a href="javascript:;" data-toggle="modal" data-target="#default-example-modal-center">詳細資料</a></span></p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸出功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">輸入功率</p>
<p class="mb-0">1.7</p>
<p class="mb-0">kw</p>
</div>
</div>
<div class="list-group-item px-2 bg-info-20">
<div class="d-flex">
PR
<span class="d-inline-block ml-auto">36.3%</span>
</div>
<div class="progress progress-sm mb-3">
<div class="progress-bar bg-info-400" role="progressbar" style="width: 36.3%;" aria-valuenow="36" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="list-group-item px-2">
<div class=" d-flex justify-content-between">
<p class="mb-0">日發電量</p>
<p class="mb-0">83.1</p>
<p class="mb-0">kWh</p>
</div>
</div>
</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="modal fade" id="inverterdetailmodal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">逆變器022020001010001</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true"><i class="fal fa-times"></i></span>
</button>
</div>
<div class="modal-body">
<table class="table table-bordered mb-3 text-center">
<thead class="thead-themed">
<tr>
<th>供應商</th>
<th>型號</th>
<th>廠商序號</th>
</tr>
</thead>
<tbody>
<tr>
<td>SOLAREDGE</td>
<td>SE82.8K</td>
<td>20210831002</td>
</tr>
</tbody>
</table>
<table class="table table-bordered mb-3 text-center">
<thead class="thead-themed">
<tr>
<th colspan="3">交流</th>
</tr>
<tr>
<th>組別</th>
<th>電壓(V)</th>
<th>電流(A)</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td>230.6</td>
<td>3.66</td>
</tr>
<tr>
<td>B</td>
<td>230.6</td>
<td>3.66</td>
</tr>
<tr>
<td>C</td>
<td>230.6</td>
<td>3.66</td>
</tr>
<tr>
<td colspan="3">輸出功率 <span class="color-info-700 font-weight-bold">4800</span> KW</td>
</tr>
<tr>
<td colspan="3">PR <span class="color-info-700 font-weight-bold">96.23</span> %</td>
</tr>
</tbody>
</table>
<table class="table table-bordered mb-3 text-center">
<thead class="thead-themed">
<tr>
<th colspan="5">直流</th>
</tr>
<tr>
<th>組別</th>
<th>電壓(V)</th>
<th>電流(A)</th>
<th>功率 KW</th>
<th>RA %</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>230.6</td>
<td>3.66</td>
<td>3.66</td>
<td>89.12</td>
</tr>
<tr>
<td>2</td>
<td>230.6</td>
<td>3.66</td>
<td>3.66</td>
<td>89.12</td>
</tr>
<tr>
<td>3</td>
<td>230.6</td>
<td>3.66</td>
<td>3.66</td>
<td>89.12</td>
</tr>
<tr>
<td>4</td>
<td>230.6</td>
<td>3.66</td>
<td>3.66</td>
<td>89.12</td>
</tr>
<tr>
<td>5</td>
<td>230.6</td>
<td>3.66</td>
<td>3.66</td>
<td>89.12</td>
</tr>
<tr>
<td colspan="5">直流功率 <span class="color-info-700 font-weight-bold">5200</span> KW</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">關閉</button>
</div>
</div>
</div>
</div>
<style>
/*Now the CSS Created by R.S*/
* {
margin: 0;
padding: 0;
}
.tree ul {
padding-top: 20px;
position: relative;
transition: all 0.5s;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
}
.tree li {
float: left;
text-align: center;
list-style-type: none;
position: relative;
padding: 20px 0.75rem 0 0.75rem;
transition: all 0.5s;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
}
/*We will use ::before and ::after to draw the connectors*/
.tree li::before, .tree li::after {
content: '';
position: absolute;
top: 0;
right: 50%;
border-top: 1px solid #ccc;
width: 50%;
height: 20px;
}
.tree li::after {
right: auto;
left: 50%;
border-left: 1px solid #ccc;
}
/*We need to remove left-right connectors from elements without
any siblings*/
.tree li:only-child::after, .tree li:only-child::before {
display: none;
}
/*Remove space from the top of single children*/
.tree li:only-child {
padding-top: 0;
}
/*Remove left connector from first child and
right connector from last child*/
.tree li:first-child::before, .tree li:last-child::after {
border: 0 none;
}
/*Adding back the vertical connector to the last nodes*/
.tree li:last-child::before {
border-right: 1px solid #ccc;
border-radius: 0 5px 0 0;
-webkit-border-radius: 0 5px 0 0;
-moz-border-radius: 0 5px 0 0;
}
.tree li:first-child::after {
border-radius: 5px 0 0 0;
-webkit-border-radius: 5px 0 0 0;
-moz-border-radius: 5px 0 0 0;
}
/*Time to add downward connectors from parents*/
.tree ul ul::before {
content: '';
position: absolute;
top: 0;
left: 50%;
border-left: 1px solid #ccc;
width: 0;
height: 20px;
}
.tree li a:hover + ul li::after,
.tree li a:hover + ul li::before,
.tree li a:hover + ul::before,
.tree li a:hover + ul ul::before {
border-color: #94a0b4;
}
/*Thats all. I hope you enjoyed it.
Thanks :)*/
</style>

View File

@ -399,6 +399,7 @@
console.log(`Sorry, we are out of ${val.solarType}.`); console.log(`Sorry, we are out of ${val.solarType}.`);
} }
$('#card_' + val.id).find('#editSolarUrl').find('#Solarimg').attr('src', val.mainDisplay); $('#card_' + val.id).find('#editSolarUrl').find('#Solarimg').attr('src', val.mainDisplay);
$('#card_' + val.id).find('#editSolarUrl').find('#Solarimg').attr('style', "width: 100%;height: 210.5px;");
$('#card_' + val.id).find('#stationtype').html(type); $('#card_' + val.id).find('#stationtype').html(type);
var time = new Date(val.createdAt); var time = new Date(val.createdAt);
$('#card_' + val.id).find('#editSolarUrl').attr('href', localurl + '/Info?stationId=' + val.id); $('#card_' + val.id).find('#editSolarUrl').attr('href', localurl + '/Info?stationId=' + val.id);

View File

@ -756,7 +756,7 @@
del_btn.parents("tr").remove(); del_btn.parents("tr").remove();
toast_ok(rel.msg); toast_ok(rel.msg);
userTable.ajax.reload();
}, 'json'); }, 'json');
} }
}); });
@ -834,7 +834,7 @@
}); });
$("#add-user-manager-station-modal").modal(); $("#add-user-manager-station-modal").modal();
userTable.ajax.reload();
}, 'json'); }, 'json');
} }

View File

@ -0,0 +1,10 @@
var time = true;
function timer() {
console.log("haha");
postMessage("ok");
}
if (time) {
var myVar = setInterval(function () { timer() }, 300000);
time = false;
}