Automating the bathroom window
Our bathroom gets humid really fast after taking a shower and stays that way for some time. We open the window to let the steam out, but then we have to go to work and would have to keep the window open. That’s not a problem in spring or fall, but gets too hot or too cold in summer and winter.
Finding a solution
Then I started looking into automatic window openers, and found a cheap one on Amazon:
https://www.amazon.de/gp/product/B075F29YRT
These openers work by extending a chain that is connected to the window:
It can be controlled with two relays: one to open the window and one to close it. I’m using a Shelly 2PM, which is essentially an ESP8266 with two relays and energy monitoring built inside.
The wiring is quite simple, but if you are not sure what you are doing, make sure to call an electrician.
This is how the window opener looks when it is installed:
Flashing it
For the firmware, I chose to go with the preinstalled firmware from Shelly. So no flashing this time! They have an integration for Home Assistant,
and I only had to set the device as a cover
device to make it work correctly with the two relays. It even has an option
to automatically stop the relays if it detects the endstops of the motor triggered by measuring the power draw. This unfortunately did
not work for me, which is why I chose to use the manual timing options. Configuring one of those options allows you to set
an opening percentage if you need it.
Controlling it
Besides a button to open and close the window manually, I wanted to open the window automatically after taking a shower and closing it when the humidity is back to normal. I have done this with a humidity sensor and a derivative sensor.
The derivative sensor shows the change rate of the bathroom humidity and its curve looks like this:
In this diagram, you can clearly see that I took a shower at around 7 AM, where the humidity went up at a rate of two percent.
We can use this as a trigger to open the window: If the change rate is above two percent, open the window. When the humidity is below 60 percent, I close the window again.
You might need to use different values than me, but you can use my configuration as a starting point and tinker from there:
Extending it
I also have a smart thermostat, and combined with the smart window, the temperature levels are now fully automated in the bathroom and I have one less room to worry about.
Using Tailscale to access Home Assistant from everywhere
When you start using Home Assistant, you’ll quickly find yourself wanting to access it from everywhere, not just from your couch while being connected to the home wifi.
There are many ways to achieve this, but the easiest is problably the Home Assistant Cloud integration. They offer a subscription based service that also allows you to easily integrate Amazon Alexa and Google Assistant.
But the great thing about Home Assistant is that they allow you to do things more than one way, and there are actually even more ways to open your Home Assistant instance to the internet. I’ll just briefly mention that you can open a port on your router and use a service like DuckDNS to give you a URL to access Home Assistant, but this is hard to make right regarding security and is sometimes even impossible if your ISP only issues IP v6 addresses or has a double NAT setup. If you’ve never heard of these things, be prepared for a long journey - or use Home Assistant Cloud or the Tailscale method this post is about.
If you chose this method and don’t need the other features Home Assistant Cloud offers, consider subscribing anyway! By subscribing, you help fund the development of Home Assistant.
What is Tailscale
Their headline says “Tailscale makes networking easy”. And that’s not an understatement. If you’ve worked with router configurations, VPNs, secret keys, SSL certificates and all those things before, you’ll appreciate how easy and fast it is to connect devices and services using Tailscale.
The core feature of Tailscale is a VPN, where you can connect devices without actually having to do all the networking normally required. If you’ve never heard of Tailscale before, I recommend reading What is Tailscale? from their documentation. If, after reading this article, you decide that you want to use Tailscale, you can read their Quickstart guide which leads you through creating an account and adding a machine to it.
Here is a Screenshot of my tailnet:
From now on, I’ll assume that you have a Tailscale account with your computer connected to your tailnet (their name for the VPN all your devices are in).
A newer feature of Tailscale is Tailscale Funnel, which allows you to access a service from your tailnet via the public internet. This is what we’ll use to make Home Assistant accessible from the internet.
What to expect
We’ll setup Home Assistant to join your tailnet, configure Tailscale, and then make Home Assistant available on a URL that looks like this: https://homeassistant.yak-bebop.ts.net
.
Configuring Tailscale
We’ll need to change some things in the Tailscale admin console. First, you’ll have to enable HTTPS support, which you can do by following their guide Enabling HTTPS. Next, we will enable Tailscale Funnel. For this, follow their guide Tailscale Funnel on how to edit the tailnet policy file. For me, it was as simple as pressing a button on the right side of the code editor there, but editing the file by hand is not much harder.
That’s it already for this part.
Adding Home Assistant to your tailnet
Start by opening the addon store and install the Tailscale addon.
After installing, go to configuration, click on the three dots in the top right corner and edit as YAML. There, you can paste this config:
funnel: true
proxy: true
userspace_networking: false
Click save, then start the addon. Open the web ui of the Tailscale addon and authenticate.
Congratulations, your Home Assistant instance is now part of your tailnet and available from the internet.
Check the logs for an entry that looks like this to find out the address:
[20:51:32] INFO: Tailscale Funnel is enabled:
[20:51:32] INFO: Your Home Assistant instance is publicly available on the internet at
[20:51:32] INFO: https://homeassistant.yak-bebop.ts.net
You can now connect to Home Assistant from everywhere:
Wrapping up
We now have an easy and secure way to connect to a Home Assistant instance via the internet “without fiddling with router settings or ssl certificates” (although still more steps than Home Assistant Cloud).
You can also configure the Tailscale addon to act as an exit node, which enables you to access other devices on the same network that are not part of the tailnet via any machine connected to the tailnet. Check out the addon documentation for more info on that.
From Image to JSON: How to Automatically Convert Meal Plans with Python, OpenCV, and Tesseract
DIY Ambilight with HDMI 2.1 support
Save songs from radio to a Spotify playlist
Let Alexa welcome you home
Save and restore light states using Home Assistant
Alexa connected to an audio receiver (with Home Assistant)
Monitor remaining water bottles with ESPHome and Home Assistant
After we ran out of sparkling water twice in a row, I decided to do something against that. The plan is to receive a notification when there are only three bottles left:
Out of water! There are only 3 bottles of water left. You should get some new ones!
Ideas
I need a way to sense how many bottles are left. Here are some ideas I had:
- put a light sensor under each bottle in the box
- put a scale under the crate
- use a camera and a neural network to do some object detection
I don’t know enough about neural networks and object detection, but I think this would be rather complicated and over-engineered for what I want to achieve. It may be really hard to distinguish full bottles of water from empty ones, even if I lift them slightly to check if they are full or empty. It could work for colored beverages though.
Using light sensors for each bottle is still an idea I want to check out in the future, as this solves the weight problem I’ll go into in the next section.
Why weighing the bottles may not work for you
Before we begin weighing bottles, this approach probably only works for a few plastic bottles. I put a scale under the bottles and weight them (I normalized the result by subtracting the weight of the crate). With the result, let’s call it W, we can calculate the number of bottles like this:
Those brackets mean “round the result down”. I measured that one full bottle weighs 1070g, and one crate holds 12 bottles, so the maximum weight is 12840g.
For my example, we will get the right result every time, because if all bottles are empty, the whole crate weighs 70g × 12 = 840g which is equal to zero bottles. Here is the problem: If you have glass bottles, and probably a crate of 24 bottles, this approach won’t work for you. Let’s assume an empty glass bottle weighs *200g. *The drink itself weighs 330g for a 0,33l bottle. Then, our formula would be:
For W = 1795g, this can either be 3 full and 1 empty bottle (1790g) or 9 empty bottles (1800g). As the scale doesn’t return exact values and not every bottle weighs the same, it is impossible to tell these cases apart. If you have an idea of how to solve this, please leave a comment below.
Now we learned that weighting the bottles will only work if:
Put a scale under the crate
I decided to make the scale myself and use a cheap HX711 module from a Chinese supplier. Check out this instructables to see how to wire them up.
I’ll use ESPHome to program a WeMOS D1 Mini which is connected to the HX711.
esphome:
name: water_bottles
platform: ESP8266
board: d1_mini
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
api:
ota:
logger:
sensor:
- platform: hx711
name: "water_bottles_weight"
id: water_bottles_weight
dout_pin: D2
clk_pin: D1
gain: 128
update_interval: 60s
filters:
- lambda: |-
auto first_mass = 0.0; // first known mass was 0kg
auto first_value = 25136; // value for the first known mass was
auto second_mass = 12840; // second mass was
auto second_value = 24568; // second value was
auto r = map(x/1000, first_value, second_value, first_mass, second_mass);
if (r > 0) return r;
return 0;
unit_of_measurement: g
- platform: template
name: "water_bottles_count"
lambda: |-
return floor(id(water_bottles_weight).state / 1000);
update_interval: 60s
Above, you see the code on how I programmed the scale. It sends the weight and the count to home assistant, where you only need to go to Config > Integrations > ESPHome (Add) and enter water_bottles.local
. To get started with ESPHome, check out the documentation.
Now, you can add automations as desired. My automation reminds me to buy new water if there are fewer than 4 bottles left.
Do you have an alternative idea to achieve this? Toot me on Mastodon and tell me about it.