Skip to content

Automations

Automations are Bifrost's "when this, then that" layer: a trigger fires on a change in your home, optional conditions gate it, and one or more actions run — server-side, off the same live device feeds the dashboards use, so nothing needs a browser open.

Every rule reads as a sentence, and is built as one in a single editor:

When Office stays empty for 15 minonly between 21:00 and 06:00then Office off.

Manage them on the Automations page (each rule grouped under its trigger), or from a sensor's detail panel on the Devices page.


Triggers

A trigger watches one subject and fires on a transition — never on a level, so a sensor re-reporting "motion" can't re-run your actions, and a restart never replays state that was already true.

Rooms (occupancy)

The most powerful subject: a Room's aggregate occupancy, fed by every presence sensor in the room (Hue motion, MotionAware areas, Home Assistant occupancy — interchangeable). "Office empty for 15 minutes → off" is one rule no matter how many sensors the room has, and a sensor added to the room later joins the aggregate automatically.

Events: becomes occupied · becomes empty · stays empty for… · stays occupied for…

Sensors

A single sensor's reading. Events adapt to what the sensor measures:

  • Motion / occupancy — detects motion · clears · stays clear for… · stays detected for…
  • Contact (door/window) — opens · closes · stays open for… ("the fridge door has been open ten minutes") · stays closed for…
  • Illuminance / temperature / humidity — rises above · drops below a threshold. These fire on the crossing, not while the value sits past it.

Devices (power)

A device's power state: turns on · turns off · stays on for… · stays off for… — for lights, switches, and TVs/speakers. The classic:

When BRAVIA turns on, then Hallway off, Living Room to 20%.

Device triggers watch the same live feeds as the dashboards, so a change made outside Bifrost (the TV's own remote, a physical switch) triggers too. A smart TV that only answers when asked gets polled tightly while a rule watches it — within seconds of the TV coming on — and isn't touched at all once no rule does.

Macro (I press a button)

A rule with no event input at all — it never fires on its own. It's just a named list of actions run on demand: the Action button board widget, the ▶ Run control, or voice. This is how one press does several things at once — "movie night" turns off the lights and opens Hulu on the bedroom TV. Because it never event-fires, a macro also skips conditions; it's purely its actions.

Timer (a painted schedule)

Pick Timer instead of Trigger at the top of the editor and the "when" becomes the same paintable 24-hour timeline the kiosk display plan uses, with two modes per hub-local hour: On and Off. The "then" is simply the rooms, lights, and switches the timer powers — picked from one checklist, no verbs or clauses.

A timer only switches power: when an On hour begins the targets turn on, and when an Off hour begins they turn off. The writes carry no colour or brightness, so a lamp you keep blue comes back blue at the next On edge — a timer never restyles anything.

It's still edge-driven: nothing re-applies while an hour holds, so a manual change mid-window sticks until the next boundary. Conditions gate the On edge like any other fire; the Off edge always runs (off is the safety direction). After a restart the plan reconciles the On direction — an evening reboot still lights the porch — but never forces things off at boot; the next real Off edge squares that. (Neither "put things back" nor cooldown is offered on a timer: the plan brings its own off direction, and a timer already fires at most once an hour.)


Conditions ("only if")

Conditions are checked at the moment the trigger fires; all must hold.

  • Time window21:0006:00 style, server-local. Overnight windows wrap midnight, and an optional weekday filter applies to the day the window starts (a Saturday-night window still covers Sunday 2 am).
  • Another sensor's reading — "only when the lux sensor is below 20", "only while the door sensor is closed". An unknown reading never satisfies a condition: a rule would rather skip than fire blind.
  • Another room's occupancy — "only while the living room is empty".
  • A device's power — gate on a light, speaker/TV, or switch being on or off. The off-polarity is the natural "unless" clause: "between 20:00 and 07:00, if motion detected, set brightness to 45% — unless the TV is on" is a time window + a motion trigger + a device gate reading "unless it's on". Like every gate, an unknown device fails closed.

Actions ("then")

Each action drives the same shared control paths as the UI and voice:

  • A room — on, off, or on with a brightness/colour. Room on/off is the pure power command: it also stops the room's speakers and switches; a brightness or colour clause touches only the lights.
  • A single light — on, off, or on with a brightness/colour.
  • A power device — on or off.
  • Power toggle — flip a device's power (light, switch, or TV/speaker): reads its current state and applies the inverse. This is the relative action a physical macro button wants — one press turns it on, the next turns it off. (A device whose state is unknown is skipped rather than guessed.)
  • A scene — apply any saved scene.
  • Open a TV app — launch a streaming app (Hulu, Netflix, …) on a TV/streamer remote. The app list is that TV's own catalog, and the launch routes through the same path the remote UI uses (per-vendor handling, recents recording). Playing a specific title isn't cracked yet — this opens the app.

An action step reads as a sentence: a verb (turn on, turn off, or apply scene), then its targets — pick several at once from one searchable, room-grouped checklist. "Turn on" can chain "and…" clausesand set brightness to 40%, and set colour to ▮ — which compose into one command per target, not separate writes. Clauses only exist on "turn on": a light won't change colour while off, so "set colour" without the power verb would silently do nothing — the sentence always says it. Switches sharing a clause step simply turn on. A rule can carry several steps; they run in order, best-effort (one unreachable device doesn't stop the rest).

Cooldown ("don't re-run within N minutes") stops rapid re-fires — useful for anything triggered by motion in a busy hallway.

Put things back — a timed hold: when the rule fires, Bifrost first snapshots the current state of everything the actions touch (each light's full colour/brightness, each switch's power — room and scene targets expand to their member devices), applies the actions, and restores the snapshot after the configured time. "Someone's at the door → porch to 100% — put things back after 5 minutes" returns the porch to whatever it was, not just "off". A re-fire during the hold extends the timer but keeps the original snapshot, and holds survive a restart. When two rules' holds overlap on the same device, the later one inherits the earlier capture — whichever timer runs last, the device returns to its true pre-automation state, never to another rule's output. (Speakers aren't resumed — playback isn't a state.)

Manual override wins. The hold exists to undo what the automation did — so once anything else changes a held device (the Bifrost UI, the Hue app, a wall switch: they all arrive on the same live push streams), that device is released from the hold and keeps your change; the rest of the snapshot still restores on time. "Motion turned the hall on at 30%, I bumped it to full" — the hall stays at full, it doesn't snap off ten minutes later. Detection is tolerant of device-side rounding and ignores reachability blips, so only a genuine change counts as yours.


Running, testing, and pausing

Every rule row has:

  • Run (▶) — execute the actions right now, skipping the trigger and conditions. The way to test a rule without walking past a sensor.
  • An enable switch — pause a rule without deleting it.
  • Duplicate — copies the rule disabled, ready to retune.
  • A last ran readout ("ran 5m ago").

Rule edits take effect immediately — the engine re-reads rules per event, and a rule created mid-flight baselines its subject at creation, so the very next transition fires it.


Debugging: why didn't it fire?

Enable developer mode (Settings → Developer) and open the event log: it streams the server's own records live — every device state push, every rule fire, and every skip reason (in cooldown, condition not met), plus the voice pipeline and discovery. Filter to Automations or Device state, act on the device, and watch the decision happen.


Worked examples

Goal Rule
Hall light on motion, at night only When Hall motion detects motion · only 21:00–06:30 · then Hallway on at 30%
Room off when everyone leaves When Office stays empty for 15 min · then Office off
Movie lighting when the TV wakes When BRAVIA turns on · then Living Room to 20%, Hallway off
Fridge door alarm When Fridge contact stays open for 5 min · then Kitchen light on (blink your attention)
Dark-day lamp When Office lux drops below 15 · only Mon–Fri 08:00–17:00 · then Desk lamp on
Doorbell spotlight When Porch motion detects motion · then Porch at 100% · put things back after 5 min
Evening porch light Timer: on 18–23 · powers Porch (off again at 23:00, colour untouched)

Notes

  • Triggers are edge-only: a rule fires when the state changes into place, not continuously while it holds.
  • "Stays … for" timers cancel the moment the state breaks (motion cancels an "empty for 15 min" countdown) and survive restarts.
  • A Room trigger needs at least one presence sensor in the room — Bifrost refuses to save a rule that could never fire.
  • Automations are configured per hub and run entirely locally.