@htag/node-red-contrib-hypertegrity-environment 0.3.2
Hypertegrity NodeRED Environment Nodes.
Hypertegrity Node-RED Environment Nodes
A collection of Node-RED nodes for environmental sensor data and natural event monitoring.
📝 Introduction
This package provides nodes for monitoring environmental sensordata, like:
- water levels and flood data (Pegelonline, LANUK Hochwasserportal NRW, Endress+Hauser Netilion)
- air quality and environmental sensors (Umweltbundesamt air quality API, openSenseMap)
Included Nodes
| Node | Description |
|---|---|
opensensemap |
Retrieves sensor data of selected senseBoxes from openSenseMap |
luftdaten |
Retrieves current air quality measurements and forecasts from the Umweltbundesamt air quality API (palette name luftdaten-api) |
pegelonline |
Streams water level data from the Pegelonline MQTT service of the German Federal Waterways and Shipping Administration |
lanuk |
Downloads the water-level measurement archive of the Hochwasserportal NRW (operated by LANUK) and maps it to FloodMonitoring entities (FIWARE Smart Data Model) |
eh-floodmonitoring |
Fetches water level data of configured sensors from the Endress+Hauser Netilion API and maps it to FloodMonitoring entities |
Configuration by message
Every node accepts an optional msg.config object on its input. Its properties use the same names as the node settings in the editor and override them for this message only; the stored configuration stays unchanged. Existing message properties of earlier versions keep working. pegelonline is an event source: there, msg.config rebuilds the subscriptions until the next override, msg.reset = true or the next deploy. The help text of each node lists the supported properties.
msg.config = { stations: ["2700010"], lookahead: 12 };
Security notes
The editor helper endpoints of all nodes require the <node type>.read permission when adminAuth is enabled. The host check only applies to the editor helper endpoints (station lists, map selection): they only fetch http(s) URLs of public hosts. Internal hosts (for example a mirror in your network) can be allowed in settings.js:
hypertegrity: { allowedHosts: ["mirror.example.internal"] }
At runtime the nodes fetch the configured URLs (from the editor or from msg.config, e.g. apiUrl, apiBaseUrl, zipUrl, stationsUrl, brokerUrl, dictApiUrl) without this check. Therefore take msg.config only from trusted sources.
Editor requests to hosts that are not trusted (not the built-in service, not in allowedHosts) check the address again when connecting (protection against DNS rebinding); internal IPv4 addresses in IPv6 notation (e.g. ::7f00:1, ::ffff:0:7f00:1, 64:ff9b::a00:1, 2002:7f00:1::) and site-local addresses (fec0::/10) are recognised as internal. The stored EDIS credentials of pegelonline are only sent to the broker configured in the editor. eh-floodmonitoring sends its stored credentials only to the origin of its API base URL (default https://api.netilion.endress.com; a message that points msg.config.baseUrl to another origin uses only its own credentials and requires msg.config.apiKey); requests that carry credentials do not follow redirects to another host. Its editor lookups only use the public Netilion API or the address the node is deployed with, and stored credentials only go to the deployed address.
Notes on upgrading to 0.3.2
- All nodes: boolean values in
msg.config(debug,useDistanceThreshold) only accepttrue/falseor"true"/"false"; other values (e.g."yes",1) raise an error instead of being treated asfalse. - opensensemap: a box whose response is not JSON (HTML page, broken or truncated JSON) or contains no box with
_idis listed inmsg.failedBoxesinstead of being output as an empty box.failedBoxes[].statusholds the HTTP status only for error responses (400 or higher), otherwisenull(earlier versions reported e.g.200for a connection lost in the middle of the response).msg.config.boxIdsentries must be strings or numbers.msg._rawBoxesis a separate copy.numericValueis parsed strictly: blank values, booleans, arrays and hexadecimal notation givenull(earlier e.g.0,1or26), a decimal comma ("12,5") gives 12.5 (earliernull). A sensor withoutsensorTypeandtitleis stored inmeasurementsunder its sensor ID (earlier under the key"undefined"). Trailing/of the API URL are removed (earlier.../boxes//<id>). - luftdaten: unknown or wrongly cased pollutant names in
msg.config.componentsraise an error. Editor coordinatesnull, empty or outside ±90°/±180° count as missing (warning, yellow status) instead of producing the point[0, 0]without warning. Responses without valid JSON or withoutdataare reported as warnings; a station list without any usable station is not cached. Closing the node ends a running retry pause at once. If all observation and forecast requests of a message fail, the node reports an error to the Catch node and shows a red status (earlier only warnings and a green status); partial failures keep the warnings and turn the status yellow. A missing trailing/of the API base URL is added. Station IDsnull,"null"or empty are ignored. The help documents thatlookaheadis limited to 1–48 (invalid values: 24) and the units of CO (mg/m³) and BaP/arsenic/cadmium/nickel (ng/m³). - pegelonline:
msg.config.brokerUrlwith a broker other than the one configured in the editor requiresmsg.config.usernameandmsg.config.password; otherwise the message is rejected with an error and the running subscriptions stay unchanged.msg._stationis a copy per message. Without coordinates in the master datalocation.coordinatesis[null, null]in the message object as well (earlier[undefined, undefined], identical after JSON serialisation). The description shows river kilometre 0 askm 0(earlierkm ?). A text inmsg.config.stations/parametersthat is not a JSON array is read as a comma/space separated list, so a single ID such as"2730010"works (earlier an error). Set-up and connection errors of a configuration started by a message (msg.config,msg.reset) now reach Catch nodes with that message. The texts of the errors "credentials missing" and "credentials rejected" are output in the runtime language instead of as message keys. - lanuk: measurements are parsed strictly:
"1,080.5"becomes 1080.5 (earlier 1.0805); values with additional text (e.g."12.5cm") are skipped. In split mode every message has its ownmsg.lanukobject. An empty, 0, negative or invalid timeout in the editor means 60 s (earlier a negative value caused uncaught errors); the editor marks negative values as invalid. A station list given as text is only read as JSON if it starts with[, otherwise as comma/space separated list (a single number such as"2711300"now filters in the editor and inmsg.config). Lines without a valid timestamp are discarded with one warning per run (earlierobservationDateTime: ""). Astations.jsonthat is not a list is reported with one warning per run.messwerte.txtis preferred over other.txtfiles in the archive, and a column named exactlytimewins over columns liketimeseries_id. Station numbers likeconstructorno longer break the retrieval. Its warnings are output in the runtime language instead of as message keys (e.g.lanuk.warn.invalidStations). The measurement archive (about 12 MB of text with roughly 240,000 readings) is read line by line, and only the selected stations are kept, in "latest" mode only their newest reading: a retrieval needs a few MB of memory instead of about 40 MB, and stored output messages no longer keep the whole archive text in memory (earlier about 12 MB per stored message). The output is unchanged. - eh-floodmonitoring: a Netilion value
null, missing or not numeric creates nocurrentLevel/measuredDistance(earlier 0 cm ornullwith HQ class 150) and a warning per sensor. A response that is not JSON or has novalueslist (e.g.{}) is reported as an error for this sensor instead of an entity without values. The editor lists (instrumentations, value keys) report such responses as an upstream error (HTTP 502); an empty list stays valid. A sensor with only one or invalid coordinates gets[0, 0]with a warning. Redirects are only followed within the Netilion API. Closing the node also aborts a running OAuth token request. Entities carry the new fieldunitCode: "CMT"(unit ofcurrentLevel,measuredDistanceandalertLevel). The placeholders{{id}}and{{name}}in links are inserted URL-encoded. Instrumentation IDs that are not numeric are reported as an error for this sensor without a request. OAuth without user name or password is reported at start-up (warning, status "not configured"); the start-up warning is no longer repeated with the first message. A level exactly on an HQ threshold belongs to the higher class (earlier one class lower for decimal thresholds). As ineh-bodenfeuchte: OAuth tokens are cached per set of credentials including a hash of the password (another password inmsg.configno longer gets the cached token); after the first authentication error of a message (failed token request or HTTP 401, also with Basic auth) the remaining sensors of this message get the same error without a further request or login; an HTTP 401 with a cached token discards the token, logs in again once per message and repeats the request. Values spread over several pages (pagination.next) are read completely, at most 10 pages (beyond that one warning per sensor), at runtime and in the editor. In the editor a failed token request is reported as upstream error with the HTTP status of Netilion (502, earlier 500 without status), a token response withoutaccess_tokenas invalid response (502), and value entries that are not objects (e.g.null) are skipped, at runtime as well (earlier the whole sensor failed).${VAR}in image and dashboard links is resolved from the flow/tab environment like the credentials (earlier only from the process environment). A sensor list in which no sensor has an instrumentation ID raises the error "No sensors configured or provided in payload" (earlier the message ended without output or error). The new setting API base URL (default: the public Netilion API) points the node to a proxy or a test mock;msg.config.baseUrlchanges it for one message (another origin than the configured one uses only the credentials of the message and requiresmsg.config.apiKey).
Installation
Install via the Node-RED Palette Manager or using npm:
npm install @htag/node-red-contrib-hypertegrity-environment
🌍 About the Project / Über das Projekt
📍 Über dieses Projekt / About this Project
DE: Dieses Open Source Projekt ist im Rahmen der Förderung Modellprojekte Smart Cities entstanden und wurde durch die Initiative des Projekts Südwestcluster ermöglicht.
EN: This open source project was created as part of the Smart City Pilot Projects (Modellprojekte Smart Cities) funding and was made possible by the initiative of the Südwestcluster project.
💡 Hintergrund / Background
DE: Die Entwicklung wurde durch öffentliche Gelder im Kontext der Förderung Modellprojekte Smart Cities unterstützt. Dadurch können wir diese Lösung der gesamten Community als Open Source zur Verfügung stellen.
EN: The development was supported by public funds in the context of the Smart City Pilot Projects (Modellprojekte Smart Cities) funding. This allows us to make this solution available to the entire community as open source.
🌐 Open Source Philosophie / Open Source Philosophy
DE: Wir unterstützen aktiv die OSS-Community und fördern kollaborative Entwicklung. Durch die Veröffentlichung als Open Source profitieren alle Beteiligten:
- Community: Freier Zugang zu moderner Smart City Technologie
- Transparenz: Nachvollziehbare und überprüfbare Lösungen
- Innovation: Gemeinsame Weiterentwicklung durch verschiedene Akteure
- Nachhaltigkeit: Langfristige Verfügbarkeit und Wartbarkeit
EN: We actively support the OSS community and promote collaborative development. Releasing it as open source benefits everyone involved:
- Community: Free access to modern Smart City technology
- Transparency: Traceable and verifiable solutions
- Innovation: Collaborative development by various actors
- Sustainability: Long-term availability and maintainability
🙏 Danksagung / Acknowledgements
DE: Ein besonderer Dank gilt der Förderung Modellprojekte Smart Cities für die finanzielle Unterstützung sowie dem Projekt Südwestcluster für die Initiative und Koordination:
- Eifelkreis Bitburg-Prüm
- Stadt Kaiserslautern
- Landkreis Kusel
- Stadt und Verbandsgemeinde Linz am Rhein
- Landkreis Mayen-Koblenz
- Landkreis St. Wendel
EN: Special thanks goes to the Smart City Pilot Projects (Modellprojekte Smart Cities) funding for financial support and the Südwestcluster project for the initiative and coordination:
- Eifelkreis Bitburg-Prüm
- City of Kaiserslautern
- District of Kusel
- City and Collective Municipality of Linz am Rhein
- District of Mayen-Koblenz
- District of St. Wendel
📜 License & Contact / Lizenz & Kontakt
© 2026 HYPERTEGRITY AG. Alle Rechte vorbehalten. / All rights reserved.
⚖️ License Compatibility / Lizenz-Kompatibilität
DE: Details zur Lizenzierung und zu den Nutzungsrechten finden Sie in der beigefügten LICENSE Datei.
EN: Details on licensing and usage rights can be found in the attached LICENSE file.
📧 Contact / Kontakt: [email protected] 🌐 Website: www.hypertegrity.de