ESPHome Multisensor

Aus Laub-Home Wiki

ESPHome Projekt

Mittels ESPHome lassen sich ohne viel Aufwand diverse Sensorenund Geräte konfigurieren und z.B. über MQTT (oder direkt via Home Assistant ESPHome API) an eine Hausautomatisierung anbinden.

WiFi

ESPHome:

https://esphome.io/components/wifi.html

wifi:
  ssid: MyHomeNetwork
  password: VerySafePassword

  # Optional manual IP
  manual_ip:
    static_ip: 10.0.0.42
    gateway: 10.0.0.1
    subnet: 255.255.255.0

Fallback Portal

ESPHome:

https://esphome.io/components/captive_portal.html

# Example configuration entry
wifi:
  # ...
  ap:
    ssid: "Fallback Hotspot"
    password: "W1PBGyrokfLz"

captive_portal:

Logging

ESPHome:

https://esphome.io/components/logger.html

logger:
  # level: DEBUG

Uptime

ESPHome:

https://esphome.io/components/sensor/uptime.html

sensor:
  - platform: uptime
    name: "Uptime Sensor"

Restart

ESPHome:

https://esphome.io/components/switch/restart.html

switch:
  - platform: restart
    name: "Restart Switch"

MQTT

ESPHome:

(https://esphome.io/components/mqtt.html)

mqtt:
  broker: 10.0.0.2
  username: mqtt_username
  password: MyMQTTPassword

Temperatur

i2c:
  sda: D2   #Wemos D1 Mini , GPIO05
  scl: D1   #Wemos D1 Mini , GPIO04
  scan: True
  
sensor:
  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x76  #or 0x77
    update_interval: 60s

Feuchtigkeit

i2c:
  sda: D2   #Wemos D1 Mini , GPIO05
  scl: D1   #Wemos D1 Mini , GPIO04
  scan: True
  
sensor:
  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x76  #or 0x77
    update_interval: 60s

absolute Feuchtigkeit

i2c:
  sda: D2   #Wemos D1 Mini , GPIO05
  scl: D1   #Wemos D1 Mini , GPIO04
  scan: True
  
sensor:
  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x76  #or 0x77
    update_interval: 60s  


  # calc based on temp and humid sensor via internal ID
  # humidity: bme280
  # temperature: bme280
  - platform: template
    name: "Absolute Humidity"
    lambda: |-
      const float mw = 18.01534;    // molar mass of water g/mol
      const float r = 8.31447215;   // Universal gas constant J/mol/K
      return (6.112 * powf(2.718281828, (17.67 * id(bme280_temperature).state) /
        (id(bme280_temperature).state + 243.5)) * id(bme280_humidity).state * mw) /
        ((273.15 + id(bme280_temperature).state) * r); // in grams/m^3
    accuracy_decimals: 2
    update_interval: 60s
    icon: 'mdi:water-percent-alert'
    unit_of_measurement: 'g/m³'

Luftdruck

i2c:
  sda: D2   #Wemos D1 Mini , GPIO05
  scl: D1   #Wemos D1 Mini , GPIO04
  scan: True
  
sensor:
  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x76  #or 0x77
    update_interval: 60s

vergleichbarere Luftdruck auf Meereshöhe

i2c:
  sda: D2   #Wemos D1 Mini , GPIO05
  scl: D1   #Wemos D1 Mini , GPIO04
  scan: True
  
sensor:
  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x76  #or 0x77
    update_interval: 60s  


  # calc based on temp and pressure sensor via internal ID
  # pressure: bme280
  # temperature: bme280
  - platform: template
    name: "$devicename Equivalent sea level pressure"
    lambda: |-
      const float STANDARD_SEA_LEVEL_PRESSURE = 1013.25; //in hPa, see note
      const float STANDARD_ALTITUDE =  ((id(bme280_temperature).state + 273.15) / 0.0065) *
      (powf((STANDARD_SEA_LEVEL_PRESSURE / id(bme280_pressure).state), 0.190234) - 1); // in meter
      return id(bme280_pressure).state / powf(1 - ((0.0065 * STANDARD_ALTITUDE) /
      (id(bme280_temperature).state + (0.0065 * STANDARD_ALTITUDE) + 273.15)), 5.257); // in hPa
    update_interval: 60s
    unit_of_measurement: 'hPa'
    icon: 'mdi:weather-fog'

Taupunkt

i2c:
  sda: D2   #Wemos D1 Mini , GPIO05
  scl: D1   #Wemos D1 Mini , GPIO04
  scan: True
  
sensor:
  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x76  #or 0x77
    update_interval: 60s  


  # calc based on temp and humidity sensor via internal ID
  # humidity: bme280
  # temperature: bme280
  - platform: template
    name: "$devicename Dew Point"
    lambda: |-
      return (243.5*(log(id(bme280_humidity).state/100)+((17.67*id(bme280_temperature).state)/
      (243.5+id(bme280_temperature).state)))/(17.67-log(id(bme280_humidity).state/100)-
      ((17.67*id(bme280_temperature).state)/(243.5+id(bme280_temperature).state))));
    unit_of_measurement: °C
    update_interval: 60s
    icon: 'mdi:weather-fog'

Beleuchtungsstärke (LUX)

i2c:
  sda: GPIO21   #GPIO05
  scl: GPIO22
  scan: True

sensor:
  # LUX i2c sensor bh1750
  - platform: bh1750
    name: "ESP32 Multisensor BH1750 Illuminance"
    address: 0x23
    measurement_time: 254
    resolution: 0.5
    update_interval: 60s  
    
  # LUX i2c sensor tsl2561
  - platform: tsl2561
    name: "ESP32 Multisensor TSL2561 Illuminance"
    address: 0x39
    integration_time: 402ms
    gain: 16x
    update_interval: 60s

Bewegung

Als Bewegungssensor kommen zwei Sensoren in Frage; aufgrund der verschiedenen Techniken der Bewegungsermittlung mit entsprechenden Vor-/ Nachteilen:

Modell Technik Kosten Fakten Bild
AM312 PIR IR ca. 0,80 € - 0,90 €
  • klein
  • günstig
  • nur ein PIN benötigt
  • Abdeckung/ Kuppel muss außerhalb des Gehäuses in Abdeckungsrichtung sein
  • Abdeckung:
    • ca. 100 °
    • ca. 3-5 m
RCWL-0516 Microwave ca. 0,25 € - 0,50 €
  • klein
  • noch günstig
  • nur ein PIN benötigt
  • kann unter Umständen durch Hindernisse erkennen (wie z.B. ein verbautes Gehäuse aber ggf. auch Wände)
  • kann daher versteckt im Gehäuse platziert werden
  • Abdeckung:
    • 360 °
    • ca. 5-7 m

AM312 PIR

PIN-Anschluss:

  • GND: Ground
  • OUT: Daten PIN (z.B. Wemos D1 Mini PIN D6)
  • VIN: VCC 3,3v


ESPHome:

binary_sensor:
    #PIR Motion AM312
  - platform: gpio
    pin: D6 #GPIO12
    name: "Motion Sensor AM312"
    device_class: motion


RCWL-0516

PIN-Anschluss:

  • GND: Ground
  • OUT: Daten PIN (z.B. Wemos D1 Mini PIN D7)
  • VIN: VCC 3,3v


ESPHome:

binary_sensor:  
  - platform: gpio
    pin: D7
    name: "Motion Sensor RCWL-0516"
    device_class: motion

Luftqualität

sensor:
  # eCO2/ VOC i2c  
  - platform: ccs811
    eco2:
      name: "CCS811 eCO2 Value"
    tvoc:
      name: "CCS811 Total Volatile Organic Compound"
    address: 0x5A
    #baseline: 0xD6D8
    update_interval: 60s  
  - platform: mhz19
    co2:
      name: "MH-Z19 CO2 Value"
      id: mhz19_co2
    temperature:
      name: "$devicename MH-Z19 Temperature"
      id: mhz19_temperature
    update_interval: 60s
    automatic_baseline_calibration: false
    id: mhz19_id

eCO2 / TVOC / AQI

globals:
  - id: iaq_index
    type: int
    restore_value: no
    initial_value: '0'

i2c:
  sda: D2   #Wemos D1 Mini , GPIO05
  scl: D1   #Wemos D1 Mini , GPIO04
  scan: True
  
sensor:
  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
    humidity:
      name: "BME280 Relative Humidity"
      id: bme280_humidity
    address: 0x76  #or 0x77
    update_interval: 60s  
    
  # eCO2/ VOC i2c  
  - platform: ccs811
    eco2:
      name: "CCS811 eCO2 Value"
      id: eco2
    tvoc:
      name: "CCS811 Total Volatile Organic Compound"
      id: tvoc
    temperature: bme280_temperature
    humidity: bme280_humidity
    #baseline: 0x72B6
    address: 0x5A
    update_interval: 60s  

text_sensor:  
  # uses global variable iaq_index and several sensor IDs
  # humidity: bme280
  # eCO2: ccs811
  # TVOC: ccs811
  - platform: template
    name: "IAQ"
    icon: "mdi:air-filter"
    lambda: |-
      id(iaq_index) = 0;
      
      /*
       * Transform indoor humidity values to IAQ points according to Indoor Air Quality UK: 
       * http://www.iaquk.org.uk/
       */
      if (id(bme280_humidity).state < 10 or id(bme280_humidity).state > 90) {
        id(iaq_index) += 1;
      }
      else if (id(bme280_humidity).state < 20 or id(bme280_humidity).state > 80) {
        id(iaq_index) += 2;
      }
      else if (id(bme280_humidity).state < 30 or id(bme280_humidity).state > 70) {
        id(iaq_index) += 3;
      }
      else if (id(bme280_humidity).state < 40 or id(bme280_humidity).state > 60) {
        id(iaq_index) += 4;
      }
      else if (id(bme280_humidity).state >= 40 and id(bme280_humidity).state <= 60) {
        id(iaq_index) += 5;
      }
      
      /*
       * Transform eCO2 values to IAQ points according to Indoor Air Quality UK: 
       * http://www.iaquk.org.uk/
       */
      if (id(eco2).state <= 600) {
        id(iaq_index) += 5;
      }
      else if (id(eco2).state <= 800) {
        id(iaq_index) += 4;
      }
      else if (id(eco2).state <= 1500) {
        id(iaq_index) += 3;
      }
      else if (id(eco2).state <= 1800) {
        id(iaq_index) += 2;
      }
      else if (id(eco2).state > 1800) {
        id(iaq_index) += 1;
      }
      
      /*
       * Transform TVOC values to IAQ points according to German environmental guidelines: 
       * https://www.repcomsrl.com/wp-content/uploads/2017/06/Environmental_Sensing_VOC_Product_Brochure_EN.pdf
       */
      if (id(tvoc).state <= 65) {
        id(iaq_index) += 5;
      }
      else if (id(tvoc).state <= 220) {
        id(iaq_index) += 4;
      }
      else if (id(tvoc).state <= 660) {
        id(iaq_index) += 3;
      }
      else if (id(tvoc).state <= 2200) {
        id(iaq_index) += 2;
      }
      else if (id(tvoc).state > 2200) {
        id(iaq_index) += 1;
      }

      /*
       * Transform IAQ index to human readable text according to Indoor Air Quality UK: 
       * http://www.iaquk.org.uk/
       */
      ESP_LOGD("main", "Current IAQ index %d", id(iaq_index));
      
      if (id(iaq_index) <= 6) {
        return {"Unhealty"};
      }
      else if (id(iaq_index) <= 9) {
        return {"Poor"};
      }
      else if (id(iaq_index) <= 12) {
        return {"Moderate"};
      }
      else if (id(iaq_index) <= 14) {
        return {"Good"};
      }
      else if (id(iaq_index) > 14) {
        return {"Excellent"};
      }
      
      return {};
    update_interval: 60s

Lautstärke

Kamera

esp32cam Modul

esphome:
  name: mobile_camera
  platform: ESP32
  #board: esp32cam
  board: esp32dev

esp32_camera:
  name: ESP32Cam Camera
  external_clock:
    pin: GPIO0
    frequency: 20 MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  # the order of the data_pins is significant, don't mix up the order
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32
  vertical_flip: true
  horizontal_mirror: true
  # https://www.uctronics.com/download/cam_module/OV2640DS.pdf
  # Maximum Image Transfer Rate
  #   SXGA    15 fps    1280x1024
  #   UXGA    15 fps    1600x1200
  #   SVGA    30 fps    800x600
  #   CIF     60 fps    352x288
  resolution: 800x600
  max_framerate: 30 fps
  idle_framerate: 0.1 fps
  
output:
  # Flashlight
  - platform: gpio
    pin: GPIO4
    id: gpio_4
  # Red Power LED
  - platform: gpio
    inverted: True
    pin: GPIO33
    id: gpio_33    
light:
  - platform: binary
    output: gpio_4
    name: ESP32Cam Flashlight
  - platform: binary
    output: gpio_33
    name: ESP32Cam Red Power Light

RGB LED inkl. Effekte

light:
  #ws2812 RGB LED
  - platform: fastled_clockless
    chipset: WS2812
    pin: D5   #GPIO14
    num_leds: 1
    rgb_order: GRB
    restore_mode: ALWAYS_OFF
    name: "RGB Light"
    id: rgb_light
    effects:
      - strobe:
          name: "StrobeRed"
          colors:
            - state: True
              brightness: 75%
              red: 100%
              green: 0%
              blue: 0%
              duration: 1000ms
            - state: False
              duration: 500ms
      - lambda:
         name: "BreatheRed"
         update_interval: 1s
         lambda: |-
          static int state = 0;
          auto call = id(rgb_light).make_call();
          id(rgb_light).turn_off();
          call.set_rgb(1.0, 0.0, 0.0);
          call.set_brightness(0.0);
          if (state == 0) {
            call.set_transition_length(1000);
            call.set_rgb(1.0, 0.0, 0.0);
            call.set_brightness(0.8);
          }
          else if (state == 1)           {
            call.set_transition_length(1000);
            call.set_rgb(1.0, 0.0, 0.0);
            call.set_brightness(0.5);
          }
          call.perform();
          state++;
          if (state == 2) {
            state = 0;
          }
      - lambda:
         name: "BreatheGreen"
         update_interval: 1s
         lambda: |-
          static int state = 0;
          auto call = id(rgb_light).make_call();
          id(rgb_light).turn_off();
          call.set_rgb(0.0, 1.0, 0.0);
          call.set_brightness(0.0);
          if (state == 0) {
            call.set_transition_length(1000);
            call.set_rgb(0.0, 1.0, 0.0);
            call.set_brightness(0.8);
          }
          else if (state == 1)           {
            call.set_transition_length(1000);
            call.set_rgb(0.0, 1.0, 0.0);
            call.set_brightness(0.5);
          }
          call.perform();
          state++;
          if (state == 2) {
            state = 0;
          }

RF

https://esphome.io/components/remote_receiver.html

https://esphome.io/components/remote_transmitter.htm

PIN-Anschluss:

  • GND: Ground
  • DATA: Daten PIN (z.B. Wemos D1 Mini PIN D7)
  • VCC: VCC 3,3v

ESPHome:

Empfangen/ Dump:

remote_receiver:
  pin:
    # working:
    #   D2, D5, D6, D7 / inverted false / no pullup
    number: D6
    #inverted: True
    #mode: INPUT_PULLUP
  dump:
    - rc_switch
    - rc5
    #- all
  # Settings to optimize recognition of RF devices
  tolerance: 50%
  filter: 500us   #250
  idle: 10ms       #4
  buffer_size: 2kb

Reaktion auf empfangenes Signal-Paket:

binary_sensor:
  - platform: remote_receiver
    name: "remote open"
    internal: true
    #raw:
      #code: [1388, -446, 507, -1347, 1358, -453, 499, -1351, 1353, -457, 1395, -462, 1392, -466, 487, -1391, 1362, -466, 1338, -468, 1339, -471, 1379, -473, 1335, -474, 476, -1370, 1340, -470, 484, -1395, 461, -1365, 490, -1362, 446, -1361, 493, -1357]
    rc_switch_raw:
      code: "10101110111110100000101"
      protocol: 1
    on_press:
      then:
        - binary_sensor.template.publish:
            id: mailboxstate
            state: ON      
  - platform: remote_receiver
    name: "remote close"
    internal: true
    #raw:
      #code: [1387, -447, 505, -1348, 1404, -454, 499, -1354, 1401, -457, 1395, -462, 1392, -466, 488, -1391, 1362, -465, 1339, -467, 1339, -471, 1380, -475, 1333, -473, 475, -1371, 1339, -472, 482, -1395, 462, -1364, 491, -1361, 447, -1357, 496, -1357]
    rc_switch_raw:
      code: "10101110111110100000111"
      protocol: 1   
    on_press:
      then:
        - binary_sensor.template.publish:
            id: mailboxstate
            state: OFF

IR

https://esphome.io/components/remote_receiver.html

https://esphome.io/components/remote_transmitter.htm

PIN-Anschluss:

KY-022 Receiver Modul (ca. Reichweite 17m / Carrier Frequenz 38kHz)

  • S: Signal PIN (z.B. esp32cam PIN GPIO12)
  • +V: VCC 3.0V or 5.0V
  • -: Ground

ESPHome:

Empfangen/ Dump:

remote_transmitter:
  pin: D1
  # Infrared remotes use a 50% carrier signal
  carrier_duty_percent: 50%


Transmitter:

remote_transmitter:
  pin: GPIO25
  carrier_duty_percent: 50%
  
  
switch:
  - platform: template
    name: Samsung Power DATA
    turn_on_action:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E040BF
  - platform: template
    name: Samsung Power RAW 38k
    turn_on_action:
      - remote_transmitter.transmit_raw:
          carrier_frequency: 38kHz
          code: [-4513, 4466, -603, 1655, -601, 1656, -603, 1654, -604, 525, 
                -604, 525, -604, 525, -604, 525, -603, 525, -603, 1655, -603, 
                1654, -603, 1655, -604, 524, -605, 524, -604, 525, -604, 525, 
                -603, 526, -602, 526, -605, 1653, -603, 1655, -601, 527, -604, 
                525, -603, 1654, -604, 1654, -603, 1654, -605, 1653, -604, 525, 
                -603, 526, -600, 1657, -604, 1654, -603, 525, -604, 525, -604, 525]            
  - platform: template
    name: Samsung Power RAW
    turn_on_action:
      - remote_transmitter.transmit_raw:
          #carrier_frequency: 38kHz
          code: [-4513, 4466, -603, 1655, -601, 1656, -603, 1654, -604, 525, 
                -604, 525, -604, 525, -604, 525, -603, 525, -603, 1655, -603, 
                1654, -603, 1655, -604, 524, -605, 524, -604, 525, -604, 525, 
                -603, 526, -602, 526, -605, 1653, -603, 1655, -601, 527, -604, 
                525, -603, 1654, -604, 1654, -603, 1654, -605, 1653, -604, 525, 
                -603, 526, -600, 1657, -604, 1654, -603, 525, -604, 525, -604, 525]  
                
  - platform: template
    name: Telekom Power RAW
    turn_on_action:
      - remote_transmitter.transmit_raw:
          #carrier_frequency: 38kHz
          code: [340, -588, 333, -275, 651, -275, 324, -576, 307, -300, 650, -584, 650, -573, 333, -266, 338, -272, 650, -580, 649, -277, 324, -575, 339]

  - platform: template
    name: Telekom Power RAW 38k
    turn_on_action:
      - remote_transmitter.transmit_raw:
          carrier_frequency: 38kHz
          code: [340, -588, 333, -275, 651, -275, 324, -576, 307, -300, 650, -584, 650, -573, 333, -266, 338, -272, 650, -580, 649, -277, 324, -575, 339]