57 lines
1.9 KiB
Markdown
57 lines
1.9 KiB
Markdown
# Keeping state in a flow
|
|
|
|
Need a running total or a last-seen value? Make it a message. Function nodes
|
|
have no hidden `context` or global flow store.
|
|
|
|
## Read and write the same message
|
|
|
|
Declare `reading` and `total` as inputs, and `total` as an output:
|
|
|
|
```python
|
|
def process(reading, total):
|
|
return {"total": total + reading}
|
|
```
|
|
|
|
Add `total` to the flow's **Inputs** with a starting value of `0.0`. Each
|
|
execution reads the previous total and publishes the next one.
|
|
|
|
- A node is never downstream of itself, so its own publication does not run
|
|
it again.
|
|
- A triggering input needs a starting value. Without one, validation reports
|
|
`self_loop_needs_initial`; a Python default alone does not supply the message.
|
|
|
|
## Feedback between two nodes
|
|
|
|
A controller may read an estimate that depends on its own previous output.
|
|
Ordinary triggering inputs would form a cycle. Mark the feedback input
|
|
**non-triggering** in the flow definition instead:
|
|
|
|
```json
|
|
{"name": "estimate", "port": "estimate", "dtype": "float", "trigger": false}
|
|
```
|
|
|
|
It creates no dependency and does not wake the node. Whenever another input
|
|
runs the node, it reads the latest estimate. If no estimate exists yet, that
|
|
argument is omitted, so give it a Python default:
|
|
|
|
```python
|
|
def process(reading, estimate=0.0):
|
|
return {"command": reading - estimate}
|
|
```
|
|
|
|
Use this on the feedback input; keep the inputs that should wake the node
|
|
triggering. Configure `trigger` through the API or flow JSON; the node panel
|
|
does not currently expose it.
|
|
|
|
## Built-in state
|
|
|
|
Built-in nodes such as delay, rate limit and filter-on-change keep their own
|
|
timing or comparison state in the engine. Storage and device nodes also manage
|
|
the state needed for their connections. Your Function code still exchanges
|
|
state through declared messages.
|
|
|
|
## See also
|
|
|
|
- [Where a node's values come from](values.md)
|
|
- [Node types](../reference/node-types.md)
|