Polar: koppeling met de API

Ingediend door Dirk Hornstra op 10-jun-2018 21:11

In mijn vorige post ben ik aan de slag gegaan met de API van de Fitbit. Het opvragen van de data lukte en ik heb nu mijn eigen gegevens beschikbaar om ze op het dashing.net dashboard te tonen (link). Soms was echter mijn Fitbit leeg, hing die aan de lader en werd dus niet geregistreerd hoeveel stappen ik gedaan heb. Maar, aan mijn andere pols draag ik een Polar M400 smartwatch. Dus als ik die data op kan vragen, kan ik mijn statistieken compleet maken. Ook heb ik daar GPS op en ben ik dus benieuwd of ik ook die gegevens kan opvragen.

Eerst naar de website van Polar om te zien of er überhaupt een API is en documentatie. Dat is er: https://www.polar.com/en/developers Door naar de Polar Open AccessLink API. Daar wordt dan doorverwezen naar https://admin.polaraccesslink.com/ waar je kunt inloggen en een app aan kunt maken (en ja, het werkt met oAuth). De API is via deze URL te raadplegen: https://www.polar.com/accesslink-api/

Na het doorlopen krijg je de ClientID en de Client-Secret. De flow is bijna identiek aan die van de Fitbit. Ook hier een callback en een authorize. Verschil is dat je geen refresh-token terug krijgt. Het token wat ik krijg heeft een lange gebruiksduur, namelijk tot 7 mei 2033. Dan maak ik me eerst ook niet druk om dat refreshtoken ;)

Het ziet er anders uit dan bij de Fitbit. Daar had je feeds, waar je jouw user en datum aan mee gaf, en bam, je krijgt de data. Hier moet je zaken met ID's doen, wordt het in een soort schaduw-database opgeslagen en zijn gegevens niet meer wijzigbaar voor de gebruiker. Hmmm. Eerst maar eens even wat testen met de "simpele calls". De eerste is "notifications". Dat is trouwens een tricky one. Je roept de URL aan met het token wat je gekregen hebt. Boem: 401, no access. Wat blijkt nu, het token gebruik je voor calls naar /v3/users en alles wat daaronder valt, andere calls (dus ook de notifications!) doe je op basis van de base64 waarde van clientID:clientSecret. Ik krijg na die aanpassing geen foutmeldingen meer, maar ook geen data, dus hier kan ik niet zoveel mee.

Door dan met de "user". Je kunt met de aanroep van deze URL de gegevens van de user opvragen: GET /v3/users/{user-id} . Die user-id heb je beschikbaar, toen je het accesstoken terug kreeg, kreeg je ook de x_user_id mee terug. Als je trouwens ingelogd bent op flow.polar.com en je gaat naar je profiel, dan zie je getalletjes aan het einde van de URL: ook jouw user-id. Volgens mij gaat er iets niet goed. Hoewel ik geen foutmelding krijg, krijg ik ook hier geen data terug.

Oorzaak gevonden. Een gevalletje RTFM, read the f**ing manual. De accesslink-api is een soort dataset naast jouw data die geregistreerd is. Je moet dus eerst de user "registreren". Dat gaat nog niet zo makkelijk. Een 400 status terug, ongeldige opdracht. Op zich logisch. In het voorbeeld zie je zowel een JSON als XML-call. Ik gebruik de JSON-call, dan moet je ook het Content-Type instellen op application/json en niet zoals in het voorbeeld staat op application/xml. Daarmee krijg ik wel data terug, dit is stap 1.


                var webClient = GetAuthorizedWebClient;
                webClient.ContentType = "application/json";
                webClient.Accept = "application/json";
                webClient.Method = "POST";

Dat registreren werkt. Ik heb dit de eerste keer in "debug-mode" doorlopen. Daarna heb ik de code aangepast om het resultaat in de database op te slaan. Ik voer de code nogmaals uit en ... krijg een foutmelding. Dat werkt (dus) niet, je krijgt status 409 terug, conflict. Logisch natuurlijk, want in de eerste call is de gebruiker al aangemaakt en gekoppeld aan het eigen memberID. Dus ik ga terug naar het opvragen van de gegevens via GET /v3/users/{user-id}. Deze functie geeft me nu dus wel data terug, dit sla ik op in mijn database.

Notifications en CreateExerciseTransaction geven nog geen data terug, ook mijn aanroep naar CreateActivityTransaction geeft een lege string terug. Tijd om af te sluiten en morgen er met een frisse blik naar te kijken.

Het bovenstaande had ik vanaf 10 mei uitgewerkt. Een aantal avonden aan besteed, maar geen progressie.
Ik ben (dus) eerst met andere zaken bezig gegaan en heb 18 mei nogmaals een aantal pogingen gewaagd. Helaas, wederom zonder resultaat. Ik heb een mail naar de support-afdeling van Polar gestuurd, kijken of zij een oplossing hebben.

We zijn inmiddels 22 mei. Kudo's voor de support-afdeling van Polar, want daar had ik al snel een antwoord van ontvangen. Ik kom er nu pas aan toe om het te controleren. Het antwoord was op zich wel een beetje teleurstellend. Ze zeggen namelijk dat je via de API niet je data uit het verleden op kunt vragen, dat je alleen geüploade data na je registratie met de app kunt benaderen. Die data wil ik wel hebben, dus ik moet nog maar eens kijken of daar zelf met een soort "scraper" de data van kan opvragen. In ieder geval, deze avond heb ik mijn "rondje Swichum" gelopen, 5 kilometer. Na het uploaden (via USB-kabel aan de pc) krijg ik via de notifications-functie en de activity-transactions-call data terug. Woop, woop!

Json-Objecten gemaakt, juiste verwijzing naar de velden in de JSON die ik aangeleverd krijg en daarna de notification-call in mijn webapplicatie aangeroepen met wat break-points. Ik krijg de data goed binnen en ook het opslaan gaat goed, ik heb nu 3 records met verschillende types, EXERCISE, ACTIVITY_SUMMARY en PHYSICAL_INFORMATION. Omdat ik op de URL filter ook meteen maar even een unique-index op dat veld gezet. Oh nee, toch niet. Die notificatie geeft je namelijk de standaard URL terug, bijvoorbeeld https://www.polaraccesslink.com/v3/users/[USERID]/exercise-transactions, het geeft dus een "notificatie" dat er iets voor je wachten staat. Hierna de exercisetransaction aangeroepen, die mij netjes een record teruggeeft, met de URL https://www.polaraccesslink.com/v3/users/[USERID]/exercise-transactions/[EXERCISEID]

We zijn inmiddels 10 juni, in de afgelopen dagen met andere zaken bezig geweest. Maar ik wil dit nu eindelijk wel eens afronden, zodat ik dit artikel kan publiceren, dus aan de slag. Ik heb de call naar GET /v3/users/{user-id}/exercise-transactions/{transaction-id} uitgevoerd. Vervolgens moet ik deze middag weg, dus 's avonds, 8 uur later, voer ik nogmaals deze call uit. Nu krijg ik een 404 terug. Ik had vanmiddag de response al opgeslagen, als ik die URL's aanroep krijg ik ook een 404 terug. Het lijkt er dus op dat ik die data niet meer op kan vragen. Duidelijk, ik ben wel he-le-maal klaar met die Polar-API. Weinig data terug geven en de data die je krijgt moet je binnen een x periode opvragen, anders kun je er niet meer bij.