mqtt to homekit via home assistant

Problem:

I have an industrial IoT product that sends temperature data via the MQTT protocol. I wanted to practice using the MQTT gateway I have, so I decided to try to get data flowing from the sensor all the way to HomeKit (on my iPhone).

image

Solution:

Temperature Sensor:

Skipping any details here for now… assume a previously configured MQTT gateway or device

MQTT Broker:

I first tried AWS as the MQTT broker. It worked as a broker, but requires three different security certificates, and wasn’t compatible with the MQTT integration in Home Assistant (HA)… more on that later. I switched to HiveMQ and followed the first three bullets in this post on their blog to set up my private endpoint. I managed to set up my MQTT gateway to publish data to the cluster successfully, so ✅ on the first step.

Raspberry Pi 3:

I had a Raspberry Pi 3 that I wanted to act as the HA server. I already had a running version of HA, but installed it using Snapd, and I wasn’t able to update HA to the latest version so I decided to start over with a fresh install of HA.

Step 1

The easiest way to install Raspberry Pi OS on the Pi is to use the Raspberry Pi Imager. I picked the 32-bit version with Raspberry Pi Desktop. Follow the instructions here for the rest. It really is best to have a spare monitor and keyboard available.

Why Home Assistant? Home Assistant is free and open-source software for home automation designed to be a central control system for smart home devices with a focus on local control and privacy. Wikipedia Home Assistant

Step 2

Update some settings on the Pi, and turn on VNC and SSH to remotely connect to the Pi.

Assuming your Pi doesn’t boot into the Desktop Mode the first time (if it does you can access the command line from the terminal application, or access the config tool in the Desktop menu directly), access the Config tool with this code at the command line prompt:

sudo raspi-config

image

These are common settings to change

  1. Systems Options
    1. Wireless LAN setup > set SSID Credentials
    2. Boot / Auto Login > set to Desktop Autologin Desktop GUI
  2. Interface Options
    1. SSH > set to Enable
    2. VNC > set to Enable

Select <Finish> and reboot with:

sudo reboot

It should boot into the Desktop and connect to your WiFi. In the wireless settings in the toolbar, you can find your IP address. Note this for the next step.

Step 3

Connect to the Pi remotely using a VNC program, I like VNC Viewer. I’m not going to document how to install and set up a remote connection. Connect to your Pi remotely with the IP address you saved and entering your login info.

Step 4

Update the Pi with this code (or using the update app in Desktop):

sudo apt update

Then:

sudo apt upgrade

This takes a long time.

Home Assistant:

I followed a guide similar to this one (I can’t find the actual one I used, but the code is the similar) to install HA on the Pi. Here is the code I specifically used:

curl -fsSL https://get.docker.com -o get-docker.sh
Installs Docker
sudo sh get-docker.sh
sudo usermod -aG docker pi
docker run -d \
--name homeassistant \
--privileged \
--restart=unless-stopped \
-e TZ=America/Chicago \
-v /home/pi/homeassistant:/config \
--network=host \
ghcr.io/home-assistant/home-assistant:stable
Installs HA

Access your newly installed hosted HA service in a browser on your computer at http://<your_pi_ip_address>:8123 and follow the prompts to set your username and password for the first time. After that HA should load.

Help!

If in the future you need to access the docker container to reset your HA password (as I have had to do several times), here is the code needed:

docker exec -it homeassistant bash
hass --script auth --config /config change_password <username> <password>

MQTT Part 2:

Going back to this post and line item 4 specifically, I downloaded the certificate. Link for reference. Don’t use the rest of this guide, it is older and not required.

Step 1

Then in Home Assistant I added the MQTT integration. SETTINGS > DEVICES & SERVICES > ADD INTEGRATION > MQTT > MQTT

Add Integration Screen
Add Integration Screen

MQTT Options
MQTT Options

Step 2

Change the Broker options to match the HiveMQ configuration you set up earlier.

  • Broker
  • Port (should be 8883)
  • Username
  • Password
  • Broker Certificate Validation
    • Custom
    • Upload the custom CA certificate file you downloaded earlier

After hitting NEXT, I left all of the default settings on the next screen then his SUBMIT. If everything worked correctly you should be able to subscribe to the MQTT feed by listening for topic #. If you start getting JSON data coming in, you can further refine what topic you subscribe to by watching for the “Message X received on …” text above the formatted JSON. If you find what you want to listen for, copy what follows “received on” and paste into the Topic window and start listening.

image

Step 3

The next step covers getting a sensor added to the Home Assistant dashboard (and ultimately connected to HomeKit. The only way I’ve found so far to add a new Sensor is by editing the Configuration.yaml file (which HA references for custom settings and instructions). To do that I needed to give myself editing access to the file first.

On the command line run (adjusting the file location if you changed it):

chmod 777 /home/pi/homeassistant/configuration.yaml

Then edit the configuration file using the Programmer’s Editor (right clicking).

image

Then add these lines:

mqtt:
  sensor:
    - name: "Temperature"
      unique_id: "Temp.NCD"
      state_topic: "YOUR_TOPIC"
      unit_of_measurement: "°F"
      value_template: "{{ (float(value_json['YOUR_JSON_KEY'].temperature_celsius) * 9/5)+32 }}"

These values are all customizable. I used “Temperature” and “Temp.NCD” for my name and unique_id. They can be any value you want them to be. Then for state_topic enter the topic you were listening for earlier. My topic was “gateway/MAC_ADDRESS/sensor/MAC_ADDRESS” where MAC_ADDRESS was the mac address of the gateway and the sensor. Unit of measure was actually ℃ but I wanted it to display in ℉, so I set it to ℉ and converted it in the value template. Finally the value template took some work to figure out. The “float” is important for the calculation at the end of the entry, then my value_json[] was the KEY of the nested JSON structure and the value was “temperature_celsius”. These two values will be different for other applications.

{ 
  "key" : {
    "nested key" : "value",
    "nested key" : "value",
    "nested key" : value,
    "nested key" : value
  }
}

If you didn’t want to convert the temperature, the value template would just look like this:

value_template: "{{ value_json.temperature }}"

There is some more information on the MQTT Integration documentation page.

Once this configuration is completed and saved, restart the Home Assistant service under SETTINGS > SYSTEM > RESTART (upper right corner). If there are any errors in your configuration code, it will let you know and won’t let you restart. Likewise if you are successful, it should show some messages that the MQTT service is starting and running and you should see a new entry on the dashboard.

It’s cold in there right now!
It’s cold in there right now!
HA has a really nice graphing tool with historical data.
HA has a really nice graphing tool with historical data.

HomeKit:

The next step is to connect HA to HomeKit, and I won’t cover the details of this. It’s as simple as adding the HomeKit Integration, scanning the code that the integration generates with HomeKit to add HA as a bridge. More info can be found here. I specifically only wanted HA to add the new temperature sensor HomeKit, not any of the other integrations in HA, so I specified that during the Integration set up.

Now that the temperature sensor is showing in HomeKit, I can use it to create automations or just have it there to look at when I might want to start going out to work in the shop.

Here it is in the Home App!
Here it is in the Home App!