Created
February 7, 2013 17:38
-
-
Save jacoby/4732649 to your computer and use it in GitHub Desktop.
Simple program to read battery information and last synchronization from my FitBit device. Amongst the bugs: Only reads one device, hardcoded consumer key and secret. But an early working piece of Python code, adapted from https://groups.google.com/forum/#!msg/fitbit-api/CkXQ6-0-vMs/VaX_V6gm3BUJ.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
''' | |
Description: | |
Using the FitBit API get the device info | |
then, put it into the Redis NoSQL database for other programs to check | |
Displays: | |
<?xml version="1.0" encoding="UTF-8"?><result><summary><activeScore>44</activeScore><caloriesOut>1894</caloriesOut><distances><activityDistance><activity>total</activity><distance>0.11</distance></activityDistance><activityDistance><activity>tracker</activity><distance>0.11</distance></activityDistance><activityDistance><activity>loggedActivities</activity><distance>0</distance></activityDistance><activityDistance><activity>veryActive</activity><distance>0</distance></activityDistance><activityDistance><activity>moderatelyActive</activity><distance>0.03</distance></activityDistance><activityDistance><activity>lightlyActive</activity><distance>0.08</distance></activityDistance><activityDistance><activity>sedentaryActive</activity><distance>0</distance></activityDistance></distances><fairlyActiveMinutes>7</fairlyActiveMinutes><lightlyActiveMinutes>20</lightlyActiveMinutes><sedentaryMinutes>1413</sedentaryMinutes><steps>260</steps><veryActiveMinutes>0</veryActiveMinutes></summary></result> | |
Reference: | |
http://wiki.fitbit.com/display/API/Fitbit+API | |
http://wiki.fitbit.com/display/API/API-Get-Activities | |
http://wiki.fitbit.com/display/API/OAuth-Authentication-API#OAuth-Authentication-API-TheOAuthFlow | |
http://oauth.net/core/1.0a/ | |
Notes: | |
FitBit API rejects oauth.OAuthSignatureMethod_HMAC_SHA1() | |
generated signatures so use oauth.OAuthSignatureMethod_PLAINTEXT() | |
instead. | |
''' | |
import os, httplib | |
import datetime | |
import redis | |
import simplejson as json | |
import time | |
# Install oauth for python. On Ubuntu run: sudo apt-get install python-oauth | |
from oauth import oauth | |
#XXX: register your FitBit client: https://dev.fitbit.com/apps/new | |
#XXX: which gives you a consumer key/secret | |
CONSUMER_KEY = '#####YOUDONTGETTOHAVEMYKEYS#####' | |
CONSUMER_SECRET = '#YOUDONTGETTOHAVEMYSECRETSEITHER' | |
SERVER = 'api.fitbit.com' | |
REQUEST_TOKEN_URL = 'http://%s/oauth/request_token' % SERVER | |
ACCESS_TOKEN_URL = 'http://%s/oauth/access_token' % SERVER | |
AUTHORIZATION_URL = 'http://%s/oauth/authorize' % SERVER | |
ACCESS_TOKEN_STRING_FNAME = '/home/jacoby/dev/FitBit/access_token.string' | |
DEBUG = False | |
# pass oauth request to server (use httplib.connection passed in as param) | |
# return response as a string | |
def fetch_response(oauth_request, connection, debug=DEBUG): | |
url= oauth_request.to_url() | |
connection.request(oauth_request.http_method,url) | |
response = connection.getresponse() | |
s=response.read() | |
if debug: | |
print 'requested URL: %s' % url | |
print 'server response: %s' % s | |
return s | |
def main(): | |
connection = httplib.HTTPSConnection(SERVER) | |
consumer = oauth.OAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET) | |
# XXX: hmac-sha1 does not work; use plain text | |
#signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1() | |
signature_method = oauth.OAuthSignatureMethod_PLAINTEXT() | |
# if we don't have a cached access-token stored in a file, then get one | |
if not os.path.exists(ACCESS_TOKEN_STRING_FNAME): | |
print '* Obtain a request token ...' | |
oauth_request = oauth.OAuthRequest.from_consumer_and_token( | |
consumer, http_url=REQUEST_TOKEN_URL) | |
if DEBUG: | |
connection.set_debuglevel(10) | |
oauth_request.sign_request(signature_method, consumer, None) | |
resp=fetch_response(oauth_request, connection) | |
auth_token=oauth.OAuthToken.from_string(resp) | |
print 'Auth key: %s' % str(auth_token.key) | |
print 'Auth secret: %s' % str(auth_token.secret) | |
print '-'*75,'\n\n' | |
# authorize the request token | |
print '* Authorize the request token ...' | |
auth_url="%s?oauth_token=%s" % (AUTHORIZATION_URL, auth_token.key) | |
print 'Authorization URL:\n%s' % auth_url | |
oauth_verifier = raw_input( | |
'Please go to the above URL and authorize the '+ | |
'app -- Type in the Verification code from the website, when done: ') | |
print '* Obtain an access token ...' | |
# note that the token we're passing to the new | |
# OAuthRequest is our current request token | |
oauth_request = oauth.OAuthRequest.from_consumer_and_token( | |
consumer, token=auth_token, http_url=ACCESS_TOKEN_URL, | |
parameters={'oauth_verifier': oauth_verifier}) | |
oauth_request.sign_request(signature_method, consumer, auth_token) | |
# now the token we get back is an access token | |
# parse the response into an OAuthToken object | |
access_token=oauth.OAuthToken.from_string( | |
fetch_response(oauth_request,connection)) | |
print 'Access key: %s' % str(access_token.key) | |
print 'Access secret: %s' % str(access_token.secret) | |
print '-'*75,'\n\n' | |
# write the access token to file; next time we just read it from file | |
if DEBUG: | |
print 'Writing file', ACCESS_TOKEN_STRING_FNAME | |
fobj = open(ACCESS_TOKEN_STRING_FNAME, 'w') | |
access_token_string = access_token.to_string() | |
fobj.write(access_token_string) | |
fobj.close() | |
else: | |
if DEBUG: | |
print 'Reading file', ACCESS_TOKEN_STRING_FNAME | |
fobj = open(ACCESS_TOKEN_STRING_FNAME) | |
access_token_string = fobj.read() | |
fobj.close() | |
access_token = oauth.OAuthToken.from_string(access_token_string) | |
apiCall = '/1/user/-/devices.json' | |
oauth_request = oauth.OAuthRequest.from_consumer_and_token( | |
consumer, | |
token=access_token, | |
http_url=apiCall | |
) | |
oauth_request.sign_request(signature_method, consumer, access_token) | |
headers = oauth_request.to_header(realm='api.fitbit.com') | |
connection.request('GET', apiCall, headers=headers) | |
resp = connection.getresponse() | |
device_info = resp.read() | |
devices = json.loads( device_info ) | |
device = devices[0] | |
device_id = 'fitbit%' + device['id'] | |
rs = redis.Redis() | |
rs.hset( device_id , 'battery' , device['battery'] ) | |
rs.hset( device_id , 'lastSync' , device['lastSyncTime'] ) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment