Samsung TV / 에어컨 / SmartThings 전용 기기 Home Assistant 로컬 제어 가이드

Samsung TV / 에어컨 / SmartThings 전용 기기 Home Assistant 로컬 제어 가이드

배경: Samsung SmartThings API가 2026년 10월부터 유료화(개인 개발자 Personal Plan 예고 $4.99/월, 상업용 파트너는 별도 요금제) 됨에 따라, SmartThings 클라우드 REST API를 거치지 않고 Home Assistant에서 삼성 가전을 제어/조회하기 위한 설정을 정리한 문서. 기기를 두 부류로 나눠서 다룬다.

  1. 로컬 프로토콜이 애초에 존재하는 기기 (TV, 2018년형 에어컨 등) — 해당 기기용 로컬 통합을 바로 붙이면 된다. → 2, 3장.
  2. 와이파이로만 동작하고 SmartThings 클라우드와만 통신하도록 설계되어 로컬로 붙일 방법 자체가 없는 기기 (공기청정기, 공기질 모니터, 냉장고/세탁기 일부 상태값 등) — Matter와 SmartThings 루틴을 조합한 우회 브릿지가 필요하다. → 4장.

목차

  1. 공통 배경 – SmartThings API 유료화
  2. Samsung TV 설정
  3. Samsung 에어컨 설정
  4. SmartThings 전용 기기 – Matter 브릿지 우회
  5. Template Switch 최신 문법
  6. 참고 자료 / 링크
  7. 전체 요약

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

  • Samsung은 2026년 10월부터 SmartThings API 무료 접근을 중단합니다. 상업용 파트너는 별도 요금제가 적용되고, 개인 개발자에게는 월 $4.99 Personal Plan이 예고되어 있는데, 정확한 쿼터나 세부 요금 체계는 이 문서 작성 시점 기준으로 아직 공개되지 않았습니다.
  • Home Assistant의 SmartThings 통합 역시 내부적으로 이 REST API를 호출하는 구조이기 때문에, 유료화 정책이 그대로 적용되면 HA ↔ SmartThings 클라우드 연동이 끊기거나 유료 전환이 강제될 가능성이 높습니다.
  • 이 문서는 클라우드 API(SmartThings) 없이, 같은 네트워크(LAN) 안에서 로컬로만 통신하는 방식을 정리한 것입니다.
  • 단, 모든 기기가 로컬 대체 경로를 갖는 것은 아닙니다. 지그비(Zigbee)로 붙는 센서/스위치류는 SmartThings 허브를 거치지 않고 HA의 지그비 코디네이터로 직접 재페어링하면 되므로 애초에 이 문제와 무관합니다. 반면 와이파이 기반이면서 로컬 프로토콜 자체가 없는 기기(공기청정기, 공기질 모니터 등)는 2·3장의 방식이 통하지 않으며, 4장의 Matter 브릿지 우회가 필요합니다.
  • 로컬 방식의 공통 장점:
    • 인터넷 연결 끊겨도 동작
    • 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 카드로 표시 가능. (문법은 5장 참고)

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가 하드코딩되어 있었음 (수정 불필요, 그대로 사용):

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. SmartThings 전용 기기 – Matter 브릿지 우회

2·3장에서 다룬 TV와 2018년형 에어컨은 각각 로컬 웹소켓/REST와 토큰 기반 로컬 REST API라는, 애초에 로컬 네트워크로 직접 붙을 수 있는 경로를 가진 기기였습니다. 이번 장에서 다루는 대상은 그 경로 자체가 없는 기기, 즉 SmartThings 앱에만 등록되어야 존재를 확인하고 제어할 수 있는 삼성 가전입니다.

4.1 대상 기기와 범위

  • 공기청정기, 공기질 모니터, 냉장고나 세탁기의 일부 상태값처럼 와이파이 기반이라 로컬 프로토콜로 직접 붙일 방법이 없고, 삼성 클라우드와만 통신하도록 설계된 기기가 대상입니다.
  • 지그비로 연결되는 센서/스위치류는 이 장에서 다루지 않습니다. SmartThings 허브를 거치지 않고 HA의 지그비 코디네이터로 바로 재페어링하면 되므로, 애초에 API 유료화와 무관한 문제입니다.
  • 대상 기기는 지그비처럼 우회할 수 있는 대체 경로 자체가 없다는 게 공통적인 문제입니다.

4.2 지금 문제가 되는 구조

현재는 HA가 SmartThings 클라우드의 REST API를 거쳐서 이 기기들과 통신합니다.

  • 상태 조회: HA가 API를 폴링하거나 웹훅을 구독
  • 제어: HA가 API로 커맨드를 호출

즉 상태 조회든 제어든 전부 과금 대상이 될 REST API를 경유하는 구조이며, 이 경로 자체를 없애는 것이 이 장의 목표입니다.

4.3 핵심 아이디어

두 가지 사실을 조합합니다.

  1. SmartThings 루틴(자동화)은 API 과금과 무관하게 ST 앱과 허브 내부에서 로컬로 동작합니다.
  2. Matter는 클라우드 API가 아니라 로컬 네트워크 기반 프로토콜이므로 이번 유료화 정책과 무관합니다.

이 둘을 조합하면, HA와 SmartThings 사이에 REST API를 단 한 번도 호출하지 않고도 상태 동기화와 제어가 모두 가능한 우회로를 만들 수 있습니다.

동작 원리를 순서대로 정리하면:

  1. HA 안에 실제 SmartThings 기기를 대리하는 가상 기기를 하나 만든다.
  2. 이 가상 기기를 Matterbridge(애드온/앱)를 통해 Matter 액세서리로 바깥에 노출시킨다.
  3. SmartThings 허브 혹은 앱의 Matter 지원 기능이 이 가상 기기를 **로컬 네트워크 상에서 커미셔닝(페어링)**해서 ST 앱의 기기 목록에 추가한다. 여기까지는 전부 로컬 통신이라 API 호출이 발생하지 않는다.
  4. SmartThings 앱 안에서 실제 기기의 상태가 바뀔 때마다 가상 기기의 상태도 똑같이 맞춰주는 루틴을 만든다. → 가상 기기 상태가 바뀌는 순간 Matter의 상태 구독 리포트를 통해 HA 쪽 가상 기기 상태도 즉시 갱신되고, 결과적으로 HA에서 보는 값이 실제 ST 기기 상태와 항상 일치한다.
  5. 반대 방향(제어)도 같은 원리다. HA에서 가상 기기를 조작하면 Matter 커맨드로 SmartThings 쪽 가상 기기에 전달되고, 가상 기기 상태가 바뀌면 실제 기기를 그 상태로 제어하라는 루틴을 하나 더 만들면 된다.

정리하면 HA는 오직 Matter로만 이야기하고, 실제 기기와 가상 기기 사이의 상태 미러링은 전부 SmartThings 루틴이 전담하는 구조입니다. HA 입장에서는 SmartThings라는 존재 자체를 몰라도 됩니다.

4.4 필요한 구성 요소

구성 요소위치역할
가상 엔티티 (input_boolean / template switch / Template Climate)HA실제 기기를 대리하는 그릇
MatterbridgeHA 애드온 또는 별도 컨테이너위 엔티티를 Matter 액세서리로 노출
허브/앱의 Matter 지원 기능SmartThingsMatter 컨트롤러 겸 커미셔너로 가상 기기를 로컬 페어링
SmartThings 루틴 2개SmartThings실제 기기 ↔ 가상 기기 상태를 양방향으로 미러링

4.5 설정 절차 – 온오프형 기기 기준

전원 켜기/끄기 정도의 캐패빌리티만 있는 기기부터 봅니다.

  1. HA에 가상 스위치 정의: configuration.yamlinput_boolean을 하나 정의해 실제 기기를 대리하는 가상 스위치를 만듭니다. 상태 변경 시 알림/로그 같은 부가 기능이 필요하면 5장 문법의 template 스위치로 확장할 수도 있습니다.
  2. Matterbridge 설치: HA 애드온 스토어(공식 Matterbridge Home Assistant Application, https://github.com/Luligu/matterbridge-home-assistant-addon) 또는 도커로 설치합니다.
  3. 엔티티 브릿징: Matterbridge에서 1번의 가상 스위치 엔티티(HA 통합 대상이므로 matterbridge-hass 플러그인 사용)를 Matter 액세서리로 브릿징합니다. 이 과정에서 페어링 코드(QR/숫자 코드)가 발급됩니다.
  4. SmartThings에서 커미셔닝: SmartThings 앱 → 기기 추가 → Matter 기기 추가 플로우를 선택하고, 3번에서 발급된 코드로 로컬 커미셔닝을 진행합니다. 정상 완료되면 ST 앱 안에 “가상 기기”라는 새 기기가 생기며, 이 통신은 로컬 스레드/와이파이 기반이라 REST API를 전혀 타지 않습니다.
  5. SmartThings 루틴 2개 생성
    • 루틴 A: 실제 기기 상태(켜짐/꺼짐)가 바뀌면 → 가상 기기 상태를 동일하게 설정
    • 루틴 B: 가상 기기 상태가 바뀌면 → 실제 기기를 그 상태로 제어

루틴 A 덕분에 가상 기기 상태가 바뀌면 Matter 상태 리포트를 통해 HA의 input_boolean 상태도 즉시 갱신되고, 루틴 B 덕분에 HA에서 가상 기기를 조작하면 그게 실제 기기 제어로 이어집니다. Matter의 온오프(On/Off) 클러스터는 원래 외부에서 값을 써넣을 수 있도록 설계되어 있으므로, 전원 제어가 전부인 기기라면 이 방식이 무리 없이 통할 가능성이 높습니다.

4.6 한계 – 읽기 전용 센서형 기기는 통하지 않을 수 있음

공기질 모니터처럼 제어할 것 없이 값을 읽기만 하는 순수 센서형 기기는 사정이 다릅니다.

  • 4.3~4.5의 구조는 근본적으로 SmartThings 루틴이 가상 기기의 상태값을 특정 값으로 강제로 세팅하는 액션이 존재한다는 것을 전제로 합니다.
  • 스위치나 에어컨 전원처럼 On/Off 클러스터는 외부에서 값을 써넣을 수 있도록 설계되어 있어 이 전제가 성립합니다.
  • 반면 온도·습도·미세먼지 농도 같은 측정값 클러스터는 Matter 표준상 대체로 읽기 전용이라, 외부에서 임의의 값을 써넣도록 만들어져 있지 않습니다.
  • 즉 SmartThings 루틴의 액션 목록에 “가상 공기질 센서의 미세먼지 수치를 특정 값으로 설정하라”는 항목 자체가 아예 없을 가능성이 있습니다. 이 경우 스위치/에어컨 전원에 통했던 트릭이 센서형 기기에는 구조적으로 통하지 않습니다.

4.7 적용 가능 여부 판단 기준

정리하면, SmartThings 전용 기기를 이 방식으로 우회할 수 있는지는 결국 그 기기의 캐패빌리티가 쓰기 가능한지, 읽기 전용인지에 달려 있습니다.

캐패빌리티 성격예시이 방식 적용 가능성
쓰기 가능 (외부에서 값을 써넣을 수 있음)전원 On/Off, 모드 설정높음
읽기 전용 (측정값만 내보냄)공기질 모니터의 미세먼지 농도, 순수 온습도 센서값낮음/구조적으로 불가능할 가능성 큼

4.8 기대 효과

  • HA와 SmartThings 사이에 REST API 호출이 전혀 발생하지 않아 유료화 정책과 무관해집니다.
  • 기존 SmartThings 통합과 사용자 체감상 거의 동일한 양방향 동기화 경험을 유지할 수 있습니다.
  • Matter가 로컬 프로토콜이다 보니 기존 클라우드 폴링 방식보다 응답 속도가 더 빠를 가능성이 있습니다.

5. 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 자체 문법이므로 그대로 유지).

6. 참고 자료 / 링크

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

SmartThings 전용 기기 (Matter 브릿지 우회)

  • Matterbridge 공식 Home Assistant 애플리케이션(애드온): https://github.com/Luligu/matterbridge-home-assistant-addon
  • Matterbridge용 Home Assistant 플러그인 (matterbridge-hass, HA 엔티티를 Matter로 노출): https://github.com/Luligu/matterbridge-hass
  • Home Assistant Matter 통합(로컬 Matter 컨트롤러) 공식 문서: https://www.home-assistant.io/integrations/matter/

Template

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

7. 전체 요약

기기방식통합포트/프로토콜상태
Samsung TV로컬 REST API + 웹소켓samsungtv (HA 내장)로컬 네트워크✅ 설정 완료
Samsung 에어컨 (2018년형)로컬 토큰 기반 REST APIclimate_ip (clipman/samsungrac, HACS Custom repository)8888 (TCP/HTTPS)✅ 토큰 추출 완료 (B5F6rz6771) / HA 설정 반영 단계
SmartThings 전용 기기 (공기청정기, 공기질 모니터 등, 쓰기 가능한 캐패빌리티)가상 기기 + Matterbridge + SmartThings 루틴 미러링Matterbridge(matterbridge-hass) + SmartThings 앱 Matter 지원로컬 Matter (Thread/Wi-Fi)구조 설계 완료 / 구축 단계
SmartThings 전용 기기 (읽기 전용 측정값, 예: 공기질 미세먼지 농도)해당 없음 – 구조적 한계❌ 이 방식으로는 적용 불가 가능성 큼 (대안 검토 필요)

세 부류 모두 SmartThings 클라우드 API 없이, 같은 LAN 안에서 로컬 통신만으로 제어/동기화하는 것이 핵심 목표이며, 이를 통해 향후 SmartThings API 유료화 정책과 무관하게 안정적으로 자동화를 유지할 수 있습니다. 다만 읽기 전용 센서형 기기는 Matter 클러스터 구조상 이번 우회 방식이 통하지 않을 가능성이 크므로, 필요 시 별도의 대안(예: 유료 Personal Plan 구독, 또는 삼성 기기의 로컬 프로토콜이 추후 공개될 경우 재검토)을 고려해야 합니다.