arneandClaude Opus 5.5 6466f002e0 Add Baby Tracker client and Home Assistant integration
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>
2026-11-04 10:04:39 +00:00

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.

  1. In HACS, open the menu and choose Custom repositories.
  2. Add the repository URL, with the type Integration.
  3. 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:

  1. Go to Developer tools → Actions and run Baby Tracker: Log journal entry with the text Home Assistant test.
  2. Check that it appears in the app on your phone, after the app has synced.
  3. Restart Home Assistant and check that it still appears, once, on sensor.<baby>_recent_activity.
  4. 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 .storage folder, 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.

S
Description
No description provided
Readme
95 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 100%