Home

Awesome

<h1 align="center"> <a name="top">โ˜ข๏ธ</a><br/>Airthings Wave radon detector bridge<br/> <sup><sub>a <a href="https://balena.io">balena</a> and Docker container ๐Ÿณ</sub></sup> </h1>

GitHub Release Price AirthingsWave-to-MQTT Version balena.io Code Climate maintainability Maintainer All Contributors PRs Welcome License Tweet

Turn a single-board computer (Raspberry Pi) into a plug-in appliance to bridge your Bluetooth Airthings Wave radon detector to an MQTT broker.

Useful if your radon detector is located too far from your home automation hub, or if you need to use your hub's Bluetooth antenna for something else.

This project creates Docker/balena images based on Alpine Linux that weigh less than 120 MiB on a Raspberry Pi. ๐ŸŽˆ

<div align="center"> <p><strong>Be sure to <a href="#" title="star">โญ๏ธ</a> this repo if you find it useful! ๐Ÿ˜ƒ</strong></p> <figure> <div> <a href="https://www.youtube.com/watch?v=VJImbQU5w4A" title="Video: Radon alpha decay in a diffusion cloud chamber โ˜ข๏ธ"><img src="https://media.giphy.com/media/UQpVozKNDqWeQ/giphy.gif" alt="Radon alpha decay in a diffusion cloud chamber" width="400"></a> </div> <figcaption> <p><a href="https://www.youtube.com/watch?v=VJImbQU5w4A" title="Video: Radon alpha decay in a diffusion cloud chamber"><strong>Alpha decay. Inside your lungs. ๐Ÿ˜ฑ</strong></a></p> </figcaption> </figure> </div>

Why use the balena ecosystem?
All the goodness of Docker, plus security handling, IoT hardware optimized images, read-only rootFS, a build pipeline, a device management interface, and continuous deployment, for free (well, first 10 devices on balenaCloud โ€ฆor unlimited if you run your own OpenBalena platform).

Of course you could do all of this on your own, but do you really want to micro-manage, keep secure, always perform clean shutdowns, and generally baby something that should really be just plug-in, set-and-forget hardware? ๐Ÿค” I surely don't! ๐Ÿ˜…

<div align="center"> <figure> <div> <a href="https://www.youtube.com/watch?v=U81AuTemTkE" title="Video: Radon-220 decays into Polonium-216 then Lead-212"><img src="https://img.youtube.com/vi/U81AuTemTkE/maxresdefault.jpg" alt="Another view of radon alpha decay in a diffusion cloud chamber" width="400"></a> </div> <figcaption> <p><a href="https://www.youtube.com/watch?v=U81AuTemTkE" title="Video: Radon-220 decays into Polonium-216 then Lead-212"><strong>Radon-220 decays into Polonium-216 then Lead-212.</strong></a></p> </figcaption> </figure> </div> <p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p>

Table of contents ๐Ÿ“‘

  1. Prerequisites
  2. balena
    1. Preparation
    2. Installation
    3. Configuration
  3. Docker
  4. Alternatives
  5. Contributors
  6. Thanks
<p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p>

Prerequisites โœ…

  1. At least one Airthings Wave radon detector.
  2. Your favourite Internet of Things (IoT) device that offers both Bluetooth Low Energy (BLE) and network access, like the inexpensive Raspberry Pi Zero W.
  3. Working access to an MQTT broker, either a public one, your own hosted Mosquitto instance or the Home Assistant add-on.
  4. (Recommended) A free-tier account on balenaCloud along with a properly set SSH public key into your account.
  5. (Recommended) The balena command-line tools. Do read up on their friendly development guidelines.

Let's play! ๐Ÿค 

<p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p>

balena ๐Ÿ“ฆ

Follow these simple steps to quickly get your app running on a dedicated device using balenaCloud. If you want more control, try the Docker solution instead.

For reference, the balena framework will build the container using the ./Dockerfile.template which employs placeholders so that the correct system architecture is picked for you during installation. Easy!

Preparation ๐Ÿ”

  1. Create a new application on balenaCloud dashboard and select the appropriate IoT hardware.

  2. Add a new device to your app. Start with development mode for local testing, or go directly for production mode if you know what you're doing.

  3. (Optionally) Configure the downloaded image to give your device a custom hostname instead of the generic balena:

    sudo balena local configure /path/to/downloaded/image.img
    
  4. Burn the image to a disk and boot your IoT device.

Your hardware is ready; it's now time to install the project! โฌ‡๏ธ

<p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p>

Installation ๐Ÿ’ป

  1. Git clone this project's repository:

    git clone git@github.com:renemarc/balena-airthingswave.git
    
  2. Add your balena application as a secondary remote to the cloned repo:

    git remote add balena <username>@git.balena-cloud.com:<username>/<appname>.git
    
  3. Push the code to balenaCloud and wait for it to build and provision your device:

    git push balena master
    

Great! You are now ready to configure the project. โฌ‡๏ธ

<p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p>

Configuration โš™

Either modify the ./docker/config.yaml file with your MQTT and Airthings Wave(s) information, or ideally declare environment variables that will then be automatically replaced in the said configuration file.

I strongly suggest simply using environment variables, either at the whole fleet level, at the single device level, or at a mix of both. Configuration is easier to update this way and if you live in a McMansion you can provision multiple devices with the same codebase. Yay!

MQTT_BROKER   192.168.1.1
MQTT_PORT     1883
MQTT_USERNAME user
MQTT_PASSWORD super-secret-password

WAVES_NAME_1  radon/basement
WAVES_ADDR_1  cc:78:ab:00:00:0a
WAVES_NAME_2  radon/bedroom
WAVES_ADDR_2  cc:78:ab:00:00:0b
WAVES_NAME_3  radon/garage
WAVES_ADDR_3  cc:78:ab:00:00:0c

The Waves names are used as MQTT topic prefixes, so name them however you prefer. If you have more than one Wave that you want to query, do modify the ./docker/config.yaml file to add more entries.

Which MAC address to use? Leave that empty for now and proceed to the first run below. โฌ‡๏ธ

First run ๐Ÿƒ

There can be only one controller paired at a time, so do make sure that your Airthings Wave is "forgotten" from your mobile device by opening Airthings' mobile app and unpairing from there.

<div align="center"> <figure> <div> <a href="https://www.youtube.com/watch?v=_J3VeogFUOs" title="Video: There can be only one"><img src="http://i.imgur.com/G4yeJJo.jpg" alt="There can be only one" width="300"></a> </div> <figcaption> <p><strong>There should have only been one <em>Highlander</em> movie tooโ€ฆ</strong></p> </figcaption> </figure> </div>

SSH into your device (only if development mode was selected earlier) or use the balenaCloud app dashboard terminal to find your Wave's MAC address by issuing this command:

python /usr/src/app/find_wave.py

Press Ctrl+C when scanning seems to be done. Take note of the MAC address for the Wave that you want to use, and either modify ./docker/config.yaml or ideally create sets of environment variables for each Wave that you want to use.

Once configured, either git push your changes or restart the device.

Cron job โฒ

If your above parameters are correct, you should be receiving new MQTT messages every hour. Keep an eye on the streaming device logs in the balenaCloud dashboard and use an MQTT client to debug incoming messages.

Want to receive quicker updates? Modify the ./Dockerfile.template and change the CRON_PERIOD argument from hourly to 15min or to something else.

<div align="center"> <figure> <div> <a href="https://www.youtube.com/watch?v=k7QHB6Z-HS8" title="Video: Butters character study"><img src="https://media.giphy.com/media/3o6Zt60Fe3RpBVGBFu/giphy.gif" alt="Butters awarding himself a sunshine sticker" width="400"></a> </div> <figcaption> <p><strong>โ˜€๏ธ Good job! ๐Ÿ˜ƒ</strong></p> </figcaption> </figure> </div> <p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p>

Docker ๐Ÿณ

Want more control or wish to run this container on some multi-purpose shared hardware? Here are some useful steps.

Compared to the balena solution, here the regular ./Dockerfile is used.

<figure> <div align="center"> <img src="https://media.giphy.com/media/6AFldi5xJQYIo/giphy.gif" alt="Containers being moved in a yard"> </div> </figure>

Build and run ๐Ÿ—๏ธ

  1. Fork or clone this project's repository.

  2. Edit the ./docker/env.list file to setup your environment variables. See configuration above โฌ†๏ธ for details.

  3. Build the image:

    For a Raspberry Pi or Zero:

    docker build --tag=airthingswave .
    

    For everything else, specify the DEVICE_NAME argument with the relevant lowercase machine name from balena base images. For a Raspberry Pi 3 for instance:

    docker build --build-arg DEVICE_NAME=raspberrypi3 \
      --tag=airthingswave .
    
  4. Run the project as an auto-starting container:

    docker run --detach --restart=unless-stopped \
      --env-file=docker/env.list \
      --net=host --cap-add=NET_ADMIN \
      --name=airthingswave \
      airthingswave
    

    --net=host gives the container access to the host's network devices, including Bluetooth.
    --cap-add=NET_ADMIN gives the container network privileges.

  5. Perform the steps outlined in first run above โฌ†๏ธ using while inside the container:

    docker exec -it airthingswave bash
    
  6. Should you wish to change the cron job frequency, you can pass the CRON_PERIOD (default: hourly) argument while first building the image:

    docker build --build-arg CRON_PERIOD=15min \
      --tag=airthingswave .
    

Once ready and working, you can alternatively use this example one-liner to build and run the project:

docker run --detach --restart=unless-stopped \
  --env-file=docker/env.list \
  --net=host --cap-add=NET_ADMIN \
  --name=airthingswave $(docker build --quiet .)
<figure> <div align="center"> <img src="https://media.makeameme.org/created/containers-containers-everywhere.jpg" alt="Buzz Lightyear saying Containers everywhere!" width="400"> </div> </figure> <p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p>

Alternatives โš›

Other options exist, should you wish to try something else:

Community projects ๐ŸŒฑ

Official solutions ๐Ÿ‘ฎ

<div align="center"> <figure> <div> <a href="https://rationalwiki.org/wiki/Radiophobia" title="Definition of radiophobia"><img src="https://media.giphy.com/media/3o6Ztd4SAoP0tRDRWE/giphy.gif" alt="R is for radiophobia: the fear of radiation" width="300"></a> </div> </figure> </div> <p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p>

Contributors โœจ

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> <!-- prettier-ignore --> <table><tr><td align="center"><a href="https://renemarc.com/"><img src="https://avatars3.githubusercontent.com/u/13276793?v=4" width="100px;" alt="Renรฉ-Marc Simard"/><br /><sub><b>Renรฉ-Marc Simard</b></sub></a><br /><a href="https://github.com/renemarc/balena-airthingswave/commits?author=renemarc" title="Code">๐Ÿ’ป</a> <a href="https://github.com/renemarc/balena-airthingswave/commits?author=renemarc" title="Documentation">๐Ÿ“–</a></td><td align="center"><a href="https://www.beer.org/blog/"><img src="https://avatars0.githubusercontent.com/u/6561217?v=4" width="100px;" alt="Herb Peyerl"/><br /><sub><b>Herb Peyerl</b></sub></a><br /><a href="#ideas-hpeyerl" title="Ideas, Planning, & Feedback">๐Ÿค”</a> <a href="#plugin-hpeyerl" title="Plugin/utility libraries">๐Ÿ”Œ</a></td><td align="center"><a href="https://github.com/grangemd"><img src="https://avatars0.githubusercontent.com/u/20445621?v=4" width="100px;" alt="grangemd"/><br /><sub><b>grangemd</b></sub></a><br /><a href="https://github.com/renemarc/balena-airthingswave/issues?q=author%3Agrangemd" title="Bug reports">๐Ÿ›</a></td><td align="center"><a href="https://www.hackster.io/robin-cole"><img src="https://avatars2.githubusercontent.com/u/11855322?v=4" width="100px;" alt="Robin"/><br /><sub><b>Robin</b></sub></a><br /><a href="https://github.com/renemarc/balena-airthingswave/issues?q=author%3Arobmarkcole" title="Bug reports">๐Ÿ›</a></td></tr></table> <!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the all-contributors specification (emoji key available here). Found a bug, want to suggest an idea or share some improvements? Contributions of any kind are welcome! ๐Ÿ˜ƒ

<p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p>

Thanks ๐Ÿ’•

This Docker container is based on airthingswave-mqtt <sup>[MIT License]</sup> by Herb Peyerl (@hpeyerl) and the discovery code <sup>[MIT License]</sup> by Airthings.

Copyright ยฉ 2018, Renรฉ-Marc Simard. Project released under Apache Licence 2.0 with additional notices available here.

<p align="right"><a href="#top" title="Back to top">๐Ÿ”</a></p> <p align="center"><strong>Don't forget to <a href="#" title="star">โญ๏ธ</a> this repo! ๐Ÿ˜ƒ<br/><sub>Assembled with <b title="love">โค๏ธ</b> in Montrรฉal.</sub></strong></p>