Home Assistant

2021, Aug 18

All of this started when I tried to get my Nest Thermostat connected to my Home Assistant so my lazy butt could control the temperature from the comfort of my couch. This post won't go into setting up the Nest Thermostat, since the existing guide is pretty good, but it will go into setting up Home Assistant to be accessible from an external URL, which is a requirement for the Nest integration.

For starters, my internals are;

  • HomeHub 3000
  • HASSIO on a virtual box on OSX
  • Google Domains (Not DuckDNS).
  • LetsEcrypt in HA
  • NGINX

The biggest issue with this environment is two folds. One, I use Bell's HomeHub 3000, and this hub is known to be very restrictive in many aspects. The second point is that I do not have a static IP, since Canadian ISPs do not provide a static IP unless I pay for an enterprise package (Ha!)

What I learned when setting this up;

  • It is possible to set up a cronjob to update my google domain with my updated external IP. This bypasses the need of a static IP

    • crontab -e opens up the cron jobs for the machine
    • */60 * * * * ~/scripts/DNS.sh > ~/scripts/cronjobs.log 2>&1 will set a job to run the script and log the files

      externalIp=$(dig +short myip.opendns.com @resolver1.opendns.com)
      username=<Google DNS>
      password=<PWD>
      echo url="https://$username:[email protected]/nic/update?hostname=<domain>&myip=$externalIp" | curl -k -o ./response.log -K -
  • HomeHub 3000 does not allow for NAT loopback. This means that once I set up the external URL, I could not test it from my internal network. The router could not resolve the address. The only way I figured out it was working after hours of time wasted, I had a friend tell me it was working. I eventually set up a VPN to manage my future testing (How ridiculous.)
  • I used NGINX as an SSL proxy to bypass the problem with the HomeHub 3000 not allowing NAT loopback. To get this working I had to do the following

    • Forwarded the ports 443 and 80 to my homehub server
    • Forwarded the external port to the homehub server (I did not want the domain to access directly the server. If you wanted to do that you'd set up the HTTPS port e.g. 443 to the homehub port 8123)
    • Configure configuration.yaml to the following:

      http:
      ssl_certificate: /ssl/fullchain.pem
      ssl_key: /ssl/privkey.pem
      use_x_forwarded_for: true
      trusted_proxies:
      - 172.30.32.0/24

      Note: This configuration took a long time because the documentation said that http: didn't need ssl_certificate or ssl_key and that the NGINX configuration would handle it. However I kept encountering this error when I tried to run it following the instructions and had to brute-force the configuration to make it work

      Traceback (most recent call last):
      File "/usr/local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 314, in data_received
      messages, upgraded, tail = self._request_parser.feed_data(data)
      File "aiohttp/_http_parser.pyx", line 546, in aiohttp._http_parser.HttpParser.feed_data
      aiohttp.http_exceptions.BadStatusLine: 400, message="Bad status line 'invalid HTTP method'"
      Traceback (most recent call last):
      File "/usr/local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 314, in data_received
      messages, upgraded, tail = self._request_parser.feed_data(data)
      File "aiohttp/_http_parser.pyx", line 546, in aiohttp._http_parser.HttpParser.feed_data
      aiohttp.http_exceptions.BadStatusLine: 400, message="Bad status line 'invalid HTTP method'"
  • With NGINX working properly, this is the expected behaviour:

    • Internal network:

      • http://<internalIPAddress\> or http://homeasssistant.local does not work. It will say, This page isn't working ERREMPTYRESPONSE
      • http**s**://<internalIPAddress\> or http**s**://homeasssistant.local will give you a Not Secure site. You can ignore and proceed
      • http(s)://<domain:port> will not work
    • External network:

      • http://<domain:port\> should not work, but http**s**://<domain:port\> works
      • Internal address should work as if in the internal network
  • homeassistant.local vs \<internalIPAddress\> are different for home assistant. With the later, plugins will not work when SSL is configured. It will give a 401 Unauthorized error. I stumbled across the internal hostname address and it suddenly worked (more hours wasted)