Python client for the Baby Tracker sync server, reverse engineered from the Android app (4.53), and a HACS-installable Home Assistant integration built on it. Each baby gets a log calendar and summary sensors, and actions add entries that sync back to the group. Reading has been run against the real server. Uploading and running inside real Home Assistant have not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8.6 KiB
Baby Tracker for Home Assistant
An unofficial HACS integration that connects Home Assistant to the
sync group of the Baby Tracker app (com.nighp.babytracker_android). You can see your
baby's log in Home Assistant and add to it, and entries sync with the app on your other
devices.
It also contains a Python client for the sync API, which was reverse engineered from version 4.53 of the Android app.
Unofficial and partly unverified. Nothing here comes from the app's developer, and the server could change without notice. Reading has been checked against the real server, but uploading has not. See Your first test, and back up your data first.
Requirements
- Home Assistant 2025.1 or newer.
- A sync group, set up in the app's sync settings. Its email and password are what you sign in with.
Install
With HACS
The repository has to be public on GitHub. Before publishing it, replace
YOUR_GITHUB_USERNAME in custom_components/babytracker/manifest.json.
- In HACS, open the menu and choose Custom repositories.
- Add the repository URL, with the type Integration.
- Find Baby Tracker in HACS, download it, and restart Home Assistant.
By hand
Copy custom_components/babytracker into the custom_components folder of your Home
Assistant configuration, then restart.
Set it up
Go to Settings → Devices & services → Add integration → Baby Tracker and sign in.
Home Assistant joins the group as one more device, named "Home Assistant". Remove the integration and that device stays listed on the account, because the app has no call that removes a device.
Your first test
The first upload is the one thing that has never been tried against the real server, so start with something easy to remove:
- Go to Developer tools → Actions and run Baby Tracker: Log journal entry with
the text
Home Assistant test. - Check that it appears in the app on your phone, after the app has synced.
- Restart Home Assistant and check that it still appears, once, on
sensor.<baby>_recent_activity. - Delete it in the app. Within about five minutes it should disappear from Home Assistant.
If any step fails, stop uploading and open an issue with what you saw.
What you get
Each baby becomes a device with these entities.
| Entity | Shows |
|---|---|
calendar.<baby>_log |
The whole log, for the calendar view |
sensor.<baby>_recent_activity |
Time of the latest entry, with the last 20 in its entries attribute |
sensor.<baby>_last_diaper |
Time of the last diaper, with status and amount as attributes |
sensor.<baby>_last_feeding |
Start of the last feed of any type, with its details |
sensor.<baby>_last_sleep |
Start of the last sleep, with end and duration attributes |
sensor.<baby>_diapers_today |
Count |
sensor.<baby>_feedings_today |
Count |
sensor.<baby>_sleep_today |
Minutes |
sensor.<baby>_bottle_volume_today |
Formula and pumped milk |
sensor.<baby>_temperature |
Latest reading |
sensor.<baby>_weight |
Latest measurement |
sensor.<baby>_length |
Latest measurement |
sensor.<baby>_head_circumference |
Latest measurement |
Entries count towards the day they started on, so a sleep that runs past midnight counts for the day it began. Entries made on other devices appear within about five minutes.
Adding entries
Each of these actions takes optional baby, time and note fields.
| Action | Fields |
|---|---|
babytracker.log_diaper |
status (wet, poopy, mixed, dry), amount (light, normal, heavy, overflow) |
babytracker.log_sleep |
duration in minutes |
babytracker.log_bottle |
amount, kind (formula, pumped), unit (ml, oz) |
babytracker.log_nursing |
left_minutes, right_minutes, both_minutes, finish_side (left, right) |
babytracker.log_temperature |
value, unit (C, F) |
babytracker.log_growth |
weight, length, head, units (metric, english) |
babytracker.log_bath |
none |
babytracker.log_joy |
none |
babytracker.log_journal |
note is the entry's text, and is required |
baby: the baby's device or their name. Leave it out if the account has one baby.time: when the activity started. Leave it out and the activity is taken to have just finished, so a 30-minute sleep is logged as starting 30 minutes ago.- Units: these default to your Home Assistant unit system.
- Failures: if the upload fails, for example with no internet, the action reports an error and nothing is saved or retried.
- Response: each action can return the new entry's
id.
Dashboard examples
Buttons to log a diaper in one tap:
type: horizontal-stack
cards:
- type: button
name: Wet
icon: mdi:water
tap_action:
action: perform-action
perform_action: babytracker.log_diaper
data:
status: wet
- type: button
name: Poopy
icon: mdi:emoticon-poop
tap_action:
action: perform-action
perform_action: babytracker.log_diaper
data:
status: poopy
The log as a list, using a Markdown card. Replace sam with your baby's name:
type: markdown
title: Recent activity
content: >
{% for entry in state_attr('sensor.sam_recent_activity', 'entries') or [] %}
- **{{ as_timestamp(entry.time) | timestamp_custom('%H:%M') }}** {{ entry.summary }}{{ ' — ' ~ entry.note if entry.note }}
{% endfor %}
A reminder when the last feed was over three hours ago:
triggers:
- trigger: template
value_template: >
{{ now() - states('sensor.sam_last_feeding') | as_datetime > timedelta(hours=3) }}
actions:
- action: notify.notify
data:
message: "Last feed was over three hours ago"
Limitations
- Shown but not addable: medication, vaccines, milestones, solid foods and other activities. These pick from lists kept in the app. They do appear on the calendar and in recent activity.
- Not shown: pumping sessions, because they don't belong to a baby. Photos too.
- No editing or deleting from Home Assistant. Use the app.
- Startup: the integration keeps the log in memory and downloads it again each time it starts, so large accounts take longer to load.
- Group resets: if you reset the group in the app, reload the integration.
- Password: Home Assistant stores it unencrypted in its
.storagefolder, as it does for most integrations. The server has no separate tokens.
Python client
The library works without Home Assistant, and lives inside the integration folder because HACS installs only that folder.
pip install -e .
The server has no way to query records. It stores a database snapshot (the seed) and
an append-only log per device. Replica combines them into a local copy.
from babytracker_api import (
BabyTrackerClient, DiaperStatus, Replica, diaper, extract_seed_db,
formula, open_seed_db, read_cursors, sleep,
)
# Keep device_uuid stable between runs. A new value is a new device on the account.
client = BabyTrackerClient("you@example.com", "password", device_uuid="<a saved uuid4>")
client.login()
# Build a local copy from the seed.
extract_seed_db(client.download_seed("seed.zip"), "seed.db")
db = open_seed_db("seed.db")
replica = Replica.from_seed(db)
cursors = read_cursors(db)
# Add what happened since. Save `cursors` to continue from there next time.
# include_own is needed here because the seed predates this device's own uploads.
for device, item in client.pull(cursors, include_own=True):
replica.apply(item.op, item.object)
baby = next(iter(replica.babies.values()))
for entry in replica.entries(baby.id):
print(entry.time, entry.summary)
# Add records. These need the baby's full record.
client.add(diaper(baby.record, DiaperStatus.POOPY))
client.add(formula(baby.record, 120)) # ml; english=True for fl oz
client.add(sleep(baby.record, minutes=45, note="nap"))
# Change or remove a record. Records are plain dicts.
record = sleep(baby.record, minutes=30)
client.add(record)
client.update({**record, "duration": 40})
client.delete(record)
To check it against your account without changing anything:
BABYTRACKER_EMAIL=you@example.com BABYTRACKER_PASSWORD=... python3 examples/smoke_test.py
See docs/API.md for endpoints, record formats and open questions.
Development
python3 -m unittest discover -s tests
The tests use a mock server written from the same analysis of the app. The integration's
tests run against small stand-ins for Home Assistant's APIs in tests/ha_stubs, so they
don't show that it works in real Home Assistant. The GitHub workflow adds Home Assistant's
hassfest and the HACS validation.