Skip to main content

fitdays

An unofficial async Python client for the Fitdays (ICOMON) smart-scale cloud API.

Fitdays is the app behind a family of white-label body-composition scales — the Robi S6 and a long tail of rebadged siblings. The scale measures bio-impedance, the cloud turns that into fat / muscle / water / bone / BMR figures, and the app is the only place those numbers show up. There is no public API, so this package speaks the app's own protocol.

Read-only: it logs in, then pulls measurement history. It never writes to your account.

pip install fitdays

Quick start

import asyncio
from fitdays import FitdaysClient

async def main():
    async with await FitdaysClient.login("you@example.com", "hunter2") as client:
        latest = await client.get_latest()
        print(latest.weight_kg, "kg")
        print(latest.body_fat_pct, "% fat →", latest.body_fat_kg, "kg")
        print(latest.muscle_mass_kg, "kg muscle")

asyncio.run(main())

See examples/quickstart.py for a fuller tour.

What you get

get_sync() returns everything in one round-trip:

.measurements Measurement objects, newest first
.profiles the member profiles on the account (UserProfile)
.devices the scales bound to the account (ScaleDevice)

A Measurement carries what the scale reported — weight_kg, bmi, body_fat_pct, subcutaneous_fat_pct, visceral_fat, muscle_pct, skeletal_muscle_pct, bone_mass_kg, body_water_pct, protein_pct, bmr, body_age, heart_rate, impedance — plus derived masses the API only sends as ratios: body_fat_kg, muscle_mass_kg, skeletal_muscle_kg, body_water_kg, protein_kg.

is_weight_only tells you a weigh-in came without impedance (socks, or a quick step on the scale), so you can skip the body-composition fields rather than charting nulls.

Multiple people

One Fitdays account can hold several member profiles, each with its own suid, and the scale attributes each weigh-in to one of them:

result = await client.get_sync()
for profile in result.profiles:
    latest = result.latest(profile.suid)
    print(profile.display_name, latest.weight_kg)

Sessions and tokens

Logging in every time is unnecessary and rude to the server. Persist the session instead:

stored = client.session.to_dict()   # no plaintext password in here
...
client = FitdaysClient.from_session(stored, token_updated=save_it)

Two things happen automatically:

  • Self-healing login. Tokens are long-lived but not eternal. When one is rejected, the client re-authenticates using the stored password digest and retries the call — then fires your token_updated callback so you can persist the new token.
  • Region redirects. An account registered outside Europe answers with code 302 and the host it actually lives on. The client follows that once and remembers it.

About the password

The login endpoint expects MD5(MD5(password + "hx")), so the plaintext never leaves your process — Session stores only that digest, and re-login works from the digest alone. It is still a credential (it is password-equivalent to this API), so store it the way you would store a token.

Home Assistant

There is a companion integration: HA-Fitdays, which turns each member profile into a device with body-composition sensors.

Errors

Exception Means
FitdaysAuthError login failed, or the token is dead and cannot be renewed
FitdaysNetworkError timeout / connection problem
FitdaysAPIError the cloud returned a non-success code
FitdaysValidationError you passed something unusable

All inherit from FitdaysError.

Disclaimer

Not affiliated with, endorsed by, or supported by GUANGDONG ICOMON or Fitdays. The protocol was determined by observing the app's own traffic against the author's own account. Endpoints may change or disappear without notice. Use at your own risk.

Licence

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fitdays-1.0.0.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fitdays-1.0.0-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file fitdays-1.0.0.tar.gz.

File metadata

  • Download URL: fitdays-1.0.0.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for fitdays-1.0.0.tar.gz
Algorithm Hash digest
SHA256 d93af0f759f42af72618f0558d5a6ff4617880da8272bb4c4483cda980e7a452
MD5 740754fe761d4e613c428d392c70014d
BLAKE2b-256 84e477a88c57494fb6a85b6ea2c2ad9f5ba1c0f402d58c61d154652cdde2657a

See more details on using hashes here.

File details

Details for the file fitdays-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: fitdays-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 16.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for fitdays-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 29abc2705a8ef461fd0655f3d5cef9806f5b0565f779fcf46906a331e23f5d80
MD5 a55cd59268f42357e9fd7c6e1364432e
BLAKE2b-256 e01edcff52d707f465aa337599bb5d624cd8e807bc4442127645473da788853e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page