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>
This commit is contained in:
arneandClaude Opus 5.5 committed 2026-11-04 10:04:39 +00:00
commit 6466f002e0
51 files changed
+5199

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
"""A calendar per baby, showing the whole log."""
from __future__ import annotations
from datetime import datetime, timedelta
from homeassistant.components.calendar import CalendarEntity, CalendarEvent
from homeassistant.core import HomeAssistant
from .babytracker_api import Baby, Entry
from .coordinator import BabyTrackerCoordinator
from .entity import BabyEntity, async_add_baby_entities
# Calendar events must have a duration, and most log entries are a moment in time.
_MINIMUM_DURATION = timedelta(minutes=1)
def _event(entry: Entry) -> CalendarEvent:
return CalendarEvent(
start=entry.time,
end=max(entry.end, entry.time + _MINIMUM_DURATION),
summary=entry.summary,
description=entry.note or None,
uid=entry.id,
)
class BabyLogCalendar(BabyEntity, CalendarEntity):
def __init__(self, coordinator: BabyTrackerCoordinator, baby: Baby) -> None:
super().__init__(coordinator, baby, "log")
@property
def event(self) -> CalendarEvent | None:
entry = self.coordinator.data.latest(self.baby_id)
return _event(entry) if entry else None
async def async_get_events(self, hass: HomeAssistant, start_date: datetime, end_date: datetime) -> list[CalendarEvent]:
return [
_event(entry)
for entry in self.coordinator.data.entries(self.baby_id)
if entry.time < end_date and max(entry.end, entry.time + _MINIMUM_DURATION) > start_date
]
async def async_setup_entry(hass, entry, async_add_entities) -> None:
coordinator: BabyTrackerCoordinator = entry.runtime_data
async_add_baby_entities(
entry, coordinator, async_add_entities, lambda baby: [BabyLogCalendar(coordinator, baby)]
)