Files
HECO2/TestProgram/ErvProtocol/StatusDecoder.cs
T
jeon a502322188 chore: HERV 통합 저장소 재초기화 커밋
손상된 .git 히스토리(missing tree)로 재초기화 후 작업트리 전체 커밋.
.claude/ 만 제외(로컬 에이전트 설정). 구 저장소 백업(.git_corrupt_backup/) 포함.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 09:32:17 +09:00

98 lines
3.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace ErvProtocol
{
public static class StatusDecoder
{
public const byte STATUS = 0x81; // ERV→PC 상태
public const byte ACK = 0x82; // ERV→PC 제어 응답
public const int STATUS_LEN = 240; // 238 + 2((꺼짐)예약 잔여초 u16)
public const int THR_OFF = 134; // 모드별 오염단계 임계표 시작 오프셋
public const int TEMPHUMI_OFF = 230; // 각실 온도/습도 블록 시작 (4실 × [Temp,Humi])
public const int RESERVE_OFF = 238; // (꺼짐)예약 잔여초 u16
static int U16(byte[] p, int off) => (p[off] << 8) | p[off + 1]; // 빅엔디안
// STATUS(0x81) payload(73B) → StatusRecord. 길이 부족 시 null.
public static StatusRecord? Decode(byte[] p)
{
if (p.Length < STATUS_LEN) return null;
var s = new StatusRecord
{
Power = p[0],
RunMode = p[1],
AutoState = p[2],
FanMode = p[3],
SubMode = p[4],
Hood = p[5],
HystPreset = p[6],
HystPm25 = U16(p, 7),
HystPm10 = U16(p, 9),
HystVoc = U16(p, 11),
HystCo2 = U16(p, 13),
ErrorCode = U16(p, 15),
};
const int baseOff = 17;
for (int r = 0; r < 4; r++)
{
int o = baseOff + r * 14;
var room = s.Rooms[r];
room.Damper = p[o + 0];
room.Pm25 = U16(p, o + 1);
room.Pm10 = U16(p, o + 3);
room.Voc = U16(p, o + 5);
room.Co2 = U16(p, o + 7);
room.AirQuality = p[o + 9];
room.LedDim = p[o + 10];
room.LoadScore = U16(p, o + 11);
room.FinalVolume = p[o + 13];
}
// ERV 리셋 (offset 73)
s.Reset = p[73];
// 풍량 VSP 블록 (offset 74~, 9엔트리 × u16 SA·EA)
const int vspOff = 74;
for (int i = 0; i < 9; i++)
{
int o = vspOff + i * 4;
s.Vsp[i].Sa = U16(p, o);
s.Vsp[i].Ea = U16(p, o + 2);
}
// 히스테리시스 프리셋 테이블 (offset 110~, 3프리셋 × PM2.5/PM10/VOC/CO2 u16)
const int hystOff = 110;
for (int i = 0; i < 3; i++)
{
int o = hystOff + i * 8;
s.HystTable[i].Pm25 = U16(p, o);
s.HystTable[i].Pm10 = U16(p, o + 2);
s.HystTable[i].Voc = U16(p, o + 4);
s.HystTable[i].Co2 = U16(p, o + 6);
}
// 모드별 오염단계 임계표 (offset 134~, 3프리셋 × [CO2,PM2.5,PM10,VOC] × L1~L4 u16)
for (int i = 0; i < 3; i++)
{
int o = THR_OFF + i * 32;
for (int k = 0; k < 4; k++) s.ThrTable[i].Co2[k] = U16(p, o + 0 + k * 2);
for (int k = 0; k < 4; k++) s.ThrTable[i].Pm25[k] = U16(p, o + 8 + k * 2);
for (int k = 0; k < 4; k++) s.ThrTable[i].Pm10[k] = U16(p, o + 16 + k * 2);
for (int k = 0; k < 4; k++) s.ThrTable[i].Voc[k] = U16(p, o + 24 + k * 2);
}
// 각실 온도/습도 (offset 230~, 4실 × [Temp, Humi])
for (int r = 0; r < 4; r++)
{
int o = TEMPHUMI_OFF + r * 2;
s.Rooms[r].Temp = p[o + 0];
s.Rooms[r].Humi = p[o + 1];
}
// (꺼짐)예약 잔여초 (offset 238, u16)
s.ReserveRemainSec = U16(p, RESERVE_OFF);
return s;
}
}
}