Step by step: Forwarding Notification API events per user with Node-RED
Example target system: Loxone Miniserver
In this guide I show you step by step how to receive events from the ekey bionyx Notification API in Node-RED, identify the user behind the event, and trigger a dedicated event for that user in another system. As an example we use a Loxone Miniserver, but the last step works with any system that has an HTTP interface.
ekey bionyx controller --> Node-RED --> Loxone Miniserver
(notification) (evaluate) (virtual input)
Step 1: What you need
• ekey bionyx system in Plus Mode
• Node-RED (3.x or newer) with a fixed IP address, in the same local network as the controller
• Loxone Miniserver, or any other system with an HTTP interface
• The system export (.JSON) from the ekey bionyx app
In this example Node-RED runs on 192.168.1.20:1880 and the Miniserver is 192.168.1.50. Replace these with your own addresses.
Step 2: Create the endpoint in Node-RED
Drag three nodes onto the canvas and configure them as follows:
| Node | Setting |
|---|---|
| http in | Method: POST · URL: /api/notification/finger |
| http response | Status code: 200 |
| debug | Output: complete msg object |
Connect the http in node to both the http response node and the debug node.
[http in] --+--> [http response: 200]
+--> [debug]
Important: The http response node must be connected directly to the http in node. The controller has a timeout, and if you answer only at the end of your flow, the controller will repeat the notification.
The path /api/notification/finger is defined by ekey and cannot be changed. Click Deploy.
Step 3: Activate the Notification API
In the ekey bionyx app go to Settings → Smart Home Connections → Activate Notification API. Enter the base URL of your Node-RED instance:
http://192.168.1.20:1880
Enter the host and port only. The controller appends the path itself (/api/notification/finger for fingers, /api/notification/input for digital inputs).
Please note the ekey security implementation guidelines (see Resources at the end of this document).
Step 4: Find your user IDs
Place a finger on the scanner. In the Node-RED debug sidebar you now see the notification:
{
"type": 10,
"result": 10,
"detail": null,
"time": "2024-05-29T15:47:42Z",
"ctlDevId": "4500080101000035",
"acqDevId": "4500070101000025",
"params": {
"userId": "tKlLpvUa",
"fingerIndex": 2
}
}
The important fields:
| Field | Meaning |
|---|---|
| type | 10 = finger, 20 = digital input |
| result | 10 = Match, 20 = Filtered Match, 30 = No Match |
| params.userId | The user – this is what we route on |
| params.fingerIndex | Which finger was used |
The userId is an ID, not a name. To find out which name belongs to which ID, export the system from the ekey bionyx app. The .JSON file lists all your users and devices with names and IDs. Write down the mapping, for example:
tKlLpvUa -> max
aB3xYz91 -> anna
Step 5: Evaluate the event
Add a function node between the http in node and the debug node. Paste this code and enter your own user IDs at the top:
// Your mapping from the system export
const USERS = {
"tKlLpvUa": "max",</span><span lang="EN-US"></span>
"aB3xYz91": "anna"</span><span lang="EN-US"></span>
};
const p = msg.payload || {};
// Only process finger events
if (p.type !== 10) {
return null;
}
const userId = (p.params && p.params.userId) ? p.params.userId : null;
msg.ekey = {
userId: userId,
userName: userId ? (USERS\[userId\] || "unknown") : "unknown",
granted: p.result === 10, // true only for a real match
time: p.time
};
return msg;
Deploy and place a finger again. The debug sidebar now shows a clean object:
{ "userId": "tKlLpvUa", "userName": "max", "granted": true, "time": "..." }
This is your user-specific event. Everything that follows is only routing.
Step 6: Prepare Loxone
In Loxone Config, create one virtual input per user:
| Virtual Input | Triggered when |
|---|---|
| ekey_Max | Max is recognised |
| ekey_Anna | Anna is recognised |
| ekey_Rejected | A finger is rejected |
Save the configuration to the Miniserver and reload it, otherwise the input may still be named VI1.
Create a dedicated Loxone user (for example nodered) with permissions on these virtual inputs only. Do not use the admin account.
A virtual input is triggered like this – you can test it directly in your browser:
http://192.168.1.50/dev/sps/io/ekey_Max/Pulse
Step 7: Create one event per user
Add a switch node after the function node:
| Setting | Value |
|---|---|
| Property | msg.ekey.userName |
| Rule 1 | == string max |
| Rule 2 | == string anna |
| Rule 3 | otherwise |
Each output is now one dedicated user event.
Step 8: Send the HTTP request
Add one change node per switch output. In each one, set two properties:
| Property | Value |
|---|---|
| msg.url | http://192.168.1.50/dev/sps/io/ekey_Max/Pulse |
| msg.method | GET |
Then add a single http request node and connect all change nodes to it:
| Setting | Value |
|---|---|
| Method | set by msg.method |
| URL | leave empty (comes from msg.url) |
| Authentication | Basic authentication |
| Username / Password | your Loxone user nodered |
| Return | a UTF-8 string |
Connect a debug node to the output. The finished flow:
[http in] --+--> [http response: 200]
+--> [function] --> [switch: user] --+--> [change: ekey_Max] --+--> [http request] --> [debug]
+--> \[change: ekey_Anna\] -----+
+--> \[change: ekey_Rejected\] -+
Click Deploy.
Step 9: Test
Place a finger on the scanner. You should see:
• Node-RED debug: the user name and granted: true
• Node-RED debug: the Loxone response with Code=“200”
• Loxone Config live view: the virtual input flashes
If it does not work:
| Symptom | Solution |
|---|---|
| Node-RED receives nothing | Check the path: it must be exactly /api/notification/finger. Enter the base URL in the app without a path. |
| Controller reports a timeout | The http response node is not connected directly to http in. |
| Loxone answers 401 | Wrong password, or the Loxone user has no permission on the virtual input. |
| Loxone answers 404 | Wrong name of the virtual input. Save the configuration to the Miniserver and reload. |
| Wrong user name | The USERS table is outdated. Export the system JSON again. |
You can also test without a scanner:
curl -X POST http://192.168.1.20:1880/api/notification/finger \
-H "Content-Type: application/json" \
-d '{"type":10,"result":10,"detail":null,"time":"2024-05-29T15:47:42Z",
"ctlDevId":"4500080101000035","acqDevId":"4500070101000025",
"params":{"userId":"tKlLpvUa","fingerIndex":2}}'
Notes
• The Notification API reports every event, including rejected and unknown fingers.Use msg.ekey.granted to separate them.
• The time field is in UTC.
• Do not expose Node-RED to the internet. The endpoint belongs in the local network.
• The target system is interchangeable. Instead of Loxone, the http request node can address KNX, Home Assistant, ioBroker, MQTT or any REST endpoint.Only Step 6 and Step 8 change.
Resources
• Documentation Notification API