본문 바로가기

홈어시스턴트 IoT

레인지후드 자동화 - 열화상센서 온도 활용, 홈어시스턴트(HA)

레인지후드는 항상 켜놓고 IoT플러그로 전원 ON/OFF를 조작, 적외선 온도계 값을 기준으로 자동 작동, IoT 버튼으로 수동 조작도 가능
Wemos D1 mini 보드 전원용 USB 어댑터, 레인지후드 전원 ON/OFF용 IoT 플러그(샤오미)

주방에서 요리를 하(시)다보면 깜빡하고 레인지후드(주방환풍기)의 전원을 켜지 않는 경우가 있습니다.  이것을 자동화하는 것을 1년 반 전부터 해보고 있습니다. 처음 1년은 IoT 온습도계를 레인지후드 아래 벽에 붙여 놓고 85%의 습도 값이 나오면 켜는 것을 이용했습니다. 그후 6개월동안 추가로 현재의 적외선온도센서로도 작동을 시키고 있는데, 나름대로 쓸만한 것 같습니다.

 

현재 8x8 총 64개의 적외선 온도 값 중 최고 온도에 따른 레인지후드 전원의 처리 방법은 다음과 같이 운영하고 있습니다. 

 

  • 55도를 초과한 상태로 30초가 지나고, 온도가 상승 패턴이 맞으면 팬 작동 
  • 50도 미만으로 90초간 유지가 되면 팬 정지 

요리 하는 도중에 프라이팬에 재료를 투입하거나 냄비의 뚜껑을 닫으면 온도가 수 십 도가 급격히 떨어집니다. 그럴 때 바로 꺼지지 않도록 온도 유지 시간을 확인하는 것입니다. 참고로 상승 패턴이라 함은 오픈소스 자동화 서버인 홈어시스턴트(HA, Home Assistant)에서 제공하는 트렌드(trend) 기능을 이용하여 계산됩니다. 

 

https://imky.tistory.com/29

 

주방 환풍기를 8x8 적외선 열화상 센서를 기반으로 작동 제어하기

음식 할 때 수증기나 냄새때문에 주방 후드 환풍기를 켜게 됩니다. 수증기의 경우에 실내 습도를 높일 뿐 큰 문제는 아닙니다. 기름에 뭔가 볶거나 튀길 때에는 초미세먼지가 급증하므로 반드시

imky.tistory.com

 

좀 전의 50도와 55도의 기준은 무엇일까요? 그냥 인덕션레인지에서의 경험적인 값일 뿐입니다. 적외선 온도 센서가 거리가 떨어짐에 따라 온도가 낮게 나오는데, 예를 들면 손목을 가까이 대면 35~37도가 나오지만 70~80센티미터 떨어진 곳에서는 30도 정도로 나옵니다. 그러므로 물이 끓는다해도 100도가 나오는 것이 아닙니다. 

 

 그러면 어제 저녁에 사골 떡만두국을 끓였을 때의 온도 변화를 살펴보겠습니다. 

 

사골이 끓기 시작하면 온도가 급상승하고, 도중에 뚜껑을 닫아서 20~30도 하강, 불을 끄고 서서히 식는 모습

55도를 초과했을 때 30초 후 계속 온도 상승이므로 레인지후드가 돌아가서 수증기 처리에 큰 문제는 없었고, 도중에 뚜껑을 닫아서 20~30도 떨어졌지만 잠시 동안이므로 무시됩니다. 17시46분25초에 불을 끄고 냄비를 치우면 가열된 인덕션레인지 표면 온도가 가장 높을테고 그 온도가 60도 부근(실제로는 센서 오차 때문에 온도가 더 높으므로 손을 대면 화상 위험!!!)입니다. 17시49분52초에 50도를 통과하고 1분30초 뒤인 17시51분22초에는 47.25도가 되면서 레인지후드가 꺼졌습니다. 결과적으로 한 5분간 혼자 돌다가 멈춘 셈입니다. 

 

자동화는 역할이 분담되어 있습니다. IoT 버튼을 눌렀을 때 레인지후드를 끄고 켜는 부분과 습도가 높을 때 켜는 부분은 샤오미의 Mi Home앱에서 자동화를 담당합니다. 누르면 IoT 플러그의 전원을 반전(toggle)시킵니다(켜기 <-> 끄기). 레인지후드 밑에 설치한 Aqara 온습도 센서의 습도가 85%가 넘으면 IoT플러그를 켜는 기능도 Mi Home에서 자동화했습니다. 이렇게 하면 가끔 홈어시스턴트나 샤오미 IoT 클라우드가 이상 동작할 때에도 불편없이 레인지후드를 끄고 켤 수 있습니다. 나머지 적외선 온도 센서의 처리는 홈어시스턴트가 전담합니다. 

 

그러면, 적외선 온도 센서를 홈어시스턴트에 연동하는 방법을 정리해 보겠습니다. 홈어시스턴트의 구축부터 시작하면 너무나 길어지게 되므로 홈어시스턴트(이하, HA)를 이미 설치했다고 가정하고 진행합니다. 홈어시스턴트를 설치해서 24시간 계속 켜 놓을 Raspberry Pi 3B+ 이상의 성능을 가지면 되는데, 메모리는 2GB면 잘 돌아가는 것 같습니다. microSD카드에 HAOS의 이미지를 BalenaEtcher 프로그램을 통해 구워주면 됩니다. 최초에는 랜케이블을 꼽고 설치해야 로컬 네트워크에서 홈어시스턴트 서버로 접속할 수 있습니다.(예: http://192.168.0.69:8123 혹은 http://homeassistant.local)

 

[하드웨어 준비 및 핀 연결 방법] 

회로 구성 재료 

  1. Wemos D1 mini - ESP8266 보드 : 메인보드 
  2. AMG8833 8x8 thermal sensor - Grid-EYE : 적외선 온도 센서 8행 x 8열 총64개의 온도 값
  3. TM1637 7 segments LED : 온도 표시용 
  4. 점퍼 와이어(female to female) : 8개

Wemos D1 mini의 Pin 연결 방법 

  • AMG8833 : D1=SCL, D2=SDA, GND, VCC(3.3V)  
  • TM1637 : D5=CLK, D6=DIO, GND, VCC(5V) 
  • Wemos D1 mini의 GND는 1개 밖에 없으므로 AMG8833과 TM1637이 공유해야 합니다. 점퍼 와이어 2개를 납땜 등으로 묶어 줍니다. 

[Wemos D1 mini에 ESPHome 펌웨어 준비하기]  

ESPHome은 펌웨어에 대한 장벽을 없애 주는데, 펌웨어 개발자가 아니더라도 다양한 장치를 쉽게 제어할 수 있게 도와줍니다. 물론 어느 정도 회로나 납땜에 대한 지식이 필요할 수도 있지만 아주 기초적인 부분이라서 짧은 시간에 습득이 가능하고 어렵지 않습니다.   

 

펌웨어 작업은 Mac에서는 작업이 불편한 부분(예: 알 수 없는 컴파일 오류나 도커에서 USB 미지원 문제 등)들이 있으므로, MS 윈도우나 리눅스, WSL등에서 작업하는 편이 좋습니다.

 

사전에 필요한 것은 Wemos D1 mini를 PC에 연결 했을 때 시리얼포트(예: COM3)인식을 위한 USB to Serial 드라이버의 설치와  Python 3.7이상의 설치입니다. 참고로, HA에서는 Addon의 형태(HA설치 시 HAOS나 수퍼바이저 모드로 설치해야만 이용 가능)로 ESPHome 펌웨어 수정(사실상 .yaml 편집 수준)과 펌웨어 업로드를 지원하고 있습니다. 하지만, 아무래도 불편하긴 하지만 커맨드 라인(윈도우의 명령 프롬프트나 파워쉘)에서 작업하는 것이 문제 발생 시 상황 파악에 더 유리한 것 같습니다. 

 

1) ESPHome 설치 

 

먼저 커맨드라인에서 ESPHome을 작업하기 위해 필요한 프로그램을 설치해 보겠습니다. 아래 글을 참고해 주세요. 어렵지 않습니다. 

Installing ESPHome Manually — ESPHome

 

Installing ESPHome Manually — ESPHome

Make sure you check “Add Python to PATH”, and go all the way through the installer. Log out and back in, or restart your computer. Whichever is easiest. Open the start menu and type cmd. Press the enter key. Note Don’t copy the >. That’s used to sh

esphome.io

윈도우의 경우 좌하단의 돋보기 아이콘이 있는 "찾기" 부분에 cmd를 넣으면 명령 프롬프트 앱을 찾아서 실행할 수 있습니다.  C:\Users\각자의윈도우아이디> python --version 명령을 넣어서 Python 3.X.X등으로 응답이 나오면 ESPHome을 설치할 수 있습니다. 아니면 MS 윈도우의 경우, Python Releases for Windows | Python.org에서 Download Windows installer (64-bit)을 받아서 설치하면 됩니다. 편의상 C:\Users\각자의윈도우아이디\esphome과 같이 작업용 폴더를 만든 후 그곳에서 가상 환경을 만든 후 작업하면 좋을 듯합니다. 아래의 각 명령을 내린 후 완료되기를 기다리고 다음 단계로 넘어가면 됩니다. 

 

C:\Users\각자의윈도우아이디\esphome > pip install virtualenv 

C:\Users\각자의윈도우아이디\esphome > python -m venv venv 

C:\Users\각자의윈도우아이디\esphome > venv\Scripts\activate.bat 

(venv) C:\Users\각자의윈도우아이디\esphome > pip install wheel 

(venv) C:\Users\각자의윈도우아이디\esphome > pip install esphome

 

한참을 기다려서 설치가 완료되고, 

 

(venv) C:\Users\각자의윈도우아이디\esphome > esphome version

 

을 했을 때,  Version: 2023.4.4와 같이 응답이 나오면 준비 완료입니다. 

 

2) USB 드라이버 설치 

 

Wemos D1 mini를 컴퓨터에 연결하면 장치관리자에서 볼 때 COM포트가 생깁니다. 만약 포트가 없다면 CH340 드라이버를 설치하여야 합니다. 보통 아두이노 호환 제품이 사용하는 https://sparks.gogo.co.nz/ch340.html 에서 드라이버를 받아 설치합니다. 

 

3) AMG8833 제어용 펌웨어 소스 받기  

 

https://github.com/TheRealWaldo/AMG8833-ESPHOME의 소스를 받아서(git를 이용하거나 Code의 Download Zip을 이용합니다. 

 

(venv) C:\Users\각자의윈도우아이디\esphome\AMG8833-ESPHOME-main> esphome run amg8833.yaml 

 

명령을 내리면 컴파일되고 펌웨어 업로드까지 진행이 됩니다. 하지만, 먼저 몇 가지 작업이 필요합니다. 우선 WiFi에 접속하기 위해 집(사무실)에 있는 공유기의 SSID와 패스워드가 무엇인지를 담은 secrets.yaml 파일을 만들어야 합니다. 처음에는 USB cable을 통해 펌웨어를 올리지만 그 다음부터는 WiFi로 무선 펌웨어 업데이트가 가능합니다.  

 

# Sample secrets file 
ssid: 'iptime_extender' 
password: '각자의WiFi암호'
domain: '.local'

 

위 파일을 만들고 나서 다시 한번 esphome run amg8833.yaml 명령을 내리면, 필요한 여러 도구들을 차례 차례 설치하기 시작합니다. 5~10여분 가량 설치가 끝나면 자동으로 소스를 컴파일을 시작합니다.  아래와 같이 빌드가 완료되면 보드에 업로드할 수 있습니다. [2]번 메뉴는 처음에는 나타나지 않습니다.  [1]은 앞서 설치한 드라이버가 정상 작동한 경우이고 COM6로 펌웨어가 전송됩니다. 

 

====================== [SUCCESS] Took 16.80 seconds=============================
INFO Successfully compiled program.
Found multiple options, please choose one:
  [1] COM6 (USB-SERIAL CH340(COM6))
  [2] Over The Air (192.168.0.42)
(number): 1

 

[홈어시스턴트에서 ESPHome 장치 확인 및 LED용 온도 표시 펌웨어 수정]  

 

1) HA(Home Assistant)에서 확인

 

방금 올린 펌웨어에 의해 새로운 장치(통합구성요소)가 자동으로 추가되는 것을 확인할 수 있습니다. 만약 AMG8833보드를 연결하였다면 홈어시스턴트 웹 화면(http://homeassistant.local:8123) 에서 다음과 같이 나오게 됩니다. 

 

홈어시스턴트에 결합된 후 정상작동할 때의 모습, 자동화는 나중에 추가합니다.

참고로 1초(저의 경우 5초로 수정)마다 16진수로 값들이 계속 들어와서 HA의 로그에 쌓이게 됩니다. 그러므로, HA의 configuration.yaml에 다음 내용을 반드시 추가해야 합니다. 

 

history:
  exclude:
    entities:
      - sensor.sensor_pixels

 

2) TM1637 7 세그먼트 디스플레이를 사용하기 위해 .yaml에 다음 내용을 추가

 

이 작업은 물론 미리 할 수도 있으나, 우선 AMG8833센서가 정상 작동하는 것을 확인해야 하고, 홈어시스턴트에 그 값이 저장되어야만 7세그먼트 표시 장치에 뭔가 표시할 것이 생겨서 여기에 내용을 썼습니다. 

 

아까 amg8833.yaml에 아래 내용을 추가한 후, 다시 한번 esphome run amg8833.yaml을 해서 펌웨어를 올려야 하겠습니다. 

#기존 파일에 sensor: 항목이 이미 있으므로 들여 쓰기를 맞추어서 추가합니다. 
  - platform: homeassistant
    entity_id: sensor.thermal_sensor_max
    id: thermal_max_temp
    internal: true
 
# amg8833의 최고 온도를 7세그먼트 LED에 표시 
display:
    platform: tm1637
    id: tm1637_display
    clk_pin: D5
    dio_pin: D6
    inverted: false
    intensity: 2
    length: 4
    lambda: |-
        it.printf(0,"%4.0f", id(thermal_max_temp).state);

 

[홈어시스턴트에서 자동화 추가하기] 

1) FAN - 50도 미만 90초 유지시 끄기

 

홈어시스턴트 웹에서 설정 -> 자동화 및 장면 -> 자동화 추가하기 -> 새로운 자동화 생성 -> 트리거 추가하기 -> 수치상태 -> 구성요소에 Thermal Sensor Max를 추가하고 "미만" 아래 쪽 칸에 50을 입력합니다. 그리고 "~동안"에 1분30초를 설정합니다. 아래 쪽의 동작추가하기 -> 기기 -> 구성요소에 IoT 플러그를 선택하고 "전원 끄기"에 해당하는 값을 선택하면 됩니다. 

 

2) FAN - 55도 초과 30초 및 상승트렌드 시 켜기 

 

위에 끄는 부분과 비슷하게 작업하면 되며, 트렌드가 추가가 되어서 아래와 같이 조건이 추가되어야 합니다. 

 

트렌드로 만든 induction_thermal_rising이 "조건"항목에 추가됨

트렌드 센서는 HA의 configuration.yaml에 다음 내용을 추가하면 됩니다. 아래 값들은 직관적으로 추정하여 입력한 값이어서 각자 환경에 맞게 변경할 수 있습니다. 저의 경우 amg8833에서 5초에 1회 데이터가 나와서 180초에 36번 값을 읽고 있습니다. 0.0416667이라는 값은 7.5도/180초에 의해 계산된 값입니다. 즉, 3분간 7.5도의 변화가 있으면 induction_thermal_rising이란 바이너리 센서 값을 'on'로 설정하라는 의미가 되겠습니다. 

 

# Trend sensor
binary_sensor:
  - platform: trend
    sensors:
      induction_thermal_rising:
        entity_id: sensor.thermal_sensor_max
        sample_duration: 180
        max_samples: 36
        min_gradient: 0.0416667
        device_class: heat
      induction_thermal_falling:
        entity_id: sensor.thermal_sensor_max
        sample_duration: 180
        max_samples: 36
        min_gradient: -0.022222
        device_class: cold

 

 

[부록 - AMG8833의 센서가 부분 불량일 때 최고 온도 가져오는 부분 소스 코드 고치기] 

 

AMG8833의 제어는 아래 글을 참고하였습니다. 

https://github.com/TheRealWaldo/AMG8833-ESPHOME 

 

GitHub - TheRealWaldo/AMG8833-ESPHOME

Contribute to TheRealWaldo/AMG8833-ESPHOME development by creating an account on GitHub.

github.com

HA에서 8x8개의 온도 값을 그래프로 보여주어서 열화상 카메라 영상처럼 보여주는 기능까지 포함하고 있습니다.  이 기능을 사용하려면 HACS에서 Thermal Vision을 추가해 주어야 합니다. 이 부분까지 쓰려니 너무 길어져서 이 분의 글을 참고하시면 될 듯합니다.  

빨간부분이 가열된 부분(실제 위치는 위쪽으로 상하반전상태)

위 그림에서 빨간색 중간에 있는 부분이 파란 이유는 제가 (알리익스프레스)에서 저렴하게 구입한 센서가 불량이기 때문입니다. 제가 2개 샀는데 AMG8833부품에 냉납이 있어서 1개는 결국 버렸고, 나머지 1개는 갖은 노력(?) 끝에 겨우 살렸으나 64개(8x8) 중 2개 행이 작동을 안하는 상태입니다. 이것 때문에 위 amg8833의 헤더 파일(.h) 소스들을 수정해야 했습니다. 죽은 픽셀 값을 인접한 값으로 대체하기 위해서요... 그리고 기본 1초인데 5초마다 갱신하도록 변경했습니다. 

 

ESPHome을 설치(pip3 install esphome) 후 작업 디렉터리에는 amg8833.yaml과 헤더(.h) 파일 3개가 필요합니다. 저는 센서에 문제가 있어서 수정을 했습니다. 물론 amg8833부품에 문제가 없으면 수정할 필요가 없습니다. 

 

amg8833_camera.h의 수정 사항 

// 수정 부분 - 5초마다 
AMG8833CameraComponent() : PollingComponent(5000) {}
 
// 수정 부분 - 2개 행 오류 수정 
for (unsigned char i = 0; i < total_pixels; i++)
{
    // 2행과 4행의 센서가 오류라서 이전 값을 복사  
    if(i / 8 == 1 || i / 8 == 3)
    {
        payload += PixelTemperatureRaw;
    }
    else
    {
        payload += grideye.getPixelTemperatureRaw(i);
        PixelTemperatureRaw = grideye.getPixelTemperatureRaw(i);
    }
}

amg8833.h의 수정 사항 - 최대 온도 값 뽑아 내는 부분 수정 

// 수정 부분 - 5초마다
AMG8833CameraComponent() : PollingComponent(5000) {}
 
// 수정 부분 - 최대 온도인 값 뽑아 내기 수정 
for (unsigned char i = 0; i < total_pixels; i++)
{
    // 첫줄과 끝줄은 무시하고, 둘째와 넷째 줄은 불량 센서라서 무시
    if(i / 8 == 0 || i / 8 == 1 || i / 8 == 3 || i / 8 == 7) ;
    else
    {
        pixel_temperature = grideye.getPixelTemperature(i);
        // 세번째 줄 첫 온도 값이거나...
        if (i == 15 || pixel_temperature > max)
        {
            max = pixel_temperature;
            local_max_index = i;
        }
        if (i == 15 || pixel_temperature < min)
        {
            min = pixel_temperature;
            local_min_index = i;
        }
        avg += pixel_temperature;
    }
}

 

 

[기타] 

레인지후드의 물리 전원 스위치를 잘못 조작해서 켜지지 않은 경우가 있었습니다. 

 

아침에 자동 작동이 안된 사례(습도값)

점심이나 저녁에는 습도가 65%내외까지만 올라간 반면, 아침에는 레인지후드가 작동하지 않아서 습도가 80%까지 올라간 것을 볼 수 있습니다. 즉, 적외선 측정 온도에 의해서 팬이 돌면 습도가 많이 오르지 않고 잘 배출된다는 의미입니다. 아침에는 끓여 놓은 국을 데우는 수준이라서 85%까지는 도달하지 못했습니다. Aqara 무선 스위치를 눌러도 작동이 안되던 상황이었기도 했구요.  

 

[추가] 

근래 센서가 아예 고장이 나서 다른 통신 방식의 동일한 센서(GY-MCU8833)로 변경했습니다.