Replaces the prior stub/partial wiki with a Home + Reference-{Architecture,
Contracts,Examples,Limitations} + _Sidebar structure. Topic-contract and
data-model sections wrapped in AUTOGEN markers for the future wiki-gen tool.
Source-vs-spec contradictions surfaced and flagged inline (not silently
fixed). Pending-review notes mark sections that need a full node review.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8.9 KiB
Reference — Examples
Note
Every example flow shipped under
nodes/measurement/examples/, plus how to load them, what they show, and the debug recipes that go with them. Live source:nodes/measurement/examples/.Pending full node review (2026-05). Tier-1/2/3 visual-first example flows are still TODO (tracked in the superproject
MEMORY.md"TODO: Example Flows"). The current shipped flows pre-date the refactor; treat them as smoke tests, not as production templates.
Shipped examples
| File | Tier | Dependencies | What it shows | Status |
|---|---|---|---|---|
basic.flow.json |
1 | EVOLV only | Single measurement node driven by inject buttons — analog scalar input, scaling enabled, three debug taps on Port 0/1/2. | Legacy pre-refactor shape, still imports. |
integration.flow.json |
2 | EVOLV only | Parent-child wiring — measurement registers as a child of another node and emits its <type>.measured.<position> events. |
Legacy pre-refactor shape. |
edge.flow.json |
3 | EVOLV only | Invalid / edge payload driving for robustness checks (non-numeric strings, object in analog mode, …). | Legacy pre-refactor shape. |
The three legacy files predate the AssetResolver refactor and the analog-vs-digital mode flag. They still deploy (the editor will accept the older shape and nodeClass.buildDomainConfig reshapes whatever it finds), but the recommended Tier-1/2/3 visual-first replacements are still to be written.
Important
TODO — Tier-1/2/3 visual-first flows. Replace the three legacy files with:
01 - Basic Analog.json— one measurement, inject + scaling + smoothing + outlier-detection toggle + simulator.02 - Integration with rotatingMachine.json— measurement registered as a pressure sensor on arotatingMachine, Port 2 auto-register on deploy, parent's prediction updates as the measurement value moves.03 - Digital Multi-Channel.json— one measurement indigitalmode with 2–3 channels (e.g.level-a,temp-a,flow-a) fed by a single object-payload inject.
Loading a flow
Via the editor
- Open the Node-RED editor at
http://localhost:1880. - Menu → Import → drag the JSON file.
- Click Deploy.
Via the Admin API
curl -X POST -H 'Content-Type: application/json' \
--data @nodes/measurement/examples/basic.flow.json \
http://localhost:1880/flows
Example — basic.flow.json
Single-measurement flow with the minimum kit to exercise scaling.
Nodes on the tab
| Type | Purpose |
|---|---|
inject |
One-shot topic: 'measurement', payload: 42 (legacy alias of data.measurement) |
measurement |
The unit under test — analog mode, scaling enabled (0..100 → 0..10), mean smoothing, window 5 |
debug × 3 |
Port 0 (process), Port 1 (InfluxDB), Port 2 (registration) |
What to do after deploy
- Click the inject. Port 0 fires with
mAbs ≈ 4.2(42 scaled into 0..10),mPercent ≈ 42. - Send another value via the same inject (edit the inject payload to
60).totalMinValue/totalMaxValuestart tracking,mAbsjumps to ~6.0. - Send
topic: 'set.simulator'(use a second inject).tick()starts drivinginputValuethroughSimulator.step()every 1000 ms; Port 0 updates appear automatically. - Send
topic: 'cmd.calibrate'. IfstdDev <= 0.01(the defaultstabilityThreshold),config.scaling.offsetjumps toinputMin - currentOutput; if not, a warn appears in the log. - Send
topic: 'set.outlier-detection', then inject a wildly out-of-band value (e.g.9999). With outlier detection on the value is dropped withOutlier detected. Ignoring value=9999.
Important
Screenshot needed. Editor capture of
basic.flow.jsonplus the Port 0 debug output. Save aswiki/_partial-screenshots/measurement/basic-flow.png. Replace this callout with the image link.
Example — integration.flow.json
Demonstrates the parent-child handshake: the measurement node's Port 2 auto-fires child.register to its parent on deploy, and the parent then receives the <type>.measured.<position> event whenever a new reading lands.
Important
Screenshot needed. Editor capture of
integration.flow.jsonshowing the wiring. Save aswiki/_partial-screenshots/measurement/integration-flow.png.
Note
TODO: confirm the integration flow targets a real EVOLV parent (e.g.
rotatingMachine) versus a mock function node; if it's a mock, the Tier-2 replacement should use a real parent.
Example — edge.flow.json
Drives the node with malformed inputs to verify the warn paths land cleanly:
- Non-numeric string in analog mode →
Invalid numeric measurement payload: <value>. - Object payload in analog mode →
analog mode received an object payload (keys: …). Switch Input Mode to 'digital' …. - Numeric scalar in digital mode →
digital mode received a number (…); expected an object …. - Outlier toggle on/off mid-stream → verifies
analogChannel.outlierDetection.enabledmirrorsconfig.outlierDetection.enabled.
Important
Screenshot needed. Editor capture of
edge.flow.jsonplus the log lines each inject triggers. Save aswiki/_partial-screenshots/measurement/edge-flow.png.
Debug recipes
| Symptom | First thing to check | Where to look |
|---|---|---|
Parent never receives <type>.measured.<position> |
asset.type must match the parent's filter exactly (e.g. flow — not flow-electromagnetic). Position labels lowercase in the event name. |
config.asset.type + parent's childRegistrationUtils filter. |
| Outliers seem to pass through | outlierDetection.enabled may be off (default false). Toggle with set.outlier-detection. With <2 samples in the buffer, _isOutlier returns false regardless. |
Channel._isOutlier. |
cmd.calibrate does nothing |
Calibrator requires stdDev <= calibration.stabilityThreshold over storedValues. If storedValues.length < 2, isStable() returns false (legacy shape). |
src/calibration/calibrator.js isStable, calibrate. |
| Digital payload silently dropped | Unknown channel keys are reported only at debug log level (digital payload contained unmapped keys). Numeric values that fail Number.isFinite warn at warn. |
Measurement.handleDigitalPayload. |
| Simulator still running after toggle off | tick() reads config.simulation.enabled each tick. Confirm the toggle actually mutated the config (the set.simulator handler is idempotent — it just flips). |
Measurement.tick, toggleSimulation. |
Port 0 emits nothing after data.measurement |
Analog: _writeOutput only emits when rounded !== outputAbs. A repeated identical value is silent by design. |
Channel._writeOutput. |
mPercent is stuck at 0 or unbounded |
processRange <= 0 (i.e. absMax <= absMin); percent falls back to totalMinValue / totalMaxValue which start at 0 / 0. Configure absMin < absMax. |
Channel._computePercent. |
| Scaling output looks clamped | _applyScaling clamps the input to [inputMin, inputMax] before mapping. Wide-band sensors need inputMin / inputMax set to the full physical range. |
Channel._applyScaling. |
mAbs jumps after cmd.calibrate |
Expected. Calibration sets config.scaling.offset = baseline - currentOutputAbs, which makes the next reading land on the baseline (inputMin when scaling enabled, absMin otherwise). |
Calibrator.calibrate. |
Legacy setpoint / simulator topics work without warning |
First fire emits a one-time deprecation warning via BaseNodeAdapter's alias handling. Subsequent fires are silent — the topic still works. |
commands/index.js aliases. |
Never ship
enableLog: 'debug'in a demo — fills the container log within seconds and obscures real errors.
Docker compose snippet
To bring up Node-RED + InfluxDB with EVOLV nodes pre-loaded:
# docker-compose.yml (extract)
services:
nodered:
build: ./docker/nodered
ports: ['1880:1880']
volumes:
- ./docker/nodered/data:/data/evolv
influxdb:
image: influxdb:2.7
ports: ['8086:8086']
Full file: EVOLV/docker-compose.yml.
Related pages
| Page | Why |
|---|---|
| Home | Intuitive overview |
| Reference — Contracts | Topic + config + child registration |
| Reference — Architecture | Code map + per-Channel pipeline + lifecycle |
| Reference — Limitations | Known issues and open questions |
| rotatingMachine — Examples | Most common consumer of measurement |
| EVOLV — Topology Patterns | Where measurement fits in a larger plant |