namespace ErvProtocol { // 펌웨어 없이 UI/파이프라인 검증용 합성 STATUS payload(73B) 생성. public static class DemoStatus { public static byte[] BuildPayload(int tick) { var p = new byte[StatusDecoder.STATUS_LEN]; p[0] = 1; // power p[1] = (byte)RunMode.Auto; // runMode p[2] = (byte)((tick / 5) % 2); // autoState 분산/집중 p[3] = (byte)(2 + (tick % 3)); // fanMode 2~4 p[4] = SubModeBits.SmartSleep; // subMode p[5] = (byte)(tick % 2); // hood p[6] = (byte)HystPreset.Normal; // preset WriteU16(p, 7, 30); WriteU16(p, 9, 50); WriteU16(p, 11, 300); WriteU16(p, 13, 700); WriteU16(p, 15, 0x0000); // errorCode for (int r = 0; r < 4; r++) { int o = 17 + r * 14; int seed = tick + r * 13; p[o + 0] = (byte)((seed % 2) | (((seed % 3) == 0) ? 0x02 : 0)); // bit0 급기 / bit1 배기 WriteU16(p, o + 1, 10 + (seed * 3) % 60); WriteU16(p, o + 3, 15 + (seed * 5) % 90); WriteU16(p, o + 5, 100 + (seed * 7) % 400); WriteU16(p, o + 7, 450 + (seed * 11) % 700); p[o + 9] = (byte)(1 + (seed % 4)); p[o + 10] = (byte)(seed % 10); WriteU16(p, o + 11, (seed * 17) % 100); p[o + 13] = (byte)(seed % 5); } p[73] = 0; // reset (토글 off) // 풍량 VSP 설정값 (1바이트, 사양서 DL H-ERV VSP 실측표) : 환기1~4, 바이패스, 공청1~4 의 SA/EA int[] sa = { 56, 63, 70, 86, 67, 65, 72, 78, 80 }; int[] ea = { 57, 63, 70, 85, 75, 0, 0, 0, 0 }; for (int i = 0; i < 9; i++) { int o = 74 + i * 4; WriteU16(p, o, sa[i]); WriteU16(p, o + 2, ea[i]); } // 히스테리시스 데드밴드(하강) (ECO/NORMAL/TURBO 의 PM2.5/PM10/VOC/CO2) - 사양서 int[,] hyst = { { 2, 5, 5, 50 }, { 2, 5, 5, 50 }, { 2, 5, 3, 30 } }; for (int i = 0; i < 3; i++) { int o = 110 + i * 8; WriteU16(p, o, hyst[i, 0]); WriteU16(p, o + 2, hyst[i, 1]); WriteU16(p, o + 4, hyst[i, 2]); WriteU16(p, o + 6, hyst[i, 3]); } // 모드별 오염단계 임계표 (3프리셋 × [CO2,PM2.5,PM10,VOC] × L1~L4 상한) - 사양서 int[][,] thr = { new int[,] { {1000,1300,1600,2000}, {20,38,60,86}, {40,86,126,173}, {171,195,308,438} }, // ECO new int[,] { {800,1100,1400,1700}, {14,29,49,69}, {28,66,102,138}, {120,150,250,350} }, // NORMAL new int[,] { {700,1000,1300,1600}, {12,23,38,52}, {24,53,78,104}, {103,120,192,263} }, // TURBO }; for (int i = 0; i < 3; i++) { int o = StatusDecoder.THR_OFF + i * 32; for (int g = 0; g < 4; g++) // g: 0 CO2,1 PM2.5,2 PM10,3 VOC for (int k = 0; k < 4; k++) WriteU16(p, o + g * 8 + k * 2, thr[i][g, k]); } // 각실 온도/습도 (offset 230~, 4실 × [Temp, Humi]) for (int r = 0; r < 4; r++) { int o = StatusDecoder.TEMPHUMI_OFF + r * 2; p[o + 0] = (byte)(22 + (tick + r) % 6); // 22~27℃ p[o + 1] = (byte)(40 + (tick + r * 7) % 30); // 40~69% } return p; } static void WriteU16(byte[] p, int off, int v) { p[off] = (byte)((v >> 8) & 0xFF); p[off + 1] = (byte)(v & 0xFF); } } }