SkinnyPi

A Raspberry Pi that flashed lights and played music whenever my Fitbit scale showed I had lost weight. A Laravel backend watched the Fitbit API, and when the number dropped it published over MQTT to Python running on the Pi. Built for one person, me.
SkinnyPi

Built 2017 to 2019  ·  Status Retired  ·  Stack Laravel 5.6, PHP, MySQL, Redis, Fitbit OAuth2, MQTT, Python on Raspberry Pi

SkinnyPi was a Raspberry Pi that threw a small party whenever I lost weight. My Fitbit scale reported to a Laravel backend, and when the number went down, the Pi flashed lights and played music. I called it Party Mode, or the Happy Dance.

Purpose

This one solved a problem I had, and only I had. Weighing yourself every morning is a quiet feedback loop: the number moves a little, you note it, nothing happens. I wanted the good mornings to be loud. Making the reward physical and immediate seemed like better positive reinforcement than another line on a chart, and it was a nicer way to start the morning.

It was also an excuse to build something. I had just finished an Internet of Things course at MIT in grad school, so I had a basic understanding of communication protocols. SkinnyPi was where I wired them to actual hardware.

What it did

The system was two pieces of software talking over a message broker.

On the server side, a Laravel application authenticated against the Fitbit Web API using OAuth 2, pulled the readings from my Fitbit Aria scale, and stored them along with the Fitbit access tokens, so the connection kept working without me re-authorizing it. Each new reading was compared against the previous one, and a drop was the trigger condition. The Laravel app also had its own user accounts and login, and it ran on hosted infrastructure at Cloudways.

When a drop registered, the Laravel side published a message to an MQTT broker, hosted on CloudMQTT. On the other end, Python code running on a Raspberry Pi 3 Model B held a subscription to that topic. Receiving a message was the cue to run the celebration: lights and audio.

Publishing and subscribing, rather than having the Pi poll an endpoint, is the part worth explaining. A Raspberry Pi sitting on a home network has no public address for a server to call into. With a broker in the middle, both sides opened outbound connections to it, and the server never had to know or reach the device's address. That is what carried the trigger from a hosted PHP application to a device at home without any inbound access to the network it sat on.

Features

  • Fitbit sync. Authenticated against the Fitbit Web API over OAuth 2 and pulled weight readings from a Fitbit Aria wifi scale.
  • Token storage. Kept the Fitbit access tokens in the database, so the connection held between runs instead of needing a fresh authorization each time.
  • Weight loss trigger. Compared each reading against the previous one and fired only when the number had gone down.
  • Publish and subscribe messaging. Sent the trigger from the Laravel app to a hosted MQTT broker, which the Raspberry Pi subscribed to.
  • Party Mode. Python on the Raspberry Pi 3 Model B answered the message by flashing lights and playing music.
  • User accounts. Login on the Laravel side.

Impact

The honest scope is one person and one Raspberry Pi. I built it for myself and ran it in my own house. It was never a product and it never had users other than me.

What it did produce was a complete IoT loop I designed and built end to end, from a wifi scale through a third-party API, a hosted PHP application, a message broker, and out to hardware in my house. I built it in 2017, shelved it, and came back in early 2019 to finish the documentation, record a demo, and publish the code.

Screens