E+H Soil Moisture
For every configured sensor the node fetches the current readings of an instrumentation from the Endress+Hauser Netilion cloud, maps the selected value keys to the attributes soil moisture, volumetric water content and soil temperature, and emits one message per sensor containing a GreenspaceRecord entity. It is suited for irrigation control and monitoring of municipal green spaces.
- Node type
- eh-bodenfeuchte
- Package
- @htag/node-red-contrib-hypertegrity-parksandgardens
- Inputs / outputs
- 1 / 1
- Data source
- Endress+Hauser Netilion API (API key and user account required)
When to use this node
Netilion is the IIoT cloud of Endress+Hauser in which measuring devices are managed as so-called instrumentations. Soil moisture sensors deliver several readings there under technical keys, for example moisture, volumetric water content (VWC) and temperature. The node fetches these readings via the Netilion REST API and brings them into the Smart Data Model GreenspaceRecord from the Parks and Gardens domain, so they can be combined with other environmental data in an urban data platform.
Typical use cases are:
- Irrigation management for parks, flower beds and street trees based on current soil moisture.
- Green space monitoring with dashboards showing moisture and temperature per location.
- Transfer into a context broker as
GreenspaceRecordentities via the NGSI-LD Builder.
How the node works
Trigger
An incoming message starts the fetch. Optionally it names different sensors.
Authenticate
With Basic Auth, API key and user credentials accompany every request; with OAuth the node obtains a token, keeps it in memory and renews it before it expires.
Fetch readings
One GET request per sensor to /v1/instrumentations/<ID>/values of the Netilion API.
Map and emit
The configured value keys are mapped to soilMoisture, soilMoistureVwc and soilTemperature; one message per sensor leaves the node.
Result: One GreenspaceRecord entity per sensor with observation time, location and the mapped readings.
The node is trigger-based and queries the sensors one after another. Combine it with an Inject node whose interval matches the measuring interval of the sensors, for example every 15 to 60 minutes. Soil moisture changes slowly; more frequent fetches yield no new values.
Configuration
The edit dialog has three tabs.
Tab "General"
| Field | Type | Default | Meaning |
|---|---|---|---|
| Name | Text | empty | Display name of the node in the flow. |
Tab "Sensors"
The list (sensors) contains one entry per sensor with the following fields. Entries can be added, sorted and removed.
| Field | Type | Default | Meaning |
|---|---|---|---|
Sensor ID (instrumentationId) | Select | empty | Id of the instrumentation in Netilion. The refresh button loads all instrumentations of your account (with tag and serial number) using the credentials of the "Authentication" tab. |
Sensor Name (sensorName) | Text | empty | Display name that becomes name in the entity; the id is used as a fallback. |
Latitude (Lat), Longitude (Lon) (lat, lon) | Numbers in decimal degrees | empty | Location of the sensor. Only if both values are valid does the entity get a location attribute. |
Moisture Value (moistureKey) | Select | empty | Key of the Netilion value emitted as soilMoisture. Its timestamp determines dateObserved. |
Moisture VWC (moistureVwcKey) | Select | empty | Key of the volumetric water content, emitted as soilMoistureVwc. |
Temperature Value (temperatureKey) | Select | empty | Key of the soil temperature, emitted as soilTemperature. |
| Values (button) | Button | – | Loads the available value keys of the selected instrumentation with their current value so that you can make the three mappings via select lists. When the Sensor ID changes, the values are loaded automatically. |
Tab "Authentication"
| Field | Type | Default | Meaning |
|---|---|---|---|
Authentication Method (authMethod) | Select | "Basic Auth (API Key + User)" | basic: API key, username and password are sent with every request. oauth: API key and API secret are used to obtain a short-lived OAuth token with username and password, which is renewed automatically. |
| API Key | Password (credential) | empty | API key of your Netilion application; sent as header Api-Key. |
| API Secret | Password (credential, visible only for OAuth) | empty | Secret of the Netilion application for the token request. |
| Username | Text (credential) | empty | Username of the Netilion account. |
| Password | Password (credential) | empty | Password of the Netilion account. |
All four credentials are stored encrypted in the credentials store. They may contain environment variables in the form ${NAME}; the node resolves them at runtime.
You need a Netilion user account with access to the instrumentations and an application created in the Netilion Developer Portal, which provides API key and API secret. For Basic Auth, API key, username and password are sufficient; for OAuth the API secret is added. According to the dialog hint, the OAuth token is valid for about 11 minutes and is renewed 60 seconds before expiry.
Input
Every message triggers the fetch. Without special properties the configured sensors are queried; three variants allow replacing the sensor list for that message.
| Property | Type | Meaning |
|---|---|---|
msg.payload | any | Triggers the fetch of the configured sensors. |
msg.payload | array of objects with instrumentationId | Replaces the sensor list. Each object may additionally contain sensorName, lat, lon, moistureKey, moistureVwcKey and temperatureKey. |
msg.sensors | array of objects | As above, if msg.payload is not such an array. |
msg.instrumentationId | string or number | Queries exactly this one sensor; alternatively as instrumentationId in msg.payload. The name comes from msg.sensorName or from sensorName in msg.payload. Without value keys the entity contains no readings in this case. |
The credentials always come from the configuration. Properties of the incoming message are carried over to the output messages.
Output
The node sends a separate message per sensor. msg.payload is an array with exactly one GreenspaceRecord entity.
[
{
"id": "urn:ngsi-ld:GreenspaceRecord:123456",
"type": "GreenspaceRecord",
"name": "City Park Bed North",
"dateObserved": "2026-10-01T06:30:00.000Z",
"location": {"value": {"type": "Point", "coordinates": [7.7689, 49.4447]}},
"soilMoisture": 31.4,
"soilMoistureVwc": 27.8,
"soilTemperature": 14.2
}
]
| Field | Meaning |
|---|---|
id | urn:ngsi-ld:GreenspaceRecord: followed by the instrumentation id. |
type | Always GreenspaceRecord. |
name | Configured sensor name, or the id as a fallback. |
dateObserved | Timestamp of the moisture value from Netilion; without a moisture key that of the VWC value; otherwise the time of the fetch. |
location | GeoJSON point [longitude, latitude], only with configured coordinates. |
soilMoisture, soilMoistureVwc, soilTemperature | Numeric values of the mapped Netilion keys. Unmapped values or values missing in the response are omitted. Units are not carried over (see notes). |
Example flow
The package ships with an example flow. Import it in Node-RED via Menu → Import → Examples → @htag/node-red-contrib-hypertegrity-parksandgardens → eh-bodenfeuchte. Alternatively download eh-bodenfeuchte.json and import it via Menu → Import. Enter sensors and credentials after importing.
Inject
An Inject node (Go!) triggers the fetch manually or at a fixed interval.
E+H Soil Moisture
The node queries the configured sensors via the Netilion API and emits one GreenspaceRecord entity per sensor.
Debug
A Debug node shows the entities in the sidebar.
Show example flow as JSON
[
{"id": "tab1", "type": "tab", "label": "E+H Bodenfeuchte", "disabled": false, "info": ""},
{"id": "inject1", "type": "inject", "z": "tab1", "name": "Go!", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 140, "y": 120, "wires": [["eh1"]]},
{"id": "eh1", "type": "eh-bodenfeuchte", "z": "tab1", "name": "", "sensors": [], "authMethod": "basic", "x": 370, "y": 120, "wires": [["debug1"]]},
{"id": "debug1", "type": "debug", "z": "tab1", "name": "soil moisture data", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 660, "y": 120, "wires": []}
]
Status and errors
| Indicator | Meaning |
|---|---|
| Blue dot "fetching 3 sensors..." | The fetch of the named number of sensors is running. |
| Green dot "3 sensor(s) ok" | All sensors were fetched successfully. |
| Yellow dot "2 ok, 1 err" | Some sensors failed; messages were sent for the successful ones. |
| Red dot "1 error(s)" | All sensors failed. |
| Red ring "no sensors" | Neither the configuration nor the message names any sensors. Error message: "No sensors configured or provided in message". |
| Error "Failed to fetch sensor City Park Bed North (123456): …" | The request for this sensor failed (HTTP status, timeout after 15 seconds) or the OAuth login was not possible ("OAuth token request failed (HTTP 401): …"). |
| Warning on start "No API key configured. …", "OAuth mode selected but no API Secret configured.", "No sensors configured." | Incomplete configuration at deploy time. |
| Warning "OAuth token refresh failed, performing full re-authentication: …" | The token could not be renewed; the node logs in again with username and password. |
Errors are reported via node.error and can be handled with a Catch node.
Notes
- Units: The node carries over only the numeric values; the unit of the respective Netilion key is not emitted. Check in Netilion which unit the values use (for example vol. % for volumetric water content and °C for temperature) and document it in further processing.
- Data model: The Smart Data Model
GreenspaceRecorddefines, among others,soilMoistureVwc,soilMoistureEc,soilTemperature,dateObservedandlocation. The node emits the moisture value under the namesoilMoisture; rename it tosoilMoistureEcor another attribute in the NGSI-LD Builder if needed. - Rate limits: Every sensor produces one request per fetch. Netilion limits the number of API calls per application according to the booked plan; choose the polling interval accordingly. Requests have a timeout of 15 seconds.
- Editor requests: The buttons for loading instrumentations and values call the Netilion API from the Node-RED server. Newly typed credentials are transmitted; otherwise the editor uses the stored credentials of the node. The server logs a diagnostic line without secrets.
- Personal data: Username and password belong to a personal Netilion account; use a technical account where possible. The readings themselves have no personal reference; sensor locations are locations of municipal green spaces.