Nivus Rain Gauge
The node reads the cumulative collected height of Nivus rain gauges via the Nivus DataKiosk API, derives the precipitation since the last reading and emits one WeatherObserved and one WaterObserved object per station. Stations are picked in a dual list that the node fills directly from the API.
- Node type
- nivus-rainfall
- Package
- @htag/node-red-contrib-hypertegrity-weather
- Inputs / outputs
- 1 / 2
- Data source
- Nivus DataKiosk API (datakiosk-api.nivusweb.com/api/v2)
When to use this node
Nivus rain gauges record precipitation as the cumulative collected height of a container and transmit their readings to the Nivus portal. The DataKiosk API makes these values available. The Nivus Rain Gauge node handles authentication, the joining of master data and current values, and the conversion into precipitation per measurement interval.
Typical use cases are:
- Local precipitation measurement from your own sensor network transferred into an NGSI-LD context broker.
- Heavy rain monitoring for sewer networks, flood protection or the depot with hourly precipitation values.
- Container fill levels monitored to plan maintenance and emptying.
How the node works
Trigger
An incoming message starts the run. Without an input message the node produces no output.
Load master data
Via GET /stations and GET /stations/{Id} the node resolves name, GPS position and the value channel of every station and stores them in the node context.
Fetch values
Via POST /channels/curdata the node fetches the current channel values, drops placeholder values and joins the rest with the master data.
Calculate precipitation and emit
The difference of the collected height to the previous device reading yields the precipitation. Output 1 receives WeatherObserved, output 2 WaterObserved.
Result: One precipitation and one collected-height object per station with geoposition, as an array or as individual messages.
The node is trigger-based. Every input message first rewrites the master data cache and then fetches the current values. In addition, the node can warm the cache at a fixed interval and at startup; these runs produce no output.
Precipitation is the increase of the cumulative collected height between two distinct device readings, identified by the timestamp CurValueTS. On the first fetch of a station the value is 0. If you trigger the node repeatedly without a new reading, the last computed value is emitted again and the baseline is kept. Negative differences caused by emptying the container or a counter overflow are clamped to 0.
Configuration
The edit dialog is divided into four tabs.
Tab "General"
| Field | Type | Default | Meaning |
|---|---|---|---|
| Name | Text | empty | Display name of the node in the flow. |
Message format (messageFormat) | Select | One message (array) | One message (array): one message per output with all entities as an array. One message per station: a separate message per station and output. |
Tab "Stations"
| Field | Type | Default | Meaning |
|---|---|---|---|
Available stations / Selected stations (stations) | Dual list | empty | Restricts the fetch to the right-hand list. Without a selection all stations of the API are queried. "Reload" fetches the station list again via the API, "Clear selection" removes all entries. The search field filters the left-hand list. |
The editor loads the station list through the Node-RED backend using the stored API key or the API_KEY environment variable. After entering a new key a deploy may be necessary for this.
Tab "Authentication"
| Field | Type | Default | Meaning |
|---|---|---|---|
API Key (apiKey) | Credential (password) | empty | Sent as HTTP header X-API-Key. Leave empty to use the API_KEY environment variable of the Node-RED process. |
Tab "Advanced"
| Field | Type | Default | Meaning |
|---|---|---|---|
| API base URL | Text, required | see below | Base of all API calls. Stored as apiBase. |
| Value channel | Text, required | in1_val | Channel whose Name or ExchangeName provides the readings. Stations without this channel are skipped. Stored as channelName. |
| Cache interval (min) | Number | 120 | Periodic rewrite of the master data cache in minutes. 0 = only on input message. Produces no output. Stored as cacheInterval. |
| Load cache on startup | Checkbox | enabled | Warms the cache about two seconds after deploy or startup. Produces no output. Stored as fetchOnStartup. |
| Timeout (sec) | Number | 60 | HTTP timeout per request. Stored as requestTimeout. |
| WeatherObserved type | Text, required | WeatherObserved | Entity type for output 1. Stored as weatherType. |
| WaterObserved type | Text, required | WaterObserved | Entity type for output 2. Stored as waterType. |
| ID prefix | Text | urn:ngsi-ld: | The entity ID is built from prefix, type, colon and station ID (see the example under Output 1). Stored as idPrefix. |
| Debug mode | Checkbox | disabled | Emits detailed logs prefixed with [Nivus] as warnings in the debug sidebar. Stored as debug. |
Default values of the URL fields:
API base URL: https://datakiosk-api.nivusweb.com/api/v2
Obtaining an API key
The key for the DataKiosk API belongs to your Nivus customer account. Contact your Nivus representative or Nivus support to have access to the DataKiosk API enabled. Quotas and terms of use follow from your contract with Nivus; the node itself imposes no limits.
Input
The input acts as trigger. The content of the message is not evaluated; its properties are, however, copied to the outgoing messages unless overwritten by payload, topic or nivus.
| Property | Type | Meaning |
|---|---|---|
msg | any | Every message starts the master data refresh and the value fetch. If a value fetch is still running, the new run is skipped. |
Output
All attributes are emitted flat; only location is structured as an NGSI-LD GeoProperty as expected by the Stellio context broker. The objects can be handed to the NGSI-LD Builder.
Output 1: WeatherObserved
In array mode an array of all stations with msg.topic = "WeatherObserved", in split mode one message per station with msg.topic = entity ID.
[
{
"id": "urn:ngsi-ld:WeatherObserved:123",
"type": "WeatherObserved",
"name": "Rain gauge treatment plant",
"alternateName": "in1_val",
"location": {"type": "GeoProperty", "value": {"type": "Point", "coordinates": [7.77, 49.44]}},
"dateObserved": "2026-10-01T08:00:12.000Z",
"precipitation": 1.4,
"nivusHeight": 238.6
}
]
| Field | Meaning |
|---|---|
id | ID prefix + WeatherObserved type + : + station ID. |
type | The configured WeatherObserved type. |
name | Station name from the API. |
alternateName | Name of the value channel (Channel.Name). |
location | GeoProperty with GeoJSON point [longitude, latitude] from the GPS data of the station. |
dateObserved | Time of the fetch in ISO 8601 format. |
precipitation | Precipitation since the previous device reading, two decimals, in the unit of the channel after applying Unit.Factor (mm for rain gauges). |
nivusHeight | Raw sensor value CurValue without conversion. |
Output 2: WaterObserved
In array mode an array of all stations with msg.topic = "WaterObserved", in split mode one message per station with msg.topic = entity ID.
[
{
"id": "urn:ngsi-ld:WaterObserved:123",
"type": "WaterObserved",
"name": "Rain gauge treatment plant",
"alternateName": "in1_val",
"location": {"type": "GeoProperty", "value": {"type": "Point", "coordinates": [7.77, 49.44]}},
"dateObserved": "2026-10-01T07:55:00.000Z",
"height": 238.6,
"waterLevel": 1.4
}
]
| Field | Meaning |
|---|---|
id | ID prefix + WaterObserved type + : + station ID. |
type | The configured WaterObserved type. |
name, alternateName, location | As on output 1. |
dateObserved | Timestamp of the device reading (CurValueTS). |
height | Cumulative collected height CurValue × Unit.Factor, two decimals. |
waterLevel | Change of the collected height since the previous reading, identical to precipitation. |
Additional message properties
| Property | Meaning |
|---|---|
msg.nivus | Fetch metadata: source (Nivus DataKiosk API), apiBase, channelName, retrievedAt, stationCount and containsPersonalData: false. |
msg.topic | In array mode the entity type, in split mode the entity ID. |
Example flow
The package ships with an example flow. Import it in Node-RED via Menu → Import → Examples → @htag/node-red-contrib-hypertegrity-weather → nivus. Alternatively download nivus.json and import it via Menu → Import.
Inject
An Inject node triggers the fetch manually or at a fixed interval matching the measurement rate of the devices.
Nivus Rain Gauge
The node queries all stations of the account. In the example the API key has to be added.
Debug
Two Debug nodes show WeatherObserved and WaterObserved in the sidebar.
Show example flow as JSON
[
{"id": "tab1", "type": "tab", "label": "Nivus", "disabled": false, "info": ""},
{"id": "inject1", "type": "inject", "z": "tab1", "name": "Go!", "props": [{"p": "payload"}, {"p": "topic", "vt": "str"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 150, "y": 160, "wires": [["nivus1"]]},
{"id": "nivus1", "type": "nivus-rainfall", "z": "tab1", "name": "", "apiBase": "https://datakiosk-api.nivusweb.com/api/v2", "channelName": "in1_val", "stations": [], "weatherType": "WeatherObserved", "waterType": "WaterObserved", "idPrefix": "urn:ngsi-ld:", "messageFormat": "array", "cacheInterval": 120, "requestTimeout": 60, "fetchOnStartup": true, "debug": false, "x": 380, "y": 160, "wires": [["debug1"], ["debug2"]]},
{"id": "debug1", "type": "debug", "z": "tab1", "name": "WeatherObserved", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 610, "y": 140, "wires": []},
{"id": "debug2", "type": "debug", "z": "tab1", "name": "WaterObserved", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 600, "y": 180, "wires": []}
]
Status and errors
| Indicator | Meaning |
|---|---|
| Blue dot "loading metadata..." | Master data is being loaded. |
| Blue dot "loading values..." | Current values are being fetched. |
| Green dot "n station(s)" | The run succeeded; n stations were emitted. |
| Green ring "n station(s) cached" | A cache run (startup or interval) stored n stations; no output was produced. |
| Yellow ring "no stations" | No stations with the configured value channel were found. |
| Red ring "error" | A run failed; details are given by the corresponding error message. |
| Error "Nivus input run failed: …" / "Nivus value fetch failed: …" | Master data or values could not be loaded, for example "No API key configured (credential or env API_KEY)." |
| Error "Nivus metadata refresh failed: …" | A cache run failed. |
| Warning "Nivus: failed to load station …: …" | The detail fetch of a single station failed; it is skipped. |
Errors are reported via node.error together with the triggering message and can be handled with a Catch node.
Notes
- API calls per run: Every input message causes one list call, one detail call per station and one value fetch. A station selection reduces the detail calls. Do not trigger the node more often than the devices measure, typically hourly.
- Context storage: Master data (
stationsMeta) and baseline heights (heights) live in the node context. With the default context store they are lost on restart or deploy; the first precipitation value afterwards is0. Configure a persistent context store insettings.jsif the calculation should survive restarts. - Environment variable: Without a stored key the node reads
API_KEYfrom the environment of the Node-RED process, for example from a container secret. - Proxy: There is no separate proxy setting;
axioshonours the environment variablesHTTP_PROXYandHTTPS_PROXY. - Units: Collected height and precipitation are emitted in the unit of the channel after
Unit.Factor; for rain gauges this is mm. Values with the placeholder unit00000000-0000-0000-0000-000000000000are dropped. - Personal data: The output contains only technical station and measurement data including the GPS position of the gauges.
msg.nivus.containsPersonalDatais alwaysfalse.