Samsung TV / 에어컨 Home Assistant 로컬 제어 가이드

Samsung TV / 에어컨 Home Assistant 로컬 제어 가이드

배경: Samsung SmartThings API가 2026년 10월부터 유료화(Personal Plan, $4.99/월) 됨에 따라, SmartThings 클라우드 API를 거치지 않고 로컬 네트워크 통신만으로 TV와 에어컨을 Home Assistant에서 제어하기 위한 설정 정리.


목차

  1. 공통 배경 – SmartThings API 유료화
  2. Samsung TV 설정
  3. Samsung 에어컨 설정
  4. Template Switch 최신 문법
  5. 참고 자료 / 링크

1. 공통 배경 – SmartThings API 유료화

  • Samsung은 2026년 10월부터 SmartThings API 무료 접근을 중단하고, 유료 Personal Plan 구독($4.99/월)이 있어야 API를 사용할 수 있도록 정책을 변경했습니다.
  • 이 문서는 클라우드 API(SmartThings) 없이, 같은 네트워크(LAN) 안에서 로컬로만 통신하는 방식을 정리한 것입니다.
  • 로컬 방식의 공통 장점:
    • 인터넷 연결 끊겨도 동작
    • Samsung 계정/구독 불필요
    • 응답 속도가 빠름 (클라우드 왕복 없음)
  • 공통 단점:
    • 공식 지원이 아닌 커뮤니티/리버스 엔지니어링 기반 통합이 많음
    • HA와 기기가 반드시 같은 네트워크(VLAN)에 있어야 함
    • 일부 기능(앱 목록, 채널명 등)은 SmartThings 클라우드 전용이라 로컬 방식에서는 제한될 수 있음

2. Samsung TV 설정

2.1 기기 정보 (예시)

항목
MAC 주소80:8A:BD:80:E1:6A
IP 주소192.168.219.5
WOL(Wake on LAN) 지원O

2.2 사용하는 통합: Samsung Smart TV (내장 통합, samsungtv)

  • Home Assistant 공식 내장 통합이며 SmartThings 클라우드가 아니라 로컬 REST API + 웹소켓으로 직접 통신합니다.
  • 지원 기능:
    • 전원 켜기 (내부적으로 WOL 매직 패킷 사용)
    • 전원 끄기 (로컬 웹소켓 명령)
    • 리모컨 기능 (볼륨, 채널, 앱 실행 등)
    • 미디어 재생 정보, 상태 업데이트

2.3 설정 방법

  1. HA → 설정 → 기기 및 서비스 → 통합 추가 → “Samsung Smart TV” 검색
    • 같은 네트워크에 있으면 자동으로 발견(Discovered)되는 경우가 많음
  2. IP 주소 입력: 192.168.219.5
  3. TV 화면에 뜨는 연결 허용 팝업을 리모컨으로 즉시 승인
    • ⚠️ 이 팝업을 놓치면 페어링이 실패함 → TV 전원 껐다 켜고 재시도
  4. 완료되면 media_player.xxx 엔티티가 생성됨

2.4 참고: 순수 wake_on_lan 통합 (대안, 켜기 전용)

TV 자체 통합 없이 WOL만 쓰고 싶다면 아래처럼도 가능하지만, 끄기는 별도 구현이 필요합니다.

switch:
  - platform: wake_on_lan
    mac: "80:8A:BD:80:E1:6A"
    host: 192.168.219.5
    name: "거실 TV"
  • turn_off에 스크립트/shell_command를 연결하지 않으면 HA 화면상 스위치만 꺼지고 실제 TV는 켜진 채로 남음.
  • 삼성 TV의 경우 samsungtv 통합이 켜기/끄기를 모두 로컬로 지원하므로, 이 방식보다 samsungtv 통합 사용을 우선 권장.

2.5 switch 엔티티로 감싸기 (Template Switch)

samsungtv는 기본적으로 media_player 엔티티지만, 아래처럼 template switch로 감싸면 switch 카드로 표시 가능. (문법은 4장 참고)

template:
  - switch:
      - name: "거실 TV"
        unique_id: tv_power
        state: "{{ is_state('media_player.tv이름', 'on') }}"
        turn_on:
          action: media_player.turn_on
          target:
            entity_id: media_player.tv이름
        turn_off:
          action: media_player.turn_off
          target:
            entity_id: media_player.tv이름

2.6 알려진 이슈 / 주의사항

이슈원인 / 해결
VLAN/서브넷 분리 시 연결 안 됨웹소켓 연결은 다른 VLAN을 지원하지 않는 경우가 많음. HA와 TV를 같은 대역에 두어야 함
TV 완전히 꺼진 상태에서 WOL 안 됨TV 자체 네트워크 설정에서 “빠른 시작 모드” / “네트워크 대기모드”를 켜둬야 대기 전력 상태에서도 네트워크 카드가 살아있어 매직 패킷 수신 가능
구형 모델(H, J 시리즈) 반응 느림웹소켓이 아닌 레거시 폴링(10초 간격) 방식 사용 → 정상 동작이나 지연 있음
웹소켓 끄기 명령이 가끔 씹힘 (최신 Tizen)HACS의 서드파티 통합 ha-samsungtv-smart (SmartThings 토큰 없이 로컬 전용 모드 지원)로 대체 검토
MAC 주소 표기하이픈(-)이 아닌 콜론(:)으로 입력해야 함 (80:8A:BD:80:E1:6A)
IP 변동라우터에서 TV에 고정 IP(DHCP reservation) 할당 권장

3. Samsung 에어컨 설정

3.1 기기 정보 (예시)

항목
모델 연식2018년형
IP 주소192.168.219.8
개방 가능 포트8888번만 오픈 가능
프로토콜 세대신세대 REST API (토큰 기반 HTTPS)
확보한 토큰B5F6rz6771

8888 포트 = 20182022년형 삼성 에어컨에서 쓰이는 토큰 기반 로컬 HTTPS REST API. 참고로 더 구형(20132015년형, AR**HSFS 계열)은 2878 포트(DPLUG/AC14K 프로토콜)를 사용하며 이 문서의 대상과 다름.

3.2 사용하는 통합: Climate_IP (samsungrac, HACS 커스텀 통합)

  • 원저작자 SebuZet가 활동 중단(MIA) → 여러 포크가 존재하며, 이 문서에서는 clipman/samsungrac (atxbyea/samsungrac의 포크)을 사용.
  • 저장소: https://github.com/clipman/samsungrac
  • 지원 범위:
    • 포트 8888 (신세대 REST API) ← 2018년형 대상 기종은 이쪽
    • 포트 2878 (구세대 소켓 통신)
    • MIM-H03 컨트롤러 (REST API, 포트 8888)
    • MIM-H04 컨트롤러 (SmartThings 클라우드 경유, 참고용 – 본 목적과는 다름)

3.3 설치 (HACS Custom Repository)

  1. HACS → 우측 상단 (점 3개) 메뉴 → Custom repositories 클릭
  2. 입력창에 아래 정보 입력 후 추가:
    • Repository: https://github.com/clipman/samsungrac
    • Type: Integration
  3. 추가된 samsungrac (Climate_IP) 저장소를 HACS 목록에서 찾아 Download 클릭
  4. Home Assistant 재시작

재시작 후 config/custom_components/climate_ip 폴더가 자동으로 생성되어 있으면 설치 완료입니다. 이후 3.4절의 configuration.yaml 설정만 추가하면 됩니다.

3.4 설정 (configuration.yaml) – 8888 포트 / 신세대 기준

climate:
  - platform: climate_ip
    config_file: '/config/custom_components/climate_ip/samsungrac.yaml'
    ip_address: 192.168.219.xx   # 에어컨 실제 IP (고정 IP 권장)
    token: 'AC에서_추출한_토큰'
    cert: 'ac14k_m.pem'
    name: '거실 에어컨'
파라미터설명필수 여부
config_fileYAML 설정 파일 경로필수
ip_address에어컨 IP 주소필수
token기기에서 추출한 액세스 토큰필수
cert / cert_file인증서 파일명 (기본값: ac14k_m.pem, 검증 생략 시 None)대부분 필수
macMAC 주소2878 포트 기기만 필수
name표시 이름선택
poll상태 폴링 여부선택 (구세대는 기본 활성)
debug디버그 로그선택

3.5 토큰(Token) 추출 – 실제 성공한 절차 (2026년형 Python 환경 기준)

8888 포트 방식은 기기 내부에 저장된 액세스 토큰이 있어야 통신이 가능합니다. 이 토큰은 SmartThings 앱으로 최초 등록할 때 에어컨 내부에 발급/저장되므로, 이미 SmartThings에 1회 이상 등록된 적이 있는 기기라면 클라우드 API 없이도 로컬 네트워크에서 토큰을 “가로채서” 추출할 수 있습니다.

원문 출처: creatingsmarthome.com “Guide: Samsung A/C to Home Assistant” (2021, 8888 포트 기준) 작성자가 Google Drive에 배포한 server.py / actest.py / cert.pem 3개 파일 사용.

⚠️ 중요: 원본 스크립트는 2021년에 작성되어 Python 3.14 + 최신 OpenSSL 3.x 환경에서는 그대로 동작하지 않습니다. 아래는 실제로 막혔던 지점과, 최종적으로 동작을 확인한 수정 코드입니다.

실제 사용 환경

항목
에어컨 IP192.168.219.8
토큰 수신 서버(작업 머신) IP192.168.219.137
Python 버전3.14 (HA venv, /root/homeassistant/bin/activate)
작업 디렉토리~/samsung-token

사전 준비물

  • 에어컨의 고정 IP (DHCP 예약 권장)
  • SSH 접속 가능한 환경 (HA Supervisor의 SSH & Web Terminal Add-on, 또는 같은 네트워크의 리눅스 머신)
  • 원본 3개 파일: server.py, actest.py, cert.pem (2021년 creatingsmarthome.com 가이드에서 배포된 Google Drive 파일)
  • 에어컨 리모컨 (전원 끄기/켜기용)

1단계. 포트 확인 (성공)

telnet 192.168.219.8 8888

실제 결과:

Trying 192.168.219.8...
Connected to 192.168.219.8.
Escape character is '^]'.

→ 8888 포트 정상 확인. Ctrl+]quit으로 텔넷 세션 종료.

2단계. SSH 환경 준비

HA Supervisor → Add-on Store → SSH & Web Terminal 설치 후 접속. 작업은 ~/samsung-token 디렉토리에서 진행.

mkdir -p ~/samsung-token && cd ~/samsung-token
# server.py, actest.py, cert.pem 3개 파일을 이 디렉토리로 scp 등으로 복사

3단계. actest.py의 AC IP 확인

원본 파일에는 이미 IP가 하드코딩되어 있음 (IP는 수정 필요):

import requests
s = requests.Session()
headers = {'content-type': 'text/xml'}
resp = s.post("https://192.168.219.8:8888/devicetoken/request", data={"DeviceToken":"xxxxxxxxxxx"}, headers=headers, stream=True, verify=False, cert='cert.pem')

4단계. 에어컨 전원 끄기

리모컨으로 전원 OFF (플러그를 뽑지 않고 리모컨 전원만 끔).

5단계. server.py 실행 → 오류 1: AttributeError: module 'ssl' has no attribute 'wrap_socket'

원본 코드의 ssl.wrap_socket()Python 3.12부터 제거되어 최신 환경에서 바로 에러가 남.

해결: SSLContext 객체 방식으로 교체.

6단계. 재실행 → 오류 2: ssl.SSLError: [SSL: CA_MD_TOO_WEAK] ca md too weak

cert.pem이 오래된 약한 해시(MD5 등) 서명 인증서라서 OpenSSL 3.x의 기본 보안 레벨에서 거부됨.

해결: context.set_ciphers('DEFAULT:@SECLEVEL=0')load_cert_chain() 호출 전에 추가.

7단계. server.py 최종 성공 버전

from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl

class RequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        request_path = self.path
        print("\n----- Request Start ----->\n")
        print("Request path:", request_path)
        print("Request headers:", self.headers)
        print("<----- Request End -----\n")
        self.send_response(200)
        self.send_header("Set-Cookie", "foo=bar")
        self.end_headers()

    def do_POST(self):
        request_path = self.path
        print("\n----- Request Start ----->\n")
        print("Request path:", request_path)

        request_headers = self.headers
        content_length = request_headers.get('Content-Length')
        length = int(content_length) if content_length else 0

        print("Content Length:", length)
        print("Request headers:", request_headers)
        print("Request payload:", self.rfile.read(length if length else 28))
        print("Body:", self)
        print("<----- Request End -----\n")

        self.send_response(200)
        self.end_headers()

    do_PUT = do_POST
    do_DELETE = do_GET

def main():
    port = 8889
    print('Listening on localhost:%s' % port)
    server = HTTPServer(('', port), RequestHandler)

    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    context.minimum_version = ssl.TLSVersion.TLSv1      # 구형 TLS 1.0 허용 (AC가 구형 프로토콜만 지원)
    context.maximum_version = ssl.TLSVersion.TLSv1_2
    context.set_ciphers('DEFAULT:@SECLEVEL=0')           # 약한 해시(MD5 등) 인증서 허용
    context.load_cert_chain(certfile='cert.pem')
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
    server.socket = context.wrap_socket(server.socket, server_side=True)

    server.serve_forever()

if __name__ == "__main__":
    main()

python3 server.py 실행 → Listening on localhost:8889만 뜨고 에러 없이 대기 상태 확인.

8단계. actest.py 실행 → 오류 3: ssl.SSLError: [SSL: CA_MD_TOO_WEAK]

requests 라이브러리는 기본 SSL 컨텍스트를 내부적으로 생성하므로, cert= 파라미터만으로는 SECLEVEL을 조정할 수 없음.

해결: HTTPAdapter를 커스텀 SSLContext로 오버라이드하는 어댑터 작성.

9단계. 재실행 → 오류 4: ssl.SSLError: [SSL: UNSUPPORTED_PROTOCOL] unsupported protocol

SECLEVEL 문제는 해결됐지만, Python 3.14 기본 SSLContextTLS 1.2 이상만 허용하도록 강제되어 있어, AC의 구형 TLS 핸드셰이크가 거부됨.

해결: 어댑터에 minimum_version = ssl.TLSVersion.TLSv1 추가.

10단계. actest.py 최종 성공 버전

import requests
import ssl
from requests.adapters import HTTPAdapter

class LegacySSLAdapter(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
        context.minimum_version = ssl.TLSVersion.TLSv1      # 오래된 TLS 1.0 허용
        context.maximum_version = ssl.TLSVersion.TLSv1_2
        context.set_ciphers('DEFAULT:@SECLEVEL=0')
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE
        context.load_cert_chain(certfile='cert.pem')
        kwargs['ssl_context'] = context
        return super().init_poolmanager(*args, **kwargs)

s = requests.Session()
s.mount('https://', LegacySSLAdapter())

headers = {'content-type': 'text/xml'}
resp = s.post(
    "https://192.168.219.8:8888/devicetoken/request",
    data={"DeviceToken": "xxxxxxxxxxx"},
    headers=headers,
    stream=True,
    verify=False
)
print(resp.status_code)

실행 결과 (성공):

/root/samsung-token/actest.py:8: DeprecationWarning: ssl.TLSVersion.TLSv1 is deprecated
.../urllib3/.../connectionpool.py:1110: InsecureRequestWarning: Unverified HTTPS request is being made...
200

DeprecationWarning, InsecureRequestWarning은 무시 가능. 200이 반환되면 AC가 요청을 정상 수신한 것.

11단계. 에어컨 전원 켜기 → 토큰 캡처 (성공)

server.py가 대기 중인 터미널에서, 리모컨으로 에어컨을 켜자 아래 로그가 출력됨:

----- Request Start ----->
Request path: /devicetoken/response
Content Length: 0
Request headers: Host: 192.168.219.137:8889
Accept: */*
X-API-Version : v1.0.0
Content-Type: application/json
Content-Length: 28
Request payload: b'{"DeviceToken":"B5F6rz6771"}'
Body: <__main__.RequestHandler object at 0x735f57c590>
<----- Request End -----
192.168.219.8 - - [23/Jul/2026 18:14:54] "POST /devicetoken/response HTTP/1.1" 200 -

추출된 토큰: B5F6rz6771

🔑 이 토큰은 이번 실제 작업에서 확보한 값입니다. 다른 사람과 이 문서를 공유할 경우, 이 값은 반드시 가리거나 삭제하고 공유하세요 (기기 접근 권한에 해당하는 자격 증명입니다).

12단계. 마무리

  • server.py 터미널에서 Ctrl + C로 종료
  • SSH 세션 종료, SSH & Web Terminal Add-on 비활성화(또는 삭제) 권장
  • 확보한 토큰을 3.4 설정에 반영:
climate:
  - platform: climate_ip
    config_file: '/config/custom_components/climate_ip/samsungrac.yaml'
    ip_address: 192.168.219.8
    token: 'B5F6rz6771'
    cert: 'ac14k_m.pem'
    name: '거실 에어컨'

참고: climate_ip 통합이 요구하는 ac14k_m.pem은 이번 토큰 추출에 쓴 cert.pem과 이름만 다를 뿐 동일 계열 인증서인 경우가 많음. 저장소에 파일이 없다면 cert.pemac14k_m.pem으로 복사해 시도.


트러블슈팅 종합표 (실제로 겪은 순서대로)

단계오류 메시지원인해결
server.py 1차 실행AttributeError: module 'ssl' has no attribute 'wrap_socket'Python 3.12부터 ssl.wrap_socket() 제거됨SSLContext + load_cert_chain() 방식으로 교체
server.py 2차 실행ssl.SSLError: [SSL: CA_MD_TOO_WEAK] ca md too weak인증서가 약한 해시(MD5)로 서명되어 OpenSSL 3.x 기본 보안 레벨에서 거부context.set_ciphers('DEFAULT:@SECLEVEL=0')load_cert_chain() 전에 추가
server.py 3차 실행정상 (Listening on localhost:8889)
actest.py 1차 실행ssl.SSLError: [SSL: CA_MD_TOO_WEAK] ca md too weakrequests가 기본 SSLContext 사용, cert= 파라미터로는 SECLEVEL 조정 불가HTTPAdapter 상속한 LegacySSLAdapter 작성, 커스텀 SSLContextmount()
actest.py 2차 실행ssl.SSLError: [SSL: UNSUPPORTED_PROTOCOL] unsupported protocolAC가 TLS 1.0급 구형 프로토콜만 지원, Python 3.14 기본값은 TLS 1.2 이상만 허용context.minimum_version = ssl.TLSVersion.TLSv1 추가
actest.py 3차 실행성공 (200, 경고만 출력)
server.py (initial, TLS 미조정 상태)에러 없이 대기만 하고 로그 무응답AC 콜백 접속 시 SSL 핸드셰이크가 프로토콜 불일치로 조용히 실패 (애플리케이션 레벨까지 도달 못 함)server.py에도 minimum_version = TLSv1 동일하게 추가 후 재시도 → 토큰 로그 정상 수신
InsecureRequestWarning, DeprecationWarning (양쪽 스크립트 공통)자체서명 인증서 미검증 경고, TLSv1 deprecated 경고로컬 LAN 통신 및 레거시 기기 호환 목적상 의도된 설정무시 가능 (동작에 영향 없음)

핵심 교훈: 2021년 작성된 스크립트를 최신 Python(3.12+)/OpenSSL(3.x) 환경에서 쓰려면 ssl.wrap_socket()SSLContext 전환, ② SECLEVEL=0으로 약한 인증서 허용, ③ minimum_version=TLSv1로 구형 프로토콜 허용 — 이 세 가지를 클라이언트(actest.py)와 서버(server.py) 양쪽 모두에 적용해야 함.

토큰 재추출이 필요한 경우: 에어컨을 공장 초기화하거나 SmartThings 앱에서 기기를 삭제/재등록하면 토큰이 갱신되므로, 이 경우 위 과정을 처음부터 다시 진행해야 합니다.

3.6 기능별 스위치 만들기 (Template Switch)

climate_ip 통합은 climate.climate_ip_set_property 서비스를 제공하여 정화(purify), 특수 모드(comfort/quiet 등) 같은 기기별 속성을 조작할 수 있습니다. 이를 개별 switch 엔티티로 노출하려면 Template Switch로 감쌉니다.

template:
  - switch:
      - name: "에어컨 공기청정"
        unique_id: ac_purify
        state: "{{ is_state_attr('climate.거실_에어컨', 'purify', 'on') }}"
        turn_on:
          action: climate.climate_ip_set_property
          data:
            entity_id: climate.거실_에어컨
            purify: 'on'
        turn_off:
          action: climate.climate_ip_set_property
          data:
            entity_id: climate.거실_에어컨
            purify: 'off'

동일한 패턴으로 auto_clean, beep, special_mode 등도 스위치/셀렉트로 확장 가능 (자세한 속성 목록은 samsungrac.yaml 설정 파일 참고).

3.7 신세대(8888) 지원 기능 목록

  • 전원 켜기/끄기
  • 목표/최소/최대 온도 설정 및 조회
  • 풍향(swing) 설정 및 조회
  • 팬 속도 설정 및 조회 / 최대 팬 레벨 설정
  • 특수 모드 설정 (2Step, Comfort, Quiet 등)
  • Good Sleep 모드 설정
  • 공기청정(purify) 켜기/끄기
  • 자동 청소(auto clean) 켜기/끄기
  • 비프음(beep) 켜기/끄기
  • 실내 온도 조회
  • 기기 설정 정보 조회

3.8 알려진 이슈

이슈비고
pip install 시 SSL 오류GitHub 이슈 #25에서 해결 방법 논의 중
토큰 미존재 (SmartThings 미등록 기기)스마트폰 앱으로 1회 등록 후 토큰 추출 필요
MIM-H03/H04 등 중앙 컨트롤러 사용 시device_id 파라미터 별도 설정 필요 (기본값 032000000)

3.9 실제 설정 가능한 값 총정리 (실기기 로그로 검증)

samsungrac.yaml(8888 포트, 신세대) 기준으로 climate.* 엔티티에서 조작 가능한 값들을 실제 기기 응답 로그로 검증한 결과입니다. 대상 기기는 두 대(FAC_BORA_RAC_17K 안방, FAC_BORA_17K 거실)이며, 두 모델의 내부 응답 구조가 달라 설정값 이름은 같아도 원문 로그로 재검증이 필요했습니다 (자세한 내용은 3.11).

climate 엔티티 표준 속성 (UI에서 바로 조작 가능)

속성HA 값기기 값비고
hvac_modecoolCool
heatHeat
dryDry
fan_onlyWind
autoAuto원래 heat_cool로 정의돼 있었으나, 실제 기기 동작이 완전자동 선택(HVACMode.AUTO)에 더 가까워 auto로 변경
offOperation.power: Off
fan_modeauto / low / medium / high / TurbospeedLevel: 0~4
swing_modeoffFix (안방) 또는 Off (거실)두 모델이 서로 다른 문자열로 “스윙 없음”을 보고함. Offoff로 정규화 처리함
verticalUp_And_Low실기기로 미검증 (문서/코드 추정값)
horizontalLeft_And_Right실기기로 미검증
bothAll실기기로 미검증
preset_modeNoneComode_Off✅ 실기기 로그로 검증됨 (두 기기 모두 기본값)
Good SleepComode_Sleep미검증 (로그상 관측된 적 없음)
Fast TurboComode_Speed미검증
2 StepComode_2Step미검증
ComfortComode_Comfort미검증
QuietComode_Quiet미검증
Single UserComode_Smart미검증
Wind FreeComode_Nano미검증

표준 속성이 아닌, 서비스로만 제어 가능한 값 (3.10 참고)

속성명(서비스 파라미터)기기 값비고
auto_cleanon / offAutoclean_On / Autoclean_Off✅ 실기기 로그로 검증됨, 두 기기 모두 정상
specialpreset_mode와 동일 값 세트Comode_*preset과 소스가 같은 항목 (중복)
good_sleep정수 0~24 (시간)Sleep_{N}✅ 검증됨 (현재값 0)
beepon / offVolume_100 / Volume_Mute안방은 정상 매핑되나, 거실 유닛은 Volume_33처럼 on/off 외 중간값을 보고해 이 경우 원문 그대로 노출됨 (알려진 한계)
purifyon / offSpi_On / Spi_Off⚠️ 두 기기 응답 어디에도 Spi_ 값이 관측되지 않음. 이 기종/펌웨어에서 실제 지원 여부 미확인
fan_maxauto/low/medium/high/TurbomaxSpeedLevel: 0~4실기기로 미검증

3.10 커스텀 속성 서비스로 제어하기 (climate_ip_set_property)

auto_clean, purify, beep, special, good_sleep, fan_max는 표준 climate 속성이 아니라서 카드 UI에 바로 안 뜨고, 아래 서비스로만 조작할 수 있습니다.

service: climate_ip.climate_ip_set_property
target:
  entity_id: climate.livingroom_aircon   # 대상 climate 엔티티 (개발자 도구 > 상태 에서 실제 값 확인)
data:
  auto_clean: "on"    # 또는 "off"
  • services.yaml이 비어 있어 개발자 도구 UI에 파라미터 폼이 뜨지 않음 → YAML 모드로 직접 입력해야 함.
  • 값은 대상 속성의 HA 쪽 키(on/off 등) 문자열 그대로 입력.
  • 여러 속성을 한 번에 바꿀 수도 있음(예: auto_cleanbeep을 같은 서비스 콜에 함께 지정).
  • 3.6처럼 Template Switch로 감싸면 대시보드에 토글 버튼으로 노출 가능. auto_clean도 동일한 패턴 적용:
template:
  - switch:
      - name: "거실 에어컨 자동청소"
        unique_id: ac_livingroom_autoclean
        state: "{{ is_state_attr('climate.livingroom_aircon', 'auto_clean', 'on') }}"
        turn_on:
          action: climate_ip.climate_ip_set_property
          data:
            entity_id: climate.livingroom_aircon
            auto_clean: "on"
        turn_off:
          action: climate_ip.climate_ip_set_property
          data:
            entity_id: climate.livingroom_aircon
            auto_clean: "off"

3.11 기기별 실측 차이 & yaml 버그 수정 이력

두 대(안방 FAC_BORA_RAC_17K, 거실 FAC_BORA_17K)를 같은 samsungrac.yaml로 물렸는데, 실제 기기 응답의 Mode.options 배열 구조가 모델마다 달라서 원본 yaml(고정 인덱스 참조 방식)이 한쪽 기기에서만 정상 동작하는 문제가 있었습니다.

항목원인증상수정 방법
preset_mode / special거실 유닛의 Mode.options 배열 맨 앞에 Operation_Family 항목이 하나 더 있어, 이후 모든 인덱스가 1칸씩 밀림거실 유닛의 프리셋이 Operation_Family라는 값(없는 프리셋)으로 표시되며 매핑 실패고정 인덱스(options.0) 대신, 배열 전체를 순회해 Comode_ 접두어를 가진 항목을 찾도록 status_template 변경
good_sleep위와 동일한 인덱스 밀림거실 유닛에서 Comode_Off의 뒷부분(_Off)이 숫자처럼 파싱되어 잘못된 값 노출Sleep_ 접두어 검색 방식으로 변경
auto_clean위와 동일거실 유닛에서 Sleep_0이 on/off 값으로 잘못 읽힘Autoclean_ 접두어 검색 방식으로 변경
beep원본이 options.14처럼 배열 끝 쪽 고정 인덱스를 참조안방(배열 길이 10)은 인덱스 자체가 범위를 벗어나 값이 안 뜨고, 거실은 엉뚱한 값(ModelInfo_...)이 뜸Volume_ 접두어 검색으로 변경 (단, 거실은 Volume_33처럼 중간값이 있어 on/off로 완전히 표현은 안 됨 — 알려진 한계로 남김)
swing_mode“스윙 없음” 상태를 안방은 Fix, 거실은 Off로 서로 다르게 보고거실 유닛의 스윙 상태가 매핑 테이블(Fix/Up_And_Low/Left_And_Right/All)에 없는 값이라 인식 실패status_template에서 OffFix로 정규화 후 매핑
hvac_mode원본 키가 heat_cool로 정의됨기능상 문제는 아니었으나, HA의 HVACMode.AUTO(“완전 자동”)와 의미가 더 맞아 사용자 요청으로 변경yaml 키를 heat_coolauto로 rename (기기 값 Auto는 그대로)

위 수정 내역은 실제 두 기기의 로그(Mode.options, Wind.direction 원문)를 놓고 템플릿을 직접 렌더링해 검증했습니다. purify(Spi_)는 두 기기 로그 어디에도 값이 관측되지 않아 여전히 지원 여부 미확인 상태입니다.


4. Template Switch 최신 문법

Home Assistant는 switch: - platform: template 방식을 2025.12부터 deprecated, 2026.6부터 완전 제거했습니다. 최상위 template: 키를 사용하는 새 문법으로 전환해야 합니다.

변경 비교

항목예전 (제거됨)최신
최상위 키switch: + platform: templatetemplate:
여러 스위치 묶기switches: 딕셔너리switch: 리스트 (항목별 딕셔너리)
이름 지정friendly_name:name:
상태 판별value_template:state:
서비스 호출 키service:action: (service:도 동작은 하나 action:이 표준)
고유 ID선택unique_id 부여 시 UI에서 이름/아이콘 편집 가능 (권장)

최신 문법 기본 골격

template:
  - switch:
      - name: "스위치 이름"
        unique_id: 고유_id
        state: "{{ 상태_판별_템플릿 }}"
        turn_on:
          action: 도메인.서비스명
          target:
            entity_id: 대상_엔티티
        turn_off:
          action: 도메인.서비스명
          target:
            entity_id: 대상_엔티티
  • template: 키는 파일 내에서 하나만 존재해야 하므로, 기존에 sensor:, binary_sensor: 등 다른 template 항목이 있다면 그 아래에 switch: 항목만 추가.
  • 설정 반영: 개발자 도구 → YAML → 설정 다시 로드 → Template Entities 리로드로 재시작 없이 적용 가능.
  • ⚠️ ESPHome 기기 YAML 안의 platform: template은 이 deprecation과 무관 (ESPHome 자체 문법이므로 그대로 유지).

5. 참고 자료 / 링크

TV

  • Home Assistant 공식 문서: https://www.home-assistant.io/integrations/samsungtv/
  • SmartThings 통합(참고, 유료화 공지 포함): https://www.home-assistant.io/integrations/smartthings/
  • 서드파티 통합 (SmartThings 토큰 활용, 로컬 옵션 포함): https://github.com/ollo69/ha-samsungtv-smart

에어컨

  • 사용 통합 저장소 (HACS Custom repository로 등록): https://github.com/clipman/samsungrac
  • 상위 저장소 (fork 대상): https://github.com/atxbyea/samsungrac
  • 원본 저장소 (활동 중단): https://github.com/SebuZet/samsungrac
  • 토큰 추출 참고 가이드: https://www.creatingsmarthome.com/index.php/2021/06/09/guide-samsung-a-c-to-home-assistant/
  • 삼성 AC 프로토콜 설명 (openHAB 커뮤니티): https://community.openhab.org/t/newgen-samsung-ac-protocol/33805
  • 구세대(2878 포트, 2013~2015년형) 전용 대안 통합: https://github.com/porech/samsung_ac_dplug

Template

  • Home Assistant Template 통합 공식 문서: https://www.home-assistant.io/integrations/template/

6. 전체 요약

기기방식통합포트/프로토콜상태
Samsung TV로컬 REST API + 웹소켓samsungtv (HA 내장)로컬 네트워크✅ 설정 완료
Samsung 에어컨 (2018년형)로컬 토큰 기반 REST APIclimate_ip (clipman/samsungrac, HACS Custom repository)8888 (TCP/HTTPS)✅ 토큰 추출 완료 (B5F6rz6771) / HA 설정 반영 단계

두 기기 모두 SmartThings 클라우드 API 없이, 같은 LAN 안에서 로컬 통신만으로 제어하는 것이 핵심 목표이며, 이를 통해 향후 SmartThings API 유료화 정책과 무관하게 안정적으로 자동화를 유지할 수 있습니다.