This project piggybacks on my last article Creating an IoT Scrolling Marquee with Slack and Particle.
Instead of a scrolling marquee displaying unique messages, I wanted to only receive notifications when a continuous integration platform failed a build. Things that would be helpful in this notification would be, what branch failed and who was the user.
CircleCI is a great continuous integration platform that I use a lot for personal projects, however I sure this approach (or similar) will work with most.
The CircleCI config.yml allows you to call a command on "Build Failed". This is great, because we can cURL a POST request to an API passing it our CIRCLE_BRANCH and CIRCLE_USERNAME. Easy!
Once additional spin on my approach with this project is that I wanted to use Particle Mesh Networking. Essentially, a Particle mesh network consists of a gateway device with network access, and one/may endpoint devices. A much better explanation can be found here on the Particle blog.
My example is going to use the Argon WiFi gateway device and 2 x Xenon endpoint devices.
Gateway and endpoint devices can communicate with each other by publishing or subscribing to events. Only devices on this network will have access to these events.
Knowing this, we can define a function on our gateway device (Argon) display_broken_build, which when called by the API, can then emit a custom event on our network matrix_display_message. Our endpoints, which will be subscribing to the event matrix_display_message, can then perform a specific action.
My plan is to have 1 Xenon endpoint operate a scrolling marquee, while the other Xenon endpoint displays a tally of the amount of broken builds. What this showcases is that in a workplace environment, we could have multiple devices on our network displaying notifications of broken builds and perhaps more detailed statistics.
First we need a build that will fail. Create a git repo and create a .circleci/config.yml file. (see example)Make sure you then select your git repo in the CircleCI app.Also create a package.json file in your new repo.
This manifest will have no dependencies or scripts. (see example)
my-failing-repo | - .circleci/config.yml | - package.json
Pushing this to github with cause CircleCI to build your project.
First it will install npm dependencies, and then npm foo which shouldn't existing in your package.json file, resulting in a failed build.
I've created a expressJS API (index.js) with a single route /display.
On /api/display the API will log into my device and call it's display_broken_build function, passing it the branch and user values.
The API references environment variables stored in a local.env file.
PDEVICE=particle_device_id PUSER=particle_user PPASS=particle_password
The API is then hosted on now and my now.json manifest exposes my route and secrets to the API.
You can provide your secrets to your now deployment like so:
now secret add mesh-pub-user email@example.com
Once the API has deployed, update the reference to the endpoint in your .circleci/config.yml file.
I’m using the Argon as my gateway device.
Using Particles’ Workbench, I flashed the argon-publish.ino on my device.
You'll notice on setup I define the function display_broken_build that accepts a command (string), and on the event that function is called via the API, I call a displayMessage function, which will then emit matrix_display_message out onto the network.
The code for this device (xenon-subscribe-scrolling-marquee.ino) is very similar to my original scrolling marquee example.
The difference being that on setup this device subscribes to a matrix_display_message event. Once received, call displayMessage, resulting in writing to the LCD.
The code for this device (xenon-subscribe-counter.ino) is pretty simple.
I initialise a count of 0, and every time matrix_display_message is published it calls logToDisplay, incrementing the count by one and sending it to the LCD display.
Once the API was deployed, devices flashed, and failing CircleCI repo published, I had my own sweet IoT network of displays notifying me when a build had failed.