@strato-automation/node-red-contrib-strato-automation-v4
v2.0.9
Published
Obfuscated build of Strato Automation nodes (parity with node-red-strato + bacnet-discovery)
Readme
@strato-automation/node-red-contrib-strato-automation-v4
Node-RED palette for Strato Automation's OCN building-automation platform. Provides nodes to read and write BACnet points via the OCN server API, plus HVAC control-logic nodes (PID, linear resets, hysteresis, signal generation, unit and psychrometric conversion).
Nothing in this package speaks BACnet directly — every interaction goes through the OCN
server's HTTP API (/api/v4) and its real-time channel (SignalR).
v4 only. OCN API v3 and its MQTT transport were removed in 1.1.0 and are maintained in a separate repository — see docs/MIGRATION-V3.md if you are upgrading from 1.0.x.
Requirements
- Node.js ≥ 22.9.0, npm ≥ 10
- Node-RED ≥ 3.0.0
- A reachable Strato OCN server
Install
npm install @strato-automation/node-red-contrib-strato-automation-v4Develop and test locally
Run the palette against a real Node-RED 5 instance, isolated from your own
~/.node-red:
npm install && npm run dev:install
npm run devThat builds without obfuscation and starts Node-RED on http://127.0.0.1:1880. See docs/DEVELOPMENT.md for the full harness, including why a separate dev build exists and how to confirm a clean palette load.
Editor launch configs are provided for VS Code (.vscode/launch.json) and Claude Code
(.claude/launch.json).
Build from source
npm install
npm run buildbuild.mjs bundles each node directory with Rollup, obfuscates the output, then copies
and minifies the editor HTML into dist/. See
docs/BUILD-AND-RELEASE.md — in particular the note about
obfuscator.json's reservedNames, which you must extend when adding cross-module
entry points.
npm test runs twenty regression checks, 398 assertions in total — the
datapoint-identifier path against captured and synthesized fixtures, the catalog store,
the value store's timestamp gate, subscription bucket planning, SignalR row extraction,
editor/backend conversion parity, the func-ramp input and clamping contract,
psychrometrics, prog-function one-shot rejections, credential storage, OCN URL parsing,
the TLS toggle on both REST and SignalR, and that a flow saved by the 2.0.x palette still
loads and still behaves. Each pins a defect that was fixed or a contract that must hold;
it is not a full suite. See
docs/BUILD-AND-RELEASE.md for the per-file table.
npm run itest is separate: an end-to-end suite that drives a real OCN server through
real Node-RED flows — write/read round trips, alarm rule lifecycle, and schedule windows.
It runs as a standing monitor, each scenario looping on its own interval, with a health
endpoint and optional failure webhooks; npm run itest:once is the single-pass CI form.
It needs a live server and an application token, so it is not part of npm test. See
test/integration/README.md.
Nodes
Configure an OCN Server config node first — every OCN-aware node references one.
| Node | Type | Purpose |
|---|---|---|
| OCN Server | ocn-server | Connection and credentials for one OCN |
| BACnet Controller | bacnet-controller | Represents one controller; spawns point nodes |
| BACnet Connection | bacnet-conn | Auth config node |
| BACnet Discovery | bacnet-discovery | Caches the controller/object inventory |
| BACnet Point In | bacnet-point-in | Reads a point live over SignalR, seeded over REST |
| BACnet Point Out | bacnet-point-out | Writes a point, with priority support |
| Trend Log | trend-log | Queries point history over REST and reduces it |
| Program | prog-function | User JavaScript with OCN point access |
| PID | strato-pid | PID control loop |
| Linear Reset | func-ramp | Two-point linear interpolation |
| ON/OFF | func-on-off | Asymmetric hysteresis |
| Constant | const | Emits a fixed value |
| Input Topic | input-topic | Stamps a topic for multi-input routing |
| Unit Converter | unit-converter | Temperature / pressure / enthalpy conversion |
| Psychrometric Calculator | psychrometric-calculator | Dew point, enthalpy, wet bulb, vapour pressure |
| Signal Generator | signal-generator | Sine / saw / triangle / square / sigmoid |
Deprecated but still registered: not-gate.
Registered but hidden from the palette, purely so older flows still load: bacnet-point
— the pre-1.0 name of BACnet Point In, kept as a compatibility alias for flows saved by
the 2.0.x palette — and the v3 palette's input, output-generic, output-ip,
output-mstp and ocn-telemetry. Each translates its stored config onto the v4
equivalent, and nothing new is ever created as one. The first five also retype themselves
as they arrive (bacnet-point and input to bacnet-point-in, the three output types to
bacnet-point-out). ocn-telemetry is the exception: it keeps its own type permanently
and translates each query at runtime, because it takes the whole query from msg.payload
where trend-log needs a configured point list — so a flow containing one loads unchanged.
See docs/nodes/bacnet-point.md,
docs/nodes/legacy-v3-io.md and
docs/nodes/ocn-telemetry.md.
Removed in 1.1.0 along with OCN API v3: ocn-diagnostic, which has no replacement node,
and the v3 I/O and telemetry nodes — input, output-generic (which the v3 manifest
filed under the key output, so searching a v3 flow for "type": "output" finds
nothing), output-ip, output-mstp and ocn-telemetry. Those five went as usable
nodes: their MQTT and /api/v1 transports are gone for good. Since 3.0.0 they load again
as the compatibility aliases above, translated onto the v4 nodes rather than revived —
ocn-telemetry onto queryTelemetry(), the modern surface for which is Trend Log.
See docs/MIGRATION-V3.md,
docs/nodes/legacy-v3-io.md and
docs/nodes/ocn-telemetry.md.
Multi-input convention
Nodes with several logical inputs use one Node-RED input port, multiplexed by
msg.topic: in1…in6, plus default for the primary value. Wire an input-topic
node in front of each source to stamp the right topic. This is why a four-input ramp
appears as four input-topic nodes feeding one func-ramp.
Documentation
| | | |---|---| | ONBOARDING.md | Start here if you are about to contribute. Setup, the traps, and how to make a change end to end | | docs/ARCHITECTURE.md | How the layers, transport and message conventions fit together | | docs/DEVELOPMENT.md | Running the palette locally on Node-RED 5 | | docs/MIGRATION-3.0.md | Upgrading a flow from palette 2.x — what 3.0.0 renamed, and what it still reads from the old names | | docs/MIGRATION-V3.md | Upgrading a site from 1.0.x, where OCN API v3 still existed | | docs/INVENTORY.md | Every file, its size, and what actually ships | | docs/BUILD-AND-RELEASE.md | Build pipeline and publish process | | docs/ISSUES.md | Verified defect register, ranked by severity | | docs/nodes/ | Reference page per node type | | docs/lib/ | Reference page per shared module |
Read docs/ISSUES.md before making changes. It documents several defects in
shipped nodes, including a PID derivative sign error and an unencrypted credential path.
Repository layout
build.mjs the real build (not the npm bundle/copy-html scripts);
its `nodes` array decides what reaches dist/
obfuscator.json obfuscation config; reservedNames is load-bearing
package.json node-red.nodes decides what Node-RED registers
src/lib/ shared modules: API clients, SignalR, BACnet hub
src/server-node/ the ocn-server config node + utils.js served to the editor
src/<node>/ one directory per node (.js runtime + .html editor)
test/ twenty regression checks + fixtures; integration/ needs a live OCN
scripts/ release.mjs (release), applyStratoThemeHtml.mjs (stale one-shot)
docs/ this documentationAll 16 node directories under src/ ship. A node type loads only if it is registered in
package.json under node-red.nodes and its directory appears in the nodes array in
build.mjs; both lists are currently complete, so nothing under src/ is dead. That is
recent — twelve unregistered directories, and the stale src/package.json that
registered half of them, were deleted in the 2026-07 cleanup. See
docs/INVENTORY.md for the full file list.
Licence
MIT — see LICENSE.
