Personal Setup: VPS, VPN, faster Tuya and more

Hi everyone,

I have been lurking around the forums for a while now, but after completing (most of) my setup today, I figured it was time to give back and finally made an account.

It’s been a while since I wrote a post so it might be a bit messy, but I’ll do my best to keep everything as clear as possible.

Alright, so let’s start with an outline and some of the “unique” features/solutions of my configuration:

  1. Introduction to my situation (devices etc.) and solutions before switching to Home Assistant
  2. Hosted Off-Site on a Digital Ocean VPS
    a. Why, how (VPN)
    b. Experience so far
  3. Tuya Smart Lights
    a. Initial Solution
    b. Faster Solution (near-zero lag)
  4. Nefit Thermostat
  5. Google Home
  6. Tuya Motion Sensor
  7. Mystrom Button

When I got started with HA, I was a total beginner on home automation. So, I will try to make this guide as comprehensive as possible. Hopefully many more beginners will be able to host their own instance of HA, without requiring dedicated local hardware (RPi) but with the flexibility that self-hosted instances offer.


1. Introduction and history

My house has a couple of main rooms: living room, kitchen, hallway, 1st floor, bedroom.
All of these rooms are equipped with Tuya smart lights (“LSC Smart Connect” from Action).
Each room has a Google Home Mini to control the lights.
The TV is an Android TV (Sony Bravia), and the thermostat is a Bosch Nefit Easy.
The router is a TP-Link Archer C1200, which supports OpenVPN (acting as server, handy later), and is able to handle all the devices (almost 50 at this point) just fine, while sitting at 30% CPU usage.
Oven and Coffee machine are Siemens Home Control (but these are yet to be added, and frankly quite irrelevant)

Before switching to Home Assistant (HA), I used the LSC Smart Life app and controlled the lights through that and the Google Home Minis. This worked fine, had some delay but nothing major, and most importantly, had almost zero setup. I also use one of the GH Minis as an alarm clock with lights (using the routines in GH app).


2. Moving to HA

However, there was one problem, I wanted to integrate the Nefit thermostat with Google Home, which was impossible. (I tried using IFTTT but that did not work for Dutch and performance was spotty in English) Looking online I soon figured out that Nefit through Home Assistant would be a great solution. Lacking a recent Raspberry Pi, I started looking for other options, one of them being a VPS. I use DigitalOcean for my website as well and figured that their datacenters in Amsterdam would be able to offer low latency. I found a Reddit post but although it was helpful, it did not give me the exact result I wanted. So here is my quick and dirty guide to hosting HA on a VPS, but with access to the home network, and without RPi.

  1. Set up a new VPS (i.e. a new Droplet on DigitalOcean, I went with the cheapest option $5/mo, you can always scale it up if necessary), strongly recommend to use an SSH key
  2. Set up HA on Ubuntu (instructions here deprecated), since this method has been deprecated there is no official support for it anymore. If you want to go ahead anyway, there is a fork of the installer here
  3. Set up a domain and Cloudflare (plenty of tutorials out there, I hope) for the Droplet, I use a subdomain. Make Cloudflare point to the Droplet’s IP and enable the proxy (orange cloud). Also, this is the time to enable Cloudflare’s Flexible SSL to enable support for Google Assistant.
  4. Verify that HA works when using the Droplet’s IP address to access it
  5. Set up Nginx and create a reverse proxy, like so: (in /etc/nginx/sites-enables/default)
Nginx Config
# Default server configuration
#
server {
	listen 80;
	listen [::]:80;

	# SSL configuration
	#
	# listen 443 ssl default_server;
	# listen [::]:443 ssl default_server;
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# Don't use them in a production server!
	#
	# include snippets/snakeoil.conf;

	# root /var/www/html;

	# Add index.php to the list if you are using PHP
	# index index.html index.htm index.nginx-debian.html;

	# server_name xyz.abc.com;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		# try_files $uri $uri/ =404;
		proxy_pass http://127.0.0.1:8123;
		
		# WebSocket support
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
	}

	# pass PHP scripts to FastCGI server
	#
	#location ~ \.php$ {
	#	include snippets/fastcgi-php.conf;
	#
	#	# With php-fpm (or other unix sockets):
	#	fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
	#	# With php-cgi (or other tcp sockets):
	#	fastcgi_pass 127.0.0.1:9000;
	#}

	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	#
	#location ~ /\.ht {
	#	deny all;
	#}
}
  1. Then modify configuration.yaml to include the following (might not be necessary but I did it still)
http:
  base_url: xyz.abc.com
  1. Then try to access it from the (sub)domain you set up in step 3. Because of the reverse proxy it should now work. Set up an account in HA, like you normally would.

Now it’s time for the real magic, accessing your local devices (i.e. TV and Google Cast) from the VPS.

  1. Set up OpenVPN on your router (guide for the TP link)
  2. Let the VPS connect to your router, I use the following .sh files to do so:
openvpn.sh
openvpn /etc/openvpn/homevpn.ovpn
startopenvpn.sh
screen -d -m ./openvpn.sh

Now don’t forget to chmod +x [file] both files, so they are executable and make sure the homevpn.ovpn config file is present on the server (as required by openvpn.sh). Then, run the startopenvpn.sh file to start the VPN connection. You can (usually) check your router interface to see if a connection has been established. Alternatively, use ifconfig on the VPS and see if there is a OpenVPN interface.

  1. With the VPS connected to your router, it has access to all the local IPs and can control local devices. I didn’t need it but I came across this tip (setting the router to allow internet, since some routers block other subnets if internet access through VPN is disabled).

Now my experience so far has been great, it performs great and has been running for a month without any problems so far.


3. Tuya Smart Lights

With an initial setup of 21 light bulbs, switching apps is no joy. However, it was necessary to switch from the LSC Smart Connect app to the Smart Life app, the former does not work with HA. I then followed the official guide to add the lights to HA and made groups from the different lights.

With the lights in the app and controlling them as an HA group, there is a noticeable lag (because of all the requests to the Tuya server). Sometimes this can take up to 10 seconds and that’s annoying.

The solution: I figured the lag was due to some sort of overload or rate-limit from HA to Tuya, the way around this (and achieve near-zero lag) is as follows:

  1. Set up “smart” actions in the Smart Life app, two for each light bulb group (ON/OFF), these will sync to HA as scenes.
  2. Using a helper (an input_boolean) in HA (just like a light switch) we can then trigger these scenes when the switch is flipped. Additionally, a ‘dummy’ light can be created to later integrate this input_boolean with Google Home. Here is an example config:
Example Config
# Input Boolean
- id: 'xxxxx'
  alias: Thomas Scene - Manual On
  description: ''
  trigger:
  - entity_id: input_boolean.keukentafel
    from: 'off'
    platform: state
    to: 'on'
  condition: []
  action:
  - scene: scene.xxxxx #This is the scene defined in the app as "on"

# Dummy Lights
light:
  - platform: template
    lights:
      thomas_dlight:
        friendly_name: "Thomas"
        turn_on:
        turn_off:
        set_level:

These dummy lights can be set to change the input_boolean (the “helper” switch), allowing Google Home to control the dummy, making HA sent the scene update to Tuya.

Although this adds complexity, it does make turning lights on and off almost instantaneous! Which is great, especially for wifi buttons (we’ll get to that in a bit).

As part of a kitchen renovation, half the kitchen lights did not have a physical switch anymore, so having this instant light on/off functionality is great, but more on that later.

And yes, I am aware of this topic, but I did not want to mess with bulbs, so I did not use Tuya-Convert.


4. Nefit Thermostat

I used this custom component to add the thermostat to HA. Sometimes, when HA restarts, the component will fail to connect to the Bosch Cloud. There is a (somewhat hacky) fix for this, go into the custom_components directory, into the nefiteasy component, and delete the __pycache__ directory. (For me this is: /usr/share/hassio/homeassistant/custom_components/nefiteasy).


5. Google Home

Using the Cloudflare Flexible SSL, and the inherent public IP that the VPS provides, we don’t have to fiddle around with DuckDNS or Let’s Encrypt. Adding the HA server to Google Home is now as simple as following the official guide (clicking through the Google Developer portals).

After that, I exposed the following things to Google Assistant:

google_assistant:
  project_id: xxxxx
  service_account: !include SERVICE_ACCOUNT.JSON
  report_state: true
  exposed_domains:
    - climate
    - light
  entity_config:

This was good enough for me, and allowed me to add the dummy lights and the thermostat to their rooms, while keeping the individual lamps unassigned. Finally the Nefit now works great with Google Home!


6. Tuya Motion Sensor

Then I got started on the automation bit, I wanted to turn on the lights downstairs on “first light”. However, as noted in this topic, the Tuya motion sensor does not show up in HA. There are numerous work arounds, but a very practical one ended up working for me.

The first floor has a corridor that has two Tuya lightbulbs installed in a ceiling lamp. These are triggered by the motion sensor for two minutes (through an automation in the Smart Life app). Watching one of these lights, it’s possible detect first light from the lamp instead and trigger all the subsequent actions (turning on the lamps downstairs, setting thermostat etc.).


7. Mystrom Button

As I mentioned, as part of a kitchen renovation, 8 out of 16 lightbulbs in the kitchen no longer had a physical switch. For convenience, especially late at night, I wanted to add a physical wifi button to trigger these lights. To my surprise, it’s actually quite hard to find a wifi button. Most buttons are zigbee or zwave and require some sort of hub (which, because of the VPS, would complicate things). After a long search I opted for the Mystrom Button+. There has been some talk on the forums about it too. When I got it, I had some trouble setting it up through the official integration.

So, in the end I just connected it to my wifi network again (after resetting it, by pressing it for 10 seconds), and issued the following curl command, from my laptop, to make it use webhooks on each button press:

curl -d "single=post://xyz.abc.com/api/webhook/webhookid1&double=post://xyz.abc.com/api/webhook/webhookid2&long=post://xyz.abc.com/api/webhook/webhookid3&touch=post://xyz.abc.com/api/webhook/webhookid4" http://[button IP]/api/v1/device/[button MAC]

Then each of these webhooks just triggers the input_booleans created earlier (the ones that trigger the Smart Life scenes).

All in all, this means that the button-less lights now have a button that turns them on almost instantaneously.


So that was a very long post, I hope it helps others who want a similar setup, or who run into some of the same issues as I have in the past month. Feel free to ask any questions and/or give me some tips on how to improve something that I may have overlooked. I’m still a beginner myself but will try to shed my light on it.

4 Likes

Or for the same $5 a month you could use nabu casa, not have to worry about the complicated setup and the money goes to supporting home assistant development.

1 Like

Yup definitely also an option. It’s just that I prefer self-hosted. Also, correct me if I’m wrong, but does nabu casa also support local devices like my setup does? Because the lack of a local device (such as a raspberry pi) means that my only option was the OpenVPN of the router.

Well yeah, because it is connecting from a local server.

Yeah I get that, but that means that I would still need a local server, right? Anyway, this is how I set it up, the aim of the post is not to prevent people from using nabu casa, but rather to showcase some other solutions to problems that I encountered.

1 Like

The solution that @tom_l talks about is not an alternative.

Nabu Casa makes it only possible to remotely access your HA instance hosted locally. Saves time not setting up a vpn server, port forwardings etc

Thanks for sharing @tkon99, im sure some users will want to use this :slight_smile:

1 Like

Hi @tkon99,

Thank you for making the guide!

I’m trying to use your guide to setup a similar configuration on my own VPS. But i’m having trouble making the connection from Home Assistant (on my VPS) to the VPN. Do you know if there is any additional configuration needed when you’re running Home Assistant via Docker instead of directly on the VPS (which i’m not able to get running)?

Thank you for the help!

Hi,

Lots of parameters at play. After the “deprecation” of the supervised installer, I use this script now (fork of the original): https://github.com/krdesigns-com/supervised-installer
Note: this is not officially supported, so only use it if you (kind of) know what you’re doing.

I have little experience with Docker so I cannot say anything about that, other than that the supervised install (which uses docker as well), does not need additional setup to pick up the VPN. If I put the local IP of the device in Home Assistant it just works. Of course, this also depends on the router you’re using, and the local network IPs of the VPS and of your home network. You can try to ping a local device to find out if the VPN is connected properly and the (likely different) subnet is reachable.

I’d recommend going for the supervised install, and following the guide, that’s the only way I’ve done it so I can’t really help you further, but if you post some details (router model number & guide you followed for the docker install) then we can see how far we get.

Hi @tkon99,

Thank you for the fast response.

First I’m gonna try to see if i can get it working with the supervised installer you provided.

I checked if my VPN (server) is setup correctly by connection to it via a 4G connection, with this setup i can reach/ping IP adressen in my home network, so it is setup properly.

Thanks for the help!