Esphome DIY

Esphome~Diy

1、紅外線二氧化碳感測器 MH-Z19B空氣品質監
2、GY-BME280-3.3V 5V高精度 大氣壓力強 溫濕度感測器模組
3、GY-302 數位光強度 光照感測器 BH1750FVI 模組代碼
4、MC-38 門磁
5、R13-507 綠色 無鎖 16MM自重設按鍵開關
6、小型帶線防水金屬電源指示燈6mm開孔發光號誌燈3V-6V
7、0.96吋OLED顯示屏液晶螢幕模組

※所有模塊均可拔插抽換(含oled螢幕)方便日後維修

substitutions:
  device_name: "smartbox1"
  friendly_name: 環境監測盒子
esphome:
  name: ${device_name}
  name_add_mac_suffix: true
  #name_add_mac_suffix 添加mac位址在name後面
  #不需要再name後面增加mac位址需把此行註解掉
  #缺點 ota時需產出bin並登入web頁面更新
  #優點 每個設備加入時都會是不同的id方便辨識  

esp8266:                  # 指定使用 ESP8266 平台
  board: d1_mini         # 设置开发板型号为 D1 Mini
  framework:              # 定义所使用的框架
    version: latest      # 使用最新版本的框架
packages:
  device_web: !include templates/device_web.yaml

##########################################################    
uart:
#  - id: uart_mhz19  
  rx_pin: GPIO3 #RX
  tx_pin: GPIO1 #TX
  baud_rate: 9600
##########################################################  
i2c:
   sda: D2
   scl: D1
   scan: true
   id: bus_a
   frequency: 100kHz

display:
# 參考網址:https://esphome.io/cookbook/display_time_temp_oled.html  
# 0.96寸蓝色 黄蓝双色 白色 I2C IIC通信 显示器 OLED液晶屏模块購買網址:https://item.taobao.com/item.htm?_u=l25c5khj392e&id=43639171586&spm=a1z09.2.0.0.1a752e8dmdvWhu  
# 模塊接法:vcc(3.3v),gnd,scl(D1),sda(D2)
  - platform: ssd1306_i2c
    model: SSD1306_128X64           # 使用 128x64 像素 SSD1306 OLED 顯示器
    address: 0x3C                  # OLED I2C 位址
    id: my_display                 # 顯示器 ID
    pages:
      - id: page1
        lambda: |-
          // 顯示時間,X軸64(寬度中間),Y軸0(最上方),使用小字體置中對齊
          it.strftime(64, 0, id(font1), TextAlign::TOP_CENTER, "%Y/%m/%d %H:%M", id(esptime).now());

          // 顯示溫度,X軸64(寬度中間),Y軸56(接近底部),使用最大字體底線置中對齊
          it.printf(64, 56, id(font3), TextAlign::BASELINE_CENTER, "%.1f°C", id(R1).state);


font: 
  - file: "arial.ttf"
    id: font1
    size: 16                        # 小字體,時間與小字資訊用
  - file: "arialbd.ttf"
    id: font2
    size: 20                        # 中等字體,可用於中階文字
  - file: "arialbd.ttf"
    id: font3
    size: 38                        # 最大字體,專用於溫度顯示(字體較大)


##########################################################   
sensor:
  - platform: mhz19   # GND+5V+GPIO1+GPIO3 
#    uart_id: uart_mhz19  
    update_interval: 30s
    id: Co2master
    automatic_baseline_calibration: false  #true 表示開啟ABC功能/如果設為 false,則關閉 ABC,適合密閉或無法定期通風的環境。
    co2:
      name: "${device_name}"
      filters:
        - sliding_window_moving_average:   ### sliding window moving average(滑動視窗移動平均),可以用來平滑數值輸出,降低雜訊 ###
            window_size: 3                 ### 維持一個長度為 3 的資料視窗,也就是最近的 3 筆讀值 ###
            send_every: 3                  ### 每收到 3 筆資料後才送出一次平均值。###
    temperature:
      name: "${device_name}Temperature"   
##########################################################
  - platform: bh1750              # GND+3.3V+sda:33+scl:32
    name: "${device_name}Illuminance n"
    address: 0x23
    update_interval: 20s
##########################################################
# 參考網址:https://esphome.io/components/sensor/bme280     esphome官網
# GY-BME/BMP280 3.3V-5V 温湿度/大气压强传感器模块購買網址:https://item.taobao.com/item.htm?_u=k25c5khjd9d1&id=558228648682&skuId=4877906215314&spm=a312a.7700846.0.0.15744c27MlglaH    
# 模塊接法:vcc(3.3v),gnd,scl(D1),sda(D2),csb,sdo。"开始也是0x76和0x77都不行,后面把sdo〈接GND〉接地拉低",然后用0x76连接上了。3.3v版   
  - platform: bme280_i2c  #(GYBME280-3.3v)版
    temperature:
      name: "${device_name} BME280 Temperature"
      filters:                            #以下內容為溫度校驗結果,可自行修改,需放置一個晚上穩定才準確
        - calibrate_linear:
            - 28.4 -> 24.3               #ESPhome實際讀取溫度->校驗後溫度
            - 30.4 -> 26.3               #ESPhome實際讀取溫度->校驗後溫度 
      id: R1
      oversampling: 16x 
    pressure:
      name: "${device_name} BME280 Pressure"
      id: R6
      oversampling: 16x
    humidity:
      name: "${device_name} BME280 Humidity"
      filters:                           #以下內容為濕度校驗結果,可自行修改,需放置一個晚上穩定才準確
        - calibrate_linear:
            - 54.5 -> 68.6         #ESPhome實際讀取濕度->校驗後濕度
            - 56.6 -> 70.7         #ESPhome實際讀取濕度->校驗後濕度     
      id: R7
      oversampling: 16x
    address: 0x76
    update_interval: 60s
##########################################################
  - platform: uptime
    name: Uptime
    filters:
      - lambda: return x / 3600;
    unit_of_measurement: "hours"
    accuracy_decimals: 1
##########################################################
  - platform: wifi_signal
    id: wifi_1
    update_interval: 60s

  - platform: template
    name: "${device_name} Wifi signal"
    id: R3
    unit_of_measurement: '%'
    accuracy_decimals: 0
    icon: "mdi:wifi"
    lambda: |-
        if (id( wifi_1).state < -92.0)
          return 100.0;
        if (id( wifi_1).state > -21.0)
          return 1.0;
        else
          return round(( -0.0154 * id( wifi_1).state * id( wifi_1).state ) - ( 0.3794 * id( wifi_1).state ) + 98.182 );
##########################################################          
time:
  - platform: sntp        # 從 Home Assistant 同步時間,方便顯示當地時間
    id: esptime
    timezone: Asia/Taipei
########################################################## 
binary_sensor:  # GND+GPIO2
  - platform: gpio
    pin:
     number: D6 
     mode: INPUT_PULLUP
    name: "${device_name}door"
    device_class: window
##########################################################
  ## Button 01
  - platform: gpio
    id: button_01
    pin:
      number: GPIO2 # GND+D4
      mode: INPUT_PULLUP
      inverted: True
    filters:
      - delayed_on: 50ms
      - delayed_off: 50ms
    on_multi_click:
      - timing:
          - ON for at most 1s
          - OFF for at least 400ms
        then:
          - text_sensor.template.publish:
              id: buttons
              state: "button_pressed"
          - delay: 50ms
          - text_sensor.template.publish:
              id: buttons
              state: "button_01_single"
          - switch.turn_off: alarm_led1
          - delay: 200ms
          - switch.turn_on: alarm_led1
          - delay: 200ms
          - switch.turn_off: alarm_led1
          - delay: 2s # 增加 2 秒延遲
          - text_sensor.template.publish:
              id: buttons
              state: "" # 重設狀態
      - timing:
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at most 1s
          - OFF for at least 400ms
        then:
          - text_sensor.template.publish:
              id: buttons
              state: "button_pressed"
          - delay: 50ms
          - text_sensor.template.publish:
              id: buttons
              state: "button_01_double"
          - switch.turn_off: alarm_led1
          - delay: 200ms
          - switch.turn_on: alarm_led1
          - delay: 200ms
          - switch.turn_off: alarm_led1
          - delay: 1s # 增加 1 秒延遲
          - switch.turn_off: alarm_led1
          - delay: 200ms
          - switch.turn_on: alarm_led1
          - delay: 200ms
          - switch.turn_off: alarm_led1
          - delay: 2s # 增加 2 秒延遲          
          - switch.turn_off: alarm_led1          
          - text_sensor.template.publish:
              id: buttons
              state: "" # 重設狀態

      - timing:
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at most 1s
          - OFF for at least 400ms
        then:
          - text_sensor.template.publish:
              id: buttons
              state: "button_pressed"
          - delay: 50ms
          - text_sensor.template.publish:
              id: buttons
              state: "button_01_triple"
          - delay: 2s # 增加 2 秒延遲
          - text_sensor.template.publish:
              id: buttons
              state: "" # 重設狀態

      - timing:
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at most 1s
          - OFF for at least 400ms
        then:
          - text_sensor.template.publish:
              id: buttons
              state: "button_pressed"
          - delay: 50ms
          - text_sensor.template.publish:
              id: buttons
              state: "button_01_quadruple"
          - delay: 2s # 增加 2 秒延遲
          - text_sensor.template.publish:
              id: buttons
              state: "" # 重設狀態
      - timing:
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at most 1s
          - OFF for at most 399ms
          - ON for at least 400ms
        then:
          - text_sensor.template.publish:
              id: buttons
              state: "button_pressed"
          - delay: 50ms
          - text_sensor.template.publish:
              id: buttons
              state: "button_01_many"
          - delay: 2s # 增加 2 秒延遲
          - text_sensor.template.publish:
              id: buttons
              state: "" # 重設狀態
      - timing:
          - ON for at least 2s
        then:
          - text_sensor.template.publish:
              id: buttons
              state: "button_pressed"
          - delay: 50ms
          - text_sensor.template.publish:
              id: buttons
              state: "button_01_long"
          - delay: 2s # 增加 2 秒延遲
          - text_sensor.template.publish:
              id: buttons
              state: "" # 重設狀態
##########################################################      
switch:
  - platform: gpio  # GND+GPIO13 
    pin: GPIO13 # GND+D7
    restore_mode: ALWAYS_OFF
    inverted: no
    id: alarm_led1
    name: "${device_name}alarm_led1"
    icon: "mdi:alarm-light"
  - platform: restart
    name: "${device_name}_restart"
  - platform: template
    name: "${device_name}_ABC"   #自動基線校正(ABC)功能:感測器會在運行過程中,根據長期最低的 CO2 讀數自動調整零點基準,避免長時間使用後基準點漂移。設備放在戶外或是通風良好地方時開啟
    optimistic: true
    on_turn_on:
      mhz19.abc_enable: Co2master
    on_turn_off:
      mhz19.abc_disable: Co2master
  - platform: template
    id: mh_z19_manual_calibrate
    name: "MH-Z19 手動校正"        #手動校正前先放戶外約 20 分鐘穩定環境,校正後再放戶外約 5~15 分鐘讓感測器內部數值穩定,讀數才會接近 400 ppm
    turn_on_action:
      - uart.write: [0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78]
      - delay: 1s
      - switch.turn_off: mh_z19_manual_calibrate
##########################################################    
 #此为开关,须在前面调用
  - platform: template
    name: "${device_name} 螢幕狀態"
    id: sw
    lambda: |-
      // 回傳顯示器目前狀態(開或關)
      return id(my_display).is_on();
    turn_on_action:
      - lambda: id(my_display).turn_on();
    turn_off_action:
      - lambda: id(my_display).turn_off();
button:
  - platform: restart
    name: "Restart"  

text_sensor:
  - platform: template
    name: "TCP/IP Address"
    lambda: 'return {WiFi.localIP().toString().c_str()};'
    id: tcp_ip_address
  - platform: wifi_info
    ip_address:
      name: "${device_name} IP Address"
      icon: "mdi:ip-network"
    ssid:
      name: "${device_name} Connected SSID"
      icon: "mdi:signal-variant"
    mac_address:
      name: "${device_name} Mac Wifi Address"
      icon: "mdi:wifi-marker"
  - platform: version
    name: "ESPHome Version"   

  - platform: template
    name: "${device_name}Switches"
    id: buttons
    icon: "mdi:light-switch"
    lambda: |-
      return {};

    
interval:
  - interval: 1s
    then:
      - lambda: |-
          static bool display_timer_active = false;
          static uint32_t display_timer_start = 0;
          if (id(buttons).state == "button_01_single" && !display_timer_active) {
            id(my_display).turn_on();
            ESP_LOGD("screen", "button_01_single 按下,螢幕開啟");
            display_timer_start = millis();
            display_timer_active = true;
          }

          if (display_timer_active && millis() - display_timer_start > 15000) {
            id(my_display).turn_off();
            ESP_LOGD("screen", "15秒到,螢幕關閉");
            display_timer_active = false;
            id(buttons).publish_state("");  // 重置狀態,避免重複觸發
          }

1個讚