삼성스탠드에어컨 동작구성 정보 Samsung NonNASA 로컬 구성 변경 기록
작성자 정보
- 최고관리자 작성
- 192.♡.0.1 아이피
- 작성일
컨텐츠 정보
- 246 조회
- 목록
링크
첨부
본문
삼성스탠드에어컨 동작구성 정보 Samsung NonNASA 로컬 구성 변경 기록
정보저장
https://naver.me/xZKRJ1cj
# Samsung NonNASA 로컬 구성 변경 기록
문서 기준: 2026-08-19
## Local 수정 목적 요약
### 문제점
오리지널 GitHub 코드를 사용자의 Samsung NonNASA 에어컨과 MAX485 보드에 적용했을
때 다음 문제가 확인되었습니다.
- UART 수신은 되었지만 전원, 모드, 온도 변경 명령의 실제 TX가 동작하지 않음
- 사용자의 기존 구성에서는 에어컨 상태를 받을 수는 있어도 제어 명령을 안정적으로
에어컨까지 전달하지 못함
- 전원 ON 직후 이전 `Cmd20(power=0)`이 다시 수신되면 UI가 OFF로 되돌아감
- 첫 번째 전원 ON이 무시된 것처럼 보이고 두 번째 명령에서 동작하는 현상 발생
- 냉방, 제습, 자동, 난방의 수신 raw mode가 잘못 매핑되어 UI에 다른 모드로 표시됨
- OFF 상태에서 모드나 온도를 변경해도 전원 ON과 설정 변경이 하나의 request로
처리되지 않음
- 송신과 수신 상태를 로그만으로 즉시 구분하기 어려움
### 수정 목적
오리지널 NonNASA 프로토콜의 정상적인 raw mode 규칙과 송신 구조는 유지하면서,
사용자의 보드 및 배선 환경에서 실제 전원·모드·온도 제어가 성공하도록 로컬
구성을 보완하는 것이 목적입니다.
구체적인 목적은 다음과 같습니다.
1. MAX485 DE/RE 방향제어를 올바르게 수행하여 실제 TX를 보장합니다.
2. 첫 전원 ON과 OFF 동작이 이전 상태 프레임에 의해 덮어쓰이지 않게 합니다.
3. OFF 상태에서 모드 또는 설정을 변경하면 전원 ON과 함께 송신합니다.
4. 수신 raw mode를 원본 규칙대로 해석하여 UI 모드를 정상 표시합니다.
5. RX와 TX 통신 상태를 LED 및 binary sensor로 확인할 수 있게 합니다.
### 수정 내용
- `flow_control_pin: GPIO13`을 사용하여 MAX485 DE/RE 방향을 제어
- 부팅 직후 DE/RE를 LOW로 설정하여 수신 상태로 시작
- 송신 전 DE/RE HIGH, UART 전송 및 flush 후 DE/RE LOW 처리
- request queue 등록, 장치 등록·깨우기, 송신 예약 및 재시도 흐름 보완
- 전원 ON 시 마지막 수신 모드와 설정값 재사용
- OFF 상태의 모드·온도·팬·프리셋·스윙 변경 시 자동 전원 ON
- 초기 ON request가 pending인 동안 이전 OFF 응답의 상태 덮어쓰기 방지
- NonNASA 수신 mode raw 값과 decoded mode 로그 추가
- RX 빨강, TX 초록 LED 및 TX/RX/Bus Online binary sensor 연동
- GPIO13 DE/RE 방향 상태를 `rs485_de_re_active` binary sensor에 복사
- DE/RE TX 이벤트를 `RS485 DE RE TX Direction 2s` template switch로 2초 표시
- ON/OFF 전원 request의 확인 기반 재송신 및 timeout 처리
- MODE 변경 시 전원과 수신 mode를 함께 확인
- 온도·팬·스윙 변경 시 요청한 상태 필드 확인
### 개선 효과
이번 수정은 UI 명령을 단순히 송신하는 구조에서, 에어컨의 실제 수신 상태를
확인한 뒤 성공 처리하는 구조로 변경한 것입니다.
- 첫 번째 전원 ON/OFF가 무시된 것처럼 보이는 현상 감소
- 이전 `Cmd20(power=0)`이 새 ON request를 덮어쓰는 현상 감소
- OFF 상태에서 MODE 선택 시 `전원 ON + MODE 전환`을 함께 수행
- 냉방, 제습, 자동, 송풍, 난방의 실제 MODE 변경 여부 확인
- 온도·팬·스윙은 요청한 항목만 확인하여 불필요한 timeout 감소
- 응답이 없으면 제한된 횟수로 자동 재송신
- 통신 단선 시 무한 송신하지 않고 timeout으로 종료
- RX/TX 로그와 LED를 통해 실제 통신 방향 확인 가능
### 오리지널 GitHub 대비 설명
오리지널 GitHub는 NonNASA 송신 기능 자체가 없는 수신 전용 코드가 아닙니다.
원본에도 request 변환, 프레임 생성, UART 전송, 등록 및 재시도 흐름이 있습니다.
다만 사용자의 실제 보드·배선·ESPHome 구성에서는 원본의 송신 경로가 실행되거나
성공하기 위한 조건이 맞지 않아 RX만 동작했습니다.
따라서 이번 Local 수정의 의미는 다음과 같습니다.
| 구분 | 오리지널 GitHub | Local 수정 목적 및 결과 |
|---|---|---|
| 송신 기능 | 소스에 송신 경로는 있음 | 사용자의 보드에서 실제 TX가 성공하도록 보완 |
| DE/RE 방향 | 환경과 설정에 의존 | GPIO13을 명시하고 송수신 방향 전환 안정화 |
| 초기 상태 | 부팅 직후 수신 방향 보장 부족 | 초기 DE/RE LOW로 수신 상태 보장 |
| 첫 전원 ON | 이전 상태 응답에 의해 되돌림 가능 | pending request 보호 및 송신 재시도 |
| 모드 수신 | 원본 enum 규칙 사용 | 잘못된 Local 재매핑 제거, 원본 규칙 복원 |
| OFF 상태 변경 | 전원 ON과 설정 request 연계 부족 | 모드·온도 등 변경 시 자동 ON 송신 |
| 통신 확인 | UART 로그 중심 | RX/TX LED와 binary sensor 추가 |
| 전원 확인 | 응답 지연 시 송신 재시도 지연 가능 | ON/OFF power 비트 확인 및 제한 재송신 |
즉, 오리지널 GitHub 대비 핵심 개선은 프로토콜을 다른 방식으로 바꾼 것이 아니라
**사용자 장치에서 실제 송신이 이루어지는 전기적 방향제어와 request 처리 흐름을
보완한 것**입니다. 수신 mode 매핑 수정은 UI 표시 정상화이고, TX 정상화의 핵심은
DE/RE 방향제어와 송신 큐·등록·재시도 처리입니다.
## ON/OFF 확인 기반 재송신
전원 명령은 송신 1회만 수행하고 `CmdC6`에만 의존하지 않습니다. NonNASA 장치가
mode·온도 필드를 전원 상태보다 늦게 갱신할 수 있으므로, request 종류에 따라
확인 필드를 분리합니다.
### 처리 정책
```text
ON/OFF request 등록
-> 즉시 송신 예약
-> 요청한 power/mode/설정 필드가 Cmd20과 일치하면 성공 처리
-> 미확인 시 2.5초 후 재송신
-> 최대 3회 재시도
-> 계속 미확인 시 timeout 및 request 제거
```
최초 송신을 포함하면 최대 4회 전송됩니다. 재송신은 `CmdC6` 수신에만 의존하지
않으며, `protocol_update()`에서 직접 다음 TX를 예약합니다. 따라서 에어컨이
일시적으로 조용하거나 등록 응답이 늦어도 전원 명령이 다음 요청 제어 프레임까지
무기한 대기하지 않습니다.
### 성공 판정
- ON: 송신 후 `Cmd20.power == true` 수신
- OFF: 송신 후 `Cmd20.power == false` 수신
- mode·온도·팬·스윙: 전원 확정 이후 수신되는 후속 상태 프레임에서 반영
- MODE 변경: `Cmd20.power`와 요청 `NonNasaMode`가 모두 일치
- 온도·팬·스윙 변경: 요청한 상태 필드까지 일치
- 미확인: 최대 재시도 후 `NonNASA MODE/power confirmation timeout` 로그 출력
MODE와 전원 확인에 사용하는 mode 값은 송신 byte가 아니라 NonNASA 내부 enum으로
비교합니다. 예를 들어 송신 Cool 값은 `1`이지만 수신 Cool raw 값은 `0x02`이므로
송신 byte와 수신 raw byte를 직접 비교하지 않습니다. 무한 재송신은 RS485 버스
점유와 오프라인 장치에 대한 지속적인 트래픽을 만들 수 있으므로 사용하지 않습니다.
## 최종 동작 모델
### 전원 ON
```text
ON 명령
-> 마지막 mode/온도/팬/스윙 보완
-> power=true 송신
-> Cmd20.power=true 확인
-> ON 확정
```
### 전원 OFF
```text
OFF 명령
-> power=false 송신
-> Cmd20.power=false 확인
-> OFF 확정
```
### OFF 상태에서 MODE 선택
```text
OFF + Dry 선택
-> power=true + Dry 송신
-> Cmd20.power=true 확인
-> Cmd20.raw_mode=0x04 확인
-> ON + Dry 확정
```
### ON 상태에서 MODE 변경
```text
Cool -> Dry
-> power=true + Dry 송신
-> power=true 확인
-> raw_mode=0x04 확인
-> Dry 확정
```
### 설정값 변경
```text
온도 변경 -> target temperature 일치 확인
팬 변경 -> fanspeed 일치 확인
스윙 변경 -> wind_direction 일치 확인
```
전원과 MODE가 함께 변경되는 경우에는 두 조건을 모두 확인합니다. MODE 확인은
송신 byte가 아니라 NonNASA 내부 enum으로 처리하여 송신 mode 값과 수신 raw mode
값이 다른 프로토콜 특성을 반영합니다.
## 로그 기준
정상 처리 시 다음 순서의 로그를 확인할 수 있습니다.
```text
NonNASA TX queued
NonNASA TX send
Cmd20 received
Cmd20: Removed matching request
```
응답이 없으면 다음과 같은 재시도 및 timeout 로그가 출력됩니다.
```text
NonNASA MODE confirmation missing, retry 1/3
NonNASA power OFF confirmation timeout after 3 retries
```
`TX send`는 실제 UART 송신 요청, `Cmd20 received`는 에어컨 상태 수신,
`Removed matching request`는 요청한 상태가 확인되어 queue가 제거된 단계입니다.
따라서 UI가 먼저 변경되었더라도 최종 상태 확정은 `Cmd20` 수신과 queue 제거를
기준으로 판단합니다.
## 잔여 검증 항목
실제 장치에서 다음 항목을 순서대로 확인합니다.
1. ON: 첫 명령에서 `power=true`가 수신되는지 확인
2. OFF: 첫 명령에서 `power=false`가 수신되는지 확인
3. OFF + Cool: ON과 Cool mode가 모두 확인되는지 확인
4. OFF + Dry: `raw_mode=0x04`가 확인되는지 확인
5. Cool -> Dry: 이전 Cool 상태가 최종 상태로 되돌아가지 않는지 확인
6. Dry -> Cool: `raw_mode=0x02`가 확인되는지 확인
7. MODE 미응답: 2.5초 간격 재송신과 최대 3회 timeout 확인
8. 온도·팬·스윙: 변경하지 않은 필드 때문에 timeout이 발생하지 않는지 확인
9. 통신 단선: 무한 TX 없이 timeout으로 종료되는지 확인
## 결론
현재 동작 차이는 두 가지를 구분해야 합니다.
1. 냉방, 제습, 자동 등이 잘못 표시된 문제는 로컬 코드에서 수신 mode 값을
임의로 재매핑했던 것이 원인이었습니다.
2. 원본 GitHub에도 NonNASA 송신 코드 자체는 있었지만, 사용자 환경에서는
실제 송신이 이루어지지 않고 수신만 되는 상태였습니다. 로컬 수정은 송신
코드를 새로 만든 것이 아니라, 실제 보드에서 송신이 성립하는 조건과
전원 제어 흐름을 보완한 것입니다.
원본 GitHub의 NonNASA 수신 구조를 복원하고, 전원 동작과 모드 변경 시 자동 전원 ON
동작, 통신 상태 표시, 실제 RS485 송신 조건은 로컬 요구사항에 맞게 유지합니다.
## 원본 송신과 로컬 송신의 차이
원본 소스는 다음 송신 경로를 이미 포함하고 있습니다.
- NonNASA request를 송신 mode 값으로 변환
- NonNASA 프레임 생성 및 UART 전송
- 장치 등록 요청과 C6 응답 처리
- request queue와 송신 재시도
- `flow_control_pin`을 통한 RS485 방향 전환
따라서 “원본 GitHub는 프로토콜상 수신 전용”이라고 판단하면 안 됩니다. 정확한
표현은 “사용자의 원본 설치 환경에서는 수신만 확인되었고, 현재 로컬 구성에서는
송신 조건이 보완되어 RX/TX가 모두 실제 동작한다”입니다.
### 실제 TX 동작을 만든 주요 조건
| 조건 | 역할 | 모드 매핑과의 관계 |
|---|---|---|
| `flow_control_pin: GPIO13` | MAX485 DE/RE를 송신 방향으로 전환 | 모드 표시와 무관, 물리 송신에 필수 |
| 송신 전 GPIO13 HIGH | MCU TX 데이터를 A/B 선로로 출력 | 모드 표시와 무관 |
| 송신 완료 후 GPIO13 LOW | 다시 수신 방향으로 복귀 | 모드 표시와 무관 |
| 초기 GPIO13 LOW | 부팅 직후 수신 상태를 보장 | 초기 응답 수신에 영향 |
| request queue 예약 및 등록/깨우기 보완 | 첫 ON 또는 설정 변경 request를 실제 송신 시점까지 유지 | 실제 TX 성공률에 영향 |
| 송신 timeout/retry | 첫 프레임 미응답 시 재전송 | 실제 TX 성공률에 영향 |
| pending 상태 보호 | 이전 `Cmd20(power=0)`이 새 ON 명령을 덮어쓰지 않게 함 | UI/상태 반영 안정성 |
| 수신 mode raw 매핑 복원 | `0x02=Cool`, `0x04=Dry` 등 표시를 정상화 | TX를 가능하게 하지는 않음 |
즉, 수신 mode 매핑 수정만으로는 송신이 가능해지지 않습니다. 송신은 UART TX
핀, MAX485 DI/RO 연결, DE/RE 방향제어, request 예약 및 에어컨 응답 절차가
모두 맞아야 합니다. 현재 보드에서 `inverted: false`로 RX/TX가 정상인 것은
해당 보드의 UART 논리 극성과 MAX485 회로가 맞는 것이며, 이것도 실제 TX 성공의
구성 조건 중 하나입니다.
### 사용자 환경 기준 비교
| 항목 | 원본 GitHub 소스 | 사용자 원본 설치 결과 | 현재 로컬 구성 |
|---|---|---|---|
| NonNASA 송신 코드 | 있음 | 코드상 존재하지만 실제 TX 미확인 | 있음, 실제 TX 확인 |
| NonNASA 수신 | 있음 | 정상 | 정상 |
| RS485 DE/RE | 지원 | 보드/배선/초기 상태에 따라 TX 실패 가능 | GPIO13으로 명시 및 초기 수신 상태 설정 |
| 첫 전원 ON | 기본 queue/상태 흐름 | 첫 명령이 무시된 것처럼 보임 | queue 등록, 등록/깨우기, 재시도 보완 |
| mode 수신 표시 | 원본 enum 기준 | local 재매핑으로 오표시 | 원본 raw enum 복원 |
| 최종 사용자 결과 | 환경 의존 | RX만 동작 | RX/TX 및 모드 표시 정상 |
이 표에서 “원본 설치 결과”는 모든 사용자에게 적용되는 원본의 일반적 한계가
아니라, 현재 장치와 배선에서 관찰된 결과입니다. 원본 소스의 송신 구현 유무와
특정 환경에서 송신이 실제 성공했는지는 별개의 문제입니다.
## 사용자 구성에서 원본 송신이 실패한 결론
사용자의 기존 보드, 배선 및 ESPHome 구성에서는 원본을 적용했을 때 **수신은
되었지만 송신은 실제 동작하지 않은 것**으로 판단합니다.
단, 이는 원본 코드가 송신 기능을 포함하지 않았다는 의미가 아닙니다. 원본에는
NonNASA request 생성, 송신 프레임 변환, UART 전송 코드가 포함되어 있습니다.
문제는 사용자의 실제 구성에서 다음 송신 성공 조건이 충족되지 않았던 것입니다.
- MAX485의 DE/RE 방향 전환이 송신 시점에 정확히 이루어지지 않음
- 부팅 직후 또는 송신 후 RS485가 수신 방향으로 안정적으로 복귀하지 않음
- request가 등록·깨우기·송신 큐 처리 조건을 만족하지 못함
- 첫 송신이 응답 전에 timeout 또는 이전 상태 프레임에 의해 무효화됨
- 송신 재시도 및 pending 상태 처리가 충분하지 않음
RX는 상대적으로 쉽게 확인될 수 있습니다. MAX485가 수신 방향에 있으면 에어컨
프레임을 받을 수 있지만, TX는 송신 순간에 DE/RE를 송신 방향으로 전환해야 하며
전송 완료 후 다시 수신 방향으로 복귀해야 합니다. 따라서 RX 정상만으로 TX까지
정상이라고 판단할 수 없습니다.
현재 로컬 구성에서는 다음 조건을 추가 또는 보완하여 송신을 정상화했습니다.
```text
GPIO13 DE/RE 초기 LOW
-> request 생성 및 queue 등록
-> 등록/깨우기 후 송신 예약
-> DE/RE HIGH
-> GPIO11 TX 및 UART flush
-> 송신 완료 대기
-> DE/RE LOW
-> 에어컨 응답 수신 및 상태 반영
-> 미응답 시 timeout/retry
```
그러므로 최종 판단은 다음과 같습니다.
> 원본은 프로토콜상 송신을 지원하지만, 사용자의 기존 구성에서는 송신 조건이
> 충족되지 않아 RX만 동작했습니다. 로컬 수정은 송신 기능을 새로 만든 것이
> 아니라 DE/RE 방향제어와 송신 큐·등록·재시도·상태 보호를 보완하여 실제 TX가
> 성공하도록 만든 것입니다.
수신 mode 매핑 복원은 냉방, 제습, 자동 등의 UI 표시를 정상화한 변경입니다.
이 변경만으로 송신이 가능해진 것은 아니며, 실제 TX 정상화의 핵심은 MAX485
방향제어와 송신 처리 흐름입니다.
원본 참고:
- https://github.com/omerfaruk-aran/esphome_samsung_hvac_bus
- https://github.com/omerfaruk-aran/esphome_samsung_hvac_bus/blob/main/components/samsung_ac/protocol_non_nasa.h
- https://github.com/omerfaruk-aran/esphome_samsung_hvac_bus/blob/main/components/samsung_ac/protocol_non_nasa.cpp
## NonNASA 수신 mode 규칙
`Cmd20` 수신 프레임의 byte 8 하위 6비트를 원본 enum 값으로 직접 해석합니다.
| 수신 raw mode | 의미 | ESPHome mode |
|---:|---|---|
| `0x01` | Heat | `HEAT` |
| `0x02` | Cool | `COOL` |
| `0x04` | Dry | `DRY` |
| `0x08` | Fan | `FAN_ONLY` |
| `0x21` | Auto Heat | `HEAT_COOL` |
| `0x22` | Auto | `HEAT_COOL` |
수신 mode를 `0x01=Cool`, `0x22=Cool` 등으로 별도 변환하면 냉방, 제습,
자동 표시가 잘못됩니다. 현재는 원본처럼 raw 값을 직접 `NonNasaMode`로 변환합니다.
## 송신 mode 규칙
NonNASA 송신 프레임은 원본 구현의 request mode 변환을 유지합니다.
수신 raw 값과 송신 request 값은 같은 숫자 테이블로 취급하지 않습니다.
| ESPHome 요청 | request mode 값 |
|---|---:|
| Auto | `0` |
| Cool | `1` |
| Dry | `2` |
| Fan | `3` |
| Heat | `4` |
따라서 수신값 `0x02=Cool`과 송신값 `Cool=1`이 서로 달라도 정상입니다.
두 값은 서로 다른 동작 단계의 필드입니다.
## 현재 유지하는 로컬 변경
### 1. 전원 ON 시 마지막 모드 유지
전원을 다시 켤 때 마지막으로 수신된 유효 모드를 request에 넣습니다.
- 파일: `components/samsung_ac/samsung_ac_device.h`
- 동작: `_cur_mode`가 있으면 전원 ON request에 mode를 함께 지정
### 2. OFF 상태에서 모드 또는 설정 변경 시 자동 ON
에어컨이 OFF인 상태에서 모드, 온도, 팬, 프리셋, 스윙을 변경하면
첨부 파일을 스킨보드에 구성 PDF보기( W:\g5\skin\board\BS4-Basic-Webzine_11q_pdf_php82\view.skin.php + view_pdf.php구성)
관련자료
-
링크
-
이전
-
다음
댓글 0
등록된 댓글이 없습니다.