Making a shower sensor

by 3D printing a stand for the Aqara Water Leak Sensor
10 December 2024
Home automation
3D printing

A niche problem

The lights in my bathroom are automated; they’re toggled on and off via a motion sensor. They’ll come on immediately when motion is detected, and will go off after 4 minutes of no motion. This timeout decreases to 1 minute during the night. Here’s the high-level code:

<MotionLights
    offFor={isSleepyTime() ? ONE_MINUTE : ONE_MINUTE * 4}
    lightSensorId={[
      "light.upstairs_bathroom_spotlight_1",
      // ...
      "light.upstairs_bathroom_spotlight_6",
    ]}
    luxSensorId="sensor.upstairs_bathroom_motion_sensor_illuminance_lux"
    luxThreshold={100}
    motionSensorId={"binary_sensor.upstairs_bathroom_motion_sensor_occupancy"}
/>

(See the TypedAssistant addon for Home Assistant for more info on writing home automations in TypeScript/React.)

This automation works great 99% of the time. However, it fails when you’re in the shower and out of sight of the motion sensor. You are suddenly plunged into darkness. The immediate solution is sticking a leg out the shower door to get the attention of the motion sensor.

And if you’re the kind of person to say this could be solved by using the light switch, this blog is not for you. We like to create problems for ourselves around here.

The intermediate solution

We need a way to detect when the shower is running. I once experimented with a humidity sensor for this. If the humidity climbs above a certain threshold—say 90%—we can safely assume the shower is on and creating all that moisture. The issue with this setup is that it’s pretty inconsistent. Humidity levels in the room can take time to rise, and they’re easily thrown off by an open window or shower door.

My next thought would be sensing the presence of water itself. I already had an Aqara Water Leak Sensor lying around and figured that would be worth a try. Lets throw one in the shower tray and update our code:

<MotionLights
    // ...
    preventLightTurnOff={(entities) =>
      entities["binary_sensor.upstairs_bathroom_shower_sensor_water_leak"]
        ?.state === "on"
    }
/>

This works a treat.

When I’m in the shower, a layer of water accumulates in the shower tray and triggers the sensor. And so, the light turns on with motion and stays on with water.

However, I noticed that long after I get out the shower, the lights stay on. I’d wake up in the night and wonder why the ensuite was still lit up. After checking Home Assistant, I could see the sensor was in the “wet” state for 9+ hours after the shower had stopped.

A diagram of how water beads under the sensor, forcing it to remain in the “wet” state.
A diagram of how water beads under the sensor, forcing it to remain in the “wet” state.

After the shower has stopped, most of the water runs freely down the drain. However, since the sensor has a small gap under the electrodes that detect the water, we get water beading up and staying there under tension. We need a way to lift those electrodes up a little higher, so water doesn’t have an opportunity to bead up.

Enter 3D printing

I recently got myself a 3D printer, and when you have a hammer everything looks like a nail. Luckily this isn’t a hammer—it’s a 3D printer. A hammer would be of no use in this situation.

Using Fusion 360, I got to work designing thesolution:

A CAD model showing a base plate for the water leak sensor. It has 3 bolts to allow height adjustment.
A CAD model showing a base plate for the water leak sensor. It has 3 bolts to allow height adjustment.

It’s a simple design: A base plate to go under the sensor so it can be lifted, along with 3 legs in the form of bolts, which allow the height to be adjusted. The trick with the height is to get it low enough that the pool of water can reach the electrodes when the shower is running, but high enough that water can run away freely without beading up when the shower stops.

When water is running, it pools enough to touch the electrodes. When it stops running, water is able to flow freely away.
When water is running, it pools enough to touch the electrodes. When it stops running, water is able to flow freely away.

I printed a few iterations of these, but the first one—with a very narrow base and low surface area—turned out to be the best. Wider bases caused water to get trapped between the base and the sensor, which kept the sensor stuck in the “wet” state.

Now, when I turn the shower on, the sensor switches to “wet” within a few seconds, just like before. The difference now is that when the shower is off, the sensor flips back to “dry” in 5-30 seconds—a huge improvement over the hours it used to take.

The final product
The final product

The print files are available for download on Maker World. I’ve got a few ideas for improvements, like adding small tabs around the rim to keep the sensor centred. That said, the current stands work great, and I don’t want to create unnecessary waste. Let me know on Bluesky if you make any improvements, I’d love to see them.