diff --git a/SmartAquaViewer/DataAnalisys/AppDbContext.cs b/SmartAquaViewer/DataAnalisys/AppDbContext.cs index 52c178d..e5ce2ed 100644 --- a/SmartAquaViewer/DataAnalisys/AppDbContext.cs +++ b/SmartAquaViewer/DataAnalisys/AppDbContext.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore; +using SmartAquaViewer.DataAnalysis; using System.Collections.Generic; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; diff --git a/SmartAquaViewer/DataAnalisys/AquarDataControl.cs b/SmartAquaViewer/DataAnalisys/AquarDataControl.cs index d8b0174..1e2f852 100644 --- a/SmartAquaViewer/DataAnalisys/AquarDataControl.cs +++ b/SmartAquaViewer/DataAnalisys/AquarDataControl.cs @@ -1,4 +1,5 @@ -using System; +using SmartAquaViewer.DataAnalysis; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -64,7 +65,7 @@ namespace SmartAquaViewer.DataAnalisys // TODO: 라인 파싱 로직 WaterQualityVO vo = new(); //vo.PH = 10.5; - vo.Timestamp = DateTime.Now; + vo.RecordedTime = DateTime.Now; iwaterQuality.OnParsed(vo); db.Add(vo); diff --git a/SmartAquaViewer/DataAnalisys/IWaterQuality.cs b/SmartAquaViewer/DataAnalisys/IWaterQuality.cs index 157ef0b..67aea5e 100644 --- a/SmartAquaViewer/DataAnalisys/IWaterQuality.cs +++ b/SmartAquaViewer/DataAnalisys/IWaterQuality.cs @@ -1,4 +1,5 @@ -using System; +using SmartAquaViewer.DataAnalysis; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/SmartAquaViewer/DataAnalisys/WaterQualityVO.cs b/SmartAquaViewer/DataAnalisys/WaterQualityVO.cs index 01afa1e..8b008dd 100644 --- a/SmartAquaViewer/DataAnalisys/WaterQualityVO.cs +++ b/SmartAquaViewer/DataAnalisys/WaterQualityVO.cs @@ -1,88 +1,47 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; -namespace SmartAquaViewer.DataAnalisys +namespace SmartAquaViewer.DataAnalysis { - - - using System; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; - using System.Security.Policy; - - [Table("WaterQuality")] + [Table("water_quality")] public class WaterQualityVO { - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 자동 증가 - public int Id { get; set; } // PK, Auto Increment + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } /// - /// 저수조 + /// 측정 시각 /// - public WaterTank WaterTank { get; set; } + [Column("recorded_time")] + public DateTime RecordedTime { get; set; } /// - /// 여과 시스템 + /// 저수조 /// - public FilteringSystem FilteringSystem { get; set; } - + public WaterTank Tank { get; set; } = new(); /// - /// 살균 시스템 + /// 여과 시스템 /// - public SterilizingSystem SterilizingSystem { get; set; } - + public FilteringSystem Filtering { get; set; } = new(); /// - /// 측정 시각 + /// 살균 시스템 /// - public DateTime Timestamp { get; set; } + public SterilizingSystem Sterilizing { get; set; } = new(); public WaterQualityVO() { } - public WaterQualityVO( - int waterTankNum, double waterTankDOValue, double waterTankPh, double waterTankORP, double waterTankTemperature, double waterTankFlowRate, - bool sandFilterPower, - double sumpPH, double sumpORP, double sumpWaterLevel, double sumpFlowRate, double sumpTemperature, - bool circulationPumpPower, string? inverterControllerStatus, double flowRate, - bool heatPumpPower, double heatPumpTemperature, bool airBlowerPower, - bool ozoneGeneratorPower, - string uvSterilizerId, bool uvSterilizerPower, - bool ozoneDissolverPower, double ozoneDissolverPressure, - bool excessOzoneDestroyerPower, - DateTime timestamp) - { - WaterTank = new WaterTank(waterTankNum, waterTankDOValue, waterTankPh, waterTankORP, waterTankTemperature, waterTankFlowRate); - FilteringSystem = new FilteringSystem(sandFilterPower, sumpPH, sumpORP, sumpWaterLevel, sumpFlowRate, sumpTemperature, - circulationPumpPower, inverterControllerStatus, flowRate, - heatPumpPower, heatPumpTemperature, airBlowerPower); - SterilizingSystem = new SterilizingSystem(ozoneGeneratorPower, uvSterilizerId, uvSterilizerPower, - ozoneDissolverPower, ozoneDissolverPressure, excessOzoneDestroyerPower); - } - - public override string ToString() + public WaterQualityVO(DateTime RecordedTime, WaterTank tank, FilteringSystem filtering, SterilizingSystem sterilizing) { - //return $"Tank#{WaterTankNum} [{Timestamp}] DO: {DO} mg/L, pH: {PH}, Temp: {Temperature}°C, " + - // $"Level: {WaterLevel} m, Flow: {FlowRate} m³/s, EC: {ElectricalConductivity} µS/cm, " + - // $"Turbidity: {Turbidity} NTU, Salinity: {Salinity} ppt, ORP: {ORP} mV, " + - // $"TSS: {TSS} mg/L, TN: {TotalNitrogen} mg/L, TP: {TotalPhosphorus} mg/L"; - - return $"[{Timestamp}] " + - $"[Tank#{WaterTank.WaterTankNum}, DO: {WaterTank.DO} mg/L, pH: {WaterTank.PH}, ORP: {WaterTank.ORP} mV, Temp: {WaterTank.Temperature}°C, FlowRate: {WaterTank.FlowRate} m³/s]" + - $"[SandFilter: {(FilteringSystem.SandFilterPower ? "ON" : "OFF")}, " + - $"(SumpTank) pH: {FilteringSystem.SumpPH}, ORP: {FilteringSystem.SumpORP} mV, WaterLevel: {FilteringSystem.SumpWaterLevel} m, FlowRate: {FilteringSystem.SumpFlowRate} m³/s, Temperature: {FilteringSystem.SumpTemperature}°C," + - $"HeatPump: {(FilteringSystem.HeatPumpPower ? "ON" : "OFF")}, HeatPumpTemperature: {FilteringSystem.HeatPumpTemperature}°C, AirBlower: {(FilteringSystem.AirBlowerPower ? "ON" : "OFF")}]" + - $"[OzoneGenerator: {(SterilizingSystem.OzoneGeneratorPower ? "ON" : "OFF")}," + - $"UVSterilizerId: {SterilizingSystem.UVSterilizerId}, UVSterilizer: {(SterilizingSystem.UVSterilizerPower ? "ON" : "OFF")}," + - $"OzoneDissolver: {SterilizingSystem.OzoneDissolverPower}, OzoneDissolverPressure: {SterilizingSystem.OzoneDissolverPressure} kPa," + - $"ExcessOzoneDestroyer: {(SterilizingSystem.ExcessOzoneDestroyerPower ? "ON" : "OFF")}]"; + this.RecordedTime = RecordedTime; + Tank = tank; + Filtering = filtering; + Sterilizing = sterilizing; } /// - /// 지정 기간 동안 임의의 수질 데이터를 생성합니다. + /// 샘플 데이터 리스트 생성 /// public static List GetSampleData(DateTime start, DateTime end, int totalRowsCount) { @@ -95,8 +54,7 @@ namespace SmartAquaViewer.DataAnalisys if (start == end) { - // 같은 날짜면 하루(24시간) 기준으로 균등 분할 - totalSeconds = 24 * 60 * 60; // 86,400초 + totalSeconds = 24 * 60 * 60; } else { @@ -110,101 +68,89 @@ namespace SmartAquaViewer.DataAnalisys { DateTime ts = start.AddSeconds(stepSeconds * i); - //var vo = new WaterQualityVO - //{ - // WaterTankNum = rand.Next(1, 6), // 1~5번 탱크 - // DO = Math.Round(rand.NextDouble() * 5 + 5, 2), // 5~10 mg/L - // PH = Math.Round(rand.NextDouble() * 2 + 6, 2), // 6~8 - // Temperature = Math.Round(rand.NextDouble() * 10 + 15, 2), // 15~25°C - // WaterLevel = Math.Round(rand.NextDouble() * 2 + 1, 2), // 1~3 m - // FlowRate = Math.Round(rand.NextDouble() * 5 + 1, 2), // 1~6 m³/s - // ElectricalConductivity = Math.Round(rand.NextDouble() * 500 + 200, 2), // 200~700 µS/cm - // Turbidity = Math.Round(rand.NextDouble() * 5 + 1, 2), // 1~6 NTU - // Salinity = Math.Round(rand.NextDouble() * 5, 2), // 0~5 ppt - // ORP = Math.Round(rand.NextDouble() * 200 + 100, 2), // 100~300 mV - // TSS = Math.Round(rand.NextDouble() * 20 + 5, 2), // 5~25 mg/L - // TotalNitrogen = Math.Round(rand.NextDouble() * 2 + 0.5, 2), // 0.5~2.5 mg/L - // TotalPhosphorus = Math.Round(rand.NextDouble() * 0.5 + 0.05, 3), // 0.05~0.55 mg/L - // Timestamp = ts - //}; - var vo = new WaterQualityVO { - WaterTank = new WaterTank( - waterTankNum: rand.Next(1, 6), // 1~5번 탱크 - doValue: Math.Round(rand.NextDouble() * 5 + 5, 2), // 5~10 mg/L - ph: Math.Round(rand.NextDouble() * 2 + 6, 2), // 6~8 - orp: Math.Round(rand.NextDouble() * 200 + 100, 2), // 100~300 mV - temperature: Math.Round(rand.NextDouble() * 10 + 15, 2), // 15~25°C - flowRate: Math.Round(rand.NextDouble() * 5 + 1, 2) // 1~6 m³/s + RecordedTime = ts, + Tank = new WaterTank( + number: rand.Next(1, 6), + 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) ), - FilteringSystem = new FilteringSystem( - sandFilterPower: rand.Next(0, 2) == 1, // true or false - sumpPH: Math.Round(rand.NextDouble() * 2 + 6, 2), // 6~8 - sumpORP: Math.Round(rand.NextDouble() * 200 + 100, 2), // 100~300 mV - sumpWaterLevel: Math.Round(rand.NextDouble() * 2 + 1, 2), // 1~3 m - sumpFlowRate: Math.Round(rand.NextDouble() * 5 + 1, 2), // 1~6 m³/s - sumpTemperature: Math.Round(rand.NextDouble() * 10 + 15, 2), // 15~25°C - circulationPumpPower: rand.Next(0, 2) == 1, // true or false - inverterControllerStatus: rand.Next(0, 2) == 1 ? "Normal" : "Error", // "Normal" or "Error" - flowRate: Math.Round(rand.NextDouble() * 5 + 1, 2), // 1~6 m³/s - heatPumpPower: rand.Next(0, 2) == 1, // true or false - heatPumpTemperature: Math.Round(rand.NextDouble() * 10 + 15, 2), // 15~25°C - airBlowerPower: rand.Next(0, 2) == 1 // true or false + Filtering = new FilteringSystem( + sandFilterPower: rand.Next(0, 2) == 1, + 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, + 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), + airBlowerPower: rand.Next(0, 2) == 1 ), - SterilizingSystem = new SterilizingSystem( - ozoneGeneratorPower: rand.Next(0, 2) == 1, // true or false - uvSterilizerId: "UV" + rand.Next(1, 100), // UV1, UV2, ... - uvSterilizerPower: rand.Next(0, 2) == 1, // true or false - ozoneDissolverPower: rand.Next(0, 2) == 1, // true or false - ozoneDissolverPressure: Math.Round(rand.NextDouble() * 100 + 50, 2), // 50~150 kPa - excessOzoneDestroyerPower: rand.Next(0, 2) == 1 // true or false + Sterilizing = new SterilizingSystem( + ozoneGeneratorPower: rand.Next(0, 2) == 1, + uvSterilizerId: "UV" + rand.Next(1, 100), + uvSterilizerPower: rand.Next(0, 2) == 1, + ozoneDissolverPower: rand.Next(0, 2) == 1, + ozoneDissolverPressure: Math.Round(rand.NextDouble() * 100 + 50, 2), + excessOzoneDestroyerPower: rand.Next(0, 2) == 1 ) }; + list.Add(vo); } return list; } - } + [Owned] public class WaterTank { /// /// 저수조 번호 /// - public int WaterTankNum { get; set; } + [Column("tank_number")] + public int Number { get; set; } /// /// Dissolved Oxygen (mg/L) /// - public double DO { get; set; } - + [Column("tank_do_value")] + public double DOValue { get; set; } /// /// pH (산도) /// + [Column("tank_ph")] public double PH { get; set; } - /// /// 산화환원전위 (mV) /// + [Column("tank_orp")] public double ORP { get; set; } - /// /// 수온 (°C) /// + [Column("tank_temperature")] public double Temperature { get; set; } - /// /// 유량 (m³/s) /// + [Column("tank_flow_rate")] public double FlowRate { get; set; } - public WaterTank(int waterTankNum, double doValue, double ph, double orp, double temperature, double flowRate) + public WaterTank() { } + + public WaterTank(int number, double doValue, double ph, double orp, double temperature, double flowRate) { - WaterTankNum = waterTankNum; - DO = doValue; + Number = number; + DOValue = doValue; PH = ph; ORP = orp; Temperature = temperature; @@ -212,72 +158,86 @@ namespace SmartAquaViewer.DataAnalisys } } + [Owned] public class FilteringSystem { /// /// 모래여과기 전원 (true: ON, false: OFF) /// + [Column("filter_sand_filter_power")] public bool SandFilterPower { get; set; } - /// /// 섬프탱크 pH (산도) /// + [Column("filter_sump_ph")] public double SumpPH { get; set; } /// /// 섬프탱크 산화환원전위 (mV) /// + [Column("filter_sump_orp")] public double SumpORP { get; set; } /// /// 섬프탱크 수위 (m) /// + [Column("filter_sump_water_level")] public double SumpWaterLevel { get; set; } /// /// 섬프탱크 유량 (m³/s) /// + [Column("filter_sump_flow_rate")] public double SumpFlowRate { get; set; } /// /// 섬프탱크 수온 (°C) /// + [Column("filter_sump_temperature")] public double SumpTemperature { get; set; } /// /// 순환펌프 전원 (true: ON, false: OFF) /// + [Column("filter_circulation_pump_power")] public bool CirculationPumpPower { get; set; } /// /// 인버터 제어기 상태 /// + [Column("filter_inverter_controller_status")] public string? InverterControllerStatus { get; set; } /// /// 순환펌프 유량 (m³/s) /// + [Column("filter_flow_rate")] public double FlowRate { get; set; } /// /// 히트펌프 전원 (true: ON, false: OFF) /// + [Column("filter_heat_pump_power")] public bool HeatPumpPower { get; set; } /// /// 히트펌프 온도 (°C) /// + [Column("filter_heat_pump_temperature")] public double HeatPumpTemperature { get; set; } /// /// 에어브로와 전원 (true: ON, false: OFF) /// + [Column("filter_air_blower_power")] public bool AirBlowerPower { get; set; } - public FilteringSystem(bool sandFilterPower, - double sumpPH, double sumpORP, double sumpWaterLevel, double sumpFlowRate, double sumpTemperature, - bool circulationPumpPower, string? inverterControllerStatus, double flowRate, + public FilteringSystem() { } + + public FilteringSystem( + bool sandFilterPower, double sumpPH, double sumpORP, double sumpWaterLevel, double sumpFlowRate, double sumpTemperature, + bool circulationPumpPower, string? inverterControllerStatus, double flowRate, bool heatPumpPower, double heatPumpTemperature, bool airBlowerPower) { SandFilterPower = sandFilterPower; @@ -295,42 +255,50 @@ namespace SmartAquaViewer.DataAnalisys } } + [Owned] public class SterilizingSystem { /// /// 오존 발생기 전원 (true: ON, false: OFF) /// + [Column("ster_ozone_generator_power")] public bool OzoneGeneratorPower { get; set; } /// /// 자외선 살균기 ID /// + [Column("ster_uv_sterilizer_id")] public string UVSterilizerId { get; set; } /// /// 자외선 살균기 전원 (true: ON, false: OFF) /// + [Column("ster_uv_sterilizer_power")] public bool UVSterilizerPower { get; set; } /// /// 오존용해장치 전원 (true: ON, false: OFF) /// + [Column("ster_ozone_dissolver_power")] public bool OzoneDissolverPower { get; set; } /// /// 오존용해장치 압력 (kPa) /// + [Column("ster_ozone_dissolver_pressure")] public double OzoneDissolverPressure { get; set; } /// /// 배오존장치 전원 (true: ON, false: OFF) /// + [Column("ster_excess_ozone_destroyer_power")] public bool ExcessOzoneDestroyerPower { get; set; } - public SterilizingSystem(bool ozoneGeneratorPower, - string uvSterilizerId, bool uvSterilizerPower, - bool ozoneDissolverPower, double ozoneDissolverPressure, - bool excessOzoneDestroyerPower) + public SterilizingSystem() { } + + public SterilizingSystem( + bool ozoneGeneratorPower, string uvSterilizerId, bool uvSterilizerPower, + bool ozoneDissolverPower, double ozoneDissolverPressure, bool excessOzoneDestroyerPower) { OzoneGeneratorPower = ozoneGeneratorPower; UVSterilizerId = uvSterilizerId; diff --git a/SmartAquaViewer/Migrations/20250812043735_AddWaterQualityTable.Designer.cs b/SmartAquaViewer/Migrations/20250812043735_AddWaterQualityTable.Designer.cs new file mode 100644 index 0000000..c25276a --- /dev/null +++ b/SmartAquaViewer/Migrations/20250812043735_AddWaterQualityTable.Designer.cs @@ -0,0 +1,190 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using SmartAquaViewer.DataAnalisys; + +#nullable disable + +namespace SmartAquaViewer.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20250812043735_AddWaterQualityTable")] + partial class AddWaterQualityTable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("SmartAquaViewer.DataAnalysis.WaterQualityVO", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RecordedTime") + .HasColumnType("datetime(6)") + .HasColumnName("recorded_time"); + + b.HasKey("Id"); + + b.ToTable("water_quality"); + }); + + modelBuilder.Entity("SmartAquaViewer.DataAnalysis.WaterQualityVO", b => + { + b.OwnsOne("SmartAquaViewer.DataAnalysis.FilteringSystem", "Filtering", b1 => + { + b1.Property("WaterQualityVOId") + .HasColumnType("int"); + + b1.Property("AirBlowerPower") + .HasColumnType("tinyint(1)") + .HasColumnName("filter_air_blower_power"); + + b1.Property("CirculationPumpPower") + .HasColumnType("tinyint(1)") + .HasColumnName("filter_circulation_pump_power"); + + b1.Property("FlowRate") + .HasColumnType("double") + .HasColumnName("filter_flow_rate"); + + b1.Property("HeatPumpPower") + .HasColumnType("tinyint(1)") + .HasColumnName("filter_heat_pump_power"); + + b1.Property("HeatPumpTemperature") + .HasColumnType("double") + .HasColumnName("filter_heat_pump_temperature"); + + b1.Property("InverterControllerStatus") + .HasColumnType("longtext") + .HasColumnName("filter_inverter_status"); + + b1.Property("SandFilterPower") + .HasColumnType("tinyint(1)") + .HasColumnName("filter_sand_filter_power"); + + b1.Property("SumpFlowRate") + .HasColumnType("double") + .HasColumnName("filter_sump_flow_rate"); + + b1.Property("SumpORP") + .HasColumnType("double") + .HasColumnName("filter_sump_orp"); + + b1.Property("SumpPH") + .HasColumnType("double") + .HasColumnName("filter_sump_ph"); + + b1.Property("SumpTemperature") + .HasColumnType("double") + .HasColumnName("filter_sump_temperature"); + + b1.Property("SumpWaterLevel") + .HasColumnType("double") + .HasColumnName("filter_sump_water_level"); + + b1.HasKey("WaterQualityVOId"); + + b1.ToTable("water_quality"); + + b1.WithOwner() + .HasForeignKey("WaterQualityVOId"); + }); + + b.OwnsOne("SmartAquaViewer.DataAnalysis.SterilizingSystem", "Sterilizing", b1 => + { + b1.Property("WaterQualityVOId") + .HasColumnType("int"); + + b1.Property("ExcessOzoneDestroyerPower") + .HasColumnType("tinyint(1)") + .HasColumnName("ster_excess_ozone_destroyer_power"); + + b1.Property("OzoneDissolverPower") + .HasColumnType("tinyint(1)") + .HasColumnName("ster_ozone_dissolver_power"); + + b1.Property("OzoneDissolverPressure") + .HasColumnType("double") + .HasColumnName("ster_ozone_dissolver_pressure"); + + b1.Property("OzoneGeneratorPower") + .HasColumnType("tinyint(1)") + .HasColumnName("ster_ozone_generator_power"); + + b1.Property("UVSterilizerId") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ster_uv_sterilizer_id"); + + b1.Property("UVSterilizerPower") + .HasColumnType("tinyint(1)") + .HasColumnName("ster_uv_sterilizer_power"); + + b1.HasKey("WaterQualityVOId"); + + b1.ToTable("water_quality"); + + b1.WithOwner() + .HasForeignKey("WaterQualityVOId"); + }); + + b.OwnsOne("SmartAquaViewer.DataAnalysis.WaterTank", "Tank", b1 => + { + b1.Property("WaterQualityVOId") + .HasColumnType("int"); + + b1.Property("DOValue") + .HasColumnType("double") + .HasColumnName("tank_do_value"); + + b1.Property("FlowRate") + .HasColumnType("double") + .HasColumnName("tank_flow_rate"); + + b1.Property("Number") + .HasColumnType("int") + .HasColumnName("tank_number"); + + b1.Property("ORP") + .HasColumnType("double") + .HasColumnName("tank_orp"); + + b1.Property("PH") + .HasColumnType("double") + .HasColumnName("tank_ph"); + + b1.Property("Temperature") + .HasColumnType("double") + .HasColumnName("tank_temperature"); + + b1.HasKey("WaterQualityVOId"); + + b1.ToTable("water_quality"); + + b1.WithOwner() + .HasForeignKey("WaterQualityVOId"); + }); + + b.Navigation("Filtering") + .IsRequired(); + + b.Navigation("Sterilizing") + .IsRequired(); + + b.Navigation("Tank") + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/SmartAquaViewer/Migrations/20250812043735_AddWaterQualityTable.cs b/SmartAquaViewer/Migrations/20250812043735_AddWaterQualityTable.cs new file mode 100644 index 0000000..e141175 --- /dev/null +++ b/SmartAquaViewer/Migrations/20250812043735_AddWaterQualityTable.cs @@ -0,0 +1,93 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace SmartAquaViewer.Migrations +{ + /// + public partial class AddWaterQualityTable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "WaterQuality"); + + migrationBuilder.CreateTable( + name: "water_quality", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + recorded_time = table.Column(type: "datetime(6)", nullable: false), + tank_number = table.Column(type: "int", nullable: false), + tank_do_value = table.Column(type: "double", nullable: false), + tank_ph = table.Column(type: "double", nullable: false), + tank_orp = table.Column(type: "double", nullable: false), + tank_temperature = table.Column(type: "double", nullable: false), + tank_flow_rate = table.Column(type: "double", nullable: false), + filter_sand_filter_power = table.Column(type: "tinyint(1)", nullable: false), + filter_sump_ph = table.Column(type: "double", nullable: false), + filter_sump_orp = table.Column(type: "double", nullable: false), + filter_sump_water_level = table.Column(type: "double", nullable: false), + filter_sump_flow_rate = table.Column(type: "double", nullable: false), + filter_sump_temperature = table.Column(type: "double", nullable: false), + filter_circulation_pump_power = table.Column(type: "tinyint(1)", nullable: false), + filter_inverter_status = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + filter_flow_rate = table.Column(type: "double", nullable: false), + filter_heat_pump_power = table.Column(type: "tinyint(1)", nullable: false), + filter_heat_pump_temperature = table.Column(type: "double", nullable: false), + filter_air_blower_power = table.Column(type: "tinyint(1)", nullable: false), + ster_ozone_generator_power = table.Column(type: "tinyint(1)", nullable: false), + ster_uv_sterilizer_id = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ster_uv_sterilizer_power = table.Column(type: "tinyint(1)", nullable: false), + ster_ozone_dissolver_power = table.Column(type: "tinyint(1)", nullable: false), + ster_ozone_dissolver_pressure = table.Column(type: "double", nullable: false), + ster_excess_ozone_destroyer_power = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_water_quality", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "water_quality"); + + migrationBuilder.CreateTable( + name: "WaterQuality", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + DO = table.Column(type: "double", nullable: false), + ElectricalConductivity = table.Column(type: "double", nullable: false), + FlowRate = table.Column(type: "double", nullable: false), + ORP = table.Column(type: "double", nullable: false), + PH = table.Column(type: "double", nullable: false), + Salinity = table.Column(type: "double", nullable: false), + TSS = table.Column(type: "double", nullable: false), + Temperature = table.Column(type: "double", nullable: false), + Timestamp = table.Column(type: "datetime(6)", nullable: false), + TotalNitrogen = table.Column(type: "double", nullable: false), + TotalPhosphorus = table.Column(type: "double", nullable: false), + Turbidity = table.Column(type: "double", nullable: false), + WaterLevel = table.Column(type: "double", nullable: false), + WaterTankNum = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WaterQuality", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + } + } +} diff --git a/SmartAquaViewer/Migrations/AppDbContextModelSnapshot.cs b/SmartAquaViewer/Migrations/AppDbContextModelSnapshot.cs index ad78d1d..266868d 100644 --- a/SmartAquaViewer/Migrations/AppDbContextModelSnapshot.cs +++ b/SmartAquaViewer/Migrations/AppDbContextModelSnapshot.cs @@ -19,57 +19,167 @@ namespace SmartAquaViewer.Migrations .HasAnnotation("ProductVersion", "8.0.1") .HasAnnotation("Relational:MaxIdentifierLength", 64); - modelBuilder.Entity("SmartAquaViewer.DataAnalisys.WaterQualityVO", b => + modelBuilder.Entity("SmartAquaViewer.DataAnalysis.WaterQualityVO", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("DO") - .HasColumnType("double"); + b.Property("RecordedTime") + .HasColumnType("datetime(6)") + .HasColumnName("recorded_time"); - b.Property("ElectricalConductivity") - .HasColumnType("double"); + b.HasKey("Id"); - b.Property("FlowRate") - .HasColumnType("double"); + b.ToTable("water_quality"); + }); - b.Property("ORP") - .HasColumnType("double"); + modelBuilder.Entity("SmartAquaViewer.DataAnalysis.WaterQualityVO", b => + { + b.OwnsOne("SmartAquaViewer.DataAnalysis.FilteringSystem", "Filtering", b1 => + { + b1.Property("WaterQualityVOId") + .HasColumnType("int"); - b.Property("PH") - .HasColumnType("double"); + b1.Property("AirBlowerPower") + .HasColumnType("tinyint(1)") + .HasColumnName("filter_air_blower_power"); - b.Property("Salinity") - .HasColumnType("double"); + b1.Property("CirculationPumpPower") + .HasColumnType("tinyint(1)") + .HasColumnName("filter_circulation_pump_power"); - b.Property("TSS") - .HasColumnType("double"); + b1.Property("FlowRate") + .HasColumnType("double") + .HasColumnName("filter_flow_rate"); - b.Property("Temperature") - .HasColumnType("double"); + b1.Property("HeatPumpPower") + .HasColumnType("tinyint(1)") + .HasColumnName("filter_heat_pump_power"); - b.Property("Timestamp") - .HasColumnType("datetime(6)"); + b1.Property("HeatPumpTemperature") + .HasColumnType("double") + .HasColumnName("filter_heat_pump_temperature"); - b.Property("TotalNitrogen") - .HasColumnType("double"); + b1.Property("InverterControllerStatus") + .HasColumnType("longtext") + .HasColumnName("filter_inverter_status"); - b.Property("TotalPhosphorus") - .HasColumnType("double"); + b1.Property("SandFilterPower") + .HasColumnType("tinyint(1)") + .HasColumnName("filter_sand_filter_power"); - b.Property("Turbidity") - .HasColumnType("double"); + b1.Property("SumpFlowRate") + .HasColumnType("double") + .HasColumnName("filter_sump_flow_rate"); - b.Property("WaterLevel") - .HasColumnType("double"); + b1.Property("SumpORP") + .HasColumnType("double") + .HasColumnName("filter_sump_orp"); - b.Property("WaterTankNum") - .HasColumnType("int"); + b1.Property("SumpPH") + .HasColumnType("double") + .HasColumnName("filter_sump_ph"); - b.HasKey("Id"); + b1.Property("SumpTemperature") + .HasColumnType("double") + .HasColumnName("filter_sump_temperature"); + + b1.Property("SumpWaterLevel") + .HasColumnType("double") + .HasColumnName("filter_sump_water_level"); + + b1.HasKey("WaterQualityVOId"); + + b1.ToTable("water_quality"); + + b1.WithOwner() + .HasForeignKey("WaterQualityVOId"); + }); + + b.OwnsOne("SmartAquaViewer.DataAnalysis.SterilizingSystem", "Sterilizing", b1 => + { + b1.Property("WaterQualityVOId") + .HasColumnType("int"); + + b1.Property("ExcessOzoneDestroyerPower") + .HasColumnType("tinyint(1)") + .HasColumnName("ster_excess_ozone_destroyer_power"); + + b1.Property("OzoneDissolverPower") + .HasColumnType("tinyint(1)") + .HasColumnName("ster_ozone_dissolver_power"); + + b1.Property("OzoneDissolverPressure") + .HasColumnType("double") + .HasColumnName("ster_ozone_dissolver_pressure"); + + b1.Property("OzoneGeneratorPower") + .HasColumnType("tinyint(1)") + .HasColumnName("ster_ozone_generator_power"); + + b1.Property("UVSterilizerId") + .IsRequired() + .HasColumnType("longtext") + .HasColumnName("ster_uv_sterilizer_id"); + + b1.Property("UVSterilizerPower") + .HasColumnType("tinyint(1)") + .HasColumnName("ster_uv_sterilizer_power"); + + b1.HasKey("WaterQualityVOId"); + + b1.ToTable("water_quality"); + + b1.WithOwner() + .HasForeignKey("WaterQualityVOId"); + }); + + b.OwnsOne("SmartAquaViewer.DataAnalysis.WaterTank", "Tank", b1 => + { + b1.Property("WaterQualityVOId") + .HasColumnType("int"); + + b1.Property("DOValue") + .HasColumnType("double") + .HasColumnName("tank_do_value"); + + b1.Property("FlowRate") + .HasColumnType("double") + .HasColumnName("tank_flow_rate"); + + b1.Property("Number") + .HasColumnType("int") + .HasColumnName("tank_number"); + + b1.Property("ORP") + .HasColumnType("double") + .HasColumnName("tank_orp"); + + b1.Property("PH") + .HasColumnType("double") + .HasColumnName("tank_ph"); + + b1.Property("Temperature") + .HasColumnType("double") + .HasColumnName("tank_temperature"); + + b1.HasKey("WaterQualityVOId"); + + b1.ToTable("water_quality"); + + b1.WithOwner() + .HasForeignKey("WaterQualityVOId"); + }); + + b.Navigation("Filtering") + .IsRequired(); + + b.Navigation("Sterilizing") + .IsRequired(); - b.ToTable("WaterQuality"); + b.Navigation("Tank") + .IsRequired(); }); #pragma warning restore 612, 618 }