The port name follows the message until it is typed by hand, and clearing it follows again. The second line holds the message, so a list port's item type no longer squeezes the name.
168 lines
7.2 KiB
Markdown
168 lines
7.2 KiB
Markdown
# The flow editor
|
|
|
|
The canvas is where most of the work happens. It floats its chrome over a
|
|
full-bleed graph, so what you are looking at is always the flow.
|
|
|
|
## The canvas
|
|
|
|
Nodes are laid out for you, left to right on a desktop and top to bottom on a
|
|
phone, and the arrangement is recomputed as the graph changes. There is
|
|
nothing to drag and nothing to tidy.
|
|
|
|
The edges come from message names, so there is no layout to store or to merge
|
|
when two people edit the same flow.
|
|
|
|
What is drawn:
|
|
|
|
- **Your nodes**, with a status dot — running, succeeded, failed, or nothing at
|
|
all when idle. Status is always named in words too, never colour alone.
|
|
- **Edges**, which pulse when a value goes down them. Click one to inspect it.
|
|
- **Endpoints** — anything wired into this flow that is not a node in it: a
|
|
dashboard control writing a message, a tile reading one, a node in another
|
|
flow on the far side of a dotted name. Drawn as labelled boxes at the
|
|
boundary, so a value never appears to come from nowhere.
|
|
|
|
Values are live. The editor holds a websocket to the engine, and the connection
|
|
banner tells you when it is not.
|
|
|
|
## Adding a node
|
|
|
|
**Add node** on the dock, or ⌘P / Ctrl-P for the command palette, which also
|
|
jumps between flows and offers your shared nodes. Pick a type and it appears on
|
|
the canvas with its panel open.
|
|
|
|
## The node panel
|
|
|
|
Floats on the right; a full-screen sheet on a phone.
|
|
|
|
**Consumes** and **Provides** are the ports. Each port has two lines: its name
|
|
and payload type (a `list` also says what its items are), then the message it
|
|
is bound to, how often at most it is delivered, and, on an output, a
|
|
*streaming* toggle for ports that publish repeatedly during one execution. The
|
|
message field suggests messages already in the flow, which is usually how you
|
|
wire something: type the name that already exists.
|
|
|
|
A port is named after its message until you name it yourself. Its name field
|
|
then stays empty and shows the name it follows. A name typed there stays when
|
|
the message changes, which is how a port is bound to a message called
|
|
something else, as a [`wren`](../reference/node-types.md#wren) target is;
|
|
clear it to follow the message again. The name is what the node's code sees,
|
|
so it is letters, digits and `_`, not starting with a digit, and no two inputs
|
|
or two outputs of a node share one. The field keeps the name it had otherwise.
|
|
|
|
Renaming an output renames the message everywhere it is read. Inputs are not
|
|
renamed, because an input is more often re-pointed at a different message than
|
|
renamed.
|
|
|
|
**Settings** is generated from the node type's parameter schema, so an MQTT
|
|
node shows broker, topic and QoS, and an ntfy node shows server, topic and
|
|
priority. A field marked as a credential renders as a picker over your stored
|
|
[secrets](operations.md) instead of a text box.
|
|
|
|
A Function node gets a second settings section where you add your own: a
|
|
setting is a constant of this node's code and arrives as an argument beside its
|
|
ports. See [Where a node's values come from](../concepts/values.md).
|
|
|
|
**Timeout** (Function nodes) is how many seconds the code may be *silent*
|
|
before it is stopped: it measures silence, not duration, so a node that yields
|
|
every few seconds can run for hours under a timeout of 300. Left empty there is
|
|
no limit, which is the default. Set one where a node going quiet means it is
|
|
stuck rather than working. A `0` says so explicitly.
|
|
|
|
**Code** is the editor. It saves as you type and applies on ⌘S; the node
|
|
reloads without the flow stopping. A node file defines `process(...)`; if it
|
|
defines exactly one public function under another name, that one is used
|
|
instead.
|
|
|
|
**Shared** turns a node's code into a library entry other flows can reuse.
|
|
Editing a shared node edits the copy every flow using it runs, which is the
|
|
point and also the caution.
|
|
|
|
!!! note "Not in the panel yet"
|
|
|
|
`device` and `device_policy`, which machine a node's code runs on, are set
|
|
through the API rather than the panel, with `PUT /flows/{name}`. See
|
|
[Remote workers](../code/workers.md).
|
|
|
|
## The flow panel
|
|
|
|
Click the canvas title to open the flow's own settings.
|
|
|
|
- **Running** — the switch that starts and stops the flow. Stopped means none
|
|
of its subscriptions, schedules or webhooks exist.
|
|
- **Mode** — `live` or `batch`. Live reacts to what arrives; batch only runs
|
|
when a run asks it to. See [Runs](../concepts/runs.md).
|
|
- **Inputs** — messages the flow takes from outside, with the value each starts
|
|
from. For a batch flow these are also the run's parameters.
|
|
- **Outputs** (batch only) — which messages a run reports as its result.
|
|
- **Contents** — a reminder that this flow's name namespaces every message
|
|
inside it.
|
|
|
|
## Inspecting an edge
|
|
|
|
Click a wire. You get the last payload that went down it, when, and a sparkline
|
|
of its recent numeric history. You can also republish that value from the node
|
|
that produced it, which re-runs everything downstream. It is the fastest way to
|
|
test a change without waiting for the real sensor.
|
|
|
|
## The dock
|
|
|
|
Along the bottom, floating over the canvas.
|
|
|
|
| Control | What it does |
|
|
|---|---|
|
|
| **Add node** | opens the palette |
|
|
| **Fit** | returns to the view the flow opened with |
|
|
| **Run** | injects a value by hand; on a batch flow, opens the parameters dialog |
|
|
| **Pause / Resume** | holds messages instead of running them |
|
|
| **Step** | releases exactly one held message |
|
|
| **Publish** | puts the draft live |
|
|
| **Discard** | throws the draft away |
|
|
| **Issues** | what is stopping this flow from running, per node |
|
|
| **Logs** | what the nodes printed, filterable |
|
|
|
|
Pause and step together are how you test a flow before it moves anything
|
|
physical: pause it, inject a value, step it through, watch the values appear on
|
|
the edges, then publish.
|
|
|
|
## Shortcuts
|
|
|
|
| Chord | Action |
|
|
|---|---|
|
|
| ⌘P / Ctrl-P | command palette |
|
|
| ⌘S / Ctrl-S | publish the flow — or, with focus in the code editor, apply the code |
|
|
| ⌘Z / ⌘⇧Z | undo / redo (the flow; the code editor has its own) |
|
|
| ⌘C / ⌘V | copy and paste nodes, including between flows |
|
|
|
|
## Drafts and publishing
|
|
|
|
Saving writes a draft; the engine keeps running what was published. Publishing
|
|
promotes it and reloads.
|
|
|
|
If someone else saved the same flow while you were working, publishing answers
|
|
with a conflict rather than overwriting them. The Flows list offers **Publish
|
|
all changes** when several flows are sitting on drafts.
|
|
|
|
## Issues
|
|
|
|
The canvas validates as you edit and marks the node each issue belongs to:
|
|
|
|
- a port that needs a message nothing in reach provides
|
|
- a message that exists but has never held a value
|
|
- a dependency cycle
|
|
- a node reading a message it also writes, with nothing to start it from
|
|
- code that did not load
|
|
- a webhook with no shared secret (advisory — it does not stop the flow)
|
|
- a node that loaded but reports itself down, such as a connector that cannot
|
|
reach its device
|
|
|
|
A flow with any of these except the last two does not run, and the health
|
|
summary on Home counts it. The last one clears on its own once the node reports
|
|
itself well again.
|
|
|
|
## See also
|
|
|
|
- [Flows, nodes and messages](../concepts/flows.md) — the model behind the canvas
|
|
- [Node types](../reference/node-types.md) — everything the palette offers
|
|
- [Writing node code](../code/nodes.md) — what goes in the editor
|