Building a 21st century star chart using a Raspberry Pi and Amazon Dash Buttons
The world is full of tech evangelists who think that technology is our route to salvation. Faced with any problem, they think all you need to do is rub a bit of tech on and pow, the problem disappears. I am not one of those people, but I like to think I’m on the way to helping my son behave better at school, and it’s all thanks to a Raspberry Pi, a couple of Amazon dash buttons and some software I wrote at work.
My son’s school has a behaviour and reward system of points. Achievement points are rewarded for good work, and behaviour points are issued when they misbehave. This is all logged on a terrible proprietary system built by Capita. Since he started school last year, I decided to build a screen scraper to monitor this system. It would then email me and my wife if there had been any issues that day, and log the points in my own install of Bothan, a system I helped build at work for tracking and visualising metrics. I then could visualise the points on a dashboard, saving me the pain of having to log into the hateful school system every day (You can see the code on Github here).
This worked reasonably well, and churned away in the background for the whole my son’s first year of school (and probably saved me a whole bunch of time). When my son reached Year One however, I realised that we were going to need something else.
In his first few weeks of school, he’d racked up 29 behaviour points, not for any sort of major naughtiness, just low level cheekiness and messing around, y’know, the sort of stuff that five year olds do. Whether or not I agreed with what the school was doing, I knew I needed to help him get better at school.
My wife and I therefore decided we were going to set up our own behaviour and achievement points system at home — if he has a bad day at school, he gets a behaviour point (unlike the FIVE points the school give him for ever misdemeanour), if he has a good day, he gets two reward points (my son responds MUCH better to the carrot than the stick). We’d also give him points for his general behaviour at home. If he gets a certain amount of reward points by the end of November (his birthday), he can have a big birthday party with all his friends.
The problem then became, how can we log these points in a way that’s engaging for him? We’d tried star charts before, and they were fine for a few weeks, but then the novelty wore off, the charts got tatty and he ended up disengaging from the whole process. Luckily, Amazon dash buttons have just been released in the UK, and I was itching for an excuse to do something with them.
I ordered two buttons, together with a Raspberry Pi 3, and set to work. Whenever I set out on a project of this nature, I always reach for the language I feel comfortable with, and that’s Ruby. After installing a modern version of Ruby on my Pi, I installed the Dashed gem, and followed the instructions to set it up. However, no matter what I did, I couldn’t get it to work. After some furious googling, I found that the firmware in Dash buttons had changed, and the protocol had switched from ARP to UDP. I also found a Node Library that was much better supported, and came with great documentation, so decided to use that instead.
After installing Node and the node-dash-button library, as well as libpcap (which is required to sniff network traffic) on my Pi (instructions here), the next thing I needed to do was to set up my Dash buttons. I opened the Amazon app, and in settings, there’s a link to set up your dash buttons. This gets your buttons connected to the web via your WiFi network, and allows you to choose what product you want to order every time the button is pressed.
I skipped that last step, and followed the instructions to sniff my network to get the MAC addresses of my buttons, by running `node_modules/node-dash-button/bin/findbutton` on my Pi. I pressed each button in turn and got the MAC addresses of the buttons without any trouble at all.
Then came my favourite part, writing code. The first thing I did was to catch each button press and log to the console, to check everything was working:
var dash_button = require('node-dash-button');var bad_button = '' // The MAC address for the good button goes herevar good_button = '' // The MAC address for the bad button goes here
var dash = dash_button([bad_button, good_button], null, null, 'all');
dash.on("detected", function (dash_id){if (dash_id === bad_button){console.log("Naughty!")} else if (dash_id === good_button){console.log("Good!");}});
I saved this (as index.js), and ran the code from the command line via `sudo node index.js` (you need sudo, as libpcap requires administrator priviliges), and to my astonishment, it worked! I did have a problem that every time I pressed the button I got a nagging push notification on my phone from the Amazon app, telling me to finish setting up my button, but luckily you can turn this off in the Amazon app settings. The next step was to log these button presses somewhere.
I mentioned earlier about Bothan. I was already logging the school’s points in there, so it made sense to store the points from home there too.
Bothan started out as a simple API for the Open Data Institute to log financial and other metrics, we then built on visualisation components (so you can see the data as a graph, pie chart, simple number or target graph), and finally a dashboard building tool. Anyone can deploy their own version of Bothan, and metrics are added via a simple REST API. It was this REST API that I needed to leverage to log the points, so, armed with the request library, I set to work and wrote a method to get the current score for a behaviour or merit point, add one, and then push the latest data to Bothan:
var bothan_url = '' // The URL of your Bothan installvar bothan_username = '' // The URL of your Bothan installvar bothan_password = '' // The URL of your Bothan install
var postPoint = function(metric) {var bothanURL = bothan_urlvar metricURL = bothanURL + '/metrics/' + metric + '.json'var date = new Date()
request(metricURL, function(error, response, body) {json = JSON.parse(body)value = (json == null) ? 0 : json.value
request.post(metricURL, {
auth: {
user: bothan\_username,
pass: bothan\_password
},
json: {
time: date.toISOString(),
value: value + 1
}
})
})}
(I realise it’s a faff to get the latest metric and add one (as well as an extra HTTP request), so one of the improvements I’d like to make to Bothan is to add an /append API method to just add one to a given metric)
With this method, it was just a case of calling the method with the metric name to log either a behaviour or merit point to Bothan, like so:
dash.on("detected", function (dash_id) {if (dash_id === bad_button){console.log("Naughty!")postPoint('home-behaviour-points')} else if (dash_id === good_button){console.log("Good!");postPoint('home-acheivement-points')}});
I then added a package.json file with the dependencies, together with a script definition, so the code could be run vianpm start, and then looked at how I could automatically run this on my Pi on boot. I’ve done this before in other projects (like Ellie Harrison’s Vending Machine art piece, which me and a colleague rengineered after the original laptop powering it broke down), and used init.d scripts, but this seemed like overkill. This time, I just added the following command to /etc/rc.local to make the script chug away happily in the background:
cd /home/pi/quantified-boy && npm start &
(The final & is important here, as it forks the process, otherwise the Pi would just run this script and never boot properly)
I rebooted, tested and it worked. The final piece of the puzzle was displaying the metrics, so I could see at a glance how my son was doing, and crucially, so he could get instant feedback after he pressed the button. I used Bothan’s dashboarding feature to build a dashboard (linking to a demo one here), and added the following to the~/.config/lxsession/LXDE-pi/autostart file to open the dashboard URL in Chromium in kiosk mode, and stop the Pi from going to sleep, so I could see the dashboard at any time:
@xset s off@xset -dpms@xset s noblank@chromium-browser --kiosk --incognito http://demo.bothan.io/dashboards/bothan
I then rebooted the Pi, and after the boot completed I saw my dashboard. Finally, I invested £27 in a 5 inch screen from Amazon, and set the whole lot up in the kitchen:
A week or so has passed, and my son loves engaging with the button (I say ‘button’, because he never wants to press the behaviour point button for some reason). He loves the instant gratification of seeing his points go up, and it’s a great way of getting him to engage beyond the normal star chart.
The final code is available on Github here, and you can install your own free instance of Bothan via bothan.io. You can use this code to measure anything. The only limit, as they say, is your imaaaaaaaagination!