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>
50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
"""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)]
|
|
)
|