One thing that is REALLY handy to know for automating your home is if anyone or everyone is in bed. Based on this information you can turn off lights, decrease the thermostat temperature or close the window covers. Also you can turn on the lights at night if somebody gets up, probably because he wants to use the bathroom. Or if you have automatic windows, you can open them after everybody got up in order to air your room. Also think of arming your alarm system. There are endless possibilities.
Therefore I searched for a reliable and cheap solution in order to detect bed occupancy. There have been several cool approaches using load cells or strain gauges but since I had some very cheap ultrasonic sensors laying around, I decided to try using them. The idea was to attach the sensor to the slatted frame of the bed pointing downwards to the floor. So whenever somebody lays into bed the frames would bend and the distance between the frame and the floor would decrease. With some simple sensors in Home Assistant I would then be able to detect if the bed is occupied or not. I attached the ultrasonic sensor to a Wemos D1 Mini, hacked some yaml for ESPhome and gave it a try. And here is the result of the measured distance values:
actually I wanted to add an image here but since I’m a new user I can only post one image
As you can see, the tracking is very good. If I’m not in bed, the distance to the floor is about 25 cm and if I’m in bed a little less than 23 cm.
Here you can see the binary sensor that tracks the occupancy state based on the ultrasonic sensor state.
I’ve been using this solution for more than three months now and it is really very reliable. I also built a second one for my wife’s side of the bed and this also works like a charm even though she is much more lightweight than me
In a second step I also added a BME280 sensor (temperature, air pressure, humidity) to the board in order to track these values as well. Currently I don’t do any automations based on them.
Here is my yaml file:
esphomeyaml:
name: bed_husband
platform: ESP8266
board: d1_mini
wifi:
ssid: 'top'
password: 'secret'
mqtt:
broker: '192.168.x.x'
username: 'top'
password: 'secret'
i2c:
sda: D2
scl: D1
# Enable logging
logger:
ota:
sensor:
- platform: ultrasonic
trigger_pin: D7
echo_pin: D8
name: "Ultrasonic Sensor Bed Husband"
update_interval: 2s
accuracy_decimals: 5
filters:
- filter_nan:
- sliding_window_moving_average:
window_size: 20
send_every: 4
- lambda: if(x > 0.18) return x;
- platform: bme280
temperature:
name: "Temperature Bedroom"
pressure:
name: "Air Pressure Bedroom"
humidity:
name: "Humidity Bedroom"
address: 0x76
update_interval: 240s
Note that I calculate a sliding average of the measured distance values in order to eliminate noise. Also I send the distance data very frequently, because I want my automations to trigger instantaneously if I need them to (e.g. switching on the light in the corridor if I get up at night).
And here is my binary_sensor:
binary_sensor:
- platform: template
sensors:
husband_in_bed:
value_template: >-
{{ states('sensor.ultrasonic_sensor_bed_husband')|float < 0.24 and states('sensor.ultrasonic_sensor_bed_husband')|float > 0.18 }}
friendly_name: 'Husband is napping'
A few remarks at the end:
- if you want to implement this, consider things that could potentially get under your bed and trigger false positives. For me this is my vacuum cleaner robot, so I only trigger actions (like turning on the lights) if the robot is docked.
- this might not work if you have carpet under your bed, since the ultrasonic signal has to be reflected by a solid surface in order for the sensor to work reliably.
- if you are very sensitive, you MIGHT hear the ultrasonic which might influence your sleep. For my wife and me this is not an issue.
I’m curious what you think of this project and if you have any ideas for improvements or cool automations!