[Automation] Shower detection: trigger when humidity increases in 10 minutes?

Recent updates of Home Assistant require the int filter to provide a default value. So both times you see an int in the template above, change this to int(0).

Thanks!

So for other visitors coming to this thread, this is what we should have under the value template block, per the recent updates, at least as of today (24-Feb-2022).

    value_template: >-
      {{ states("sensor.your_bathroom_humidity_sensor") | int(0) >
         states("sensor.bathroom_humidity_stats") | int(0) + 5 and
         states("sensor.bathroom_humidity_stats") != "unknown" }}

I set up the average sensor. What I want is to trigger when there is a quick change over 5% and then to off when it comes back to close to the average. I don’t see how the automation does this? Am I missing something?

That is what the binary sensor does and how the fan is controlled.

The binary sensor is on, based on the value template and calculation, when the sensor humidity is greater than the average humidity plus the threshold

The automation then uses this binary sensor to turn on and off the bathroom fan.

Also just posted an update to how I’m doing today, as this method above has changed, albeit only slightly: Quick Bathroom Fan Humidity Switch Control

What confused me is you said you only need the average sensor and the automation.

Hey all! There is another clean way to solve the task.

I am using the statistics component to act based on the change over given time of the humidity in my bathroom. This covers @Domoticon 's original question for a solution for “when humidity increases (by x%) within y minutes”.
The example below does this for turning my fan off but of course this can be adapted to other wishes.

The statistics sensor for humidity stats over the last 5min:

sensor:
  - platform: statistics
    name: Bad Luftfeuchte Statistics 5min Change
    entity_id: sensor.bad_raumsensor_bme280_humidity
    state_characteristic: change
    max_age:
      minutes: 5
    sampling_size: 30

The automation rule in question:

  - alias: Regel Bad Lüftung aus bei gleichbleibender Luftfeuchte
    trigger:
      - platform: state
        # Trigger for every humidity change
        entity_id: sensor.bad_raumsensor_bme280_humidity
    condition:
      condition: and
      conditions:
        - condition: state  
          # Condition: fan on for at least 5 minutes
          entity_id: switch.bad_luftung
          state: "on"
          for:
            minutes: 5
        - condition: numeric_state
          # Condition: Humidity reached at least 60%
          entity_id: sensor.bad_raumsensor_bme280_humidity
          below: 60
        - condition: numeric_state
          # Condition: Humidity change over the last 5 minutes is smaller than 2%
          entity_id: sensor.bad_luftfeuchte_statistics_5min_change
          above: -2
    action:
      - service: switch.turn_off
        entity_id: switch.bad_luftung

Further automation rules I have defined:

  • Turn the fan on when humidity exceeds 70%
  • Turn the fan off after 60 minutes maximum duration. This is a fallback rule in case the above rule does not work and this even is logged for error handling
4 Likes

That’s interesting. Is the change under the statistics component the same or similar to the trend component?

Personal experience: a couple of weeks ago I tested using mean under statistics components vs trend components side by side, tweaking parameters, and found that statistics being more reliable and sensitive (to my setup / my humidity sensor.)
Wasn’t aware that average_linear being a thing until I see Mark’s remark above. So thank you Mark, I’m planning to test that also.

I’ve gotten some useful tips from this thread so thanks to all. I’ve noticed that the binary_sensor will turn to 'on' when no shower is running i.e. no humidity changes but just from the ambient temperature in my bedroom, therefore it interferes with my automation logic. Anyone else experience this and have any workaround?

Thanks!

Given 3 months of statistics, I notice that the absolute humidity in my house pretty much follows the humidity so I’ll probably update my automation to enable my fan base of an offset with the external absolute humidity.

Here is the graph - orange is the external absolute humidity, the other ones are elsewhere in my house (when the lines are flat I either had a flat battery or an internet connection issue):

1 Like

Nice one! I had a similar revelation some time ago. The challenge was that, logically speaking, your bathroom humidity can’t go below the outside humidity. Therefore, if fan-off-humidity-level is lower than outside-humidity-level, the fan never turns off.

Instead of acting on absolute humidity levels (in relation to the outside humidity) I ended up using the humidity-change-rate - the topic of this thread :slight_smile:

I see that you are talking about enabling the fan, so I guess your use case is slightly different and the logic probably makes sense. Congrats on your discovery :wink:

I’ve been using this for a few months now and the settings seem to suit our use case, at least over the summer!

This is my sensor:

# https://community.home-assistant.io/t/automation-shower-detection-trigger-when-humidity-increases-in-10-minutes/162250/32
  - platform: statistics
    name: Bathroom Humidity Change
    unique_id: dfcf05f4-1d98-45cd-99dd-a91664024257
    entity_id: sensor.bathroomenvironment_humidity
    state_characteristic: change
    max_age:
      minutes: 3
    sampling_size: 30

I use one automation to control the switch, values set in helpers and a countdown timer, again, this seems to work well for us:

- id: '1658846877074'
  alias: Bathroom Extractor
  description: ''
  trigger:
  - platform: event
    event_type: timer.finished
    event_data:
      entity_id: timer.extractorcountdown
    id: Trigger-TimerFinished
  - platform: numeric_state
    entity_id: sensor.bathroom_humidity_change
    above: input_number.bathroomhumiditychangehigh
    id: Trigger_HumidityUp
  - platform: numeric_state
    entity_id: sensor.bathroom_humidity_change
    below: input_number.bathroomhumiditychangelow
    id: Trigger_HumidityDown
  condition: []
  action:
  - choose:
    - conditions:
      - condition: trigger
        id: Trigger-TimerFinished
      sequence:
      - type: turn_off
        device_id: fd9afcc8e32d00faa76950ffc521b51d
        entity_id: switch.extractor_fan
        domain: switch
    - conditions:
      - condition: trigger
        id: Trigger_HumidityDown
      sequence:
      - type: turn_off
        device_id: fd9afcc8e32d00faa76950ffc521b51d
        entity_id: switch.extractor_fan
        domain: switch
    - conditions:
      - condition: trigger
        id: Trigger_HumidityUp
      - condition: state
        entity_id: input_boolean.holiday
        state: 'off'
      sequence:
      - type: turn_on
        device_id: fd9afcc8e32d00faa76950ffc521b51d
        entity_id: switch.extractor_fan
        domain: switch
      - service: timer.start
        data: {}
        target:
          entity_id: timer.extractorcountdown
      - if:
        - condition: time
          after: '22:00:00'
          before: input_datetime.economy7offtimelocal
        then:
        - service: input_boolean.turn_on
          data: {}
          target:
            entity_id: input_boolean.wettowel
    default: []
  mode: single

Chris

I’m using the following template sensors based on the above information:

In my sensor.yaml file:

# Records Last 3 Mins of Bathroom Humidity
- platform: statistics
  name: Bathroom Humidity Stats
  entity_id: sensor.bathroom_humidity_sensor_2
  state_characteristic: change
  sampling_size: 30
  max_age:
    minutes: 3

In my template.yaml file:

# Showering
- binary_sensor:
  - name: "Showering"
    unique_id: binary_sensor.showering
    icon: 'mdi:shower-head'
    device_class: occupancy
    state: >
      {{ states('sensor.bathroom_humidity_sensor_2') | int(0) >
         states('sensor.bathroom_humidity_stats') | int(0) + 5 and
         states('sensor.bathroom_humidity_stats') != "unknown" }}

I currently have a couple of issues with this code:

  1. Whenever I restart Home Assistant the binary sensor is turned on with a message of: ‘Detected triggered by state of Bathroom Humidity Stats changed to 0.0’; and

  2. For some reason, when the statistics sensor had a value of -4.0 it turned on the binary sensor with the message of ‘Detected triggered by state of Bathroom Humidity Stats changed to -4.0’

Is anyone able to provide any assistance?

Thanks for your help.

EDIT: I think I need to remove the ‘state_characteristic: change’ section of the statistics sensor.

Hey!

First of all, let me suggest to switch to a packages based setup: https://www.home-assistant.io/docs/configuration/packages/

homeassistant:
  packages: !include_dir_named packages

I don’t know why this isn’t made a default for new users.


Furthermore, I’m not saying the binary sensor is a bad idea (I also like to have “flags” to indicate e.g. showering) but with an automations based approach you would be a lot more empowered to troubleshoot the issues you are seeing. It is certainly better for learning and more scalable, you should consider it.

EDIT: I think I need to remove the ‘state_characteristic: change’ section of the statistics sensor.

No I don’t think so. I think your state logic is wrong. But that really depends on your use case. What are you trying to accomplish?
Your state template says “humidity > (humidity_change+5)” which doesn’t make sense.

If your wish is to detect showering, you want to either trigger on high humidity. To detect the end of the shower, you can also just look at the absolute humidity. Imho no statistics sensor needed. The tricky part for me was to decide when to turn on and off a ventilation fan. That is where a statistics sensor with the “change” characteristic was invaluable. Have a look at my automations again

Thanks for this. I’ll look into packages!

I think I did need to change the state_characteristic as this would then default to mean. This way the state logic would be better as it would be comparing an absolute measure of humidity (average over the last hour) against an absolute measure of humidity (current humidity). However, I’ve gone back to using the ‘change’ state_characteristic and updated the template binary sensor to:

# Showering
- binary_sensor:
  - name: "Showering"
    unique_id: binary_sensor.showering
    icon: 'mdi:shower-head'
    device_class: occupancy
    state: >
      {{ states('sensor.bathroom_humidity_stats') | int(0) > 5
         and states('sensor.bathroom_humidity_stats') != "unknown"
         and is_state('input_boolean.bathroom_occupancy', 'on')
          }}

I was originally using an automation based approach in NodeRed - using absolute humidity states - that also triggered a counter in Home Assistant. However, I liked the idea of not using absolute humidity values, as these often struggled to pick up different showers within a relatively small space of time, which is why the template sensor relying on change in humidity appealed to me.

I’ll see how this goes!

Hi Thom. Do you mind to share your automation:

  • Turn the fan on when humidity exceeds 70%

Fiddling around with it for some time now based on your “Switch fan to OFF” but can not find a sweet spot.

Thank you in advance.

Hey there, not sure what you are struggling with as this automation is rather simple. Should be something like this:

  - trigger:
      - platform: numeric_state
        entity_id: sensor.bad_raumsensor_bme280_humidity
        above: 70
    action:
      - service: switch.turn_on
        entity_id: switch.bad_luftung

Thank you for your reply.

I am using a similar automation. However, the bathroom exhaust fans seem to switch ON/OFF kind of uncontrolled.

Since I live in a tropical country with a fast changing average humidity between 72% - 79% I may have to work on the sensor (max_age & sampling_size) to get this working correctly.

I just use % humidity above 57%, if that happens I want the fan to start. At least where I live that works well. I have 2 bathrooms, both with the same ventilation fan (house fan) so I check the triggering sensor to set the fan back to medium speed. If the sensor does not come down to below 53% after 1h 30m then set to medium speed anyway (that never happens).

alias: House Ventilation Fan Automasjon
description: Turn on ventilation fan to max when someone is in the shower
trigger:
  - type: humidity
    platform: device
    device_id: 3d2eb894b7e477272c3ba089e22c8348
    entity_id: b363171b2d3789ea19c6df9990153ebb
    domain: sensor
    above: 57
    id: moist-1
  - type: humidity
    platform: device
    device_id: ee22b3674c83e100c9f03ef1be8b6f1d
    entity_id: 34e6631b03658e2e75091a730d80f5b2
    domain: sensor
    above: 57
    id: moist-u
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - moist-1
        sequence:
          - service: fan.set_percentage
            metadata: {}
            data:
              percentage: 100
            target:
              entity_id: fan.house_vent_fan
          - wait_for_trigger:
              - type: humidity
                platform: device
                device_id: 3d2eb894b7e477272c3ba089e22c8348
                entity_id: b363171b2d3789ea19c6df9990153ebb
                domain: sensor
                below: 53
            continue_on_timeout: true
            timeout:
              hours: 1
              minutes: 30
              seconds: 0
              milliseconds: 0
          - service: fan.set_percentage
            metadata: {}
            data:
              percentage: 66
            target:
              entity_id: fan.house_vent_fan
      - conditions:
          - condition: trigger
            id:
              - moist-u
        sequence:
          - service: fan.set_percentage
            metadata: {}
            data:
              percentage: 100
            target:
              entity_id: fan.house_vent_fan
          - wait_for_trigger:
              - type: humidity
                platform: device
                device_id: ee22b3674c83e100c9f03ef1be8b6f1d
                entity_id: 34e6631b03658e2e75091a730d80f5b2
                domain: sensor
                below: 53
            continue_on_timeout: true
            timeout:
              hours: 1
              minutes: 30
              seconds: 0
              milliseconds: 0
          - service: fan.set_percentage
            metadata: {}
            data:
              percentage: 66
            target:
              entity_id: fan.house_vent_fan
mode: single

Hey corvy,
that you can always do. It’s the easy approach which should be good enough for most use cases.
What I found is that your relative humidity change via a fan depends on the outside humidity (air intake). Therefore, a simple trigger by relative humidity % will switch the ventilation on too early or off too late.

My approach using humidity change automation from above worked pretty well in an apartment bathroom.

In another use case of mine to ventilate a basement room, I went with something that is commonly refered to as “dew point ventilation”.

Yeah I see that and I guess this could also be done in my use case. I can see that the sensor moves at least 5% when someone showers, unless many shower in a row.

I will give this a closer look into my use-case.