diff --git a/SmartAquaViewer.sln b/SmartAquaViewer.sln index 44473df..261bd86 100644 --- a/SmartAquaViewer.sln +++ b/SmartAquaViewer.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.13.35931.197 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartAquaViewer", "SmartAquaViewer\SmartAquaViewer.csproj", "{B1AF5CCA-731E-42E1-8ECD-9B8FC7237A95}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FFMPEGPlayer", "..\FFMPEGPlayer\FFMPEGPlayer\FFMPEGPlayer.csproj", "{1A33B46E-B95E-491A-B7A1-6D9EDCA40FD4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,14 @@ Global {B1AF5CCA-731E-42E1-8ECD-9B8FC7237A95}.Release|Any CPU.Build.0 = Release|Any CPU {B1AF5CCA-731E-42E1-8ECD-9B8FC7237A95}.Release|x64.ActiveCfg = Release|x64 {B1AF5CCA-731E-42E1-8ECD-9B8FC7237A95}.Release|x64.Build.0 = Release|x64 + {1A33B46E-B95E-491A-B7A1-6D9EDCA40FD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A33B46E-B95E-491A-B7A1-6D9EDCA40FD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A33B46E-B95E-491A-B7A1-6D9EDCA40FD4}.Debug|x64.ActiveCfg = Debug|x64 + {1A33B46E-B95E-491A-B7A1-6D9EDCA40FD4}.Debug|x64.Build.0 = Debug|x64 + {1A33B46E-B95E-491A-B7A1-6D9EDCA40FD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A33B46E-B95E-491A-B7A1-6D9EDCA40FD4}.Release|Any CPU.Build.0 = Release|Any CPU + {1A33B46E-B95E-491A-B7A1-6D9EDCA40FD4}.Release|x64.ActiveCfg = Release|x64 + {1A33B46E-B95E-491A-B7A1-6D9EDCA40FD4}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SmartAquaViewer/Classes/Converter.cs b/SmartAquaViewer/Classes/Converter.cs index a955903..2e504a0 100644 --- a/SmartAquaViewer/Classes/Converter.cs +++ b/SmartAquaViewer/Classes/Converter.cs @@ -40,36 +40,4 @@ namespace SmartAquaViewer.Classes public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => !(value is bool b && b); } - - public class EnergyToGreenHouseGasConverter : IValueConverter - { - // 2024년 배출계수 (kgCO₂/kWh) - private const double EmissionFactor = 0.4747; - - /// - /// kWh → tCO₂ 변환 - /// - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is double kWh) - { - double tonCO2 = (kWh * EmissionFactor) / 1000.0; - return tonCO2.ToString("F2"); // 소수점 3자리 - } - return null; - } - - /// - /// tCO₂ → kWh 역변환 (Binding TwoWay 대응) - /// - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - if (double.TryParse(value?.ToString(), out double tonCO2)) - { - double kWh = (tonCO2 * 1000.0) / EmissionFactor; - return kWh; - } - return null; - } - } } diff --git a/SmartAquaViewer/DataAnalisys/WaterQualityVO.cs b/SmartAquaViewer/DataAnalisys/WaterQualityVO.cs index 97c4444..5903099 100644 --- a/SmartAquaViewer/DataAnalisys/WaterQualityVO.cs +++ b/SmartAquaViewer/DataAnalisys/WaterQualityVO.cs @@ -37,6 +37,11 @@ namespace SmartAquaViewer.DataAnalysis /// public double TotalEnergy { get; set; } + /// + /// 총 온실가스 배출량 (톤, tCO₂) + /// + public double TotalGreenhouseGas { get; set; } + public WaterQualityVO() { } public WaterQualityVO(DateTime RecordedTime, WaterTank tank, FilteringSystem filtering, SterilizingSystem sterilizing) @@ -67,6 +72,25 @@ namespace SmartAquaViewer.DataAnalysis vo.Sterilizing.ExcessOzoneDestroyerEnergy; } + double ConvertEnergyToGHG(double energy) + { + // 2024년 배출계수 (kgCO₂/kWh) + const double EmissionFactor = 0.4747; + return (energy * EmissionFactor); // / 1000.0; // tCO₂ + } + + double CalculateTotalGreenhouseGas(WaterQualityVO vo) + { + return vo.Filtering.AirBlowerGreenhouseGas + + vo.Filtering.CirculationPumpGreenhouseGas + + vo.Filtering.HeatPumpGreenhouseGas + + vo.Filtering.SandFilterGreenhouseGas + + vo.Sterilizing.ExcessOzoneDestroyerGreenhouseGas + + vo.Sterilizing.OzoneDissolverGreenhouseGas + + vo.Sterilizing.OzoneGeneratorGreenhouseGas + + vo.Sterilizing.UVSterilizerGreenhouseGas; + } + if (totalRowsCount <= 0) return list; double totalSeconds; @@ -86,7 +110,7 @@ namespace SmartAquaViewer.DataAnalysis for (int i = 0; i < totalRowsCount; i++) { DateTime ts = start.AddSeconds(stepSeconds * i); - + var vo = new WaterQualityVO { @@ -102,6 +126,7 @@ namespace SmartAquaViewer.DataAnalysis Filtering = new FilteringSystem( sandFilterPower: rand.Next(0, 2) == 1, sandFilterEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2), + sandFilterGreenhouseGas: 0, // 추후 계산 sumpPH: Math.Round(rand.NextDouble() * 2 + 6, 2), sumpORP: Math.Round(rand.NextDouble() * 200 + 100, 2), sumpWaterLevel: Math.Round(rand.NextDouble() * 2 + 1, 2), @@ -109,28 +134,44 @@ namespace SmartAquaViewer.DataAnalysis sumpTemperature: Math.Round(rand.NextDouble() * 10 + 15, 2), circulationPumpPower: rand.Next(0, 2) == 1, circulationPumpEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2), + circulationPumpGreenhouseGas: 0, // 추후 계산 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), + heatPumpGreenhouseGas: 0, // 추후 계산 airBlowerPower: rand.Next(0, 2) == 1, - airBlowerEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2) + airBlowerEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2), + airBlowerGreenhouseGas: 0 // 추후 계산 ), Sterilizing = new SterilizingSystem( ozoneGeneratorPower: rand.Next(0, 2) == 1, ozoneGeneratorEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2), + ozoneGeneratorGreenhouseGas: 0, // 추후 계산 uvSterilizerId: "UV" + rand.Next(1, 100), uvSterilizerPower: rand.Next(0, 2) == 1, uvSterilizerEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2), + uvSterilizerGreenhouseGas: 0, // 추후 계산 ozoneDissolverPower: rand.Next(0, 2) == 1, ozoneDissolverPressure: Math.Round(rand.NextDouble() * 100 + 50, 2), ozoneDissolverEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2), + ozoneDissolverGreenhouseGas: 0, // 추후 계산 excessOzoneDestroyerPower: rand.Next(0, 2) == 1, - excessOzoneDestroyerEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2) + excessOzoneDestroyerEnergy: Math.Round(rand.NextDouble() * 2 + 0.5, 2), + excessOzoneDestroyerGreenhouseGas: 0 // 추후 계산 ), }; vo.TotalEnergy = CalculateTotalEnergy(vo); + vo.Filtering.SandFilterGreenhouseGas = ConvertEnergyToGHG(vo.Filtering.SandFilterEnergy); + vo.Filtering.CirculationPumpGreenhouseGas = ConvertEnergyToGHG(vo.Filtering.CirculationPumpEnergy); + vo.Filtering.HeatPumpGreenhouseGas = ConvertEnergyToGHG(vo.Filtering.HeatPumpEnergy); + vo.Filtering.AirBlowerGreenhouseGas = ConvertEnergyToGHG(vo.Filtering.AirBlowerEnergy); + vo.Sterilizing.OzoneGeneratorGreenhouseGas = ConvertEnergyToGHG(vo.Sterilizing.OzoneGeneratorEnergy); + vo.Sterilizing.UVSterilizerGreenhouseGas = ConvertEnergyToGHG(vo.Sterilizing.UVSterilizerEnergy); + vo.Sterilizing.OzoneDissolverGreenhouseGas = ConvertEnergyToGHG(vo.Sterilizing.OzoneDissolverEnergy); + vo.Sterilizing.ExcessOzoneDestroyerGreenhouseGas = ConvertEnergyToGHG(vo.Sterilizing.ExcessOzoneDestroyerEnergy); + vo.TotalGreenhouseGas = CalculateTotalGreenhouseGas(vo); list.Add(vo); } @@ -202,6 +243,12 @@ namespace SmartAquaViewer.DataAnalysis [Column("filter_sand_filter_energy")] public double SandFilterEnergy { get; set; } + /// + /// 모래여과기 온실가스 (tCO₂) + /// + [Column("filter_sand_filter_greenhouse_gas")] + public double SandFilterGreenhouseGas { get; set; } + /// /// 섬프탱크 pH (산도) /// @@ -244,6 +291,12 @@ namespace SmartAquaViewer.DataAnalysis [Column("filter_circulation_pump_energy")] public double CirculationPumpEnergy { get; set; } + /// + /// 순환펌프 온실가스 (tCO₂) + /// + [Column("filter_circulation_pump_greenhouse_gas")] + public double CirculationPumpGreenhouseGas { get; set; } + /// /// 인버터 제어기 상태 /// @@ -274,6 +327,12 @@ namespace SmartAquaViewer.DataAnalysis [Column("filter_heat_pump_energy")] public double HeatPumpEnergy { get; set; } + /// + /// 히트펌프 온실가스 (tCO₂) + /// + [Column("filter_heat_pump_greenhouse_gas")] + public double HeatPumpGreenhouseGas { get; set; } + /// /// 에어브로와 전원 (true: ON, false: OFF) /// @@ -286,16 +345,24 @@ namespace SmartAquaViewer.DataAnalysis [Column("filter_air_blower_energy")] public double AirBlowerEnergy { get; set; } + /// + /// 에어브로와 온실가스 (tCO₂) + /// + [Column("filter_air_blower_greenhouse_gas")] + public double AirBlowerGreenhouseGas { get; set; } + public FilteringSystem() { } public FilteringSystem( - bool sandFilterPower, double sandFilterEnergy, + bool sandFilterPower, double sandFilterEnergy, double sandFilterGreenhouseGas, 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) + bool circulationPumpPower, double circulationPumpEnergy, double circulationPumpGreenhouseGas, string? inverterControllerStatus, double flowRate, + bool heatPumpPower, double heatPumpTemperature, double heatPumpEnergy, double heatPumpGreenhouseGas, + bool airBlowerPower, double airBlowerEnergy, double airBlowerGreenhouseGas) { SandFilterPower = sandFilterPower; SandFilterEnergy = sandFilterEnergy; + SandFilterGreenhouseGas = sandFilterGreenhouseGas; SumpPH = sumpPH; SumpORP = sumpORP; SumpWaterLevel = sumpWaterLevel; @@ -303,13 +370,16 @@ namespace SmartAquaViewer.DataAnalysis SumpTemperature = sumpTemperature; CirculationPumpPower = circulationPumpPower; CirculationPumpEnergy = circulationPumpEnergy; + CirculationPumpGreenhouseGas = circulationPumpGreenhouseGas; InverterControllerStatus = inverterControllerStatus; FlowRate = flowRate; HeatPumpPower = heatPumpPower; HeatPumpTemperature = heatPumpTemperature; HeatPumpEnergy = heatPumpEnergy; + HeatPumpGreenhouseGas = heatPumpGreenhouseGas; AirBlowerPower = airBlowerPower; AirBlowerEnergy = airBlowerEnergy; + AirBlowerGreenhouseGas = airBlowerGreenhouseGas; } } @@ -328,6 +398,12 @@ namespace SmartAquaViewer.DataAnalysis [Column("ster_ozone_generator_energy")] public double OzoneGeneratorEnergy { get; set; } + /// + /// 오존 발생기 온실가스 (tCO₂) + /// + [Column("ster_ozone_generator_greenhouse_gas")] + public double OzoneGeneratorGreenhouseGas { get; set; } + /// /// 자외선 살균기 ID /// @@ -346,6 +422,12 @@ namespace SmartAquaViewer.DataAnalysis [Column("ster_uv_sterilizer_energy")] public double UVSterilizerEnergy { get; set; } + /// + /// 자외선 살균기 온실가스 (tCO₂) + /// + [Column("ster_uv_sterilizer_greenhouse_gas")] + public double UVSterilizerGreenhouseGas { get; set; } + /// /// 오존용해장치 전원 (true: ON, false: OFF) /// @@ -364,6 +446,12 @@ namespace SmartAquaViewer.DataAnalysis [Column("ster_ozone_dissolver_energy")] public double OzoneDissolverEnergy { get; set; } + /// + /// 오존용해장치 온실가스 (tCO₂) + /// + [Column("ster_ozone_dissolver_greenhouse_gas")] + public double OzoneDissolverGreenhouseGas { get; set; } + /// /// 배오존장치 전원 (true: ON, false: OFF) /// @@ -376,24 +464,34 @@ namespace SmartAquaViewer.DataAnalysis [Column("ster_excess_ozone_destroyer_energy")] public double ExcessOzoneDestroyerEnergy { get; set; } + /// + /// 배오존장치 온실가스 (tCO₂) + /// + [Column("ster_excess_ozone_destroyer_greenhouse_gas")] + public double ExcessOzoneDestroyerGreenhouseGas { 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) + bool ozoneGeneratorPower, double ozoneGeneratorEnergy, double ozoneGeneratorGreenhouseGas, + string uvSterilizerId, bool uvSterilizerPower, double uvSterilizerEnergy, double uvSterilizerGreenhouseGas, + bool ozoneDissolverPower, double ozoneDissolverPressure, double ozoneDissolverEnergy, double ozoneDissolverGreenhouseGas, + bool excessOzoneDestroyerPower, double excessOzoneDestroyerEnergy, double excessOzoneDestroyerGreenhouseGas) { OzoneGeneratorPower = ozoneGeneratorPower; OzoneGeneratorEnergy = ozoneGeneratorEnergy; + OzoneGeneratorGreenhouseGas = ozoneGeneratorGreenhouseGas; UVSterilizerId = uvSterilizerId; UVSterilizerPower = uvSterilizerPower; UVSterilizerEnergy = uvSterilizerEnergy; + UVSterilizerGreenhouseGas = uvSterilizerGreenhouseGas; OzoneDissolverPower = ozoneDissolverPower; OzoneDissolverPressure = ozoneDissolverPressure; OzoneDissolverEnergy = ozoneDissolverEnergy; + OzoneDissolverGreenhouseGas = ozoneDissolverGreenhouseGas; ExcessOzoneDestroyerPower = excessOzoneDestroyerPower; ExcessOzoneDestroyerEnergy = excessOzoneDestroyerEnergy; + ExcessOzoneDestroyerGreenhouseGas = excessOzoneDestroyerGreenhouseGas; } } } diff --git a/SmartAquaViewer/Model/Enums.cs b/SmartAquaViewer/Model/Enums.cs index d55c773..7b25e86 100644 --- a/SmartAquaViewer/Model/Enums.cs +++ b/SmartAquaViewer/Model/Enums.cs @@ -35,4 +35,10 @@ namespace SmartAquaViewer.Model Off, On } + + public enum DataType + { + Energy, + GreenhouseGas + } } diff --git a/SmartAquaViewer/View/GreenHouseView.xaml b/SmartAquaViewer/View/GreenHouseView.xaml index 150ba6e..dd74d07 100644 --- a/SmartAquaViewer/View/GreenHouseView.xaml +++ b/SmartAquaViewer/View/GreenHouseView.xaml @@ -4,13 +4,14 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:SmartAquaViewer.View" + xmlns:control="clr-namespace:SmartAquaViewer.Controls" xmlns:helper="clr-namespace:SmartAquaViewer.Helper" xmlns:classes="clr-namespace:SmartAquaViewer.Classes" mc:Ignorable="d" d:DesignHeight="940" d:DesignWidth="1650"> - + @@ -35,17 +36,17 @@ ElementStyle="{StaticResource DataGridElmenetStyle}"/> + Binding="{Binding Filtering.SandFilterGreenhouseGas, StringFormat=\{0:F3\}}"/> + Binding="{Binding Filtering.CirculationPumpGreenhouseGas, StringFormat=\{0:F3\}}"/> + Binding="{Binding Filtering.HeatPumpGreenhouseGas, StringFormat=\{0:F3\}}"/> + Binding="{Binding Filtering.AirBlowerGreenhouseGas, StringFormat=\{0:F3\}}"/> + Binding="{Binding Sterilizing.OzoneGeneratorGreenhouseGas, StringFormat=\{0:F3\}}"/> + Binding="{Binding Sterilizing.UVSterilizerGreenhouseGas, StringFormat=\{0:F3\}}"> @@ -54,11 +55,11 @@ + Binding="{Binding Sterilizing.OzoneDissolverGreenhouseGas, StringFormat=\{0:F3\}}"/> - + Binding="{Binding Sterilizing.ExcessOzoneDestroyerGreenhouseGas, StringFormat=\{0:F3\}}"/> + @@ -86,13 +87,183 @@ helper:ComboBoxHelper.SelectFirstOnItemsChange="True" IsEditable="False" IsTextSearchEnabled="False"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +