Dashboard¶
- Status: Five-card evaluation live on OVH and rotating on the XT1058
The checked-in local implementation combines Bogotá weather, two independently attributed Yankees cards, and NYT/Guardian headlines into a bounded profile feed. The Android app offers three persistent modes: Just Clock, Bulletins, and Dashboard. Just Clock is the default and does not poll; Bulletins presents scheduled cards, while Dashboard rotates through valid cards continuously. Highlights now is a one-shot action available from any persistent mode while foreground and outside preview or another bulletin; it may use one refresh, presents the current cards, then returns to that mode. The production status is recorded in the current deployment receipt.
The evaluation profile selects API-Sports Baseball and BALLDONTLIE MLB side by side. Both normalize to the existing sports-card contract; the phone needs no new APK. The current OVH image selects both and disables MLB Stats. These are two separate sources for comparison, not an automatic fallback or two cards derived from one provider.
The selected persistent mode is saved across app restarts; the one-shot action is not a mode and does not replace that saved preference. The client keeps its verified feed and downloaded images in an origin-specific private cache. The asset and staging files share a 32 MiB default limit. Assets are written to staging, checked for declared dimensions, length, and SHA-256, then the active manifest switches atomically after all referenced images are present.
The Dashboard lets the bedside phone become useful for a few seconds at a time without turning it back into a distracting smartphone. The clock remains the resting state except in continuous Dashboard mode. Selected information temporarily takes the canvas, then yields it again.
During card rotation, the outgoing image is released at the end of its interval. Its opaque black layer stays over the clock until the next decoded image is ready, so the clock does not flash between cards. Ending a bulletin, selecting Just Clock, or running out of valid cards removes that layer and shows the clock.
Possible future card sources include:
- the next calendar item;
- a weather warning or short forecast;
- a score or match-time update for a followed team;
- one carefully selected news item; and
- family photographs, including a small rotating album or travel update.
Content flow¶
sequenceDiagram
participant Phone as Android appliance
participant API as Dashboard API
participant Source as Calendar/weather/sports/photo source
API->>Source: Fetch due public source data
API->>API: Select, resize, and bound content
Phone->>API: Conditional manifest request
alt Feed changed
API-->>Phone: Versioned JSON manifest
Phone->>API: Fetch missing immutable assets
Phone->>Phone: Validate staged content and swap atomically
else Feed unchanged
API-->>Phone: Not modified
end
Phone->>Phone: Render from verified local cache
The phone receives a small manifest and already-prepared images rather than running a modern browser engine or authenticating to each provider. A failed refresh leaves the last verified feed intact. The server has a single background refresh loop, bounded to two concurrent source fetches; requests from phones read the latest immutable profile snapshot rather than triggering provider calls. Manifest and asset ETags avoid redundant transfers. Assets are keyed by SHA-256 and retained with the current and two prior profile snapshots in process memory.
Feeds¶
The checked-in evaluation configuration defines bedroom with five assigned
sources: weather-bogota, yankees-api-sports, yankees-balldontlie,
nyt-home, and guardian-uk. The old MLB Stats source remains defined but is
disabled and unassigned. Each card still lasts 15 seconds; the bulletin cap is
75 seconds so all five can appear in one bulletin. These are independent,
server-side profile settings, so changing card count or timing needs no new
Android build within the schema-1 limits of eight cards, 5–30 seconds per card,
and a 15–240 second bulletin cap. Raising those contract limits would require
a coordinated client update. Profile IDs are presentation choices, not
credentials. A configured device bearer token
maps to a device ID and profile; the server authorizes the device and composes
its assigned feed. The configuration model supports additional profiles and
source assignments, but enrollment and profile administration are not yet
implemented. Runtime credential values are supplied outside checked-in
configuration.
Baseball source choice¶
The earlier deployed PoC asked MLB Stats for Yankees games, but requests from
OVH received HTTP 406 at an upstream edge. The current evaluation uses
API-Sports team ID 25; a bounded OVH date-only request returned the next
Yankees game while a season=2026 request was denied by the observed free-plan
entitlement. BALLDONTLIE uses Yankees team ID 19; a team-filtered request
for adjacent dates returned the recent result and next scheduled game from
both the local machine and OVH. Public HTTPS now serves both sports cards and
their assets; those checks do not establish long-term provider reliability.
The observed free plan has a 100-request daily account limit. Devices share server-side fetches rather than each spending that quota. The implementation caches day results, refreshes less often than the device manifest, and has a 90-request-per-UTC-day process ceiling; a process restart resets that ceiling. BALLDONTLIE documents free access to Games at five requests per minute. Its adapter makes one bounded nine-day team request per fetch; normal source refresh is at least 15 minutes apart, with two-minute live-game refreshes. It rejects a paginated response rather than silently omit later games. Its observed access window may exclude an adjacent date, so yesterday's result or tomorrow's game can be absent even when today's request succeeds. A missing or failed baseball source does not suppress weather or headlines, and the phone keeps the last valid card only until its validity expires. See Backend for policy and Deployment for the activation boundary.
This side-by-side feed is temporary evaluation policy. A future end-user profile would normally choose one provider and consider the other as a controlled fallback, after comparing freshness, accuracy, terms and cost.
Deliberate unknowns¶
The schema-1 contract provides bounded card metadata, fixed per-profile
rotation timing, validity, attribution, and presentation schedule fields.
Emergency interruption policy, account enrollment, and a user-facing source
selection surface remain future decisions. Contract changes must preserve
compatibility with installed API-22 clients; shared fixtures live under
contracts/dashboard/v1/.
The future administration website is also outside the current critical path. When it exists, it will edit backend policy through the same application services; it will not make the Moto X a web application.
See Architecture, Backend, and ADR 0002.