Beginning Home Automation with Home Assistant

As a techie kind of guy, I always wanted to get into the smart home game.  That was what I told myself 10 years ago in my apartment.  An apartment is fine for home automation, but it can be a bit limiting.  Can't mess with the thermostat, replacing switches and outlets is money down the drain, investing in smart appliances was money down the drain...  So many factors leading you to only consider smart light bulbs, smart outlets and maybe some sensors or NFC tags.  To say nothing of the fact that you need to run a server.  Needless to say, I did not get into home automation then.  The technology was quite immature as well.  The good stuff was all proprietary, anyway.

Fast forward to now, and my wife asked me to get some security cameras for the outside of the house.  I could buy a few Nest cameras, wire them for power, pay Google for services, wait for Google to shut down the service, and then buy new cameras, or I could just do it myself.  Ok, I admit that Google probably isn't pulling the plug on Nest anytime soon.  That doesn't mean I want to be locked into their ecosystem any more than I have to.  That means doing it myself or going with some other vendor.  I chose to go with the DIY approach, since that would be more fun and I get to do way more stuff that way.

I started looking at Home Assistant and quickly went down the rabbit hole.  I started with installing the HA container in Kubernetes.  It was fine, but Kubernetes is a little too much complexity for something I want to be able to mess with at a low level.  I discovered the HAOS or Home Assistant Operating System, which is basically an OVA with Docker underneath.  I also had a Raspberry Pi 4 kicking around, so I decided to try that.  HAOS works fine on a Raspberry Pi 4, and I started going deeper with that.  The second part was the cameras.

For cameras, I picked up two bullet style 5MP Amcrest IP5M-B1186EW-28MM units.  They came in brown OEM boxes at Microcenter and were very reasonably priced.  Maybe that's why I can't find firmware for them on Amcrest's site.  Who knows?  So these cameras are PoE, so I bought a switch for that too.  I separated those onto their own network segment.  Now for the fun.  The point of cameras is twofold: Record stuff so that you can keep a record of it and allow you to see a feed of the camera live.  Everything else is extra.  I wanted the extra, so I downloaded Frigate, a Network Video Recorder (NVR) that does this detection.  You can even install it at the click of a button on a Raspberry Pi.  Then you can turn off the heat in your house, because things are about to heat up.  The RasPi can not handle Frigate with any sort of competency.  I set the gpu_mem in the config.txt , I used the beta Frigate full access version so I could enable the correct accelerators.  I downgraded my cameras to 1080p so the RasPi could just begin to decode it.  I turned off detection altogether and I started to realize that every business since the 90s must have been using these things.  The picture quality was awful.  If I got a live feed working, it would artifact all over the place for the 4 consecutive frames it would show me before jumping around again.  I doubt it would be any better with a TPU, more on that in a minute.  I'm repurposing that RasPi back into the BirdPi I had installed on it before, it's way more competent for that.  I have a whole lab, so I just downloaded the HAOS OVA and made a VM for it.  Frigate went in a Docker container on the same host I have my Plex container on.  It already has an Nvidia GPU passed through to it and Docker is configured with the NV runtime.  Deconding the h264 would be super quick on that.

Object detection is the new hotness when it comes to home security stuff.  You analyze frames and detect when a person, dog, cat, car, whatever, comes into view.  That takes a lot of processing power, or a purpose built chip to do it for you.  This chip is the Coral TPU.  It's by Google, and is basically a neural processing chip that does object detection really fast.  The HA community is lamenting that the USB Coral is out of stock everywhere due to the chip shortage, and they are correct.  This is what you need with a RasPi to make detection work at all.  The M.2 version was on Mouser, and they have hundreds of them for less than $50 CAD.  I had to buy a PCI-E 1x to M.2 adapter card because I was already using the M.2 slot on my Frigate host, but it was only $10 on fleabay.  Unfortunately it does not work through ESXi.  Something about the MSI-X stack being out of spec for either the Coral TPU or VMWare.  It also doesn't work with EL derivatives.  I am running CentOS 7 on my docker host, so I need to get hardware to migrate frigate to.  I'll follow that up on another post.

Setting up everything in the order you need to is really: Mosquitto, Frigate, HAOS.  Mosquitto is a small MQ broker that everything can share.  That was easily done:

Create data dirs. Make initial config file.

condata=<container data dir>
mkdir -p $condata/mosquittodata/{conf,data,log}
echo """persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log

listener 1883
## Authentication ##
# allow_anonymous false
""" > $condata/mosquittodata/conf/mosquitto.conf

Create Mosquitto in docker compose:

  mqtt:
    image: eclipse-mosquitto
    container_name: mqtt
    volumes:
      - <actual condata path>/mosquittodata/conf:/mosquitto/config
      - <actual condata path>/mosquittodata/data:/mosquitto/data
      - <actual condata path>/mosquittodata/log:/mosquitto/log
    ports:
      - "1883:1883"

Bring the container up. Create a user and password. Configure Mosquitto to use the password file. Restart container.

docker-compose up -d
docker exec -ti mqtt mosquitto_passwd -c /mosquitto/config/password.txt mqttuser
echo "password_file /mosquitto/config/password.txt" >> $condata/mosquittodata/conf/mosquitto.conf
docker restart mqtt

Frigate was a little more involved, but not terribly:

Create data directory. Create media storage directoty. Create initial config file.

condata=<container data dir>
mkdir $condata/frigatedata
mkdir <media storage path>/camerafeeds
echo """mqtt:
  host: mqtt
  user: mqttuser
  password: <mqtt password from above>

ffmpeg:
  hwaccel_args: -c:v h264_cuvid

detect:
  fps: 10
  enabled: True

cameras:
  bullet1:
    ffmpeg:
      inputs:
        - path: rtsp://user:pass@<cam IP>:554/cam/realmonitor?channel=1&subtype=main
          roles:
            - rtmp
    rtmp:
      enabled: False
    detect:
      width: 2592
      height: 1944
  bullet2:
    ffmpeg:
      inputs:
        - path: rtsp://user:pass@<cam IP>:554/cam/realmonitor?channel=1&subtype=main
          roles:
            - record
            - detect
            - rtmp
    rtmp:
      enabled: False
    record:
      enabled: True
    detect:
      width: 2592
      height: 1944
"""> $condata/frigatedata/config.yml

Create Frigate in docker compose:

  frigate:
    image: blakeblackshear/frigate:stable
    container_name: frigate
    runtime: nvidia
    shm_size: "256mb"
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - FRIGATE_RTSP_PASSWORD=<a password>
    volumes:
      - <actual condata path>/frigatedata/:/config:ro
      - <media storage path>/camerafeeds:/media/frigate
      - type: tmpfs
        target: /tmp/cache
        tmpfs:
          size: 1000000000
    ports:
      - "5000:5000"
      - "1935:1935"

Bring up the container with docker compose and hopefully there's no ffmpeg errors in the logs. Check out the interface with port 5000 and you should see your cameras.

The setup for HAOS was pretty straightforward.  Deploy the OVA, do the initial setup dialogs.  I'm using a reverse proxy, so I had to set that up in the /config/configuration.yaml:

http:
  trusted_proxies: 
   - <proxy ip>
  use_x_forwarded_for: true

Add-ons for HAOS are needed for a few things in this setup.  First, the file editor and ssh terminal are pretty invaluable.  Go to your user in the bottom left of the UI, and enable Advanced Mode.  Now go to Settings> Add-ons > Add-on Store.  Install, start and enable on boot both File editor and Terminal & SSH.  Go back to the store and click the upper right dots to manage add-on repositories.  Add these two: https://github.com/allenporter/stream-addons and https://github.com/blakeblackshear/frigate-hass-addons.  I would check for updates after this and refresh the screen.  The next Add-ons will be the Frigate Proxy and RTSPtoWeb - WebRTC.  Configure Frigate proxy to point to the Frigate instance at port 5000.  The RTSPtoWeb should just work or so I am told.  I haven't gotten a good feed from HAOS yet.  I put the Frigate proxy directly on the sidebar and see the cameras through that.  

These are my rough first swings at HomeAssistant and it's components.  It's not complete by any measure, just the basic steps I took to get it up and going.  I'll follow up with some more posts to jog my memory when the time comes.