The world is excited about the new Fitbit wearable devices. So is DataArt’s Wearables Competence Center. We decided to play with some of them to find out about the new development opportunities. This article is dedicated to Fitbit.
About Fitbit devices
Currently, the Fitbit products include Zip and One clips, Flex, Charge, ChargeHR, and Surge wristbands, and Aria smart scale. ChargeHR and Surge are brand-new. 
Most of them can track your steps taken, stairs climbed, calories burned, hours slept, distance traveled, and quality of sleep, and have an alarm clock. The advanced features of the new devices are heart rate and GPS tracking, clock and notifications display, music control and others. Stats are synced wirelessly and automatically to a leading smartphone or a PC and the Fitbit servers.
How to program
The first thing to mention is that you cannot interact with a Fitbit device directly. Actually, it is a significant restriction and it will be discussed in the text below. It would be useful to be able to communicate via the Bluetooth LE interface, but it is currently not possible . You have to use the Fitbit RESTful services or the API client libraries which are available for a number of languages.
First of all, a client app must be authenticated with the OAuth 1.0 protocol (Fitbit has not transitioned to OAuth 2.0 yet). The official Fitbit documentation  suggests you use some third-party library to complete it and provides a list of those tested .
Let’s consider Temboo  together with Java. You have to register your app at dev.fitbit.com and with Temboo (or with the library of your choice). You get a consumer key and a consumer secret from Fitbit and use them to authorize. Firstly, you need to generate an authorization URL that the application can use to complete the first step in the OAuth process:
TembooSession session = new TembooSession(tembooUserName, tenbooAppName, tembooAppKey); InitializeOAuth initializeOAuthChoreo = new InitializeOAuth(session); // Get an InputSet object for the choreo InitializeOAuthInputSet initializeOAuthInputs = initializeOAuthChoreo.newInputSet(); // Set inputs initializeOAuthInputs.set_ConsumerSecret(consumerSecret); initializeOAuthInputs.set_ConsumerKey(consumerKey); InitializeOAuthResultSet initializeOAuthResults = initializeOAuthChoreo.execute(initializeOAuthInputs);
The output contains an AuthorizationURL, a CallbackID, and an OAuthTokenSecret. The application’s user needs to go to the authorization URL in order to grant access to your application. The CallbackID is used to retrieve the callback data that Temboo stores once your application’s user authorizes. The temporary OAuth Token Secret can be exchanged for permanent tokens in the next step.
When the access has been allowed via the AuthorizationURL, you can finalize the authorization as follows:
FinalizeOAuth finalizeOAuthChoreo = new FinalizeOAuth(session); // Get an InputSet object for the choreo FinalizeOAuthInputSet finalizeOAuthInputs = finalizeOAuthChoreo.newInputSet(); // Set inputs finalizeOAuthInputs.set_CallbackID(callbackID); finalizeOAuthInputs.set_OAuthTokenSecret(oAuthTokenSecret); finalizeOAuthInputs.set_ConsumerSecret(consumerSecret); finalizeOAuthInputs.set_ConsumerKey(consumerKey); // Execute Choreo FinalizeOAuthResultSet finalizeOAuthResults = finalizeOAuthChoreo.execute(finalizeOAuthInputs);
This code completes the OAuth process by retrieving an access token and token secret for the user.
That’s it! Now you can read or update the Fitbit data using the same library. Let’s get the user’s activities for a specified date:
GetActivities getActivitiesChoreo = new GetActivities(session); // Get an InputSet object for the choreo GetActivitiesInputSet getActivitiesInputs = getActivitiesChoreo.newInputSet(); // Set inputs getActivitiesInputs.setCredential(yourCredentials); getActivitiesInputs.set_Date("2013-03-18"); getActivitiesInputs.set_ResponseFormat("json"); // or xml - optional (default is json) getActivitiesInputs.set_UserID("123123"); // optional (default is the current user) // Execute Choreo GetActivitiesResultSet getActivitiesResults = getActivitiesChoreo.execute(getActivitiesInputs);
You will get the response in json or xml format, parse it and use it to be displayed or make calculations.
Data input looks practically the same. Consider logging pizza for lunch:
LogFood logFoodChoreo = new LogFood(session); // Get an InputSet object for the choreo LogFoodInputSet logFoodInputs = logFoodChoreo.newInputSet(); // Set inputs logFoodInputs.setCredential(yourCredentials); logFoodInputs.set_Amount("3"); logFoodInputs.set_MealType("Lunch"); logFoodInputs.set_Date("2011-10-14"); logFoodInputs.set_UnitID("147"); // food units; 147 is for “grams” logFoodInputs.set_FoodID("10409"); // food id for pizza // Execute Choreo logFoodChoreo.execute(logFoodInputs);
It is worth mentioning that the Fitbit API includes The Resource Access API which contains a long list of REST endpoints that allow reading and modifying user resources via their URLs (HTTPS).
We want your feedback!
But we want to get more from the Fitbit devices – to design new use cases to communicate with them or to receive some customized feedback! Most Fitbit devices have LED lights or displays and can vibrate and these seem to be a suitable means for interaction. Imagine, the wristband’s lights blink on an incoming call or it vibrates when a user presses a button in their smartphone app.
Unfortunately, there is an insurmountable hurdle outlined earlier: you cannot communicate with a Fitbit device directly, only through the Fitbit API.
Anyway, you are able to trigger lights or vibration with the help of the API. A device vibrates when:
- a daily goal is reached;
- an alarm is activated;
- sleep mode is (de)activated .
The LED lights go on when:
- a daily progress is displayed;
- an alarm is activated;
- sleep mode is (de)activated;
- the device is being charged;
- an update fails.
But even taking all that into consideration, we face another obstacle – once a user has updated the settings (for example, added new time for alarm or set a new daily goal), they need to sync the device with the server for these updates to take effect:
- sync with a PC (run a Fitbit app, stay within 20 feet);
- sync with a smartphone (run a Fitbit app, ensure Bluetooth communication enabled);
- via NPC;
- force syncing with the button in a Fitbit app;
- background syncing (ensure enabled and connected – within a range).
There are two striking points here. Firstly, it is odd that you invoke vibration for an incoming call (as an example) by setting your alarm clock. Secondly, it is evident that there is quite a low chance that a device will synchronize immediately after you update the settings. Consequently, your event will be lost.
Briefly, it is very simple to read or write ordinary Fitbit data. You can analyze or just display it in your own applications. But it is awkward to initiate any instant Fitbit operation from outside, this is mainly caused by the fact that you are not able to interact with a device directly, but only by the means of its server API.