Can anyone help me to set up an automation trigger when humidity increases (say 10%) within 10 minutes?
My goal is to switch on a bathroom fan when this happens (shower detection).
Can anyone help me to set up an automation trigger when humidity increases (say 10%) within 10 minutes?
My goal is to switch on a bathroom fan when this happens (shower detection).
I’ve got Xiaomi humidity sensors that I use to detect shower occupancy in two bathrooms. I use the trend sensor to detect the rate of change, and the rate of humidity change tells me if the shower is occupied or not. I use the trend sensors to switch on the bathroom fan, plus I’ve got the lights tied to motion detectors, and I don’t want those lights going off if somebody is in the shower.
Here are the docs for how the trend sensor works:
You’ll probably need to tweak the sample duration and the min_gradient to get things dialed in for your particular instance. I’ve included my trend sensor configuration below, so you can see an example for your use case. The code below lives in my configuration.yaml
file.
binary_sensor:
# Tracks 3 humidity readings over 10 minutes. If the change is greater than 10%, evals to true. (10/(60*10))
- platform: trend
sensors:
master_bath_shower_occupancy:
max_samples: 3
entity_id: sensor.xiaomi_master_bath_humidity
sample_duration: 600
min_gradient: 0.01666
# Tracks 2 humidity readings over 5 minutes. If the change decrease is greater than 5%, evals to true. (-5/(60*5))
# Bumped samples down from 4 to 2, because it was staying on way too long.
- platform: trend
sensors:
master_bath_shower_occupancy_off:
max_samples: 2
entity_id: sensor.xiaomi_master_bath_humidity
sample_duration: 300
min_gradient: -0.016666
# Tracks 4 humidity readings over 5 minutes. If the change is greater than 10%, evals to true. (10/(60*5))
# Guest bath trends spike faster because it's a smaller room.
- platform: trend
sensors:
guest_bath_shower_occupancy:
max_samples: 4
entity_id: sensor.guest_bathroom_humidity
sample_duration: 300
min_gradient: 0.033333
# Tracks 4 humidity readings over 5 minutes. If the change decrease is greater than 5%, evals to true. (-5/(60*5))
- platform: trend
sensors:
guest_bath_shower_occupancy_off:
max_samples: 4
entity_id: sensor.guest_bathroom_humidity
sample_duration: 300
min_gradient: -0.016666
I went back and looked at my automation, and I’m only using that trend sensor for the lights.
It turns out I handled fan automation a different way, but either method should work.
For kicking on the bathroom fan, I measured humidity in the bathroom, and in the room adjacent to the bathroom, and when the difference between those two rooms is greater than 5%, I kick on the fan. (I initially tried to tie the fan to a single humidity sensor, but since i live in a rainforest, the humidity hits 100% on occassion)
You can create a template sensor that compares the two humidity readings. Here’s the sensor creation from my sensors.yaml
- platform: template
sensors:
bath_humidity_change:
friendly_name: "Bathroom Humidity Change"
value_template: "{{ (states.sensor.xiaomi_master_bath_humidity.state | int ) - (states.sensor.zb_bedroom_humidity.state | int)}}"
device_class: "humidity"
unit_of_measurement: '%'
Here’s the automation that actually kicks on the fan from my automations.yaml
alias: Bathroom fan kicks on above 10% humidity difference
trigger:
- above: '10'
entity_id: sensor.bath_humidity_change
platform: numeric_state
condition:
- condition: state
entity_id: switch.zw_bathroom_fan
state: 'off'
- after: 06:00:00
before: '21:00:00'
condition: time
action:
- data:
entity_id: switch.zw_bathroom_fan
service: switch.turn_on```
@RyanRayNeff Thank you for responding and providing me with enough info to get things done!
Appreciated!
Anyone knows how to add this as a MQTT-binary sensor?
I get an error message saying the MQTT device: extra keys not allowed @ data['sensors']
I use Node Red trying to the sensor included with a function node with this payload:
var _payload = {
"name": "Mqtt ShowerDectectIncrease",
"unique_id": "mqtt_showerdectincr",
"state_topic": _topic + "/state",
"platform": "trend",
"sensors": {
"bath_humidity_increase": {
"max_samples": 3,
// My Bathroom Humidity sensor
"entity_id": "sensor.badkamer_badk_sens_vocht",
"sample_duration": 600,
// Calculation formula:
// (INCREASE_IN_%(60*MINUTES))
"min_gradient": 0.0166
}
},
"device": {
"name": "Mqtt ShowerDectectIncrease",
"manufacturer": "MQTT Hass.io",
"model": "Custom",
"identifiers": ["Mqtt ShowerDectectIncrease"],
"sw_version": "20200112"
}
};
Anyone have a clue how to get this done? Do I do something wrong in my configured payload?
EDIT: Made a separate topic to achieve this:
For the ones that still looking for an answer with just 1 humidity sensor. I have the following that is working consistently for the past weeks.
In configuration:
sensor:
- platform: statistics
name: Bathroom Humidity Stats
entity_id: sensor.your_bathroom_humidity_sensor
sampling_size: 40
max_age:
hours: 1
binary_sensor:
- platform: template
sensors:
showering:
value_template: “{{ states(‘sensor.your_bathroom_humidity_sensor’) | int > states(‘sensor.bathroom_humidity_stats’) | int and states(‘sensor.bathroom_humidity_stats’) != ‘unknown’ }}”
friendly_name: Showering
device_class: occupancy
Now we can know if someone is showering by checking if the current humidity percentage is higher than the average of the past hour, if so, you’re probably showering. Only thing we need to do now, is turn the ventilator on/off when showering is on/off:
- alias: '[Ventilator] Turn on/off ventilator if someone is taking a shower'
trigger:
- platform: state
entity_id: binary_sensor.showering
action:
- choose:
- conditions:
- condition: state
entity_id: binary_sensor.showering
state: 'on'
sequence:
- service: switch.turn_on
data:
entity_id:
- switch.your_bathroom_ventilator
- conditions:
- condition: state
entity_id: binary_sensor.showering
state: 'off'
sequence:
- service: switch.turn_off
data:
entity_id:
- switch.your_bathroom_ventilator
Edit: updated with better coding standards.
Hi Peter, thanks for that, it’s just what I was looking for. I’m having a problem with the binary sensor not detecting when the shower is running. My humidity sensor is sensor.ensuite_ble_humidity and the stats sensor is sensor.ensuite_bathroom_humidity_stats, which is generating correct values. This is my binary sensor:
ensuite_showering:
value_template: '{{ sensor.ensuite_ble_humidity.state | int > states.sensor.ensuite_bathroom_humidity_stats.state | int and states.sensor.ensuite_bathroom_humidity_stats.state != "unknown" }}'
friendly_name: EnSuite Shower
device_class: occupancy
I’m still getting to grips with templating, so it’s probably something obvious. The binary sensor stays off even when the humidity is greater than the stats value. I’ve tried changing the comparison to less than (<) but it still stays off. Any ideas?
Seems that you’re missing ‘states.’ in your first sensor.
Can you try this:
ensuite_showering:
value_template: '{{ states.sensor.ensuite_ble_humidity.state | int > states.sensor.ensuite_bathroom_humidity_stats.state | int and states.sensor.ensuite_bathroom_humidity_stats.state != "unknown" }}'
friendly_name: EnSuite Shower
device_class: occupancy
I thoght I had compared them, but obviously all those states confused my brain!
It’s working now, many thanks.
Pat
Wow thank you for this great sensor! this helped me a lot to do some advanced bathroom automation.
I now play a random Spotify playlist on my bathroomspeaker when i’m showering, turn on the bathroom dehumidifier and fan when i’m showering. Also the bathroom lights (that turn on with opening the door, and until now go off after 15 minutes) are prevented to go off when still showering.
And everything goes off when i leave the bathroom or Humidity is down a acceptable level.
Hi @petergerdes,
Looks like a great solution, but I’m curious about the false-positive rate of this sensor. I mean - we take the average humidity of the last hour and compare it with the current humidity.
Assuming that we calculate the average with one hour window due to the fact that a single sample is not enough (the humidity isn’t a constant through the day), so 2 samples are not equal to each other, if the latter sample is bigger than the previous - we will get a false-positive, right?
For my house these variables work best (after a trial and error period with a significant other who got annoyed ), but it might indeed not work for every bathroom. I don’t get false-positives anymore, but I would suggest to play with the variables until you have something that works perfectly for your bathroom
thank you for pointing me in the right direction in getting my fan to turn on when humidity is detected!
I’ve got a problem with false triggers though. just a question about the bathroom humidity stat- if i increase the max age of the sample to say 2 hours, do i need to double the sample size?
I would double the sample size as well.
I have just started using these sensors and automations to control some bathroom ventilation as well. Its working pretty well but want to see if I can get the fans to run a bit less.
Is it possible, in the binary sensor value template to add some maths so that it turns on at 5-10% above average humidity level? My templating skills are non existent, any help would be much appreciated.
Would it just be:
value_template: '{{ sensor.your_bathroom_humidity_sensor.state | int > states.sensor.bathroom_humidity_stats.state | int +5 and states.sensor.bathroom_humidity_stats.state != "unknown" }}'
or is that too easy?
That’s the way it should work indeed!
Maybe this is a bit more safe:
value_template: '{{ sensor.your_bathroom_humidity_sensor.state | int > (states.sensor.bathroom_humidity_stats.state | int + 5) and states.sensor.bathroom_humidity_stats.state != "unknown" }}'
See the warning box here:
Use states("sensor.your_bathroom_humidity_sensor")
. So:
value_template: >-
{{ states("sensor.your_bathroom_humidity_sensor")|int >
states("sensor.bathroom_humidity_stats")|int + 5 and
states("sensor.bathroom_humidity_stats") != "unknown" }}
Note that this looks for a 5 percentage point increase, so if the average is 95%+, it’ll never trigger.
To throw another way to accomplish this out there. I use the Average Sensor (available via HACS [also here: GitHub - Limych/ha-average: Average Sensor for Home Assistant]).
- platform: average
name: Master Bathroom Humidity Average
duration:
days: 1
entities:
- sensor.master_bathroom_sensor_relative_humidity_measurement
I then created an input_number which saves a threshold. This is used so I can easily update this threshold without having to restart HA.
master_bath_humidity_threshold:
name: Master Bath Humidity Threshold
min: 0
max: 20
initial: 9
mode: box
step: 1
I use a binary_sensor to check if the current humidity minus the average humidity is greater than the input_number threshold.
master_bath_fan_sb:
friendly_name: Master Fan S/B Status
value_template: "{{ (states('sensor.master_bathroom_sensor_relative_humidity_measurement')|int - states('sensor.master_bathroom_humidity_average')|int) > states('input_number.master_bath_humidity_threshold')|int }}"
This automation then works to turn the fan on/off based on the value of the binary_sensor changing.
- id: '1555779101294'
alias: Master Bath Fan - TOGGLE
trigger:
- entity_id: binary_sensor.master_bath_fan_sb
for: 00:00:30
platform: state
condition: []
action:
- data:
entity_id: switch.master_bath_fan
service_template: switch.turn_{{trigger.to_state.state}}
Really all you need is the average sensor and the automation - I just use the input_number to allow me to change the ‘test’ without restarting / editing the automation. Same with the binary_sensor - this could be done in the automation itself with a trigger template and/or by breaking into two automations. Anyhow, more than one way to skin a cat, as always, with HA.
trying to follow along and the binary sensor is throwing errors in the confog. Would you be able to share more of your config around the binary sensor?
You most likely have incorrect formatting. Just post the error instead.