5a96a696b1
- 펌웨어(program), C# 대시보드(TestProgram), 시뮬레이터(Simulator), 프로토콜/문서(Protocol, doc) 전체를 단일 저장소로 통합 - program 폴더의 별도 git 저장소를 제거하고 통합 저장소에 흡수 - 빌드 산출물(program/build, bin/obj, *.o/.elf/.bin/.hex 등) .gitignore 처리 - 사내 Synology NAS Git 원격 연결 예정 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
93 lines
4.6 KiB
C#
93 lines
4.6 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media;
|
|
using ERVSimulator.Model;
|
|
|
|
namespace ERVSimulator
|
|
{
|
|
// 공기질 센서 히스테리시스 팝업 : 활성 프리셋(ECO/NORMAL/TURBO)의 오염단계 임계 + 히스(하강) 표시·수정
|
|
public partial class HystWindow : Window
|
|
{
|
|
readonly ErvState _state;
|
|
public event Action<string>? Applied;
|
|
|
|
Brush Br(string key) => (Brush)FindResource(key);
|
|
|
|
public HystWindow(ErvState state)
|
|
{
|
|
InitializeComponent();
|
|
_state = state;
|
|
// MainWindow 프리셋 버튼 / 대시보드 CTRL 로 HystPreset 변경 시 팝업도 즉시 동기화
|
|
_state.PropertyChanged += OnStateChanged;
|
|
RefreshPreset();
|
|
}
|
|
|
|
void OnStateChanged(object? s, PropertyChangedEventArgs e)
|
|
{
|
|
if (e.PropertyName == nameof(ErvState.HystPreset))
|
|
Dispatcher.BeginInvoke(new Action(RefreshPreset));
|
|
}
|
|
|
|
protected override void OnClosed(EventArgs e)
|
|
{
|
|
_state.PropertyChanged -= OnStateChanged;
|
|
base.OnClosed(e);
|
|
}
|
|
|
|
void RefreshPreset()
|
|
{
|
|
foreach (var child in PresetPanel.Children)
|
|
{
|
|
if (child is Button btn && btn.Tag is string tag && byte.TryParse(tag, out var p))
|
|
{
|
|
bool active = p == _state.HystPreset;
|
|
btn.Background = active ? Br("AccentCyanBrush") : Br("CardBgBrush");
|
|
btn.Foreground = active ? Brushes.Black : Br("TextPrimaryBrush");
|
|
}
|
|
}
|
|
FillGrid(_state.HystPreset);
|
|
}
|
|
|
|
// 활성 프리셋 값으로 표 채우기
|
|
void FillGrid(int p)
|
|
{
|
|
TCo2_1.Text = _state.Co2Thr[p][0].ToString(); TCo2_2.Text = _state.Co2Thr[p][1].ToString(); TCo2_3.Text = _state.Co2Thr[p][2].ToString(); TCo2_4.Text = _state.Co2Thr[p][3].ToString();
|
|
TPm25_1.Text = _state.Pm25Thr[p][0].ToString(); TPm25_2.Text = _state.Pm25Thr[p][1].ToString(); TPm25_3.Text = _state.Pm25Thr[p][2].ToString(); TPm25_4.Text = _state.Pm25Thr[p][3].ToString();
|
|
TPm10_1.Text = _state.Pm10Thr[p][0].ToString(); TPm10_2.Text = _state.Pm10Thr[p][1].ToString(); TPm10_3.Text = _state.Pm10Thr[p][2].ToString(); TPm10_4.Text = _state.Pm10Thr[p][3].ToString();
|
|
TVoc_1.Text = _state.VocThr[p][0].ToString(); TVoc_2.Text = _state.VocThr[p][1].ToString(); TVoc_3.Text = _state.VocThr[p][2].ToString(); TVoc_4.Text = _state.VocThr[p][3].ToString();
|
|
DCo2.Text = _state.Co2Db[p].ToString(); DPm25.Text = _state.Pm25Db[p].ToString(); DPm10.Text = _state.Pm10Db[p].ToString(); DVoc.Text = _state.VocDb[p].ToString();
|
|
// 4단계(최악) : 3단계 상한 초과 = (상한+1)~ (사양서 10p)
|
|
MCo2.Text = $"{_state.Co2Thr[p][3] + 1}~"; MPm25.Text = $"{_state.Pm25Thr[p][3] + 1}~";
|
|
MPm10.Text = $"{_state.Pm10Thr[p][3] + 1}~"; MVoc.Text = $"{_state.VocThr[p][3] + 1}~";
|
|
}
|
|
|
|
static ushort P(TextBox tb) { ushort.TryParse(tb.Text, out var v); return v; }
|
|
|
|
void Preset_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (sender is Button b && b.Tag is string tag && byte.TryParse(tag, out var p) && p < 3)
|
|
{
|
|
_state.HystPreset = p;
|
|
RefreshPreset();
|
|
Applied?.Invoke($"[Manual] 히스테리시스 프리셋 → {(p == 0 ? "ECO" : p == 1 ? "NORMAL" : "TURBO")}");
|
|
}
|
|
}
|
|
|
|
void Apply_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
int p = _state.HystPreset;
|
|
_state.Co2Thr[p][0] = P(TCo2_1); _state.Co2Thr[p][1] = P(TCo2_2); _state.Co2Thr[p][2] = P(TCo2_3); _state.Co2Thr[p][3] = P(TCo2_4);
|
|
_state.Pm25Thr[p][0] = P(TPm25_1); _state.Pm25Thr[p][1] = P(TPm25_2); _state.Pm25Thr[p][2] = P(TPm25_3); _state.Pm25Thr[p][3] = P(TPm25_4);
|
|
_state.Pm10Thr[p][0] = P(TPm10_1); _state.Pm10Thr[p][1] = P(TPm10_2); _state.Pm10Thr[p][2] = P(TPm10_3); _state.Pm10Thr[p][3] = P(TPm10_4);
|
|
_state.VocThr[p][0] = P(TVoc_1); _state.VocThr[p][1] = P(TVoc_2); _state.VocThr[p][2] = P(TVoc_3); _state.VocThr[p][3] = P(TVoc_4);
|
|
_state.Co2Db[p] = P(DCo2); _state.Pm25Db[p] = P(DPm25); _state.Pm10Db[p] = P(DPm10); _state.VocDb[p] = P(DVoc);
|
|
|
|
Applied?.Invoke($"[Manual] 공기질 센서 히스테리시스 적용 (프리셋 {(p == 0 ? "ECO" : p == 1 ? "NORMAL" : "TURBO")})");
|
|
}
|
|
|
|
void Close_Click(object sender, RoutedEventArgs e) => Close();
|
|
}
|
|
}
|