You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

414 lines
15 KiB

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace SmartAquaViewer.DataAnalysis
{
[Table("water_quality")]
public class WaterQualityVO
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
/// <summary>
/// 측정 시각
/// </summary>
[Column("recorded_time")]
public DateTime RecordedTime { get; set; }
/// <summary>
/// 저수조
/// </summary>
public WaterTank Tank { get; set; } = new();
/// <summary>
/// 여과 시스템
/// </summary>
public FilteringSystem Filtering { get; set; } = new();
/// <summary>
/// 살균 시스템
/// </summary>
public SterilizingSystem Sterilizing { get; set; } = new();
/// <summary>
/// 총 전력 소비 (킬로와트, kW)
/// </summary>
public double TotalEnergy { get; set; }
public WaterQualityVO() { }
public WaterQualityVO(DateTime RecordedTime, WaterTank tank, FilteringSystem filtering, SterilizingSystem sterilizing)
{
this.RecordedTime = RecordedTime;
Tank = tank;
Filtering = filtering;
Sterilizing = sterilizing;
}
public double CalculateTotalEnergy()
{
double total = 0;
total += Filtering.SandFilterEnergy;
total += Filtering.CirculationPumpEnergy;
total += Filtering.HeatPumpEnergy;
total += Filtering.AirBlowerEnergy;
total += Sterilizing.OzoneGeneratorEnergy;
total += Sterilizing.UVSterilizerEnergy;
total += Sterilizing.OzoneDissolverEnergy;
total += Sterilizing.ExcessOzoneDestroyerEnergy;
return Math.Round(total, 2);
}
/// <summary>
/// 샘플 데이터 리스트 생성
/// </summary>
public static List<WaterQualityVO> GetSampleData(DateTime start, DateTime end, int totalRowsCount)
{
var list = new List<WaterQualityVO>();
var rand = new Random();
double CalculateTotalEnergy(WaterQualityVO vo)
{
return vo.Filtering.SandFilterEnergy +
vo.Filtering.CirculationPumpEnergy +
vo.Filtering.HeatPumpEnergy +
vo.Filtering.AirBlowerEnergy +
vo.Sterilizing.OzoneGeneratorEnergy +
vo.Sterilizing.UVSterilizerEnergy +
vo.Sterilizing.OzoneDissolverEnergy +
vo.Sterilizing.ExcessOzoneDestroyerEnergy;
}
if (totalRowsCount <= 0) return list;
double totalSeconds;
if (start == end)
{
totalSeconds = 24 * 60 * 60;
}
else
{
totalSeconds = (end - start).TotalSeconds;
if (totalSeconds < 0) throw new ArgumentException("end 날짜는 start 날짜보다 같거나 커야 합니다.");
}
double stepSeconds = totalSeconds / totalRowsCount;
for (int i = 0; i < totalRowsCount; i++)
{
DateTime ts = start.AddSeconds(stepSeconds * i);
var vo = new WaterQualityVO
{
RecordedTime = ts,
Tank = new WaterTank(
number: rand.Next(1, 4),
doValue: Math.Round(rand.NextDouble() * 5 + 5, 2),
ph: Math.Round(rand.NextDouble() * 2 + 6, 2),
orp: Math.Round(rand.NextDouble() * 200 + 100, 2),
temperature: Math.Round(rand.NextDouble() * 10 + 15, 2),
flowRate: Math.Round(rand.NextDouble() * 5 + 1, 2)
),
Filtering = new FilteringSystem(
sandFilterPower: rand.Next(0, 2) == 1,
sandFilterEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2),
sumpPH: Math.Round(rand.NextDouble() * 2 + 6, 2),
sumpORP: Math.Round(rand.NextDouble() * 200 + 100, 2),
sumpWaterLevel: Math.Round(rand.NextDouble() * 2 + 1, 2),
sumpFlowRate: Math.Round(rand.NextDouble() * 5 + 1, 2),
sumpTemperature: Math.Round(rand.NextDouble() * 10 + 15, 2),
circulationPumpPower: rand.Next(0, 2) == 1,
circulationPumpEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2),
inverterControllerStatus: rand.Next(0, 2) == 1 ? "Normal" : "Error",
flowRate: Math.Round(rand.NextDouble() * 5 + 1, 2),
heatPumpPower: rand.Next(0, 2) == 1,
heatPumpTemperature: Math.Round(rand.NextDouble() * 10 + 15, 2),
heatPumpEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2),
airBlowerPower: rand.Next(0, 2) == 1,
airBlowerEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2)
),
Sterilizing = new SterilizingSystem(
ozoneGeneratorPower: rand.Next(0, 2) == 1,
ozoneGeneratorEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2),
uvSterilizerId: "UV" + rand.Next(1, 100),
uvSterilizerPower: rand.Next(0, 2) == 1,
uvSterilizerEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2),
ozoneDissolverPower: rand.Next(0, 2) == 1,
ozoneDissolverPressure: Math.Round(rand.NextDouble() * 100 + 50, 2),
ozoneDissolverEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2),
excessOzoneDestroyerPower: rand.Next(0, 2) == 1,
excessOzoneDestroyerEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2)
),
};
vo.TotalEnergy = CalculateTotalEnergy(vo);
list.Add(vo);
}
return list;
}
}
[Owned]
public class WaterTank
{
/// <summary>
/// 저수조 번호
/// </summary>
[Column("tank_number")]
public int Number { get; set; }
/// <summary>
/// Dissolved Oxygen (mg/L)
/// </summary>
[Column("tank_do_value")]
public double DOValue { get; set; }
/// <summary>
/// pH (산도)
/// </summary>
[Column("tank_ph")]
public double PH { get; set; }
/// <summary>
/// 산화환원전위 (mV)
/// </summary>
[Column("tank_orp")]
public double ORP { get; set; }
/// <summary>
/// 수온 (°C)
/// </summary>
[Column("tank_temperature")]
public double Temperature { get; set; }
/// <summary>
/// 유량 (m³/s)
/// </summary>
[Column("tank_flow_rate")]
public double FlowRate { get; set; }
public WaterTank() { }
public WaterTank(int number, double doValue, double ph, double orp, double temperature, double flowRate)
{
Number = number;
DOValue = doValue;
PH = ph;
ORP = orp;
Temperature = temperature;
FlowRate = flowRate;
}
}
[Owned]
public class FilteringSystem
{
/// <summary>
/// 모래여과기 전원 (true: ON, false: OFF)
/// </summary>
[Column("filter_sand_filter_power")]
public bool SandFilterPower { get; set; }
/// <summary>
/// 모래여과기 전력 (kW)
/// </summary>
[Column("filter_sand_filter_energy")]
public double SandFilterEnergy { get; set; }
/// <summary>
/// 섬프탱크 pH (산도)
/// </summary>
[Column("filter_sump_ph")]
public double SumpPH { get; set; }
/// <summary>
/// 섬프탱크 산화환원전위 (mV)
/// </summary>
[Column("filter_sump_orp")]
public double SumpORP { get; set; }
/// <summary>
/// 섬프탱크 수위 (m)
/// </summary>
[Column("filter_sump_water_level")]
public double SumpWaterLevel { get; set; }
/// <summary>
/// 섬프탱크 유량 (m³/s)
/// </summary>
[Column("filter_sump_flow_rate")]
public double SumpFlowRate { get; set; }
/// <summary>
/// 섬프탱크 수온 (°C)
/// </summary>
[Column("filter_sump_temperature")]
public double SumpTemperature { get; set; }
/// <summary>
/// 순환펌프 전원 (true: ON, false: OFF)
/// </summary>
[Column("filter_circulation_pump_power")]
public bool CirculationPumpPower { get; set; }
/// <summary>
/// 순환펌프 전력 (kW)
/// </summary>
[Column("filter_circulation_pump_energy")]
public double CirculationPumpEnergy { get; set; }
/// <summary>
/// 인버터 제어기 상태
/// </summary>
[Column("filter_inverter_controller_status")]
public string? InverterControllerStatus { get; set; }
/// <summary>
/// 순환펌프 유량 (m³/s)
/// </summary>
[Column("filter_flow_rate")]
public double FlowRate { get; set; }
/// <summary>
/// 히트펌프 전원 (true: ON, false: OFF)
/// </summary>
[Column("filter_heat_pump_power")]
public bool HeatPumpPower { get; set; }
/// <summary>
/// 히트펌프 온도 (°C)
/// </summary>
[Column("filter_heat_pump_temperature")]
public double HeatPumpTemperature { get; set; }
/// <summary>
/// 히트펌프 전력 (kW)
/// </summary>
[Column("filter_heat_pump_energy")]
public double HeatPumpEnergy { get; set; }
/// <summary>
/// 에어브로와 전원 (true: ON, false: OFF)
/// </summary>
[Column("filter_air_blower_power")]
public bool AirBlowerPower { get; set; }
/// <summary>
/// 에어브로와 전력 (kW)
/// </summary>
[Column("filter_air_blower_energy")]
public double AirBlowerEnergy { get; set; }
public FilteringSystem() { }
public FilteringSystem(
bool sandFilterPower, double sandFilterEnergy,
double sumpPH, double sumpORP, double sumpWaterLevel, double sumpFlowRate, double sumpTemperature,
bool circulationPumpPower, double circulationPumpEnergy, string? inverterControllerStatus, double flowRate,
bool heatPumpPower, double heatPumpTemperature, double heatPumpEnergy, bool airBlowerPower, double airBlowerEnergy)
{
SandFilterPower = sandFilterPower;
SandFilterEnergy = sandFilterEnergy;
SumpPH = sumpPH;
SumpORP = sumpORP;
SumpWaterLevel = sumpWaterLevel;
SumpFlowRate = sumpFlowRate;
SumpTemperature = sumpTemperature;
CirculationPumpPower = circulationPumpPower;
CirculationPumpEnergy = circulationPumpEnergy;
InverterControllerStatus = inverterControllerStatus;
FlowRate = flowRate;
HeatPumpPower = heatPumpPower;
HeatPumpTemperature = heatPumpTemperature;
HeatPumpEnergy = heatPumpEnergy;
AirBlowerPower = airBlowerPower;
AirBlowerEnergy = airBlowerEnergy;
}
}
[Owned]
public class SterilizingSystem
{
/// <summary>
/// 오존 발생기 전원 (true: ON, false: OFF)
/// </summary>
[Column("ster_ozone_generator_power")]
public bool OzoneGeneratorPower { get; set; }
/// <summary>
/// 오존 발생기 전력 (kW)
/// </summary>
[Column("ster_ozone_generator_energy")]
public double OzoneGeneratorEnergy { get; set; }
/// <summary>
/// 자외선 살균기 ID
/// </summary>
[Column("ster_uv_sterilizer_id")]
public string UVSterilizerId { get; set; }
/// <summary>
/// 자외선 살균기 전원 (true: ON, false: OFF)
/// </summary>
[Column("ster_uv_sterilizer_power")]
public bool UVSterilizerPower { get; set; }
/// <summary>
/// 자외선 살균기 전력 (kW)
/// </summary>
[Column("ster_uv_sterilizer_energy")]
public double UVSterilizerEnergy { get; set; }
/// <summary>
/// 오존용해장치 전원 (true: ON, false: OFF)
/// </summary>
[Column("ster_ozone_dissolver_power")]
public bool OzoneDissolverPower { get; set; }
/// <summary>
/// 오존용해장치 압력 (kPa)
/// </summary>
[Column("ster_ozone_dissolver_pressure")]
public double OzoneDissolverPressure { get; set; }
/// <summary>
/// 오존용해장치 전력 (kW)
/// </summary>
[Column("ster_ozone_dissolver_energy")]
public double OzoneDissolverEnergy { get; set; }
/// <summary>
/// 배오존장치 전원 (true: ON, false: OFF)
/// </summary>
[Column("ster_excess_ozone_destroyer_power")]
public bool ExcessOzoneDestroyerPower { get; set; }
/// <summary>
/// 배오존장치 전력 (kW)
/// </summary>
[Column("ster_excess_ozone_destroyer_energy")]
public double ExcessOzoneDestroyerEnergy { get; set; }
public SterilizingSystem() { }
public SterilizingSystem(
bool ozoneGeneratorPower, double ozoneGeneratorEnergy,
string uvSterilizerId, bool uvSterilizerPower, double uvSterilizerEnergy,
bool ozoneDissolverPower, double ozoneDissolverPressure, double ozoneDissolverEnergy,
bool excessOzoneDestroyerPower, double excessOzoneDestroyerEnergy)
{
OzoneGeneratorPower = ozoneGeneratorPower;
OzoneGeneratorEnergy = ozoneGeneratorEnergy;
UVSterilizerId = uvSterilizerId;
UVSterilizerPower = uvSterilizerPower;
UVSterilizerEnergy = uvSterilizerEnergy;
OzoneDissolverPower = ozoneDissolverPower;
OzoneDissolverPressure = ozoneDissolverPressure;
OzoneDissolverEnergy = ozoneDissolverEnergy;
ExcessOzoneDestroyerPower = excessOzoneDestroyerPower;
ExcessOzoneDestroyerEnergy = excessOzoneDestroyerEnergy;
}
}
}