블로그에 접근 하는 중
Preparing valuable information. Just invest two seconds!
 

홈어시스턴트의 최종병기, ESPHome 완벽 가이드: 나만의 스마트기기 만들기

728x90

홈어시스턴트의 최종병기, ESPHome 완벽 가이드: 나만의 스마트기기 만들기

기성품의 한계를 넘어, 내 생각대로 움직이는 스마트홈을 꿈꾸시나요? 복잡한 코딩 없이 나만의 커스텀 스마트 기기를 만들 수 있는 가장 강력한 도구, ESPHome의 모든 것을 파헤쳐 드립니다.

안녕하세요! 홈어시스턴트(Home Assistant)로 스마트홈을 꾸미다 보면 어느 순간 갈증을 느끼게 됩니다. '이 센서에 저 기능만 더 있었으면...', '이런 모양의 기기는 왜 없을까?' 하는 아쉬움 말이죠. 저 또한 수많은 기성품을 설치하며 편리함을 누렸지만, 결국 '내 손으로 직접 제어하는' DIY의 매력에 빠져들었고, 그 중심에는 ESPHome이 있었습니다.

단언컨대, ESPHome은 홈어시스턴트 사용자가 경험할 수 있는 자동화의 수준을 한 단계, 아니 몇 단계는 위로 끌어올리는 '최종 병기'와도 같습니다. 처음에는 '마이크로컨트롤러', '펌웨어' 같은 단어에 겁을 먹을 수도 있지만, 이 글을 끝까지 따라오시면 누구나 도전할 수 있다는 자신감을 얻게 되실 겁니다.

ESPHome 완벽 가이드: 나만의 스마트기기 만들기

 

1. ESPHome이란 정확히 무엇인가?

ESPHome은 ESP32, ESP8266 같은 저렴한 마이크로컨트롤러(MCU)를 위한 커스텀 펌웨어를 아주 쉽게 생성하고 관리하게 해주는 프로젝트입니다.

여기서 핵심은 '아주 쉽게' 입니다. 본래 이런 작은 칩을 프로그래밍하려면 C++/Arduino 같은 언어로 복잡한 코드를 작성해야 합니다. 하지만 ESPHome은 이 과정을 추상화하여, 사용자가 YAML이라는 간단한 텍스트 기반 설정 파일만 작성하면, 알아서 복잡한 펌웨어 코드를 생성하고 컴파일해줍니다.

 

 

 

ESPHome의 핵심적인 장점은 다음과 같습니다.

  • YAML 기반의 쉬운 설정: 복잡한 프로그래밍 지식 없이, 미리 정의된 규칙에 따라 원하는 기능을 글로 쓰듯 설정할 수 있습니다.
  • 홈어시스턴트와의 완벽한 통합: 홈어시스턴트와 네이티브 API로 직접 통신하여 놀랍도록 빠르고 안정적인 연동을 보장합니다. 별도의 MQTT 브로커 설정이 필요 없습니다.
  • OTA (Over-the-Air) 업데이트: 최초 1회만 USB로 펌웨어를 업로드하면, 그 이후의 모든 수정과 업데이트는 Wi-Fi를 통해 무선으로 간편하게 진행할 수 있습니다.
  • 엄청난 유연성과 확장성: 수백 가지의 센서, 디스플레이, 버튼, 릴레이 등을 지원하여 상상하는 거의 모든 종류의 DIY 기기를 만들 수 있습니다.

2. 왜 기성품 대신 ESPHome을 선택해야 할까?

이미 시중에는 수많은 Wi-Fi, Zigbee 센서가 있는데 굳이 ESPHome을 써야 하는 이유가 뭘까요? 답은 명확합니다.

  1. 압도적인 비용 효율성: ESP32 보드 하나는 5천~1만원 내외, 많이 사용되는 온습도 센서는 1~2천원이면 구매합니다. 단돈 만 원으로 시중에서 3~4만원 하는 제품의 기능을 구현하거나, 그 이상의 커스텀 기기를 만들 수 있습니다.
  2. 비교 불가능한 커스터마이징: 기성품은 정해진 기능만 사용해야 합니다. 하지만 ESPHome을 사용하면 하나의 기기에 온습도, 미세먼지, 조도, CO2, 동작 감지 센서를 모두 통합하는 '나만의 만능 환경 센서'를 만드는 것이 가능합니다.
  3. 100% 로컬 제어와 프라이버시: 모든 데이터는 외부 클라우드를 거치지 않고 우리 집 홈어시스턴트와 직접 통신합니다. 이는 인터넷이 끊겨도 자동화가 멈추지 않는 안정성, 외부 서버 의존 없는 빠른 반응 속도, 그리고 내 집의 데이터가 외부로 유출되지 않는 강력한 프라이버시를 보장합니다.

3. 설치부터 첫 펌웨어 업로드까지 (Step-by-Step)

백문이 불여일견입니다. 홈어시스턴트 Add-on을 이용해 가장 대중적인 온습도 센서(DHT22)를 연결하는 과정을 단계별로 알아보겠습니다.

1단계: ESPHome 애드온(Add-on) 설치

가장 쉬운 방법입니다. 홈어시스턴트의 설정 > 애드온 > 애드온 스토어로 이동하여 'ESPHome'을 검색하고 설치합니다. 설치 후 '사이드바에 표시'를 활성화하면 접근이 편합니다.

2단계: 새 노드(Node) 생성 및 YAML 편집

ESPHome에서는 개별 기기를 '노드(Node)'라고 부릅니다.

  1. ESPHome 대시보드 우측 하단의 + NEW DEVICE 버튼을 클릭합니다.
  2. 이름(예: livingroom_sensor)을 정하고, 사용하는 보드 타입(ESP32 또는 ESP8266)을 선택합니다.
  3. Wi-Fi SSID와 비밀번호를 입력하면 기본 YAML 파일이 생성됩니다.
  4. EDIT 버튼을 눌러 생성된 YAML 파일에 센서 정보를 추가합니다.

아래는 ESP32 보드의 GPIO 15번 핀에 DHT22 센서를 연결하는 예시 YAML 코드입니다.

esphome:
  name: livingroom_sensor
  friendly_name: 거실 환경센서
  platform: ESP32
  board: esp32dev

# Wi-Fi 설정
wifi:
  ssid: "Your_WiFi_SSID"
  password: "Your_WiFi_Password"

# ... (기타 기본 설정)

# --- 이 아래 부분을 추가합니다 ---
# 온습도 센서 (DHT22) 설정
sensor:
  - platform: dht # 사용할 센서의 플랫폼을 지정
    pin: GPIO15    # 센서 데이터 핀이 연결된 ESP32의 핀 번호
    temperature:
      name: "거실 온도" # 홈어시스턴트에 표시될 이름
    humidity:
      name: "거실 습도" # 홈어시스턴트에 표시될 이름
    update_interval: 60s # 60초마다 값을 읽어옴

 

 

 

아래는 octoboard 의 각 센서별 ESP Home YAML 예제 코드 입니다

esphome:
  name: octoboard         # 장치의 시스템 내 고유 이름 (Home Assistant에서 사용)
  friendly_name: OctoBoard  # 사용자 화면에 표시될 친숙한 이름

  # ——— 부팅 시 초기 동작 정의 ———
  on_boot:
    priority: -10                  # 부팅 후 콜백 실행 우선순위 (낮을수록 먼저 실행)
    then:
      - light.turn_on:             # NeoPixel LED를 지정 값으로 켜고
          id: neopixel_id
          brightness: ${init_brightness}  # substitutions에 정의된 초기 밝기
          red: ${init_red}              # 초기 빨강 채널 값
          green: ${init_green}          # 초기 초록 채널 값
          blue: ${init_blue}            # 초기 파랑 채널 값
      - delay: 2s                   # 2초 대기
      - light.turn_off:            # NeoPixel LED 끄기
          id: neopixel_id

# ——— ESP32 보드 및 프레임워크 설정 ———
esp32:
  board: esp32-s3-devkitc-1        # 사용 중인 ESP32 개발 보드 모델
  framework:
    type: arduino                  # Arduino 프레임워크 사용

# ——— 로깅 활성화 ———
logger:

# ——— Home Assistant API 설정 ———
api:
  encryption:
    key: "XrcaxSvREzyFjasdfasdfasdfasdfsadfna8NvWevwBzE="  # API 통신 암호화 키

# ——— OTA 업데이트 설정 ———
ota:
  - platform: esphome
    password: "qweffdsadvb489fc82e9c0c420e79263c6"         # OTA 업로드 비밀번호

# ——— Wi-Fi 설정 ———
wifi:
  ssid: !secret wifi_ssid             # Wi-Fi SSID (secrets.yaml 에서 관리)
  password: !secret wifi_password     # Wi-Fi 비밀번호
  manual_ip:                          # 고정 IP 설정
    static_ip: 192.168.1.22           # 원하는 IP 주소
    gateway: 192.168.1.254             # 네트워크 게이트웨이 (공유기 IP)
    subnet: 255.255.255.0             # 서브넷 마스크

  # Wi-Fi 연결 실패 시 fallback으로 AP 모드 활성화
  ap:
    ssid: "Octoboard"       # AP 모드 SSID
    password: "asdfqBDz95Dn"         # AP 모드 비밀번호

captive_portal:                       # captive portal 기능 (설정 실패 시 웹 인터페이스 제공)

# ——— 변수 재사용을 위한 substitutions ———
substitutions:
  # 외부 우측 핀 번호
  OR1: GPIO43
  OR2: GPIO44
  OR3: GPIO36
  OR4: GPIO35
  OR5: GPIO18
  OR6: GPIO16

  # 외부 좌측 핀 번호
  OL1: EN
  OL2: GPIO2
  OL3: GPIO4
  OL4: GPIO12
  OL5: GPIO13
  OL6: GPIO11
  OL7: GPIO10

  # 내부 우측 핀 번호
  IR1: GPIO33
  IR2: GPIO37
  IR3: GPIO38
  IR4: GPIO34
  IR5: GPIO21  # PIR 센서 연결
  IR6: GPIO17

  # 내부 좌측 핀 번호
  IL1: GPIO1   # Light1
  IL2: GPIO3   # Potentiometer
  IL3: GPIO5   # Light2
  IL4: GPIO6   # Buzzer
  IL5: GPIO7   # Button1
  IL6: GPIO8   # Button2
  IL7: GPIO9

  # I2C 핀
  scl_pin: ${OR3}
  sda_pin: ${OR4}

  # MultiOne Shield 핀 매핑
  button1_pin: ${IL5}
  button2_pin: ${IL6}
  light1_pin: ${IL1}
  light2_pin: ${IL3}
  buzzer_pin: ${IL4}
  potnetiometer_pin: ${IL2}

  # PIR 센서 핀
  pir_pin: ${IR5}

  # WS2812B NeoPixel 핀
  neopixel_pin: ${IR4}

  # NeoPixel 초기 색상 및 밝기
  init_red: "50%"
  init_green: "0%"
  init_blue: "0%"
  init_brightness: "50%"

# ——— I²C 버스 설정 ———
i2c:
  scl: ${scl_pin}     # SCL 핀
  sda: ${sda_pin}     # SDA 핀
  scan: true          # 부팅 시 I2C 장치 스캔
  id: bus_a           # I2C 버스 식별자

# ——— 출력(Output) 장치 정의 ———
output:
  - id: light_output_1
    platform: gpio
    pin: ${light1_pin}  # Desk Lamp 1 제어용 GPIO

  - id: light_output_2
    platform: gpio
    pin:
      number: ${light2_pin}
      inverted: true     # 출력 극성 반전

  - id: buzzer_output
    platform: ledc
    pin: ${buzzer_pin}  # 부저 제어용 LEDC 채널

# ——— 버튼 및 모션 센서 정의 ———
binary_sensor:
  - platform: gpio
    pin:
      number: ${button1_pin}
      inverted: true        # 버튼 누를 때 Active 상태가 되도록 반전
      mode:
        input: true
        pullup: true         # 내부 풀업 저항 활성화
    name: "button1"
    filters:
      - delayed_on: 10ms    # 바운스 방지
      - delayed_off: 10ms

  - platform: gpio
    pin:
      number: ${button2_pin}
      inverted: false
      mode:
        input: true
        pulldown: true      # 내부 풀다운 저항 활성화
    name: "button2"
    filters:
      - delayed_on: 10ms
      - delayed_off: 10ms

  - platform: gpio
    pin: ${pir_pin}         # PIR 모션 센서 입력
    name: "PIR Sensor"
    device_class: motion    # Home Assistant에서 모션 센서로 인식

# ——— 아날로그 센서 정의 ———
sensor:
  - platform: adc
    pin: ${potnetiometer_pin}  # 가변저항 (포텐셔미터)
    name: "Potnetiometer"
    id: potentiometer_id
    update_interval: 1s
    accuracy_decimals: 1
    attenuation: auto
    filters:
      - multiply: 1
      - delta: 0.1
      - clamp:
          min_value: 0
          max_value: 3.1

  - platform: sht3xd             # 온습도 센서 (SHT3x-D)
    address: 0x45
    temperature:
      name: "Living Room Temperature"
      id: temp
      filters:
        - delta: 0.1
    humidity:
      name: "Living Room Humidity"
      id: hum
      filters:
        - delta: 1
    update_interval: 5s

  - platform: bh1750             # 조도 센서 (BH1750)
    name: "BH1750 Illuminance"
    address: 0x23
    accuracy_decimals: 0
    update_interval: 1s
    filters:
      - delta: 5.0

# ——— 조명(Light) 장치 정의 ———
light:
  - platform: binary
    name: "Desk Lamp 1"
    output: light_output_1

  - platform: binary
    name: "Desk Lamp 2"
    output: light_output_2

  - platform: neopixelbus
    type: RGB  # LED 순서 GRB
    variant: WS2812X
    method:
      type: esp32_rmt
      channel: 0
    pin: ${neopixel_pin}
    num_leds: 1
    name: "NeoPixel Light"
    id: neopixel_id
    default_transition_length: 0s  # 즉시 색상 변경

# ——— 스위치(Switch) 정의 (부저 토글) ———
switch:
  - platform: output
    name: "Buzzer"
    id: buzzer
    output: buzzer_output
    on_turn_on:
      then:
        - output.turn_on: buzzer_output
        - output.ledc.set_frequency:
            id: buzzer_output
            frequency: "1000Hz"
        - output.set_level:
            id: buzzer_output
            level: !lambda |-
              /* 포텐셔미터 값을 읽어 소리를 조절 */
              float MAX_VOLTAGE = 3.1;
              float voltage = id(potentiometer_id).state;
              float level = voltage / MAX_VOLTAGE;
              ESP_LOGD("potentiometer value", String(voltage).c_str());
              ESP_LOGD("potentiometer level", String(level).c_str());
              return level;
    on_turn_off:
      then:
        - output.turn_off: buzzer_output

# ——— 폰트(Font) 정의 ———
font:
  - file:
      type: gfonts
      family: Roboto
      weight: light
    id: font14
    size: 14

  - file:
      type: gfonts
      family: Noto+Sans+KR
      weight: light
    id: hg_font16_light
    size: 16
    glyphs: "온습도!%()+=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"

# ——— 디스플레이(Display) 정의 ———
display:
  - platform: ssd1306_i2c
    model: "SSD1306 64x48"
    address: 0x3C
    lambda: |-
      /* 온습도 값을 화면에 출력 */
      if (id(temp).has_state()) {
        it.printf(0, 5, id(hg_font16_light), "온도");
        it.printf(0, 25, id(hg_font16_light), "습도");
        it.printf(32, 10, id(font14), "%.1f°", id(temp).state);
        it.printf(32, 30, id(font14), "%.0f%%", id(hum).state);
      }

 

 

3단계: 컴파일 및 최초 업로드 (Flashing)

  1. YAML 파일 작성이 끝나면 SAVE  INSTALL 버튼을 누릅니다.
  2. 처음 업로드할 때는 Plug into this computer를 선택합니다.
  3. ESPHome이 YAML 파일을 C++ 코드로 변환하고 컴파일하는 과정을 거친 후, 펌웨어 다운로드 준비가 완료됩니다.
  4. 이제 ESP32 보드를 PC와 USB 케이블로 연결하고, 웹 화면의 안내에 따라 포트를 선택하고 업로드를 진행합니다.

 

[전문가의 팁]
 
USB 연결이 안 된다면?
대부분 USB-to-UART 드라이버 문제입니다. 사용하는 보드의 칩(CP210x, CH340 등)을 확인하고 PC에 맞는 드라이버를 설치해야 합니다. 또한, 일부 ESP32 보드는 업로드 시 'BOOT' 버튼을 누른 상태에서 'RST' 버튼을 눌렀다 떼야 플래싱 모드로 진입하기도 합니다.

 

업로드가 완료되고 보드가 재부팅되면, 이제 여러분만의 스마트 센서는 Wi-Fi에 연결되어 홈어시스턴트의 제어를 받을 준비를 마친 것입니다!

실제 사용 사례와 자동화 예시

ESPHome 기기가 네트워크에 연결되면, 홈어시스턴트의 설정 > 기기 및 서비스에 새로운 기기가 발견되었다는 알림이 자동으로 뜹니다. 간단히 구성 버튼만 누르면 모든 엔티티(온도, 습도 센서 값)가 추가됩니다.

이제 이 센서 값으로 무엇을 할 수 있을까요?

  • 지능형 냉난방 제어: 거실 온도가 28도 이상이고, 거실 동작 감지 센서가 '감지됨' 상태일 때 스마트 플러그에 연결된 선풍기를 켠다.
  • 최적의 실내 환경 유지: 거실 습도가 40% 미만으로 떨어지면 가습기를 작동시킨다.
  • 데이터 기반 환기 알림: ESPHome에 연결된 CO2 센서 값이 1000ppm을 초과하면, 가족에게 "창문을 열어 환기해 주세요!" 라는 푸시 알림을 보낸다.

이 모든 자동화는 홈어시스턴트의 GUI 편집기나 YAML을 통해 내 생활 패턴에 맞춰 무한하게 확장할 수 있습니다.

자주 겪는 문제와 해결 방법

문제 상황 해결 방법
Wi-Fi 연결 실패 1. YAML에 입력한 SSID/비밀번호가 정확한지 재확인하세요.
2. 대부분의 ESP 보드는 2.4GHz Wi-Fi만 지원합니다. 5GHz 네트워크에 연결하려 했는지 확인하세요.
3. 공유기 설정에서 해당 기기의 MAC 주소가 차단되지 않았는지 확인하세요.
펌웨어 업로드 실패 1. 올바른 USB 드라이버(CP210x, CH340)가 설치되었는지 확인하세요.
2. 올바른 COM 포트를 선택했는지 확인하세요.
3. 케이블 불량을 의심해보고, 데이터 전송이 지원되는 다른 USB 케이블로 교체해보세요.
4. 보드에 따라 'BOOT' 버튼을 누른 채로 업로드를 시도해보세요.
센서 값이 nan 또는 unknown으로 표시 1. 하드웨어 연결 문제일 확률이 90%입니다. 핀 번호가 YAML에 설정된 것과 일치하는지, 전선 연결(VCC, GND, DATA)이 헐겁지 않은지 꼼꼼히 확인하세요.
2. ESPHome 대시보드에서 해당 기기의 LOGS를 확인하면, 어떤 부분에서 에러가 나는지 상세한 단서를 얻을 수 있습니다.

 

스마트홈, 소비자를 넘어 창조자로

 

ESPHome은 단순히 기기를 하나 더 추가하는 것 이상의 의미를 가집니다. 내가 상상한 기능을, 내 손으로 직접 구현하며 수동적인 '소비자'에서 능동적인 '창조자'로 거듭나는 경험을 선사합니다. 처음에는 작은 실수들로 좌절할 수도 있지만, 로그를 보고 문제를 해결하며 첫 번째 자동화가 성공적으로 작동하는 순간의 희열은 그 어떤 기성품도 줄 수 없는 만족감을 안겨줄 것입니다.

만약 여러분의 스마트홈이 정체기에 머물러 있다면, 혹은 더 지능적이고 개인화된 자동화를 꿈꾸고 있다면, 망설이지 말고 ESPHome에 도전해 보세요. 여러분의 집이 진정으로 '살아 움직이는 공간'이 되는 놀라운 변화를 맞이하게 될 것입니다.

궁금한 점이나 자신만의 ESPHome 프로젝트 아이디어가 있다면 언제든 댓글로 공유해주세요. 함께 더 똑똑한 집을 만들어 갑시다!

728x90