# Use Apple HomeKit Devices with itsaSNAP and Adafruit IO

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/132/770/medium800thumb/sensors_heroGif.jpg?1727795672)

Have you ever looked at your various Apple HomeKit devices and thought "if only I could monitor and control my devices in Adafruit IO"? Now you can with the help of the itsaSNAP app. You can use Apple Shortcuts with itsaSNAP to integrate your Apple HomeKit devices with Adafruit IO. You can go even further and use CircuitPython to display and control your devices with your Adafruit IO feeds.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/673/medium800/sensors_Screenshot_2024-09-30_105351.png?1727708052)

https://youtube.com/shorts/BAKGfKN-PXg

You can setup a Shortcut to log your data from your sensor to Adafruit IO. This Shortcut can be paired with Automations to log the data over time.

![sensors_edited_P1450310.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/749/medium640/sensors_edited_P1450310.jpg?1727792473)

After you create Scenes for your devices, you can use a Shortcut to change Scenes based on the value of an Adafruit IO feed with itsaSNAP.

![sensors_toggle.gif](https://cdn-learn.adafruit.com/assets/assets/000/132/779/medium640thumb/sensors_toggle.jpg?1727797591)

For bonus points, you can use CircuitPython to display the sensor values and control your device Scenes with the press of a button.

![sensors_cpControl.gif](https://cdn-learn.adafruit.com/assets/assets/000/132/777/medium640thumb/sensors_cpControl.jpg?1727797044)

## Parts
Featured
### Adafruit ESP32-S3 Reverse TFT Feather

[Adafruit ESP32-S3 Reverse TFT Feather](https://www.adafruit.com/product/5691)
Like Missy Elliot, we like to ["put our [Feather] down, flip it and reverse it"](https://www.youtube.com/watch?v=cjIvu7e6Wq8)&nbsp;and that's exactly what we've done with this new development board. It's basically our **<a...></a...>**

In Stock
[Buy Now](https://www.adafruit.com/product/5691)
[Related Guides to the Product](https://learn.adafruit.com/products/5691/guides)
![Video of a rectangular microcontroller with a TFT display. A pink manicured finger presses each of the tactile buttons, which are recognized on the TFT display.](https://cdn-shop.adafruit.com/product-videos/640x480/5691-05.jpg)

Featured
### Pink and Purple Woven USB A to USB C Cable - 1 meter long

[Pink and Purple Woven USB A to USB C Cable - 1 meter long](https://www.adafruit.com/product/5153)
This cable is not only super-fashionable, with a woven pink and purple Blinka-like pattern, it's also made for USB C for our modernized breakout boards, Feathers, and more.&nbsp;&nbsp;[If you want something just like it but for Micro B, we...](https://www.adafruit.com/product/4111)

Out of Stock
[Buy Now](https://www.adafruit.com/product/5153)
[Related Guides to the Product](https://learn.adafruit.com/products/5153/guides)
![Angled shot of coiled pink and purple USB cable with USB A and USB C connectors.](https://cdn-shop.adafruit.com/640x480/5153-02.jpg)

Featured
### Adafruit IO+ Subscription Pass – One Year

[Adafruit IO+ Subscription Pass – One Year](https://www.adafruit.com/product/3792)
The all-in-one Internet of Things service from Adafruit you know and love is now _even better_ with IO+. The 'plus' stands for MORE STUFF! More feeds, dashboards, storage, speed. Power up your [Adafruit IO](https://io.adafruit.com/) with the $99 pass for 1 year of the...

In Stock
[Buy Now](https://www.adafruit.com/product/3792)
[Related Guides to the Product](https://learn.adafruit.com/products/3792/guides)
![Text image that reads "IO+"](https://cdn-shop.adafruit.com/640x480/3792-01.jpg)

### Matter Devices
### Part: Eve Weather Temperature &amp; Humidity Sensor (Matter)
quantity: 1
Smart Weather Station for Temperature, Humidity, Weather Trend, IPX4 Water Resistance, Display, Wireless, Google/Alexa/Siri Voice Access, Requires Thread Border Router 
[Eve Weather Temperature &amp; Humidity Sensor (Matter)](https://www.amazon.com/dp/B0D81BVH6P)

### Part: Eve Motion Sensor (Matter)
quantity: 1
Smart Motion Sensor with Light Sensor, IPX3 Water Resistance, Automatic Activation of Lights and Devices, Thread
[Eve Motion Sensor (Matter)](https://www.amazon.com/dp/B0BZT5W3V5)

### Part: Nanoleaf Smart LED Lightstrip
quantity: 1
80" Smarter Kit (2m) - RGB &amp; Whites, Controller, App &amp; Voice Control (Works with Apple Home, Google Home, Samsung SmartThings) 
[Nanoleaf Smart LED Lightstrip](https://www.amazon.com/dp/B0C1JB8ZPT?th=1)

# Use Apple HomeKit Devices with itsaSNAP and Adafruit IO

## Get Started with Adafruit IO

Adafruit IO is integrated with your&nbsp;[adafruit.com account](https://accounts.adafruit.com/)&nbsp;so you don't need to create yet another online account! You need an Adafruit account to use Adafruit IO because we want to make sure the data you upload is available to only you (unless you decide to publish your data).

## I have an Adafruit.com Account already

**If you already have an Adafruit account, then you already have access to Adafruit IO**. It doesn't matter how you signed up, your account will make all three available.

To access Adafruit IO, simply visit [https://io.adafruit.com](https://io.adafruit.com) to start streaming, logging, and interacting with your data.

## Create an Adafruit Account (for Adafruit IO)

An Adafruit account makes Adafruit content and services available to you in one place. Your account provides access to the [Adafruit shop](https://www.adafruit.com/), the [Adafruit Learning System](https://learn.adafruit.com/), and [Adafruit IO](https://io.adafruit.com/). This means only one account, one username, and one password are necessary to engage with the content and services that Adafruit offers.

If you do not have an Adafruit account, signing up for a new Adafruit account only takes a couple of steps.

Begin by visiting [https://accounts.adafruit.com](https://accounts.adafruit.com).

**Click the Sign Up button** under the "Need An Adafruit Account?" title, below the Sign In section.

![](https://cdn-learn.adafruit.com/assets/assets/000/125/220/medium800/adafruit_io_Create_account_sign_in_up_page.png?1697479894)

This will take you to the **Sign Up** page.

**Fill in the requested information,** and **click the Create Account button.**

![](https://cdn-learn.adafruit.com/assets/assets/000/125/219/medium800/adafruit_io_Create_Account_info_entered.png?1697479894)

This takes you to your Adafruit Account home page. From here, you can access all the features of your account.

You can also access the Adafruit content and services right from this page. Along the top of the page, you'll see a series of links beginning with "Shop". To access any of these, simply click the link.

![](https://cdn-learn.adafruit.com/assets/assets/000/125/217/medium800/adafruit_io_Create_account_home_page.png?1697479894)

For example, **to begin working with Adafruit IO, click the IO link** to the right of the rest of the links. This is the same for the other links as well.

That's all there is to creating a new Adafruit account, and navigating to Adafruit IO.

![](https://cdn-learn.adafruit.com/assets/assets/000/125/218/medium800/adafruit_io_Create_Account_io_homepage.png?1697479770)

# Use Apple HomeKit Devices with itsaSNAP and Adafruit IO

## Download the ItsaSnap by Adafruit App

This section will guide you through downloading and installing the ItsaSnap by Adafruit app.

## Download and Install ItsaSnap

To install and download ItsaSnap for your iOS device,

1. **Open the App Store**.
2. **Tap** on the **"Search" icon** at the bottom of the screen.
3. **Type "ItsaSnap by Adafruit" or "ItsaSnap"** in the search bar and **tap "Search".**
4. Locate the **ItsaSnap**** &nbsp;app** in the search results and tap on it

![](https://cdn-learn.adafruit.com/assets/assets/000/130/658/medium800/adafruit_io_IMG_5711-ezgif.com-resize-2.jpg?1718123186)

&nbsp; &nbsp; 5. **Tap** the **"Get" button** to download and install the app on your device.&nbsp;

You may be prompted to enter your Apple ID password or use Face ID/Touch ID to confirm the installation

![](https://cdn-learn.adafruit.com/assets/assets/000/130/659/medium800/adafruit_io_IMG_5711-ezgif.com-resize-crop.jpg?1718123294)

After you have downloaded and installed ItsaSnap, open the app.

![](https://cdn-learn.adafruit.com/assets/assets/000/130/637/medium800/adafruit_io_adaSnap5-ezgif.com-resize.png?1718070937)

You will need to enter your&nbsp; **Adafruit username** and **Adafruit IO Key** (which is _different_ from your Adafruit account password).

Your Adafruit IO key is a long string of letters and numbers. To make it easier to add to the app, we've also included a QR code scanner that allows you to easily copy the Adafruit IO Key from the Adafruit IO website to the app.

![](https://cdn-learn.adafruit.com/assets/assets/000/130/660/medium800/adafruit_io_qrbuttonscan.png?1718123519)

On the ItaSnap app, the QR code scanner is located below the Adafruit IO Key and above the login button. To access it, press the ' **Scan QR code for IO Key**' button. This will open the QR code scanner.

![](https://cdn-learn.adafruit.com/assets/assets/000/130/662/medium800/adafruit_io_IMG_5702-ezgif.com-crop.png?1718123632)

To find the QR code for your Adafruit IO account, [navigate go to the overview page](https://io.adafruit.com/overview). Once there, click the yellow button with a key in the center (it's next to the "New Device" button) to reveal your Adafruit IO Key.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/130/640/medium800/adafruit_io_Screenshot_2024-06-10_at_9.42.20%E2%80%AFPM.png?1718072559)

After clicking it, a window with your information will appear. Then, find the QR code and scan it, and log in.

![](https://cdn-learn.adafruit.com/assets/assets/000/130/653/medium800/adafruit_io_Pasted_Image_6_11_24__11_55_AM.png?1718121312)

# Use Apple HomeKit Devices with itsaSNAP and Adafruit IO

## Logging Sensors to Adafruit IO with itsaSNAP

![](https://cdn-learn.adafruit.com/assets/assets/000/132/750/medium800/sensors_edited_P1450310.jpg?1727792640)

Once your sensors are setup in Apple HomeKit, you can use Shortcuts to send the data to Adafruit IO. The two sensors that will be used to demo this are the Eve Temperature and Humidity Sensor and the Eve Light and Occupancy Sensor. Both of these sensors are Matter sensors so they are easy to setup. You should be able to adapt these Shortcuts for whatever sensors you are using though.

## Basic Shortcut Setup
To send data from a HomeKit sensor to itsaSNAP, you'll start with the **Get the state of My Home** action. You'll **select your sensor** to pass to the action. You'll use the itsaSNAP **Send Value** action to send the data to your feed.

![sensors_IMG_3061.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/756/medium640/sensors_IMG_3061.jpg?1727793647)

## Format the Data

Some sensor values include extraneous labels, like `°C`. As a result, the data sent to your Adafruit IO feed would be, for example, `23.57°C`. You probably don't want those labels included if your goal is to log the value of a sensor. You can edit the value in the Shortcut to remove the label.

Start with a **Get the state of My Home** action and **select your sensor**. Next, use a **Replace Text** action. In the replace area, **type in the text that you want to remove** from the data. In this case, it was **°C** from the temperature reading. Don't include any text in the second part of the action and pass the result from the **Get the state of My Home** action as the text to modify. In the itsaSNAP&nbsp; **Send Value** &nbsp;action, you'll send the **Updated Text** to your feed.

![sensors_IMG_3058.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/757/medium640/sensors_IMG_3058.jpg?1727793738)

Here is another example of removing a value label. In this Shortcut, the light level from a light sensor has the **lx** label removed to only send the numerical value to Adafruit IO.

![sensors_IMG_3059.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/758/medium640/sensors_IMG_3059.jpg?1727793766)

## Match and Replace Data

Another scenario may be that you want to send a specific value to a feed if a sensor returns a certain value. You can do this by using the **Match Text** action.

Start with the **Get the state of My Home** &nbsp;action and&nbsp; **select your sensor**. Next, use a **Match Text** action. **Insert the value** that you want to match from the returned **value from the sensor**. Then, you can use an **If** action to check if there was a match. The syntax for this in actions is if the result **has any value**. If you wanted to check that a match wasn't made, you would select **does not have any value**. Inside the If action, you'll use the itsaSNAP&nbsp; **Send Value** action to send your manual value to your feed.

![sensors_IMG_3060.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/759/medium640/sensors_IMG_3060.jpg?1727793819)

In this example, the occupancy sensor being used returns&nbsp; **Yes** or **No** as a value. This response does not work well with an Adafruit IO dashboard for monitoring a true/false state. To change this value to a numerical value, a **2** is sent if a **No** is found, otherwise a **1** is sent for **Yes**. This allows an&nbsp; **Indicator block** to be used on a Dashboard for the feed from the sensor.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/716/medium800/sensors_Screenshot_2024-09-30_143203.png?1727721136)

## Adafruit IO Dashboard

Speaking of Dashboards, you can take all of this data and create a Dashboard to view the sensor values over time. You can use Automations to automate running the Shortcuts to log the data to Adafruit IO. If you want to log the data consistently throughout the day, you can follow the directions in this [Playground Note](https://adafruit-playground.com/u/BlitzCityDIY/pages/create-a-looping-apple-shortcut-for-sending-data-to-itsasnap) to create a looping Shortcut with alarms.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/713/medium800/sensors_Screenshot_2024-09-30_122417.png?1727713470)

# Use Apple HomeKit Devices with itsaSNAP and Adafruit IO

## Controlling Scenes with Adafruit IO and itsaSNAP

![](https://cdn-learn.adafruit.com/assets/assets/000/132/768/medium800thumb/sensors_toggle.jpg?1727795638)

When you setup an output device in Apple HomeKit (lights, motorized blinds, etc) you can [create Scenes](https://support.apple.com/guide/iphone/create-and-use-scenes-iphb96e3f655/ios) that act as presets for the device. For example, you can have a scene that changes your RGB lights to green. When you create these Scenes, you can access them in Shortcuts and use itsaSNAP to access an Adafruit IO feed to select a Scene based on a value in the feed.

The device used for this demo is a Nanoleaf RGB lightstrip, but you should be able to adapt these Shortcuts for different devices.

## Make a Scene
![](https://cdn-learn.adafruit.com/assets/assets/000/132/760/medium800/sensors_IMG_3067.jpg?1727793949)

When you view a Room in the Apple Home app, you'll see a section called Scenes where all of your preset Scenes are. If you aren't sure how to use Scenes, you can reference [Apple's documentation for them](https://support.apple.com/guide/iphone/create-and-use-scenes-iphb96e3f655/ios).

## Shortcut for Scenes
For this Shortcut, you'll be receiving data _from_ itsaSNAP rather than sending data to it. You'll start with&nbsp;the itsaSNAP **Fetch Feed** action to read the most recent data from your feed.

![sensors_IMG_3068.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/762/medium640/sensors_IMG_3068.jpg?1727794022)

You'll use the **Match Text** action to check for a value from the incoming feed. Use an **If** action to check if the values match. If they do match, a **Control My Home** action is used to run a scene. In the demo, values of **0** , **1** and **2** are used to set three different scenes for the RGB lightstrip.

![sensors_IMG_3069.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/761/medium640/sensors_IMG_3069.jpg?1727793997)

## Dashboard Control

You can use a **Slider block** on an Adafruit IO Dashboard to control the Scene control feed.

Point the block at the feed and set the **minimum value to 0** and the **maximum value to 2**. Set the **step size to 1**. This gives you a 3 position switch to control your Scenes.

![sensors_Screenshot_2024-09-30_150210.png](https://cdn-learn.adafruit.com/assets/assets/000/132/726/medium640/sensors_Screenshot_2024-09-30_150210.png?1727723080)

You will notice this is a little clunky though. You need to set the slider to a position on the Dashboard and then run the Shortcut on your iOS device to actually set the Scene. There is a way to automate this process though using Adafruit IO Actions and Shortcut Automations.

## Hack the Automations

To add some automation to this process, you'll use [Adafruit IO Actions](https://learn.adafruit.com/how-to-use-blockly-for-actions-on-adafruit-io). Actions let you create tasks similar to the Shortcuts you've been using in iOS to have feeds trigger a series of events. In this case, you'll send an SMS message anytime a new value is added to the feed you're monitoring.

The SMS messaging Action is only available for IO+ users. However, if you do not have an IO+ account you can setup the Action to use email instead.

Featured
### Adafruit IO+ Subscription Pass – One Year

[Adafruit IO+ Subscription Pass – One Year](https://www.adafruit.com/product/3792)
The all-in-one Internet of Things service from Adafruit you know and love is now _even better_ with IO+. The 'plus' stands for MORE STUFF! More feeds, dashboards, storage, speed. Power up your [Adafruit IO](https://io.adafruit.com/) with the $99 pass for 1 year of the...

In Stock
[Buy Now](https://www.adafruit.com/product/3792)
[Related Guides to the Product](https://learn.adafruit.com/products/3792/guides)
![Text image that reads "IO+"](https://cdn-shop.adafruit.com/640x480/3792-01.jpg)

Info: The SMS messaging Action is only available for IO+ users. However, if you do not have an IO+ account you can setup the Action to use email instead.

Create an Action that uses a **Reactive trigger**. For the F **eed** , select your **lightstrip feed**. For **Operator** , select **any**. Leave the **Feed or Value section blank**. This alerts for any new value on the feed. For the **Action** select **SMS** (or Email). You can leave the body as the default entry. For **...using** select the **same lightstrip feed**.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/731/medium800/sensors_Screenshot_2024-09-26_132529.png?1727723750)

You can test this Action by going to your Dashboard and moving the Slider block. When you change the Slider value, you should receive a text.

![sensors_IMG_3073.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/763/medium640/sensors_IMG_3073.jpg?1727794075)

If you don't want to be notified every time a text comes in, you can **toggle Hide Alerts**. This lets the process run in the background.

![sensors_IMG_3074.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/764/medium640/sensors_IMG_3074.jpg?1727794105)

Now comes the hack! Head over to the Shortcuts app and create a **new Automation**. Select a **Message automation** if you have an SMS action setup. If you setup an email action, select Email.

![sensors_IMG_3072.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/765/medium640/sensors_IMG_3072.jpg?1727794137)

Under **Sender** select the **Adafruit IO number**. Under **Message Contains** , enter the **name of your feed** since it will be in every text from the Action. Check off **Run Immediately**.

![sensors_IMG_3070.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/766/medium640/sensors_IMG_3070.jpg?1727794163)

Choose the **Shortcut** that you setup to **change the Scenes**.

![sensors_IMG_3071.jpg](https://cdn-learn.adafruit.com/assets/assets/000/132/767/medium640/sensors_IMG_3071.jpg?1727794199)

Now when you change the value on the Slider, the feed updates and sends a text to your iOS device. When the text is received, the Shortcut runs and you'll see your device change to the chosen Scene.

# Use Apple HomeKit Devices with itsaSNAP and Adafruit IO

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_feather_esp32s3_reverse_tft/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_most_boards_CircuitPython_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/102/129/medium640/install_circuitpython_on_most_boards_CircuitPython_downloaded.jpg?1620922559)

![](https://cdn-learn.adafruit.com/assets/assets/000/119/387/medium800/adafruit_products_resetWithNeo.jpg?1678478978)

Plug your board into your computer, using a known-good data-sync cable, directly, or via an adapter if needed.

Double-click the **reset** button (highlighted in red above), and you will see the **RGB status LED(s)** turn green (highlighted in green above). If you see red, try another port, or if you're using an adapter or hub, try without the hub, or different adapter or hub.

For this board, tap reset and wait for the LED to turn purple, and as soon as it turns purple, tap reset again. The second tap needs to happen while the LED is still purple.

If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **FTHRS3BOOT**.

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **FTHRS3BOOT**.

![adafruit_products_s3Boot.jpg](https://cdn-learn.adafruit.com/assets/assets/000/118/996/medium640/adafruit_products_s3Boot.jpg?1677603548)

![adafruit_products_copyTos3.jpg](https://cdn-learn.adafruit.com/assets/assets/000/118/997/medium640/adafruit_products_copyTos3.jpg?1677603564)

The **BOOT** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it!

![install_circuitpython_on_most_boards_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/102/130/medium640/install_circuitpython_on_most_boards_CIRCUITPY.jpg?1620923145)

# Use Apple HomeKit Devices with itsaSNAP and Adafruit IO

## Create Your settings.toml File

CircuitPython works with WiFi-capable boards to enable you to make projects that have network connectivity. This means working with various passwords and API keys. As of [CircuitPython 8](https://circuitpython.org/downloads), there is support for a **settings.toml** file. This is a file that is stored on your **CIRCUITPY** drive, that contains all of your secret network information, such as your SSID, SSID password and any API keys for IoT services. It is designed to separate your sensitive information from your **code.py** file so you are able to share your code without sharing your credentials.

CircuitPython previously used a **secrets.py** file for this purpose. The **settings.toml** file is quite similar.

Warning: Your **settings.toml** file should be stored in the main directory of your **CIRCUITPY** drive. It should not be in a folder.

## CircuitPython **settings.toml** File

This section will provide a couple of examples of what your **settings.toml** file should look like, specifically for CircuitPython WiFi projects in general.

The most minimal **settings.toml** file must contain your WiFi SSID and password, as that is the minimum required to connect to WiFi. Copy this example, paste it into your **settings.toml** , and update:

- `your_wifi_ssid`
- `your_wifi_password`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
```

Many CircuitPython network-connected projects on the Adafruit Learn System involve using Adafruit IO. For these projects, you must _also_ include your Adafruit IO username and key. Copy the following example, paste it into your settings.toml file, and update:

- `your_wifi_ssid`
- `your_wifi_password`
- `your_aio_username`
- `your_aio_key`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
ADAFRUIT_AIO_USERNAME = "your_aio_username"
ADAFRUIT_AIO_KEY = "your_aio_key"
```

Some projects use different variable names for the entries in the **settings.toml** file. For example, a project might use `ADAFRUIT_AIO_ID` in the place of `ADAFRUIT_AIO_USERNAME`. **If you run into connectivity issues, one of the first things to check is that the names in the settings.toml file match the names in the code.**

Warning: Not every project uses the same variable name for each entry in the **settings.toml** file! Always verify it matches the code.

## **settings.toml** File Tips
Here is an example **settings.toml** file.

```auto
# Comments are supported
CIRCUITPY_WIFI_SSID = "guest wifi"
CIRCUITPY_WIFI_PASSWORD = "guessable"
CIRCUITPY_WEB_API_PORT = 80
CIRCUITPY_WEB_API_PASSWORD = "passw0rd"
test_variable = "this is a test"
thumbs_up = "\U0001f44d"
```

In a **settings.toml** file, it's important to keep these factors in mind:

- Strings are wrapped in double quotes; ex: `"your-string-here"`
- Integers are _ **not** _ quoted and may be written in decimal with optional sign (`+1`, `-1`, `1000`) or hexadecimal (`0xabcd`).
  - Floats (decimal numbers), octal (`0o567`) and binary (`0b11011`) are not supported.

- Use `\u` escapes for weird characters, `\x` and `\ooo` escapes are not available in **.toml** files
  - Example: `\U0001f44d` for 👍 (thumbs up emoji) and `\u20ac` for € (EUR sign)

- Unicode emoji, and non-ASCII characters, stand for themselves as long as you're careful to save in "UTF-8 without BOM" format

&nbsp;

&nbsp;

When your&nbsp; **settings.toml&nbsp;** file is ready, you can save it in your text editor with the **.toml** &nbsp;extension.

![adafruit_products_dotToml.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/071/medium640/adafruit_products_dotToml.jpg?1671034293)

## Accessing Your **settings.toml** Information in **code.py**
In your **code.py** file, you'll need to `import` the `os` library to access the **settings.toml** file. Your settings are accessed with the `os.getenv()` function. You'll pass your settings entry to the function to import it into the **code.py** file.

```python
import os

print(os.getenv("test_variable"))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/117/072/medium800/adafruit_products_tomlOutput.jpg?1671034496)

In the upcoming CircuitPython WiFi examples, you'll see how the **settings.toml&nbsp;** file is used for connecting to your SSID and accessing your API keys.

# Use Apple HomeKit Devices with itsaSNAP and Adafruit IO

## Display with CircuitPython

![](https://cdn-learn.adafruit.com/assets/assets/000/132/778/medium800thumb/sensors_cpControl.jpg?1727797560)

You've setup Shortcuts to log your HomeKit sensors to Adafruit IO. You've setup a Shortcut to have an Adafruit IO feed switch between Scenes. You even setup a hack to use Adafruit IO Actions and Shortcut Automations to seamlessly control your Scenes from Adafruit IO. Surely its time to call it a day?

Before you go off and take a nap, there's one more skateboard trick for you to show off with. With all of this backend work, you can use a Feather ESP32-S3 Reverse TFT running CircuitPython to display the sensor data and switch between Scenes with the press of a physical button.

## Code the Display
![](https://cdn-learn.adafruit.com/assets/assets/000/132/747/medium800/sensors_edited_P1450331.jpg?1727792136)

Once you've finished setting up your Feather with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.

To do this, click on the **Download Project Bundle** button in the window below. It will download to your computer as a zipped folder.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Matter_Devices_Dashboard/code.py

## Upload the Code and Libraries to the Feather

After downloading the Project Bundle, plug your Feather into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called **CIRCUITPY**. Unzip the folder and copy the following items to the Feather's **CIRCUITPY** drive.

- **lib** folder
- **code.py**
- **roundedHeavy-26.bdf**
- **tft\_bg.bmp**

Your Feather **CIRCUITPY** drive should look like this after copying the **lib** folder, bitmap graphic, font file the **code.py** file.

![CIRCUITPY](https://adafruit.github.io/Adafruit_Learning_System_Guides/Matter_Devices_Dashboard.png )

## Add Your **settings.toml** File

As of CircuitPython 8.0.0, there is support for [Environment Variables](https://docs.circuitpython.org/en/latest/docs/environment.html). Environment variables are stored in a **settings.toml** file. Similar to **secrets.py** , the **settings.toml** file separates your sensitive information from your main **code.py** file. Add your **settings.toml** file as described in the [Create Your settings.toml File page](https://learn.adafruit.com/blinka-led-sign/create-your-settings-toml-file) earlier in this guide. You'll need to include your `ADAFRUIT_AIO_USERNAME`, `ADAFRUIT_AIO_KEY`, `CIRCUITPY_WIFI_SSID` and `CIRCUITPY_WIFI_PASSWORD`.

```python
CIRCUITPY_WIFI_SSID = "your-ssid-here"
CIRCUITPY_WIFI_PASSWORD = "your-ssid-password-here"
ADAFRUIT_AIO_USERNAME = "your-username-here"
ADAFRUIT_AIO_KEY = "your-key-here"
```

## How the CircuitPython Code Works

At the top of the code, you'll add your feed names that you'll be monitoring over MQTT.

```python
aio_username = os.getenv("ADAFRUIT_AIO_USERNAME")
aio_key = os.getenv("ADAFRUIT_AIO_KEY")

# feeds!
temp_feed = aio_username + "/feeds/eve-temp" # temperature sensor
humid_feed = aio_username + "/feeds/eve-humid" # humidity sensor
lux_feed = aio_username + "/feeds/eve-light" # lux sensor
occupy_feed = aio_username + "/feeds/eve-occupy" # occupation sensor
light_feed = aio_username + "/feeds/nanoleaf" # lightstrip
```

## Buttons

The Feather ESP32-S3 Reverse TFT has three buttons that you can use for user input. These are setup as `digitalio` inputs.

```python
# buttons
button0 = digitalio.DigitalInOut(board.D0)
button0.direction = digitalio.Direction.INPUT
button0.pull = digitalio.Pull.UP
button0_state = False
button1 = digitalio.DigitalInOut(board.D1)
button1.direction = digitalio.Direction.INPUT
button1.pull = digitalio.Pull.DOWN
button1_state = False
button2 = digitalio.DigitalInOut(board.D2)
button2.direction = digitalio.Direction.INPUT
button2.pull = digitalio.Pull.DOWN
button2_state = False
```

## Graphics

The **tft\_bg.bmp** graphic is shown on the display as a `Bitmap`. This graphic has icons for the sensors and buttons. There are a few text objects for the data that will be shown from the feeds. Two shapes are also used to display data. A circle is used to show occupancy by changing color from red (unoccupied) to green (occupied). A rounded rectangle is used to outline the button labels to show which Scene is selected.

```python
display = board.DISPLAY
group = displayio.Group()
display.root_group = group

# load background bitmap
bitmap = displayio.OnDiskBitmap("/tft_bg.bmp")
tile_grid = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader)
group = displayio.Group()
group.append(tile_grid)

# bitmap font
font_file = "/roundedHeavy-26.bdf"
font = bitmap_font.load_font(font_file)
# text elements
temp_text = bitmap_label.Label(font, text="00.0°C", x=55, y=70, color=0xFFFFFF)
group.append(temp_text)
humid_text = bitmap_label.Label(font, text="00.0%", x=120, y=70, color=0xFFFFFF)
group.append(humid_text)
lux_text = bitmap_label.Label(font, text="00 lx", x=190, y=70, color=0xFFFFFF)
group.append(lux_text)
occupy_text = bitmap_label.Label(font, text="Occupied?", x=128,
                                 y=display.height - 12, color=0xFFFFFF)
group.append(occupy_text)
onOff_circ = Circle(display.width - 12, display.height - 12, 10, fill=0xcc0000)
group.append(onOff_circ)
scene_select = RoundRect(0, 0, 42, 40, 8, fill=None, outline=0xcccc00, stroke=6)
scene_y = [0, int(display.height / 2) - int(scene_select.height / 2),
           display.height - scene_select.height - 1]
group.append(scene_select)

display.root_group = group
```

## MQTT Methods

MQTT is used to connect to Adafruit IO. The first method `connected()` subscribes to the five feeds defined at the top of the code.

```python
def connected(client, userdata, flags, rc): # pylint: disable=unused-argument
    # This function will be called when the client is connected
    # successfully to the broker.
    print("Connected to Adafruit IO!")
    # Subscribe to all changes on feeds
    client.subscribe(temp_feed)
    client.subscribe(humid_feed)
    client.subscribe(lux_feed)
    client.subscribe(occupy_feed)
    client.subscribe(light_feed)
```

Five custom methods are defined for each feed. The methods for the temperature, humidity and lux feeds update the text with the new value when there is new data available on the feed. The occupancy sensor method changes the color of the circle depending on the value. The lightstrip method changes the `y` coordinate of the rounded rectangle to outline the selected Scene.

```python
def on_temp_msg(client, topic, msg):
    print(f"temp feed data: {msg}°C")
    temp_text.text = f"{float(msg):.01f}°C"

def on_humid_msg(client, topic, msg):
    print(f"humid feed data: {msg}%")
    humid_text.text = f"{float(msg):.01f}%"

def on_lux_msg(client, topic, msg):
    print(f"lux feed data: {msg} lx")
    lux_text.text = f"{float(msg):.00f} lx"

def on_occupy_msg(client, topic, msg):
    print(f"occupation feed data: {msg}")
    if msg == "1":
        onOff_circ.fill = 0x00cc00
    else:
        onOff_circ.fill = 0xcc0000

def on_light_msg(client, topic, msg):
    print(f"light scene selected: {msg}")
    scene_select.y = scene_y[int(msg)]
```

The callback methods are setup and then a connection is established.

```python
pool = socketpool.SocketPool(wifi.radio)
ssl_context = ssl.create_default_context()
# Initialize an Adafruit IO HTTP API object
mqtt_client = MQTT.MQTT(
    broker="io.adafruit.com",
    port=1883,
    username=aio_username,
    password=aio_key,
    socket_pool=pool,
    ssl_context=ssl_context,
)
# Setup the callback methods above
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
mqtt_client.on_message = on_message
mqtt_client.add_topic_callback(temp_feed, on_temp_msg)
mqtt_client.add_topic_callback(humid_feed, on_humid_msg)
mqtt_client.add_topic_callback(lux_feed, on_lux_msg)
mqtt_client.add_topic_callback(occupy_feed, on_occupy_msg)
mqtt_client.add_topic_callback(light_feed, on_light_msg)

# Connect the client to the MQTT broker.
print("Connecting to Adafruit IO...")
mqtt_client.connect()
```

## The Loop

In the loop, ticks are used for non-blocking timekeeping. Every 5 seconds, the MQTT client loops to check for any new messages on the feeds. If a new message is detected, the callback methods will run, automatically updating the values on the TFT.

Each of the three buttons sends a different value to the lightstrip feed using the `publish()` function. These values correspond with the values defined in the Shortcut for setting the light Scenes (`0`-`2`).

```python
while True:
    try:
        if ticks_diff(ticks_ms(), clock_clock) >= clock_timer:
            mqtt_client.loop(timeout=1)
            clock_clock = ticks_add(clock_clock, clock_timer)
        # reset button state on release
        if button0.value and button0_state:
            button0_state = False
        if not button1.value and button1_state:
            button1_state = False
        if not button2.value and button2_state:
            button2_state = False
        # buttons change light scenes
        if not button0.value and not button0_state:
            mqtt_client.publish(light_feed, 0)
            scene_select.y = scene_y[0]
            button0_state = True
        if button1.value and not button1_state:
            mqtt_client.publish(light_feed, 1)
            scene_select.y = scene_y[1]
            button1_state = True
        if button2.value and not button2_state:
            mqtt_client.publish(light_feed, 2)
            scene_select.y = scene_y[2]
            button2_state = True
    except Exception as error: # pylint: disable=broad-except
        print(error)
        mqtt_client.disconnect()
        time.sleep(5)
        microcontroller.reset()
```


## Guide Products

### Adafruit ESP32-S3 Reverse TFT Feather

[Adafruit ESP32-S3 Reverse TFT Feather](https://www.adafruit.com/product/5691)
Like Missy Elliot, we like to ["put our [Feather] down, flip it and reverse it"](https://www.youtube.com/watch?v=cjIvu7e6Wq8)&nbsp;and that's exactly what we've done with this new development board. It's basically our **<a...></a...>**

In Stock
[Buy Now](https://www.adafruit.com/product/5691)
[Related Guides to the Product](https://learn.adafruit.com/products/5691/guides)
### Pink and Purple Woven USB A to USB C Cable - 1 meter long

[Pink and Purple Woven USB A to USB C Cable - 1 meter long](https://www.adafruit.com/product/5153)
This cable is not only super-fashionable, with a woven pink and purple Blinka-like pattern, it's also made for USB C for our modernized breakout boards, Feathers, and more.&nbsp;&nbsp;[If you want something just like it but for Micro B, we...](https://www.adafruit.com/product/4111)

Out of Stock
[Buy Now](https://www.adafruit.com/product/5153)
[Related Guides to the Product](https://learn.adafruit.com/products/5153/guides)
### Adafruit IO+ Subscription Pass – One Year

[Adafruit IO+ Subscription Pass – One Year](https://www.adafruit.com/product/3792)
The all-in-one Internet of Things service from Adafruit you know and love is now _even better_ with IO+. The 'plus' stands for MORE STUFF! More feeds, dashboards, storage, speed. Power up your [Adafruit IO](https://io.adafruit.com/) with the $99 pass for 1 year of the...

In Stock
[Buy Now](https://www.adafruit.com/product/3792)
[Related Guides to the Product](https://learn.adafruit.com/products/3792/guides)

## Related Guides

- [Adafruit ESP32-S3 Reverse TFT Feather](https://learn.adafruit.com/esp32-s3-reverse-tft-feather.md)
- [QT Py CH32V203 eInk / ePaper Daily Calendar and Clock](https://learn.adafruit.com/ch32v203-eink-epaper-calendar-and-clock.md)
- [Feather Scorpio Snap Fit Case](https://learn.adafruit.com/feather-scorpio-snap-fit-case.md)
- [Using Piezo Buzzers with WipperSnapper](https://learn.adafruit.com/using-piezo-buzzers-with-wippersnapper.md)
- [QT Py RP2040 USB to Serial MIDI Friends](https://learn.adafruit.com/qt-py-rp2040-usb-to-serial-midi-friends.md)
- [Where's My Friend? A Location-Aware Display with PyPortal and ItsASnap](https://learn.adafruit.com/where-s-my-friend-a-location-display-frame-with-pyportal.md)
- [RP2040 RunCPM Emulator with USB Keyboard & HDMI screen](https://learn.adafruit.com/rp2040-runcpm-emulator-with-usb-keyboard-hdmi-screen.md)
- [Monitor Your Greenhouse with a No-Code Environmental Sensor](https://learn.adafruit.com/monitor-your-greenhouse-with-a-no-code-environmental-sensor.md)
- [DIY Turbo Button Controller - HID Remapper](https://learn.adafruit.com/diy-turbo-button-controller-hid-remapper.md)
- [MagTag James Webb Telescope Status](https://learn.adafruit.com/magtag-james-webb-telescope-status.md)
- [Theme Park Wait Time Display](https://learn.adafruit.com/park-wait-time.md)
- [Ikea Vindriktning Hack with QT Py ESP32-S3 and Adafruit IO](https://learn.adafruit.com/ikea-vindriktning-hack-with-qt-py-esp32-s3-and-adafruit-io.md)
- [Glider Paper Airplane Controller](https://learn.adafruit.com/glider-paper-airplane-controller.md)
- [Pico W PiCowBell Case](https://learn.adafruit.com/pico-w-picowbell-case.md)
- [Integrating Color Sensors with itsaSNAP and HomeKit](https://learn.adafruit.com/integrating-color-sensors-with-itsasnap-and-homekit.md)
- [Scan QR Codes with CircuitPython](https://learn.adafruit.com/scan-qr-codes-with-circuitpython.md)
