Skip to content

자동화 (Automation) 가이드 ​

HomenetBridge는 상태 변경, 패킷 수신, 스케줄 또는 시스템 시작과 같은 이벤트에 따라 자동으로 작업을 수행할 수 있는 자동화 기능을 제공합니다.

참고: 설정 파일 최상위 키는 automation이며, 실수를 줄이기 위해 automations도 동일한 의미의 별칭으로 지원합니다.

자동화 설정 옵션 (Automation Options) ​

자동화 항목에서 사용할 수 있는 공통 옵션입니다.

  • id (필수): 자동화 식별자(중복 불가).
  • name (선택): 사람이 읽기 쉬운 이름.
  • description (선택): 설명.
  • mode (선택): parallel(기본), single, restart, queued.
  • trigger (필수): 트리거 배열.
  • guard (선택): CEL 표현식. 참일 때만 실행.
  • then (필수): 트리거가 통과했을 때 실행할 액션 목록.
  • actions (선택): then과 동일한 역할의 별칭입니다. then과 동시에 정의할 수 없습니다.
  • else (선택): guard가 실패했을 때 실행할 액션 목록.
  • enabled (선택): false면 자동화를 비활성화합니다.

트리거 (Triggers) ​

자동화를 실행하는 조건입니다. 모든 트리거는 다음 공통 옵션을 가질 수 있습니다.

  • id (선택): 트리거를 구분하기 위한 식별자입니다. 하나의 자동화에 여러 트리거를 지정하고 choose나 if 액션의 CEL 표현식에서 trigger.id를 통해 어떤 트리거가 실행되었는지 확인할 때 유용합니다.
  • guard (선택): 트리거별 추가 CEL 조건식입니다. 이 식을 만족해야만 해당 트리거로 자동화가 시작됩니다.

트리거 종류:

상태 트리거 (State Trigger) ​

특정 엔티티의 상태가 변경되고 조건이 일치할 때 실행됩니다.

yaml
trigger:
  - id: light_on_event
    type: state
    entity_id: light_1
    property: state_on # 선택사항. 생략 시 전체 상태 객체 비교
    match: true # 값 또는 조건 객체 { gt: 10, lt: 20 }
    debounce_ms: 100 # 선택사항. 기본값: 0 (즉시 실행)

사용 가능한 프로퍼티

필드명필수 여부설명
id선택트리거 식별자 (CEL 내에서 trigger.id로 참조).
entity_id필수상태 변경을 감지할 엔티티 ID.
property선택상태 객체의 특정 키만 비교합니다. 생략 시 상태 객체 전체를 비교합니다. (예: state, value, state_on, state_brightness 등)
match선택비교할 값 또는 조건 객체. 생략하면 어떤 값이든 상태 변경 시 트리거됩니다.
debounce_ms선택디바운스 시간 (숫자 ms 또는 '1s' 형식). 짧은 시간에 여러 번 상태가 변할 때 마지막 변화 후 설정 시간 동안 추가 변화가 없어야 트리거됩니다. (debounce로도 사용 가능)
guard선택추가적인 CEL 조건문 표현식. 참이면 트리거 실행(자동화 공통 guard와 함께 평가).

match 스키마match는 아래 형태 중 하나를 사용할 수 있습니다.

  • 원시 값: true, false, 0, 'on' 등. === 비교로 동작합니다.
  • 정규식: '/^D_/' 처럼 /.../ 문자열 형태로 지정하면 정규식으로 비교합니다.
  • 비교 객체: 다음 키 중 하나를 사용합니다.
    • { eq: 값 } : 값이 동일할 때.
    • { gt: 값 } : 값이 더 클 때.
    • { gte: 값 } : 값이 같거나 클 때.
    • { lt: 값 } : 값이 더 작을 때.
    • { lte: 값 } : 값이 같거나 작을 때.

참고: property를 생략한 경우 match는 상태 객체 전체를 비교합니다. 이때는 보통 property를 지정해 개별 값 비교를 권장합니다.

패킷 트리거 (Packet Trigger) ​

정의된 스키마와 일치하는 원본(Raw) 패킷이 수신될 때 실행됩니다. 참고: index를 생략하면 헤더 다음 바이트부터 매칭하고, index를 명시하면 헤더 포함 전체 패킷 기준으로 매칭합니다. 참고: match가 비어 있거나 정의되지 않으면 패킷 트리거는 매칭되지 않으며 무시됩니다.

yaml
# rx_header: [0xAA]인 경우
# index 생략 → 헤더 다음부터 매칭 (AA 55 ... 패킷 매칭)
trigger:
  - id: packet_response
    type: packet
    match:
      data: [0x55]
yaml
# index 명시 → 헤더 포함 전체 패킷 기준 (packet[1] = 0x55 매칭)
trigger:
  - id: packet_custom
    type: packet
    match:
      data: [0x55]
      index: 1

이전 패킷 참조 (Previous Packet Context)

패킷 트리거는 trigger.prev_packet 변수를 통해 직전에 수신된 패킷을 참조할 수 있습니다. 이를 활용하여 특정 요청(AB 41 00) 직후에 오는 응답(B0 41)만 처리하는 등 순서 의존적인 로직을 구현할 수 있습니다.

yaml
# 예: AB 41 00 요청 직후에 온 B0 41 응답만 처리
trigger:
  - type: packet
    match:
      data: [0xB0, 0x41]
guard: "has(trigger.prev_packet) && trigger.prev_packet == [0xAB, 0x41, 0x00]"

트리거 ID 참조 및 다중 트리거 분기 (Trigger ID Context)

여러 트리거가 동일한 자동화 액션 목록을 실행할 때, 각 트리거에 부여된 id를 활용하여 분기 동작을 정의할 수 있습니다.

yaml
- id: lights_control_automation
  trigger:
    - id: light_1_command
      type: packet
      match:
        data: [0x31, 0x01]
        index: 0
    - id: light_2_command
      type: packet
      match:
        data: [0x31, 0x02]
        index: 0
  then:
    - action: choose
      choices:
        - condition: "trigger.id == 'light_1_command'"
          then:
            - action: update_state
              target_id: light_1
              state:
                state_on:
                  data: [0x01]
                  index: 2
                state_off:
                  data: [0x00]
                  index: 2
        - condition: "trigger.id == 'light_2_command'"
          then:
            - action: update_state
              target_id: light_2
              state:
                state_on:
                  data: [0x01]
                  index: 2
                state_off:
                  data: [0x00]

스케줄 트리거 (Schedule Trigger) ​

주기적으로 또는 특정 시각(Cron)에 실행됩니다. (config에서 timezone 미설정시 UTC사용, 설정시 로컬타임존을 사용합니다.)

yaml
trigger:
  - type: schedule
    every: 5m # 5분마다 실행
    # 또는
    cron: '0 0 * * *' # 매일 자정에 실행

NOTE

스케줄 트리거가 포함된 자동화의 모든 command 액션은 기본적으로 low_priority: true로 설정됩니다. 이는 주기적인 폴링이나 비동기 작업이 사용자의 실시간 명령(조명 제어 등)을 방해하지 않도록 하기 위함입니다. 이를 원치 않는 경우 low_priority: false를 명시적으로 설정하세요。

시작 트리거 (Startup Trigger) ​

애플리케이션이 시작될 때(부팅 시) 실행됩니다. 지연 실행이 필요한 경우 action 단계에서 delay를 사용해야 합니다.

yaml
trigger:
  - type: startup

액션 (Actions) ​

트리거 조건이 충족되었을 때 수행할 작업입니다.

명령 (Command) ​

엔티티에 제어 명령을 보냅니다.

yaml
action: command
target: id(light_1).command_on()
# 또는
target: id(climate_1).command_target_temp(24)
low_priority: true # 선택사항. 기본값: false (스케줄 트리거 포함 시 true)
# true로 설정 시, 일반 큐가 비어있을 때만 명령이 전송됩니다. (Polling 등 중요도가 낮은 명령에 사용)

WARNING

schedule 트리거(cron/every)를 사용하는 자동화는 시스템 안정성을 위해 command 액션의 low_priority가 자동으로 true로 설정됩니다. 즉각적인 실행이 필요한 경우 반드시 low_priority: false를 명시하십시오.

고급 입력 (Complex Input) 인자가 복잡하거나 YAML 문자열 이스케이프가 어려운 경우 input 속성을 사용할 수 있습니다.

yaml
action: command
target: id(climate_1).command_set_schedule()
input:
  days: [1, 2, 3]
  time: '12:00'

발행 (Publish - MQTT) ​

MQTT 토픽으로 메시지를 발행합니다.

yaml
action: publish
topic: homenet/event
payload: 'something happened'
retain: true # 선택사항. 기본값: false

패킷 전송 (Send Packet - Raw) ​

장치로 직접 원본 패킷을 전송합니다. ack 옵션을 사용하여 응답 패킷을 기다릴 수 있습니다.

yaml
action: send_packet
data: [0x02, 0x01, 0xFF]
# 또는 CEL 사용
data: "[0x02, 0x03, 0xFF]" # 주의: 자동화에서는 x 변수를 사용할 수 없습니다.
header: true # 선택사항. true: config의 tx_header 사용, [0xAA]: 직접 지정, false(기본값): 사용 안 함
footer: true # 선택사항. true: config의 tx_footer 사용, [0xEE]: 직접 지정, false(기본값): 사용 안 함
checksum: false # 선택사항. 기본값: true (설정된 체크섬 알고리즘 자동 적용)

# 응답 대기 (ACK) 설정
# 단순 배열 또는 CEL 표현식을 사용하여 수신될 응답 패킷을 정의합니다.
ack: [0x06]
# 또는
# ack: "data[0] == 0x06"

ACK 동작

  • ack가 없으면 패킷을 전송한 뒤 즉시 다음 액션으로 진행합니다.
  • ack가 있으면 지정한 조건과 일치하는 수신 패킷이 도착할 때까지 대기합니다.
  • 재전송/타임아웃은 packet_defaults의 tx_retry_cnt, tx_timeout, tx_delay 설정이 적용됩니다.
  • ack가 배열인 경우 내부적으로 { data: [...] } 형태의 스키마로 변환되며, 패킷 매칭은 StateSchema 규칙과 동일하게 동작합니다.

참고: send_packet 액션 자체에는 retry/timeout/interval 옵션이 없습니다. 필요 시 packet_defaults에서 전송 정책을 조정하세요.

WARNING

CEL 표현식으로 패킷 리스트(data, ack)를 생성할 때, 모든 요소는 동일한 타입(주로 int)이어야 합니다. states나 trigger 등의 동적 값(dyn)을 포함할 때는 반드시 int()로 캐스팅해야 합니다. 자세한 내용은 CEL 가이드 > 자주 발생하는 문제를 참고하세요.

상태 갱신 (Update State) ​

수신된 패킷에서 값을 추출하거나, 특정 상수 값을 강제로 대입하여 엔티티 상태를 직접 갱신합니다.

yaml
# 1. 패킷 매칭을 통한 갱신 예시 (패킷 트리거에서 사용)
action: update_state
target_id: light_1
state:
  state_on: { index: 5, data: [0x10, 0x01] }
  state_off: { index: 5, data: [0x10, 0x00] }
  state_brightness: { index: 4, length: 1 }

# 2. 상수 값을 통한 강제 갱신 예시
action: update_state
target_id: climate_1
state:
  state: "ON"             # 'state'를 "ON"으로 직접 강제 설정
  target_temperature: 24  # 정규화 속성명 사용 (또는 state_temperature_target: 24)
  • target_id: 상태를 갱신할 대상 엔티티 ID를 지정합니다. 일반 엔티티 ID 외에 CEL 표현식도 사용할 수 있습니다. (예: "'light_' + string(trigger.packet[2])")
  • state: 대상 엔티티에 이미 정의된 스키마에 대응하는 속성명만 업데이트할 수 있습니다.
    • 원래의 패킷 스키마 키(state_*) 또는 이에 대응되는 정규화 속성명을 모두 사용할 수 있습니다.
    • 패킷 스펙(state_*)과 정규화 속성명 간의 자세한 명칭 대조는 패킷 스펙과 정규화 상태 매핑 가이드를 참고하세요.
  • 값의 유형별 처리:
    • StateSchema/StateNumSchema (객체) $\rightarrow$ 수신 패킷에서 값을 추출하여 상태로 기록합니다. (이때 index 생략 시 헤더 다음 바이트부터, 명시 시 헤더 포함 패킷 기준으로 추출)
    • 상수 값 (문자열, 숫자, 불리언) $\rightarrow$ 패킷 정보와 무관하게 지정한 값으로 강제 갱신합니다.
  • 오류 처리: 엔티티에 정의되어 있지 않은 상태 속성(예: state_on이 정의되지 않은 조명에 state_on을 갱신하려는 경우)을 업데이트하려 하면 오류로 처리됩니다.

지연 (Delay) ​

일정 시간 동안 대기합니다.

yaml
action: delay
- milliseconds: 대기 시간 (숫자 ms 또는 '1s', '5m' 등의 기간 문자열). `duration` 또는 `delay` 키로도 사용 가능합니다.

로그 (Log) ​

시스템 로그에 메시지를 기록합니다. 디버깅 용도로 유용합니다.

yaml
action: log
level: info # trace, debug, info, warn, error. 기본값: info
message: '자동화가 실행되었습니다.'

스크립트 실행 (Script) ​

사전에 정의한 scripts 블록의 액션 시퀀스를 실행합니다. 설정 방법은 SCRIPTS.md를 참고하세요.

yaml
action: script
script: warm_start

조건문 (If) ​

CEL 표현식을 평가하여 조건에 따라 다른 액션을 실행합니다.

yaml
- action: if
  condition: "get_from_states('sensor_temp', 'value') < 18"
  then:
    - action: command
      target: id(heater_1).command_on()
  else: # 선택사항
    - action: command
      target: id(heater_1).command_off()

다중 조건 분기 (Choose) ​

여러 조건을 순차적으로 평가하여 첫 번째로 일치하는 조건의 액션을 실행합니다. 중첩된 if-else보다 가독성이 좋습니다.

yaml
- action: choose
  choices:
    - condition: "get_from_states('door_state', 'state') == 'D_IDLE'"
      then:
        - action: send_packet
          data: [0xB0, 0x41, 0x00]
    - condition: "get_from_states('door_state', 'state') == 'D_CALL'"
      then:
        - action: send_packet
          data: [0xB0, 0x36, 0x01]
    - condition: "get_from_states('door_state', 'state') == 'D_OPEN'"
      then:
        - action: send_packet
          data: [0xB0, 0x3B, 0x00]
  default: # 선택사항 - 일치하는 조건이 없을 때 실행
    - action: send_packet
      data: [0xB0, 0x42, 0x00]

참고: choose는 첫 번째로 일치하는 조건만 실행하고 종료합니다. 여러 조건이 동시에 참일 수 있더라도 첫 번째 것만 실행됩니다.

자동화 중지 (Stop) ​

현재 자동화의 실행을 즉시 중지합니다. 이후 액션은 실행되지 않습니다.

yaml
- action: if
  condition: "get_from_states('safety_mode', 'state') == 'on'"
  then:
    - action: stop
      reason: '안전 모드에서는 실행하지 않음' # 선택사항 - 로그에 기록됨
- action: command
  target: id(door).command_open() # 위에서 stop이 실행되면 이 액션은 건너뜀

사용 사례:

  • 특정 조건에서 자동화를 조기 종료
  • 안전 가드 구현
  • 에러 상황에서 실행 중단

반복문 (Repeat) ​

액션을 여러 번 반복 실행합니다.

고정 횟수 반복:

yaml
- action: repeat
  count: 3
  actions:
    - action: send_packet
      data: [0x01, 0x02]
    - action: delay
      milliseconds: 100

조건 기반 반복 (while):

yaml
- action: repeat
  while: "get_from_states('switch_1', 'power') == 'on'"
  max: 10 # 안전을 위한 최대 횟수 (필수, 기본값: 100)
  actions:
    - action: send_packet
      data: [0x01, 0x02]
    - action: delay
      milliseconds: 500

주의: while을 사용할 때는 반드시 max를 지정하거나 루프 내에서 조건이 변경되도록 해야 합니다. 무한 루프를 방지하기 위해 최대 반복 횟수가 제한됩니다.

조건 대기 (Wait Until) ​

특정 조건이 충족될 때까지 대기합니다. 타임아웃을 설정할 수 있으며, 조건은 CEL 표현식으로 평가됩니다.

yaml
- action: wait_until
  condition: "get_from_states('binary_sensor_1', 'state') == 'off'"
  timeout: 5s # 선택사항. 기본값: 30s
  check_interval: 200 # 선택사항. 폴링 간격(ms). 기본값: 100ms

사용 예시 - 현관문 벨 자동 열기:

yaml
- action: wait_until
  condition: "get_from_states('doorbell', 'state') == 'off'"
  timeout: 10s
- action: delay
  milliseconds: 1000
- action: command
  target: id(door_open).command_press()

팁: wait_until은 조건이 충족되거나 타임아웃이 발생하면 즉시 다음 액션으로 진행합니다. 타임아웃 발생 시 경고 로그가 기록되지만 자동화는 계속 진행됩니다.

가드 (Guards - 조건) ​

트리거 또는 자동화 전체에 guard 조건을 추가하여 특정 상황에서만 실행되도록 제한할 수 있습니다. 가드는 CEL 표현식을 사용합니다.

yaml
automation:
  - id: auto_light
    trigger:
      - type: state
        entity_id: sensor_lux
    # 조도 센서 값이 100 미만일 때만 실행
    guard: "get_from_states('sensor_lux', 'illuminance') < 100"
    then:
      - action: command
        target: id(light_1).command_on()

실행 모드 (Mode) ​

자동화가 이미 실행 중일 때 새 트리거가 발동되면 어떻게 처리할지 지정합니다.

Mode동작
parallel병렬 실행 (기본값)
single이미 실행 중이면 새 트리거 무시
restart이미 실행 중이면 취소하고 새로 시작
queued큐에 넣고 순차 실행
yaml
automation:
  - id: elevator_call_response
    mode: restart # 새 트리거 시 이전 실행 취소
    trigger:
      - type: packet
        match:
          data: [0xAD, 0x41, 0x00, 0x6C]
    then:
      - action: send_packet
        data: [0xB0, 0x2F, 0x01, 0x1E]
      - action: delay
        milliseconds: 20s
      - action: command
        target: id(elevator_call).command_off()

TIP

restart 모드는 딜레이가 있는 자동화에서 유용합니다. 새 트리거가 발동되면 이전 딜레이가 취소되고 처음부터 다시 시작합니다.

문제 해결 (Troubleshooting) ​

자동화가 예상대로 작동하지 않을 때 다음 방법을 시도해보세요.

1. 로그 액션 활용 ​

log 액션을 추가하여 실행 흐름과 변수 값을 확인할 수 있습니다.

yaml
- action: log
  level: info
  message: '자동화 시작: 조도 값 확인'
- action: if
  condition: "get_from_states('sensor_lux', 'illuminance') < 100"
  then:
    - action: log
      message: '조건 충족: 조명 켜기 실행'
    - action: command
      target: id(light_1).command_on()

2. UI 분석 도구 ​

웹 대시보드의 분석(Analysis) 탭에서:

  • 활동 로그(Activity Log): 자동화 실행, 트리거, 액션 수행 내역이 실시간으로 표시됩니다.
  • CEL 분석기: guard나 조건식이 올바르게 평가되는지 테스트해볼 수 있습니다. states 변수에 현재 상태값을 넣고 표현식을 실행해보세요.