FIC_Solar/solarApp/Service/getStationSvc.cs
jay.chang e647e6196b [solarApp]修正/優化歸檔邏輯,跑報表新增區間跑報表
[solarPower]逆便器分析因應資料搬遷修改語法。電站分析優化發電量圖表及歷史資料語法。
2025-11-14 14:48:15 +08:00

574 lines
25 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Text;
using MySql.Data.MySqlClient;
using Dapper;
using solarApp.Model;
using System.Configuration;
using Serilog;
namespace solarApp.Service
{
/// <summary>
/// 電站原始資料 rawData
/// </summary>
public class getStationSvc
{
public string Connection1 { get; set; }
private ILogger logger = Log.ForContext<getSensorSvc>();
public getStationSvc(string Connection_parame = null)
{
if (!string.IsNullOrEmpty(Connection_parame))
{
Connection1 = Connection_parame;
}
else
{
Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString;
}
}
//string Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString;
protected string tableName = "power_station";
/// <summary>
/// 電站 Raw Data
/// </summary>
/// <param name="reportDate"></param>
/// <param name="siteDB"></param>
/// <param name="siteID"></param>
/// <returns></returns>
public List<raw_statino> get_station_raw(string reportDate, string siteDB, string siteID)
{
List<raw_statino> ds = null;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open();
string sql = @"select id , FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d %H:%i') reportdate, siteid, round(KWH, 3) KWH, round(TODAYKWH, 3) TODAYKWH,
round(TOTALKWH, 3)TOTALKWH, round(PR, 3) PR, round(SOLARHOUR, 3) SOLARHOUR , round(kwhkwp, 3) kwhkwp , insertTime
from " + siteDB + ".s" + siteID + @"_station
where FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d') = @reportDate";
try
{
ds = conn.Query<raw_statino>(sql, new { reportDate = reportDate }).AsList<raw_statino>();
conn.Close();
}
catch (Exception ex)
{
logger.Error(@$"【get_station_raw】執行失敗 {siteDB}.s{siteID} _station 在{reportDate} - [Exception]" + ex.ToString());
}
return ds;
}
}
#region 使 view
public List<raw_station_day> create_v_station_inv(string date1, string date2)
{
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open();
string sql = @" select siteid, left(reportdate, 10) reportdate, round((sum(KWH)), 2) KWH, round((max(TODAYKWH)), 2) TODAYKWH, round((max(TOTALKWH)), 2) TOTALKWH,
round((max(PR)), 2) PR, round((max(SOLARHOUR)), 2) SOLARHOUR, round((max(KWHKWP)), 2) KWHKWP, count(*) count
from v_station_temp
where left(reportdate, 10) between @date1 and @date2
group by siteid, left(reportdate, 10)";
List<raw_station_day> ds = conn.Query<raw_station_day>(sql, new { date1 = date1, date2 = date2 }).AsList<raw_station_day>();
conn.Close();
return ds;
}
}
#endregion
/// <summary>
/// 電站每天平均 from RawData
/// </summary>
/// <param name="date1"></param>
/// <param name="date2"></param>
/// <returns></returns>
public List<raw_station_day> get_station_rawAvg(string date1, string date2, string siteDB, string siteID)
{
List<raw_station_day> ds = null;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open();
//string sql = @" select siteid, left(reportdate, 10) reportdate, round((sum(KWH)), 2) KWH, round((max(TODAYKWH)), 2) TODAYKWH, round((max(TOTALKWH)), 2) TOTALKWH,
// round((max(PR)), 2) PR, round((max(SOLARHOUR)), 2) SOLARHOUR, round((max(KWHKWP)), 2) KWHKWP, count(*) count
// from v_station_temp
// where left(reportdate, 10) between @date1 and @date2
// group by siteid, left(reportdate, 10)";
string sql = @" select siteid, FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d') reportdate, round((sum(KWH)), 2) KWH, round((max(TODAYKWH)), 2) TODAYKWH, round((max(TOTALKWH)), 2) TOTALKWH,
round((max(PR)), 2) PR, round((max(SOLARHOUR)), 2) SOLARHOUR, round((max(KWHKWP)), 2) KWHKWP, count(*) count
from " + siteDB+ ".s"+ siteID + @"_station
where FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d') between @date1 and @date2
group by siteid, FROM_UNIXTIME(`TIMESTAMP`/1000,'%Y-%m-%d')";
try
{
ds = conn.Query<raw_station_day>(sql, new { date1 = date1, date2 = date2 }).AsList<raw_station_day>();
conn.Close();
}
catch (Exception ex)
{
logger.Error(@$"【get_station_rawAvg】執行失敗 {siteDB}.s{siteID} _station 在{date1} - {date2} - [Exception]" + ex.ToString());
}
return ds;
}
}
/// <summary>
/// web 呈現值 station - hour
/// </summary>
/// <param name="reportDate"></param>
/// <returns></returns>
public List<web_station_hour> get_web_station_hour(string reportDate, string siteID)
{
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open();
string sql = @" select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d %H') reportdate, siteid, round(KWH, 2) KWH,
round(TODAYKWH, 2) TODAYKWH, round(TOTALKWH, 2) TOTALKWH, round(solarHour, 2) SOLARHOUR,
round(PR, 3) PR, round(KWHKWP, 3) KWHKWP,
round(money, 3) money, round(todaymoney, 3) todaymoney, round(totalmoney, 3) totalmoney,
round(carbon, 3) carbon, round(todayCarbon, 3) todayCarbon, round(totalCarbon, 3) totalCarbon
from power_station_history_hour
where siteID = @siteID and left(`TIMESTAMP`, 10) = '" + reportDate + "' ";
List<web_station_hour> ds = conn.Query<web_station_hour>(sql, new { siteID = siteID.Substring(0, 9) }).AsList<web_station_hour>();
conn.Close();
return ds;
}
}
/// <summary>
/// web 呈現值 station - day
/// </summary>
/// <param name="reportDate"></param>
/// <param name="invID"></param>
/// <returns></returns>
public List<web_station_day> get_web_station_day(string date1, string date2, string siteID)
{
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open();
//string sql = @"
// select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d') reportdate, siteid, round(TODAYKWH, 2) TODAYKWH, round(TOTALKWH, 2) TOTALKWH,
// round(PR, 3) PR, round(KWHKWP, 3) KWHKWP, money
// from power_station_history_day where left(`TIMESTAMP`, 10) between @date1 and @date2 and siteid = @siteID";
string sql = @"
select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d') reportdate, a.siteid, round(TODAYKWH, 2) TODAYKWH, round(TOTALKWH, 2) TOTALKWH, round(solarHour, 2) SOLARHOUR,
round(PR, 3) PR, round(KWHKWP, 3) KWHKWP, money, count
from power_station_history_day a left join (
select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d') reportdate, SITEID, count(*) count
from power_station_history_hour
where siteid = @siteID and left(`TIMESTAMP`, 10) between @date1 and @date2
group by DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d'), SITEID
) b on a.SITEID = b.SITEID and DATE_FORMAT(a.`TIMESTAMP`,'%Y-%m-%d') = b.reportdate
where left(`TIMESTAMP`, 10) between @date1 and @date2 and a.siteid = @siteID
order by DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d')
";
List<web_station_day> ds = conn.Query<web_station_day>(sql, new { date1 = date1, date2 = date2 , siteID = siteID}).AsList<web_station_day>();
conn.Close();
return ds;
}
}
public List<web_station_day> get_web_station_month(string date1, string date2, string siteID)
{
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open();
string sql = @" select DATE_FORMAT(`TIMESTAMP`,'%Y-%m-%d') reportdate, siteid, round(TOTALKWH, 2) TOTALKWH, round(solarHour, 2) SOLARHOUR, round(PR, 3) PR, round(KWHKWP, 3) KWHKWP, money
from power_station_history_month where left(`TIMESTAMP`, 7) between @date1 and @date2 and siteid = @siteID";
List<web_station_day> ds = conn.Query<web_station_day>(sql, new { date1 = date1, date2 = date2, siteID = siteID }).AsList<web_station_day>();
conn.Close();
return ds;
}
}
/// <summary>
/// 取得電站資訊
/// </summary>
/// <returns></returns>
public List<station_list> get_station_list()
{
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open(); // 01 控制器編號
string sql = @" select id, CompanyId, `code` , SerialNumber, CONCAT(`code` ,'01') SiteID, SiteDB, `name` SiteName
from power_station
where deleted = 0 and `status`= 1
ORDER BY id ";
// id <> 14";and id > 24
List<station_list> ds = conn.Query<station_list>(sql).AsList<station_list>();
conn.Close();
return ds;
}
}
public List<station_list> get_station_list32(bool include32)
{
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open(); // 01 控制器編號
string sql = @" select id, CompanyId, `code` , SerialNumber, CONCAT(`code` ,'01') SiteID, SiteDB, `name` SiteName
from power_station
where deleted = 0 and `status`= 1 and id <> 32 ";
if (include32)
{
sql = @" select id, CompanyId, `code` , SerialNumber, CONCAT(`code` ,'01') SiteID, SiteDB, `name` SiteName
from power_station
where deleted = 0 and `status`= 1 and id = 32";
}
// id <> 14";and id > 24
List<station_list> ds = conn.Query<station_list>(sql).AsList<station_list>();
conn.Close();
return ds;
}
}
public List<station_list> get_station_list32_by_range(int startId, int endId)
{
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open();
string sql = @"select id, CompanyId, `code`, SerialNumber, CONCAT(`code` ,'01') SiteID, SiteDB, `name` SiteName
from power_station
where deleted = 0 and `status`= 1 and id >= @startId and id <= @endId";
List<station_list> ds = conn.Query<station_list>(sql, new { startId, endId }).AsList<station_list>();
conn.Close();
return ds;
}
}
public List<PowerStation> get_powerStation()
{
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open();
string sql = @" select *
from power_station
where deleted = 0 and `status`= 1";
List<PowerStation> ds = conn.Query<PowerStation>(sql, commandTimeout: 600).AsList<PowerStation>();
conn.Close();
return ds;
}
}
public List<lackData> get_lack_stationData(string reportDate)
{
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open(); // a.powerstationid, p.`code` SITEID, a.`TIMESTAMP` , TODAYKWH, TOTALKWH , b.Irradiance, b.EnvTemperature, b.irrDay
string sql = @"select a.powerstationid, p.`code` SITEID, left(a.`TIMESTAMP`, 10) `TIMESTAMP`, b.TODAYKWH, b.TOTALKWH
from sensor_history_hour a
left join (
select powerstationid, left(`TIMESTAMP`, 10) `TIMESTAMP` , TODAYKWH, TOTALKWH from power_station_history_hour
where left(`TIMESTAMP`, 7) = @reportDate and hour(`TIMESTAMP`) = 12
) b on a.powerstationid = b.powerstationid and left(a.`TIMESTAMP`, 10) = b.`TIMESTAMP`
join power_station p on a.powerstationid = p.id
where left(a.`TIMESTAMP`, 7) = @reportDate and hour(a.`TIMESTAMP`) = 12 and b.TODAYKWH is null
order by 1, 2 ";
List<lackData> ds = conn.Query<lackData>(sql, new { reportDate = reportDate.Substring(0, 7) }, commandTimeout: 300).AsList<lackData>();
conn.Close();
return ds;
}
}
public string ExistTable(string db_name, string table_name)
{
string result;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
try
{
var sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = @DBName AND TABLE_NAME = @TableName;";
result = conn.QueryFirstOrDefault<string>(sql, new { DBName = db_name, TableName = table_name }, commandTimeout: 600);
}
catch (Exception exception)
{
throw exception;
}
finally
{
conn.Close();
}
return result;
}
}
public PowerStationHistory GetPowerStationHistoryPerHour(string dateTime, string table_name)
{
PowerStationHistory result;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
try
{
var sql = $@"
SELECT
DATE_FORMAT(FROM_UNIXTIME(timestamp / 1000), '%Y-%m-%d %H') AS TIMESTAMP,
SITEID,
SiteType,
KWH,
TodayKWh,
TotalKWH,
KWHKWP,
PR,
MP,
SolarHour
FROM {table_name} WHERE DATE_FORMAT(FROM_UNIXTIME(timestamp / 1000), '%Y-%m-%d %H') = @DateTime
";
result = conn.QueryFirstOrDefault<PowerStationHistory>(sql, new { DateTime = dateTime }, commandTimeout: 600);//加上時間
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
public PowerStationHistory GetPowerStationHistoryPerHourForPowerStation(string dateTime, string table_name)
{
PowerStationHistory result;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
try
{
var sql = $@"
SELECT
DATE_FORMAT(FROM_UNIXTIME(timestamp / 1000), '%Y-%m-%d %H') AS TIMESTAMP,
SITEID, SiteType, KWH, TodayKWh, TotalKWH,
KWHKWP, PR, MP, SolarHour
FROM {table_name}
WHERE DATE_FORMAT(FROM_UNIXTIME(timestamp / 1000), '%Y-%m-%d') = @DateTime
AND kwh > 0
order by timestamp desc";
result = conn.QueryFirstOrDefault<PowerStationHistory>(sql, new { DateTime = dateTime }, commandTimeout: 600);//加上時間
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
/// <summary>
/// 透過電站編號,取得所有土地房屋資訊
/// </summary>
/// <param name="id"></param>
/// <param name="db_name"></param>
/// <returns></returns>
public List<LandBuilding> GetAllLandBuildingInfoByPowerStationId(int id, string db_name)
{
List<LandBuilding> result;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
try
{
var sql = @$"SELECT lb.*, u.Name AS CreatorName FROM {db_name}.land_building lb
LEFT JOIN user u ON lb.CreatedBy = u.Id
WHERE lb.Deleted = 0 AND PowerStationId = @PowerStationId";
result = (conn.Query<LandBuilding>(sql, new { PowerStationId = id }, commandTimeout: 600)).AsList<LandBuilding>();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
/// <summary>
/// 透過name取得單一設定變數
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public string GetOneVariableByName(string name)
{
string result;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
try
{
var sql = $"SELECT Value FROM variable WHERE Name = @Name";
result = conn.QueryFirstOrDefault<string>(sql, new { Name = name }, commandTimeout: 600);
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
public int UpdateList(List<PowerStation> entity, List<string> properties)
{
int count;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
try
{
string sql = GenerateUpdateQuery(properties);
count = conn.Execute(sql, entity, trans, commandTimeout: 600);
trans.Commit();
}
catch (Exception exception)
{
trans.Rollback();
throw exception;
}
finally
{
conn.Close();
}
}
return count;
}
}
/// <summary>
/// 產生Update語句
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
protected string GenerateUpdateQuery(List<string> properties)
{
var updateQuery = new StringBuilder($"UPDATE {tableName} SET ");
properties.ForEach(property =>
{
if (!property.Equals("Id"))
{
updateQuery.Append($"{property}=@{property},");
}
});
updateQuery.Remove(updateQuery.Length - 1, 1); //remove last comma
updateQuery.Append(" WHERE id = @Id");
return updateQuery.ToString();
}
public List<DeviceInfo> GetListPyrheliometerByPowerStationId(int powerStationId, string db_name)
{
List<DeviceInfo> result;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
try
{
var sql = $@"SELECT temp.*
FROM(
SELECT d.*
FROM {db_name}.device d
WHERE d.PowerStationId = @PowerStationId AND d.`Type` = 'TPY' AND d.Deleted = 0 AND d.Enabled = 1 AND d.Status != 0
UNION
SELECT d.*
FROM {db_name}.sharedevice sd
LEFT JOIN {db_name}.device d ON sd.DeviceId = d.Id
WHERE sd.PowerStationId = @PowerStationId AND d.`Type` = 'TPY' AND d.Deleted = 0 AND d.Enabled = 1 AND d.Status != 0
) temp
ORDER BY temp.ColName
";
result = (conn.Query<DeviceInfo>(sql, new { PowerStationId = powerStationId }, commandTimeout: 600)).AsList<DeviceInfo>();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
public PyrheliometerHistory CalcSensorHistoryPerHour(string dateTime, List<DeviceInfo> deviceInfos, int type)
{
SensorTypeEnum SensorTypeEnum = (SensorTypeEnum)type;
var typename = "";
var calc = "";
switch (SensorTypeEnum)
{
case SensorTypeEnum.PYR: //日照計
calc = "AVG";
typename = "Irradiance";
break;
case SensorTypeEnum.MTR: //模組溫度計
calc = "AVG";
typename = "Temperature";
break;
case SensorTypeEnum.ETR: //環境溫度計
calc = "AVG";
typename = "EnvTemperature";
break;
case SensorTypeEnum.EMM: //環境濕度計
calc = "AVG";
typename = "Humidity";
break;
case SensorTypeEnum.VAN: //風速計
calc = "AVG";
typename = "Vane";
break;
case SensorTypeEnum.FOM: //落塵計
calc = "AVG";
typename = "Dust";
break;
case SensorTypeEnum.WIN: //風向計
calc = "AVG";
typename = "WingDirection";
break;
case SensorTypeEnum.TPY: //累計日照量
calc = "MAX";
typename = "IrrDay";
break;
}
PyrheliometerHistory result;
using (MySqlConnection conn = new MySqlConnection(Connection1))
{
try
{
List<string> sql_per_device = new List<string>();
foreach (var device in deviceInfos)
{
var str = @$"SELECT DATE_FORMAT(FROM_UNIXTIME(s.TIMESTAMP/ 1000), '%Y-%m-%d %H') AS TIMESTAMP, s.SITEID, CASE WHEN AVG(CASE WHEN s.{device.ColName} != 0 THEN s.{device.ColName} END) IS NOT NULL THEN AVG(CASE WHEN s.{device.ColName} != 0 THEN s.{device.ColName} END)
ELSE 0 END AS SENSOR
FROM {device.DBName}.{device.TableName} s
WHERE DATE_FORMAT(FROM_UNIXTIME(s.TIMESTAMP/ 1000), '%Y-%m-%d %H') = @DateTime
GROUP BY DATE_FORMAT(FROM_UNIXTIME(s.TIMESTAMP/ 1000), '%Y-%m-%d %H')";
sql_per_device.Add(str);
}
var sql = @$"SELECT a.TIMESTAMP, {calc}(a.SENSOR) AS {typename} FROM(" + string.Join(" UNION ", sql_per_device) + @") a GROUP BY `TIMESTAMP`";
result = conn.QueryFirstOrDefault<PyrheliometerHistory>(sql, new { DateTime = dateTime }, commandTimeout: 600);
}
catch (Exception exception)
{
throw exception;
}
finally
{
conn.Close();
}
return result;
}
}
}
}