DEV Community

loading...

Building a Fitness Insights Dashboard

Anthony Bloomer
👋
・4 min read

Introduction

As a motivator to maintain a healthy diet and to get into a routine of daily workouts, I have started to track my intake and exercise habits using MyFitnessPal and other mobile applications. Pulling data from those sources and creating custom events in New Relic Insights allows me to keep track of my progress and provides a way for me to query my data using NRQL and to create visualizations.

Data Sources

The two main applications I use for tracking is MyFitnessPal and MapMyWalk. MyFitnessPal allows you to track your diet and exercise to determine optimal caloric intake and nutrients for your overall goal. MapMyWalk allows you to track cardiovascular activities such as running, walking, and even stationary bike exercises.

Although MyFitnessPal does have an API, it is private-access only. To get around this, I found a Python library called python-myfitnesspal which allows you to scrape your data from MyFitnessPal. See the example below:

import myfitnesspal

client = myfitnesspal.Client('my_username')
day = client.get_date(2013, 3, 2)
day
# >> <03/02/13 {'sodium': 3326, 'carbohydrates': 369, 'calories': 2001, 'fat': 22, 'sugar': 103, 'protein': 110}>

For a daily summary of your nutrition information, you can use a Day object's totals property:

day.totals
# >> {'calories': 2001,
#     'carbohydrates': 369,
#     'fat': 22,
#     'protein': 110,
#     'sodium': 3326,
#     'sugar': 103}

If you want to see the amount of water you've recorded:

day.water
# >> 1

Perfect. These are exactly the data points I am interested in. So, once a day, I call the API to get those values and record a custom event using the Python Agent API:

def send_intake_data():
    client = myfitnesspal.Client(USERNAME, PASSWORD)
    day = client.get_date(datetime.datetime.now())
    totals = day.totals
    totals.update({'water': day.water})
    newrelic.agent.record_custom_event('Meal', totals, application)

Similarly to MyFitnessPal, MapMyWalk does have an API but it is private access only. To address this issue, I wrote a simple script using Selenium which logs into the MapMyWalk website and then goes to a JSON resource which holds my workout data. Once every day, I call this script to get workout data for that day and then record a custom event in Insights:

def login():
    logger.info("Logging into MapMyWalk")
    driver = webdriver.Chrome(options=chrome_options)
    driver.get(LOGIN_URL)
    driver.find_element_by_id('email').send_keys(USERNAME)
    driver.find_element_by_id('password').send_keys(PASSWORD)
    driver.find_element_by_id('password').send_keys(Keys.ENTER)
    return driver

def get_workout_data():
    d = login()
    time.sleep(3)
    today = datetime.date.today()
    d.get(WORKOUTS % (today.month, today.year))
    time.sleep(3)
    pre = d.find_element_by_tag_name("pre").text
    data = json.loads(pre)
    logger.info("JSON response: %s" % data)
    wd = data['workout_data']['workouts']
    d.close()
    d.quit()
    today = str(today)
    if today not in wd:
        logger.info("No workouts found for today.")
        return None
    else:
        return wd[today]

def send_workout_data():
    workout_data = get_workout_data()
    if workout_data is not None:
        for w in workout_data:
            logger.info(w)
            newrelic.agent.record_custom_event('Workout', w, application)

You can find the complete source code on my GitHub. The documentation covers project setup and deployment instructions.

Insights Dashboard

Image

Installation

This project uses python-myfitnesspal to programmatically interact with and analyze the information I have entered into MyFitnessPal. To authenticate, you'll need to export your username and password as environment variables:

export FITNESS_PAL_USERNAME='YOUR_USERNAME'
export FITNESS_PAL_PASSWORD='YOUR_PASSWORD'

I'm using Selenium and the ChromeDriver to automate data retrieval from the MapMyWalk website. You will need to have Google Chrome and ChromeDriver installed. If you are using macOS, you can install ChromeDriver using Homebrew:

brew cask install chromedriver

To send metrics to New Relic Insights, you will also need to export your application name and license key:

export NEW_RELIC_LICENSE_KEY='YOUR_LICENSE_KEY'
export NEW_RELIC_APP_NAME='YOUR_APP_NAME'

Then, create a new Virtual Environment and install the project requirements:

virtualenv env
source env/bin/activate
pip install -r requirements.txt

Finally, launch the worker:

python fitnesspal.py

The program uses schedule to send metrics once a day at 23:30pm.

Deploying to Heroku

Since I'm using Selenium to automate data retrieval from MapMyWalk, you'll need to install the following buildpacks:

You will also need to configure the environment variables outlined in the installation above, for example:

heroku config:set NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY

Querying Insights Data

This tool creates two custom events, Meal and Workout, which you can query using NRQL in Insights.

Examples

Get your average calorie intake since 1 week ago:

SELECT average(calories) FROM Meal SINCE 1 week AGO TIMESERIES 1 day 

Get the total number of steps walked since 1 week ago:

SELECT sum(steps) FROM Workout SINCE 1 week AGO TIMESERIES 1 day 

Get the total amount of water consumed:

SELECT sum(water) FROM Meal SINCE 1 week AGO TIMESERIES 1 day 

Discussion (0)

Forem Open with the Forem app