a502322188
손상된 .git 히스토리(missing tree)로 재초기화 후 작업트리 전체 커밋. .claude/ 만 제외(로컬 에이전트 설정). 구 저장소 백업(.git_corrupt_backup/) 포함. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
98 lines
3.7 KiB
C#
98 lines
3.7 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|