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>
89 lines
3.9 KiB
C#
89 lines
3.9 KiB
C#
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);
|
||
}
|
||
}
|
||
}
|