일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 오블완
- 해외주식
- 애플
- 티스토리챌린지
- 엔비디아
- 퀄컴
- Home Assistant
- matter
- 미국주식
- 힐스테이트 광교산
- 파이썬
- esp32
- 월패드
- 나스닥
- Python
- homebridge
- 현대통신
- Apple
- Espressif
- MQTT
- 배당
- 매터
- 국내주식
- 공모주
- RS-485
- Bestin
- 코스피
- 홈네트워크
- raspberry pi
- ConnectedHomeIP
- Today
- Total
YOGYUI
힐스테이트 광교산::환기(전열교환기) 제어 RS-485 패킷 분석 본문
도시가스, 난방 관련 제어를 하면서, RS-485 통신선 여러개가 묶여있는 포트로 오가는 패킷 중 네번째 바이트 값에 따라 어떤 기기가 관련있는지 조사해나가고 있다
총 7개 값 (0x18, 0x1B, 0x1C, 0x2A, 0x2B, 0x34, 0x48)이 네번째 바이트 값으로 설정되어 있으며, 그 중
- 0x1B: 도기가스밸브
- 0x18: 난방
인 것을 알게 되었다
이번엔 환기(전열교환기)를 제어하면서 5번째 바이트가 0x02인 명령 패킷을 캡쳐하고 분석해보자
1. 환기 가동 및 풍량 변경 패킷 분석
가스, 난방을 제외하고 패킷을 캡쳐해보자
class ParserVarious(SerialParser):
def interpretPacket(self, packet: bytearray):
if packet[2:4] == bytearray([0x01, 0x1B]): # 가스차단기
if packet[4] == 0x04: # 상태 응답
state = 0 if packet[8] == 0x03 else 1
result = {
'device': 'gasvalve',
'state': state
}
self.sig_parse_result.emit(result)
elif packet[2:4] == bytearray([0x01, 0x18]): # 난방
room_idx = packet[6] & 0x0F
if packet[4] == 0x04: # 상태 응답
if room_idx == 0: # 일반 쿼리 (존재하는 모든 디바이스)
thermostat_count = (len(packet) - 10) // 3
for idx in range(thermostat_count):
dev_packet = packet[8 + idx * 3: 8 + (idx + 1) * 3]
if dev_packet[0] != 0x00: # 0이면 존재하지 않는 디바이스
state = 0 if dev_packet[0] == 0x04 else 1
temp_current = dev_packet[1] # 현재 온도
temp_config = dev_packet[2] # 설정 온도
result = {
'device': 'thermostat',
'room_index': idx + 1,
'state': state,
'temp_current': temp_current,
'temp_config': temp_config
}
self.sig_parse_result.emit(result)
else: # 상태 변경 명령 직후 응답
if packet[5] in [0x45, 0x46]: # 0x46: On/Off 설정 변경에 대한 응답, 0x45: 온도 설정 변경에 대한 응답
state = 0 if packet[8] == 0x04 else 1
temp_current = packet[9] # 현재 온도
temp_config = packet[10] # 설정 온도
result = {
'device': 'thermostat',
'room_index': room_idx,
'state': state,
'temp_current': temp_current,
'temp_config': temp_config
}
self.sig_parse_result.emit(result)
else:
if packet[4] == 0x02:
print(self.prettifyPacket(packet))
Hi-oT 앱으로 환기 가동/중지 명령을 내리면서 캡쳐된 패킷은 다음과 같다
F7 0B 01 2B 02 40 11 01 00 84 EE : 환기 시작
F7 0B 01 2B 02 40 11 02 00 87 EE : 환기 종료
네번째 바이트가 0x2B인 패킷이 환기와 연동되어 있는 것을 알 수 있다
7번째 바이트는 다른 기기들의 경우 하위4비트가 공간 인덱스를 나타냈는데, 환기의 경우 공간 인덱스가 1로 거실인 것을 알 수 있다 (실제 Hi-oT 앱에도 거실에 '환기'가 배치되어 있다)
조명, 아울렛과 마찬가지로 8번째 바이트가 0x01이면 ON, 0x02이면 OFF 상태를 의미하고 있다
앱을 통해 세단계(약,중,강)로 풍량을 조절할 수 있기에, 각 단계별로 조정하면서 발생하는 패킷을 캡쳐한 결과는 다음과 같다
F7 0B 01 2B 02 42 11 01 00 86 EE : 풍량 약 설정
F7 0B 01 2B 02 42 11 03 00 84 EE : 중량 중 설정
F7 0B 01 2B 02 42 11 07 00 80 EE : 중량 강 설정
풍량 설정 시 6번째 바이트는 0x42가 되며, 8번째 바이트가 0x01, 0x03, 0x07이면 각각 풍량이 약, 중, 강이 된다
각 값을 이진법으로 표시해보면
- 0000 0001 : 약
- 0000 0011 : 중
- 0000 0111 : 강
풍량이 LSB 3개 비트를 사용해서 상당히 직관적으로 인코딩되어있다 ㅋㅋ
난방 때도 온도가 정수형으로 1바이트만 사용했고, 환기 풍량은 3비트만 사용하고..
개발자 입장에서 분석하고 구현하기 상당히 간편하다!
2. 쿼리 및 응답 패킷 분석
4번째 바이트가 0x2B인 패킷을 전부 캡쳐해서 분석해보자
F7 0B 01 2B 01 40 11 00 00 86 EE : 평소 쿼리
F7 0C 01 2B 04 40 11 00 02 00 86 EE : 평소 응답 (환기가 꺼져있을 경우)
F7 0B 01 2B 02 40 11 01 00 84 EE : 가동 명령
F7 0C 01 2B 04 40 11 01 01 01 85 EE : 가동 명령에 대한 응답 (풍량 = '약')
F7 0B 01 2B 01 40 11 00 00 86 EE
F7 0C 01 2B 04 40 11 00 01 01 84 EE : 평소 응답 (환기 가동중, 풍량 = '약')
F7 0B 01 2B 02 42 11 03 00 84 EE : 풍량 '중' 변경 명령
F7 0C 01 2B 04 42 11 03 01 03 87 EE : 풍량 변경에 대한 응답 (풍량 = '중')
F7 0B 01 2B 02 42 11 07 00 80 EE : 풍량 '강' 변경 명령
F7 0C 01 2B 04 42 11 07 01 07 87 EE : 풍량 변경에 대한 응답 (풍량 = '강')
F7 0B 01 2B 01 40 11 00 00 86 EE : 평소 쿼리
F7 0C 01 2B 04 40 11 00 01 07 82 EE : 평소 응답 (환기 가동중, 풍량 = '강')
패킷 명세를 정리해보자
- 4번째 바이트가 0x2B이면 환기(전열교환기) 관련 패킷
- 5번째 바이트가 0x01이면 쿼리, 0x02이면 명령, 0x04이면 응답 패킷
- 6번째 바이트가 0x40이면 평소 쿼리/응답 혹은 가동 시작/종료 명령, 0x42이면 풍량 변경 명령 및 응답 패킷
- 풍량 변경 명령 시, 8번째 바이트의 하위 3비트에 따라 풍량이 3단계로 조절됨
0x01 = '약', 0x03 = '중', 0x07 = '강' - 평소 응답 시 9번째 바이트가 0x02이면 가동 중지, 0x01이면 가동 중 상태
10번째 바이트는 풍량을 나타내며, 가동 중지 상태일 경우 값은 0이고 가동 중일 경우 풍량은 0x01, 0x03, 0x07 세 값 중 하나 - 가동, 풍량 변경 명령에 대한 응답 패킷은 평소 응답 패킷과 8번째 바이트값을 제외하고는 모두 동일하다
시리얼 패킷 파서, 쿼리/명령 패킷 생성 구문 모두 다른 기기들의 코드를 90% 이상 재활용할 수 있으므로 금방 구현할 수 있을 것 같다
'홈네트워크(IoT) > 힐스테이트 광교산' 카테고리의 다른 글
힐스테이트 광교산::시스템에어컨 제어 RS-485 패킷 분석 (0) | 2022.06.19 |
---|---|
힐스테이트 광교산::환기(전열교환기) - 애플 홈킷 + 구글 어시스턴트 연동 (1) | 2022.06.18 |
힐스테이트 광교산::난방 - 애플 홈킷 + 구글 어시스턴트 연동 (2) | 2022.06.17 |
힐스테이트 광교산::난방 제어 RS-485 패킷 분석 (0) | 2022.06.16 |
힐스테이트 광교산::도시가스차단기(밸브) - 애플 홈킷 + 구글 어시스턴트 연동 (0) | 2022.06.15 |