Ik heb mijn Withings Body+ verbonden met Home Assistant via een ESP32

Ik heb al jaren een Withings Body+. We stappen erop, de weegschaal herkent wie er staat en de metingen verschijnen in de Withings-app. Daar was niets mis mee, maar ik wilde dezelfde gegevens ook in Home Assistant hebben.

Home Assistant heeft al een Withings-integratie. Het zou slechts enkele minuten kosten om deze in te stellen, maar deze haalt de metingen op uit je Withings-account. De data volgt dan dit traject: Body+Withings cloudHome Assistant

Ik wilde die tussenstap verwijderen. Na wat onderzoek met ChatGPT bleek dat een originele ESP32 via Bluetooth met de weegschaal kon communiceren en het resultaat via ESPHome naar Home Assistant kon sturen. Ik had toevallig een ESP32 in een lade liggen, wat genoeg reden was om het te proberen.

De hardware

Ik heb de weegschaal niet geopend of aangepast. De ESP32 staat in de buurt en heeft alleen een USB-kabel nodig voor de stroomvoorziening.

Na het wegen stuurt de Body+ de meting via Bluetooth naar de ESP32. ESPHome stuurt dit vervolgens via wifi door naar Home Assistant: Body+ESP32Home Assistant

Daarnaast heb ik het opgeslagen wifi-netwerk uit de Body+ verwijderd, zodat de weegschaal zelf niets meer kan uploaden naar Withings.

De keuze voor de specifieke ESP32 is hierbij cruciaal. De Body+ synchroniseert via Bluetooth Classic, terwijl ESP32-C3 en ESP32-S3 boards alleen Bluetooth LE (Low Energy) ondersteunen. Ik had een origineel ESP32-ontwikkelingsbord, en dat was de juiste keuze. Elke originele ESP32 met Bluetooth Classic zou moeten werken; een C3 of S3 zal dit niet doen.

Reverse-engineering van de weegschaal

De ESP32 was het makkelijke gedeelte. Het probleem was dat het protocol van de Body+ niet gedocumenteerd is voor mensen die de Withings-app willen vervangen.

Ik heb het probleem voorgelegd aan OpenCode (draaiend op Codex). De tool analyseerde een oude versie van de Withings Android-app, vergeleek dit met bestaand werk over het protocol en begon een ESPHome-component te bouwen. Dit leidde tot een zeer inefficiiciete testcyclus:

  1. De ESP32 flashen.
  2. Naar de badkamer lopen.
  3. De weegschaal in de setup-modus zetten.
  4. Op de weegschaal staan.
  5. Teruglopen met de logs.
  6. De logs aan Codex geven.
  7. Herhalen.

De eerste versies deden niets. Latere versies maakten verbinding via Bluetooth, maar zorgden ervoor dat de weegschaal bleef hangen op het setup-scherm. Elke wijziging betekende een nieuwe firmware-build en een nieuwe wandeling naar de badkamer.

Uiteindelijk toonde een van de logs: Body+ association complete. Toen ik opnieuw op de weegschaal stapte, verscheen mijn gewicht in Home Assistant.

Codex deed het werk dat ik zelf realistisch gezien niet had gedaan: het lezen van gedecompileerde Android-code, het vergelijken van Bluetooth-pakketten en het omzetten daarvan naar C++ voor de ESP32. Ik leverde de weegschaal, de logs en een absurd aantal bijna identieke wegingen. Het was geen kwestie van één magische prompt, maar vooral van "het werkt nog steeds niet", gevolgd door een nieuwe firmware-build.

Twee profielen, twee sets sensoren

Ik dacht aanvankelijk dat ik zou moeten raden wie er op de weegschaal stond op basis van het gewicht. Gelukkig identificeert de Body+ de gebruikers zelf en voegt hij bij elke meting een gebruikers-ID toe.

Ik heb beide ID's in de ESPHome-configuratie geplaatst. De component gebruikt deze om ofwel mijn sensoren, ofwel die van mijn vrouw bij te werken, en negeert ID's die hij niet kent. Voor ons beiden wordt nu de historie bijgehouden voor:

  • Gewicht
  • Lichaamsvet
  • Vetmassa
  • Spiermassa
  • Lichaamswater
  • Botmassa
  • Vetvrije massa

De weegschaal bepaalt van wie de meting is; de ESP32 stuurt deze alleen naar de juiste plek.

De laatste meting bewaren in Home Assistant

ESPHome stelt alles beschikbaar als normale sensoren, waardoor Home Assistant het apparaat zonder extra werk ontdekte.

De ruwe sensoren worden echter "unavailable" zodra ik de ESP32 uitstop. Dat is technisch correct, maar niet handig voor een dashboard met gewichten. Mijn laatste gewicht zou niet moeten verdwijnen omdat ik de USB-kabel heb geleend.

Daarom heb ik Home Assistant template sensors toegevoegd die de laatste meting onthouden. De ESP32 slaat dezelfde waarden op, dus ze zijn direct weer beschikbaar na een herstart. In onze dashboards gebruiken we bovendien step charts: een meting blijft een platte lijn tot de volgende weging, in plaats van dat er gefantaseerde waarden tussen twee metingen worden geplaatst.

Het resultaat

We gebruiken de weegschaal nog precies zoals voorheen. Een paar seconden nadat een van ons erop staat, worden de juiste sensoren in Home Assistant bijgewerkt. De Body+ heeft geen wifi nodig, we hoeven de Withings-app niet te openen en de data blijft thuis.

Ik heb dit alleen getest met onze Body+, twee profielen en dit specifieke ESP32-bord. Het is geen universele integratie voor elke Withings-weegschaal, dus ik zou geen hardware aanschaffen in de veronderstelling dat het met een ander model zal werken.

Het heeft veel tokens gekost terwijl er al een officiële integratie bestaat, maar nu werkt het precies zoals ik wilde. En de ESP32 uit mijn lade heeft eindelijk een permanente baan.

Gebruikte tools in dit project

  • Home Assistant
  • ESPHome
  • ESP32-DevKitC Development Board
  • ChatGPT / Codex
  • OpenCode