Kitchen exhaust

what about the kitchen (while cooking) and need an automation to start the exhaust

tried the humidity.temp sensor above the stove but not practical

thinking in vibration sensor

—any smarter ideas?

Motion detector and timer

Maybe combine with voltage detection(electric stove)

1 Like

I solved this with a temperature sensor on the underside of the range hood. Cooking detection is then based on a derivative that gives the rate of temperature change.

To protect the sensor from grease and vapors I closed the openings on the cover with metal tape. Heat-conductive enough for quick reaction but without letting gunk get in.

3 Likes

I’ve added a PM2.5 sensor in my house and within 1 minute of starting to cook something, the thing knows it.
I suggest a pm10 sensor and a co2 sensor, automation when it goes above a level, turn on the fan…

You provably have enough resolution to control low speed and high speed with that, depending on the level of ‘pollution’ near the stove.

2 Likes

is there any cheap PM sensor? I only know about amazon and airthings

Ikea has one

PM sensors have a short enough lifetime as it is, I reckon a PM sensor installed over a cooker will be dead even quicker than usual!

What type of sensor are you using? I already have a samjin motion with temp stuck to the hood but it seems like the responsiveness of temp is too slow for my liking. I upgraded the hood to one that can be controlled so now it matters.

I’ve got a Zooz one. It turned out to be even more responsive than I thought, serving to quickly detect not only cooking but also baking.

2 Likes

I’ve got a bme680 running off an ifan04 with esphome for the hood fan. Fan operates based on air quality perfectly.

sounds cool

I like the ifan idea which of course controls the speed according to the level of humidity

can u share the automation too?

1 Like

I wanted it to happen on the device so I did it all in the esphome config.

I did have to solder in additional capacitors in order for it to control my hoodvent motor, as they are different than a ceiling fan.

esphome:
  name: hoodvent
  friendly_name: HoodVent
  includes:
    - ifan_remote.h

esp8266:
  board: esp8285
  framework:
    version: latest
  early_pin_init: true
  restore_from_flash: true

# Enable logging
# To use logging via uart (UART0 TX, GPIO01) you have to remove
# uart_bus and the IFanRemote custom text_sensor.
logger:
  baud_rate: 0
#  level: VERBOSE

# Enable Home Assistant API
api:
  encryption:
    key: "xxx"

ota:
  password: "xxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none

substitutions:
  device_name: ifan04
  device_displayname: IFAN04

preferences:
  flash_write_interval: 5min

#web_server:
#  port: 80

# GPIO00 ... Button
# GPIO01 ... UART0 TX
# GPIO03 ... UART0 RX (RF remote control)
# GPIO04 ... I2C SDA (TP11 D_RX on PCB backside)
# GPIO05 ... I2C SCL (TP10 D_TX on PCB backside)
# GPIO09 ... Light Relay (D7)
# GPIO10 ... Buzzer
# GPIO12 ... Fan Relay 2 (D11, 3uF cap on IFAN04-H)
# GPIO13 ... LED
# GPIO14 ... Fan Relay 1 (D5, 2.5uF cap on IFAN04-H)
# GPIO15 ... Fan Relay 3 (D13, no cap)

status_led:
  pin:
    number: GPIO13
    inverted: true

i2c:
  sda: GPIO04
  scl: GPIO05
  frequency: 200kHz

# UART configuration for the RF remote control
# Logging via uart must be disabled to use this.
uart:
  rx_pin: GPIO03
  baud_rate: 9600
  id: uart_bus

output:
  - platform: gpio
    id: light_relay
    pin:
      number: GPIO09
      inverted: true
  - platform: gpio
    id: buzzer
    pin:
      number: GPIO10
      inverted: true
  - platform: gpio
    id: fan_relay_1
    pin: GPIO14
  - platform: gpio
    id: fan_relay_2
    pin: GPIO12
  - platform: gpio
    id: fan_relay_3
    pin: GPIO15
  - platform: template
    id: fan_relays
    type: float
    write_action:
      - if: # Fan off
          condition:
            lambda: return (state < 0.3);
          then:
            - if:
                condition:
                  lambda: return id(buzzer_enabled).state;
                then:
                  - output.turn_on: buzzer
                  - delay: 300ms
                  - output.turn_off: buzzer
            - output.turn_off: fan_relay_1
            - output.turn_off: fan_relay_2
            - output.turn_off: fan_relay_3
      - if: # Fan low speed
          condition:
            lambda: return ((state >= 0.3) && (state < 0.6));
          then:
            - if:
                condition:
                  lambda: return id(buzzer_enabled).state;
                then:
                  - output.turn_on: buzzer
                  - delay: 50ms
                  - output.turn_off: buzzer
            - output.turn_off: fan_relay_3
            - output.turn_off: fan_relay_2
            - output.turn_on: fan_relay_1
      - if: # Fan mid speed
          condition:
            lambda: return ((state >= 0.6) && (state < 0.9));
          then:
            - if:
                condition:
                  lambda: return id(buzzer_enabled).state;
                then:
                  - output.turn_on: buzzer
                  - delay: 50ms
                  - output.turn_off: buzzer
                  - delay: 100ms
                  - output.turn_on: buzzer
                  - delay: 50ms
                  - output.turn_off: buzzer
            - output.turn_off: fan_relay_3
            - output.turn_off: fan_relay_1
            - output.turn_on: fan_relay_2
      - if: # Fan high speed
          condition:
            lambda: return (state >= 0.9);
          then:
            - if:
                condition:
                  lambda: return id(buzzer_enabled).state;
                then:
                  - output.turn_on: buzzer
                  - delay: 50ms
                  - output.turn_off: buzzer
                  - delay: 100ms
                  - output.turn_on: buzzer
                  - delay: 50ms
                  - output.turn_off: buzzer
                  - delay: 100ms
                  - output.turn_on: buzzer
                  - delay: 50ms
                  - output.turn_off: buzzer
            - output.turn_off: fan_relay_2
            - output.turn_off: fan_relay_3
            - output.turn_on: fan_relay_3
            
light:
  - platform: binary
    name: 'Light'
    id: light_comp
    output: light_relay

fan:
  - platform: speed
    name: 'Fan'
    id: fan_comp
    output: fan_relays
    speed_count: 3

switch:
  - platform: template
    name: 'Buzzer enabled'
    id: buzzer_enabled
    entity_category: config
    optimistic: True
    restore_mode: RESTORE_DEFAULT_OFF
  - platform: restart
    name: "Restart Device"

binary_sensor:

  - platform: gpio
    name: "Button"
    pin:
      number: GPIO00
      inverted: true

bme680_bsec:
    # id
    # -----------
    # Identifier for this component, useful when working with multiple devices.
    # Must be unique, and can be used in the sensor sections to refer to the correct device.
    # Default: auto-computed
    id: bme680_internal

    # i2c address
    # -----------
    # Common values are:
    # - 0x76
    # - 0x77
    # Default: 0x76
    address: 0x77

    # Temperature offset
    # ------------------
    # Useful if device is in enclosure and reads too high
    # For example, if it reads 5C too high, set this to 5
    # This also corrects the relative humidity readings
    # Default: 0
    temperature_offset: 3

    # IAQ calculation mode
    # --------------------
    # Available options:
    # - static (for fixed position devices)
    # - mobile (for on a person or other moveable devices)
    # Default: static
    iaq_mode: static

    # Sample rate
    # -----------
    # Available options:
    # - lp (low power - samples every 3 seconds)
    # - ulp (ultra-low power - samples every 5 minutes)
    # Default: lp
    sample_rate: lp

    # Interval at which to save BSEC state
    # ------------------------------------
    # Default: 6h
    state_save_interval: 6h

sensor:
  - platform: bme680_bsec
    # ID of the bme680_bsec component to use for the next sensors.
    # Useful when working with multiple devices
    bme680_bsec_id: bme680_internal

    temperature:
      # Temperature in °C
      name: "Temperature"
      sample_rate: lp
      filters:
        - median
    pressure:
      # Pressure in hPa
      name: "Pressure"
      sample_rate: lp
      filters:
        - median
    humidity:
      # Relative humidity %
      name: "Humidity"
      sample_rate: lp
      filters:
        - median
    gas_resistance:
      # Gas resistance in Ω
      name: "Gas Resistance"
      filters:
        - median
    iaq:
      # Indoor air quality value
      name: "IAQ"
      id: iaq
      filters:
        - median
      on_value_range:
        - above: 150
          below: 300
          then:
            - fan.turn_on:
                id: fan_comp
                speed: 1
        - above: 300
          then:
            - fan.turn_on:
                id: fan_comp
                speed: 2
        - below: 150
          then:
            - fan.turn_off:
                id: fan_comp
    iaq_accuracy:
      # IAQ accuracy as a numeric value of 0, 1, 2, 3
      name: "Numeric IAQ Accuracy"
    co2_equivalent:
      # CO2 equivalent estimate in ppm
      name: "CO2 Equivalent"
      filters:
        - median
    breath_voc_equivalent:
      # Volatile organic compounds equivalent estimate in ppm
      name: "Breath VOC Equivalent"
      filters:
        - median

  - platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
    name: "WiFi Signal dB"
    id: wifi_signal_db
    update_interval: 60s
    entity_category: "diagnostic"

  - platform: copy # Reports the WiFi signal strength in %
    source_id: wifi_signal_db
    name: "WiFi Signal Percent"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: "diagnostic"
    device_class: ""

text_sensor:
  - platform: bme680_bsec
    iaq_accuracy:
      # IAQ accuracy as a text value of Stabilizing, Uncertain, Calibrating, Calibrated
      name: "IAQ Accuracy"

  - platform: template
    name: "IAQ Classification"
    icon: "mdi:checkbox-marked-circle-outline"
    lambda: |-
      if ( int(id(iaq).state) <= 50) {
        return {"Excellent"};
      }
      else if (int(id(iaq).state) >= 51 && int(id(iaq).state) <= 125) {
        return {"Good"};
      }
      else if (int(id(iaq).state) >= 101 && int(id(iaq).state) <= 175) {
        return {"Lightly polluted"};
      }
      else if (int(id(iaq).state) >= 151 && int(id(iaq).state) <= 250) {
        return {"Moderately polluted"};
      }
      else if (int(id(iaq).state) >= 201 && int(id(iaq).state) <= 325) {
        return {"Heavily polluted"};
      }
      else if (int(id(iaq).state) >= 251 && int(id(iaq).state) <= 400) {
        return {"Severely polluted"};
      }
      else if (int(id(iaq).state) >= 401) {
        return {"Extremely polluted"};
      }
      else {
        return {"error"};
      }

  - platform: version
    name: 'ESPHome Version'
    
# Commands from the RF remote control are sent via
#  UART0 RX (= GPIO03)
# These commands are translated into hex strings
#  by the IFanRemote custom text_sensor (ifan_remote.h).
# The first 2 bytes (AA55) and the checksum byte
#  at the end, are removed.
#
# 1 (Light on/off)  = (AA55) 0104000104 (0A)
# 2 (Mute/buzzer)   = (AA55) 0106000101 (09)
# 3 (High speed)    = (AA55) 0104000103 (09)
# 4 (Medium speed)  = (AA55) 0104000102 (08)
# 5 (Fan off)       = (AA55) 0104000100 (06)
# 6 (Low speed)     = (AA55) 0104000101 (07)
# 7 (RF clearing)   = (AA55) 0101000102 (05)
# 8 (Wi-Fi pairing) = (AA55) 0101000102 (05)

  - platform: custom
    lambda: |-
      auto ifan_remote_sensor = new IFanRemote(id(uart_bus));
      App.register_component(ifan_remote_sensor);
      return {ifan_remote_sensor};
    text_sensors:
      name: 'RC command'
      on_value:
        then:
          - if: # Light on/off
              condition:
                lambda: return x == "0104000104";
              then:
                - light.toggle: light_comp
          # - if: # Buzzer on/off
          #     condition:
          #       lambda: return x == "0106000101";
          #     then:
          #       - switch.toggle: buzzer_enabled
          #       - output.turn_on: buzzer
          #       - delay: 10ms
          #       - output.turn_off: buzzer
          - if: # Fan off
              condition:
                lambda: return x == "0104000100";
              then:
                - fan.turn_off:
                    id: fan_comp
          - if: # Fan low speed
              condition:
                lambda: return x == "0104000101";
              then:
                - fan.turn_on:
                    id: fan_comp
                    speed: 1
          - if: # Fan mid speed
              condition:
                lambda: return x == "0104000102";
              then:
                - fan.turn_on:
                    id: fan_comp
                    speed: 2
          - if: # Fan high speed
              condition:
                lambda: return x == "0104000103";
              then:
                - fan.turn_on:
                    id: fan_comp
                    speed: 3

My sensor is in the next room. I just noticed it had good sensitivity even that far away.