Aller au contenu principal

2 articles tagués avec « iot »

Voir tous les tags

Récupérer les données de son AppleWatch avec le moteur FaaS de CWCloud

· 7 minutes de lecture
Idriss Neumann
founder cwcloud.tech

Ce blogpost va nous permettre d'illustrer un cas d'utilisation concret de l'utilisation du moteur FaaS1 de CWCloud pour à la fois exposer des fonctions serverless comme webhooks publics et également montrer comment interagir avec des LLM2.

En dehors de l'IT, j'aime pratiquer régulièrement certains sports, notamment la course à pied ou encore le powerlifting. Depuis un certain temps, j'utilise une Apple Watch SE pour récupérer les métriques et suivre la progression, entre autres au niveau de l'endurance et du cardio.

Pour un utilisateur "non-tech", le niveau de détail et de présentation des données au cours d'un exercice est très satisfaisant. Ici, vous avez par exemple le détail de ce qui se passe pendant une course : les positions GPS, le rythme cardiaque et les zones tout au long de l'exercice...

apple-activity-dashboard

La montre donne également plein d'autres données sur la qualité du sommeil, le rythme cardiaque au repos, les calories dépensées... mais il y a toujours eu un souci qui me frustre, comparé à d'autres modèles que j'ai pu avoir par le passé comme les montres Fitbit : pas d'API et webservices pour les développeurs. Or, j'aurais bien voulu récupérer ces données pour pouvoir les traiter avec des LLM en passant par le moteur FaaS low-code de CWCloud.

Cependant, pas d'API en ligne ne signifie pas pour autant qu'il est impossible de les récupérer : on voit que beaucoup d'applications sur l'iPhone sont capables de malgré tout récupérer les données de la montre, à l'exemple de Strava, MyFitnessPal...

Ces applications passent la plupart du temps par une lecture des données directement depuis l'iPhone en utilisant le framework d'Apple HealthKit et en donnant les permissions nécessaires depuis les paramètres de sécurité d'Apple.

Cependant, cela demande quand même beaucoup d'efforts pour quelqu’un qui n’est pas développeur mobile iOS de devoir builder et valider une application développée en Swift pour envoyer les données sur un webhook. J’ai cherché à voir si quelqu’un d’autre n’avait pas déjà fait ce travail. Et c’était effectivement le cas avec l’application Health Auto Export_.

Cette application est assez mal notée, mais quand on lit les commentaires, on comprend parfaitement pourquoi : les gens n'ont pas compris à quoi elle servait. Entre autres, elle ne sert pas à faire de jolis dashboards d'agrégations statistiques, mais à exporter les données de santé d'Apple dans des formats exploitables par des développeurs (CSV ou JSON), et également à programmer des envois schedulés de ces exports vers des connecteurs externes (webhook REST/HTTP, fichiers MQTT, Dropbox...).

Dans notre cas, c’est très exactement ce qu’il nous fallait. Voici comment configurer, par exemple, un webhook HTTP pour envoyer les données à CWCloud dans une automation qui va tourner toutes les minutes :

health-auto-export

Toutes les minutes, la fonction serverless de CWCloud va recevoir comme payload un JSON au format suivant :

{
"data" : {
"metrics" : [
{
"units" : "count\/min",
"data" : [
{
"Min" : 79,
"date" : "2025-06-30 23:17:40 +0200",
"Avg" : 79,
"Max" : 79,
"source" : "Idriss’s Apple Watch"
},
{
"Min" : 66,
"Max" : 66,
"Avg" : 66,
"source" : "Idriss’s Apple Watch",
"date" : "2025-06-30 23:23:45 +0200"
},
{
"Max" : 66,
"date" : "2025-06-30 23:26:52 +0200",
"source" : "Idriss’s Apple Watch",
"Min" : 66,
"Avg" : 66
}
],
"name" : "heart_rate"
}
]
}
}

Dans l'automation, on pourra noter que j’ai filtré uniquement la métrique heart_rate, car sinon cela pourrait en envoyer beaucoup d’autres, et pas uniquement provenant de l’Apple Watch, mais également d’autres applications comme MyFitnessPal, qui fait le tracking de vos macros (calories, protéines, lipides, glucides, calcium, etc.) de votre alimentation. Bref, il y a vraiment de quoi faire des usecases très intéressants 😁.

Cela étant, ce payload n’est pas compatible avec le contrat d’interface de notre moteur serverless avec les endpoints classiques que nous avons documentés dans plusieurs démos, où l’on attend à l’avance les paramètres de votre fonction.

Il existe toutefois un endpoint /v1/faas/webhook/{function_id} (ou /v1/faas/webhook/{function_id}/sync si vous souhaitez recevoir la réponse de la fonction en synchrone dans la réponse HTTP). Dans ce cas, il faut que votre fonction soit définie avec un unique argument raw_data comme ceci :

faas-raw-data-arg

Une fois que c’est fait, il devient très simple d’invoquer la fonction en lui passant ce que vous voulez comme body, que vous pourrez ensuite parser directement dans votre code :

$ curl "https://api.cwcloud.tech/v1/faas/webhook/ecb10330-02bf-400b-b6a8-d98107324ac3/sync" -X POST -d '{"foo":"bar"}' 2>/dev/null|jq .
{
"status": "ok",
"code": 200,
"entity": {
"id": "78774026-f75e-4c7c-850a-9b9eb2cb2ec0",
"invoker_id": 3,
"updated_at": "2025-07-05T14:39:53.119780",
"content": {
"args": [
{
"key": "raw_data",
"value": "{\"foo\":\"bar\"}"
}
],
"state": "complete",
"result": "The data is : {\"foo\":\"bar\"}\n",
"user_id": null,
"function_id": "ecb10330-02bf-400b-b6a8-d98107324ac3"
},
"created_at": "2025-07-05T14:39:52.443918"
}
}

Vous l'aurez compris, dans l'automation de l'application Health Auto Export c'est une URL au format https://api.cwcloud.tech/v1/faas/webhook/{function_id} qu'il faudra définir (pas besoin du /sync à la fin car vous n'aurez pas besoin d'attendre le résultat de l'exécution de la fonction).

Note : on a aussi exposé la fonction en public pour pouvoir l’invoquer sans authentification, mais ce n’est pas forcément ce qui est souhaitable. N’oubliez pas que vous êtes facturés aux tokens que vous consommerez dans le cas ou vous utilisez des modèles publics. Donc ici on le fait à des fins illustratives mais vous n’allez pas forcément vouloir que tout le monde invoque votre webhook. Vous pouvez très bien gérer cela en gardant la fonction privée et en ajoutant un header X-User-Token dans l’automation sur l’application Health Auto Export.

Maintenant qu’on sait comment créer un webhook, voici le code Blockly3 pour extraire la moyenne de votre heart rate, l’envoyer au LLM gpt4omini. Ici, on a demandé au LLM de réagir avec un emoji à la valeur qu’il reçoit et d’envoyer le résultat dans Discord :

faas-blockly-heart-rate

Vous pouvez observer que je passe la phrase suivante "You're reacting with an emoji only if the heart rate is too slow or to high" comme prompt système ainsi que le nombre de battements cardiaque récupérée des données de l'Apple Watch comme prompt utilisateur.

En outre, il faut savoir que les blocs AI vous obligent à vous authentifier pour pouvoir invoquer l'API CWCloud AI. Si vous voulez conserver le fait d'ouvrir ce webhook à n'importe qui il faudra créer une clef d'API en suivant ce tutoriel et en injectant cette clef dans une variable d'environnement AUTH_HEADER_VALUE comme ceci :

faas-authentication-cwai

Dans ce cas tous le monde pourra invoquer votre webhook et c'est votre compte qui sera facturé à la consommation si vous utilisez des modèles d'IA publics. Vous pouvez aussi chosir d'utiliser votre propre LLM hébergé sur vos instances à la place et dans ce cas cela ferait plus sens de garder le webhook public 😇.

Il faut également savoir que si la variable AUTH_HEADER_VALUE est définie, elle est prise en priorité sur l'authentification lorsque vous invoquez le webhook de façon authentifiée.

On peut également remarquer dans la capture d'écran précédant qu'un webhook pour Discord a été défini dans une autre variable d'environnement DISCORD_WEBHOOK_URL afin d'être utilisé pour envoyer la réponse du LLM dans Discord, et voici le résultat :

faas-discord-heart-rate

On peut voir que jusqu'ici tout va bien côté cardio, rien à signaler 😅

Footnotes

  1. Function as a Service

  2. Large Language Model

  3. Blockly est le langage low-code qu'on utilise dans CWCloud

Fork It Tunis 2025, résumé de la journée

· 2 minutes de lecture
Idriss Neumann
founder cwcloud.tech

On l'a fait ! Tunis 🇹🇳 a enfin eu sa journée de conférence orientée pour les développeurs à la cité de la culture le 5 avril.

forkit-tn-2025-hall

Comme annoncé dans un précédent blogpost, nous avions monté un très beau stand dans le but de challenger les conférenciers avec un concours IA, serverless et IoT et on a eu beaucoup de participant(e)s.

forkit-tn-2025-cwcloud-booth

Félicitons encore nos gagnant(e)s: Zayneb, Ala Eddine et Yassmine1!

forkit-tn-2025-winners

Le code source de la démo est disponible sur github et si vous voulez plus d'explications, vous pouvez visionner cette courte vidéo :

forkit-cwcloud-challenge

J'ai également eu la chance d'avoir la scène pour parler de Quickwit, Grafana et OpenTelemetry avec une autre démo. Il était prévu de le faire en anglais mais finalement le public a préféré la langue de molière. Je m'excuse pour les personnes qui auraient souhaité le voir en anglais, il y aura d'autres occasions 😅.

forkit-tn-2025-talk-quickwit

Il y aura un replay, les slides et supports sont disponibles sur github également et si vous souhaitez en apprendre davantage, vous pouvez également lire ce blogpost.

J'ai également pu assister à la keynote très inspirante "how do you learn" d'Olivier et Sonyth Huber et vous recommande de visionner le replay lorsqu'il sera publié.

Et pour finir, j'ai également pu faire visiter Sidi Bou Saïd à mon ami speaker Yacine, la plus belle place de la région de Tunis. Yacine qui a également donné un super talk sur comment il a réussi à porter Doom sur navigateur en utilisant WASM, une merveilleuse technologie.

forkit-tn-2025-sidibou

Si vous souhaitez garder le contact, en particulier si vous avez apprécié les démo et le challenge de CWCloud, nous avons un serveur discord communautaire que vous pouvez rejoindre.

Les prochaines conférences auxquelles j'assisterai seront DevoxxFR comme visiteur, SunnyTech et RivieraDev en tant que speaker. J'espère vous y voir nombreux(se)s comme d'habitude 🤩.

Footnotes

  1. Yassmine n'a pas pu rester pour recevoir son cadeau donc son ami l'a pris à sa place 😅.