Config reference
A brand is one config.yaml under brands/<id>/. Anything you leave out is simply off. The builder writes this file for you, and this page explains every section it writes.
brand:identity on the shell↓
device:what ships in firmware↓
hub:what the hub does with it
sources:where the numbers come from↓
moods:numbers to faces↓
alerts:when to interrupt you↓
brand
Identity. The id is the folder name under brands/, everything else lands on the device.
namethe title on the boot screenmascotwhat the pet calls itselftaglineunder the namewebsiteandlogoon the about screen
brand: id: gooshi name: TAMAGOOSHI mascot: GOOSHI tagline: keep it alive website: gooshi.me logo: logo.png
device
What ships in firmware. Every subsection is an enabled list plus a default, and the image only carries what the brand lists. Transports pick the radio: ble: gatt alone, or add wifi: mqtt for the hub over a broker.
Themes are palettes, and theme.custom takes your own three colors. Try one, default is slate.
The same shape covers typeface, mascot packs, games, and apps. buddy turns on the on-device agent view, persona bakes your name into the status bar and an about screen (long-press A on home), and timezone sets the clock.
Mascots can be custom too. mascot.custom takes any transparent PNG next to the config, and the mixer builds one from parts. persona.avatar uses the same 6-expression strip. Set mascot: true to also offer it in mascot selection.
hub · sources
A source is anything the hub polls for numbers. Every reading becomes a metric that moods and alerts can act on. Pick a type to see its shape.
Synthetic values with drift, no keys needed. The right pick for a first flash.
hub: sources: - type: demo interval_secs: 3 metrics: - {key: mrr, label: MRR, value_start: 1200, fmt: "${v}", drift: 4}
The latest point of a timeseries query. Needs DATADOG_API_KEY and DATADOG_APP_KEY in the hub's environment, and site picks the region.
hub: sources: - type: datadog interval_secs: 30 site: datadoghq.com window_secs: 900 metrics: - {key: cpu, label: CPU, query: "avg:system.cpu.user{*}", fmt: "{v}%"}
A HogQL query or a saved insight by short_id. Needs POSTHOG_API_KEY, and host points at your instance.
hub: sources: - type: posthog interval_secs: 60 host: https://us.posthog.com project_id: "12345" metrics: - {key: signups, label: SIGNUPS, query: "SELECT count() FROM events WHERE event = 'signup'", fmt: "{v}", kind: star} - {key: active, label: ACTIVE, insight: mmtixzFF, fmt: "{v}"}
Keys stay out of config. A source names the environment variables it depends on and the hub fails fast if one is missing. A metric marked kind: star gets the hero slot on the watch face.
Sources are pluggable behind one Source port. Adding a provider is a folder under hub/backend/src/services/sources/<name>/ with its own config.py and source.py, not a change to the core.
hub · moods & alerts
Moods map metrics to the face. A rule is a condition plus a mood, the highest priority match wins, and with no match the device falls back to mascot.mood. Try one.
When signups drop under 100, the mood turns
hub: moods: - {when: {metric: signups, op: lt, value: 100}, mood: sick, priority: 10}
Operators are lt, lte, gt, gte, eq, and ne. Alerts use the same condition but page you instead: a severity, a title, and an acknowledgement on the device.
hub: alerts: - {id: cpu-high, when: {metric: cpu, op: gt, value: 90}, severity: critical, title: "CPU is pegged", source: hub}
Severities are info, warning, and critical. Ready to write yours? The builder has a form for all of this.