"Get On The Beers" Indicator Using Electric Imp
Tags: showdev, electronics, twilio
Published: 2021-01-04 00:06:03

While I was building my friend an [On Air Light that turns on when streaming](https://dev.to/mitchpommers/how-i-made-a-light-that-turns-on-when-streaming-1f6l), I thought it was really cool and wanted to build my own indicator light. I don't stream so had to think of something different to use the light to indicate. I saw this tweet in my twitter feed and it gave me an idea!

{% twitter 1340944007652753411 %}

I could use a light to indicate if there was community transmission of COVID-19 and if it was safe to go to the pub! The colour of the light would indicate how long since the last case of community transmission:
- Local transmission -> Red
- First week of no local transmission -> Blue
- Second week of no local transmission -> Green
- Further weeks -> Multi-Coloured Rainbow

# Finding The Data

Finding a reliable source of data for this project took a lot of research. The data I am looking for is community transmission in New South Wales, Australia. There are an abundance of COVID-19 APIs available, almost all using data from the [John Hopkins University CSSE COVID-19 Git Repo](https://github.com/CSSEGISandData/COVID-19). This dataset does contain NSW data but does not contain information about community transmission, so any API that only uses this as its data source is out of the question.

Data.NSW has a dataset published for [COVID-19 Cases By Likely Source Of infection](https://data.nsw.gov.au/data/dataset/nsw-covid-19-cases-by-likely-source-of-infection), which could be used to determine how many days since the last case of community transmission, but this requires processing to understand. They also have some other datasets with similar information, but I was unable to find one that gave days since last community transmission as a value.

Then there is [COVID-19 in Australia Data](https://www.covid19data.com.au/) with beautiful graphs and tables visualising COVID-19 data in a variety of different ways. One of their visualisations is how many days it has been between different milestones, split by state. If I could access the data used for the visaulisations I could use it for my visualisation.

They use Datawrapper to do the visualisations and by looking at what Datawrapper does in the browser, I was able to see that it loaded a CSV from their CDN with the data in it. I can directly access the CSV files, and after checking multiple days I could see that the filenames did not change!

The CSV format used is simple. It has a single header row, then the data rows. The data rows start with the state, followed by three integer fields for local, overseas and active cases. CSV is a nice file format because it can generally be easily processed without the need for a library to understand it.

```
,Days since a new local case,Days since a new overseas case,Days since any active cases
...
NSW,0,0,0
...
```

# Coding the Electric Imp

Now that I know I have the data, I can start working on the code. For this project I'm using an [Electric Imp impExplorer Developer kit](https://store.electricimp.com/collections/featured-products-1/products/impexplorer-developer-kit), meaning I don't need to do any electronics. After [performing a BlinkUp, getting familiar with the impCentral IDE and creating a new project](https://developer.electricimp.com/gettingstarted/explorer) I was ready to start writing some code.

![The Electric Imp impExplorer board](https://dev-to-uploads.s3.amazonaws.com/i/xjrpzgam7x1vfzcv38t2.jpg "The Electric Imp impExplorer board")

The Electric Imp platform gives you both a device and an agent that you can run code on. This lets you do power/resource intensive processing on the agent and send instructions as a result to the device. It also means that as long as the device can communicate with the agent, the agent can reach out to the internet. Conversely from the internet you can talk to the device via the agent. For this project, I want to process the CSV on the agent, send the result to the device and have the device do something as a result.

## Turning the LED on

The first step in building the light is to get the light on the impExplorer to turn on and log that it has started. To do this, we need to include the [WS2812 library](https://developer.electricimp.com/libraries/hardware/ws2812), [set pin 1 to be a digital output on the ImpExplorer](https://developer.electricimp.com/hardware/resources/reference-designs/explorerkit), then configure and use the library to turn the LED on.

Logging on the device can be achieved by using [server.log](https://developer.electricimp.com/api/server/log), which will log to impCentral.

**Device Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=1. Device.nut %}

## Device To Agent Communication

Now that the LED is turning on when the device starts, we want to use device to agent communication. Electric Imp lets us do this by registering functions that will process a message from the device the the agent and vice-versa.

On the agent you use [device.on](https://developer.electricimp.com/api/device/on) to register a function to handle messages from the device. On the device you use [agent.send](https://developer.electricimp.com/api/agent/send) to send the message to the agent. Using these two functions lets us talk from the device to the agent.

**Agent Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=2. Agent.nut %}

**Device Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=2. Device.nut %}

## Agent To Device Communication

Now that we have the impExplorer asking the agent for an update, we want the agent to respond. Similar to device to agent communication, there is [agent.on](https://developer.electricimp.com/api/agent/on) to register a function to handle a message on the device and [device.send](https://developer.electricimp.com/api/device/send) on the agent to send a message to the device.

**Agent Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=3. Agent.nut %}

**Device Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=3. Device.nut %}

## Colour Decisions

Once we have the device asking the agent for an update and the agent responding, we can start programming the device to have it respond to the messages sent from the agent. The function we wrote to handle the messages from the agent has to have a parameter for the data that the agent sends. This data could be any object. Since we are sending days since the last community transmission, we can send a single integer and make the colour decision on the device from that.

**Device Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=4. Device.nut %}

## Polling For The Latest Data

Our indicator light is working! We can manually change the data we are sending to get the light to change colour to test out the different colours.

Something we haven't done is make the device poll for updates. It will get the colour at power on and not update until a restart. We don't want to have to restart the imp regularly, so we need to create a loop.

We could use a `while(true)` loop, but doing this would prevent the imp from going into low power modes and drain the battery quickly (if run on batteries). Instead we can use [imp.wakeup](https://developer.electricimp.com/api/imp/wakeup) to create a timer that will execute a function when the timer fires. If we put this in the `requestUpdate` function and have it call `requestUpdate` we create an infinite loop that allows the imp to go into low power modes.

**Device Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=5. Device.nut %}

## Getting The Correct Data

Now that we have the device polling for the agent for updates and updating the colour of the light based on the response, we need to update the agent to get our CSV, process the data and then send the our response.

**Agent Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=6. Agent.nut %}

## Working Code

We're nearly done! We have the device polling the agent and updating the lights, and the agent will reach out and get updated information when asked.

**Agent Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=7. Agent - Code Complete.nut %}

**Device Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=7. Device - Base Code Complete.nut %}

## Adding Multicoloured Lights

The light going white isn't as flashy as we want for the big achievement of reaching two weeks without any cases of community transmission. For that we want the light to go change colours! We can do this by making a Rainbow Mode! When in rainbow mode we have the light change colour slightly, travelling around the colour wheel.

**Device Code:**
{% gist https://gist.github.com/mpomery/5395012dce6cbd116937c527882d4dda file=8. Device - Code Complete.nut %}

# Housing And Mounting It

Now that the indicator light is working, we need a way to display it so that the information is understandable. Otherwise it's just a bare board and the light could be indicating anything. For this project I drew up a box that the imp could sit inside in CAD and put text on the front of it with the indicator light to explain the status.

Keeping with the Dan Andrews "Get On The Beers" theme, I went with the following:
- Red - The Pub Is Shut
- Blue - Case Last Week
- Green - Can't Be Any Clearer
- Multicoloured - Get On The Beers

Using the laser cutter at my local makerspace I was able to cut out the box and glue it together, making sure not to glue the top so that I could still access the imp inside.

![Attempting to get a good engrave on the laser cutter](https://dev-to-uploads.s3.amazonaws.com/i/b5blcjtnincnewcqt6zd.jpg "Attempting to get a good engrave on the laser cutter")
![A close up of the bad engraving. The text is fuzzy and hard to read.](https://dev-to-uploads.s3.amazonaws.com/i/6rzd0exuaaxxzjwjt894.jpg "A close up of the bad engraving.")
![The glue up of the final housing, making sure to keep the lid off](https://dev-to-uploads.s3.amazonaws.com/i/ylvs614009ljwanxjc0r.jpg "The glue up of the final housing")
![The housing glued up and ready to home. The text on it is clear and reads "Beers? Red - The Pub Is Shut. Blue - Case Last Week. Green - Can't Be Any Clearer. Multi - Get On The Beers"](https://dev-to-uploads.s3.amazonaws.com/i/rr4zwso8unw6uki84d88.jpg "The housing glued up and ready to home. The text on it is clear")

Finding somewhere to put it around the house was difficult. I wanted it somewhere where I would see it every day, but not somewhere where it would be visible to me for most of the day. I try to make sure I head out for a walk at least once a day around lunch time, so decided to mount it by the front door, plugged into an extension cord so I don't have to worry about battery life.

![The Get On The Beers Indicator Light in it's final home. It sits on top of a dusty shelf near a headphone hook, desk light and motorcycle helmet, with a figurine behind it. The indicator light is unfortunately red.](https://dev-to-uploads.s3.amazonaws.com/i/fpch1fltfo48nbm2v6yu.jpg "The Get On The Beers Indicator Light in it's final home")

# Reflection

I had a lot of fun building this indicator light and writing about it and got to learn more about the laser cutter I get to use. The more I read about Electric Imps, the more I see how I could make improvements to the code I have written. I am going to need to order more of them so I can use them in more projects. 

I have been thinking about what I could an indicator light for when COVID-19 community transmission is no longer a major concern in my area.

- I could update it to be a visual clock that indicates morning, lunch, afternoon, when it is time to head to the pub, and bedtime with different colours instead of the actual time.
- I could swap the front panel from the box and make a [busy light for meetings](https://www.youtube.com/watch?v=8_FdR-L7qrs) like Christine Sunu has done.
- I could send it to the office with my colleagues in another state and use it as a presence light so they can see when I am at my desk and available.

The possibilities are endless!