Node-RED
Node-RED bietet seine Schlösser an. Legt eine Smart-Lock-Verbindung an oder aktualisiert sie (Anbieter "nodered"); die Schlösser werden zu Smart Locks, wenn ein Administrator die Geräte dieser Verbindung synchronisiert.
POST/api/nodered/smart_lock/register
Erwartet JSON-Body: { "instance_id": "<zufällige ID der Schloss-Bridge>", "secret": "<gemeinsames Geheimnis, 32-256 Zeichen>", "name": "Node-RED Vereinsheim", "delivery": "mqtt", // mqtt (Standard, die ERP veröffentlicht auf ihrem Broker) oder push "webhook_url": "https://…", // nur push: empfängt die signierten Befehle "locks": [{"id": "front_door", "name": "Haupteingang", "state": "locked", "unlock_method": "remote"}] }
Antworten
200Ergebnis der Registrierungobject
Felder anzeigen (5)
statusstringcreated, updated oder restored
connection_idintegerlocksintegersmart_locksintegerSmart Locks, die der Administrator bereits synchronisiert hat
mqttobjectDelivery MQTT: Broker-Zugang der Bridge
Felder anzeigen (6)
urlstringusernamestringpasswordstringMQTT-JWT, gültig 30 Tage
client_idstringtopicstringvalid_untilstring
curl --request POST \
--url https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'POST', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.post(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register")
.post(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart mit package:http (kein Controller im Package iw_erp_api)
import 'package:http/http.dart' as http;
final response = await http.post(
Uri.parse('https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register'),
headers: {'x-iw-jwt-token': '<TOKEN>'},
);
print(response.body);{
"status": "string",
"connection_id": 42,
"locks": 1,
"smart_locks": 1,
"mqtt": {
"url": "https://vynst.de",
"username": "lena.hartmann@example.org",
"password": "••••••••",
"client_id": "42",
"topic": "string",
"valid_until": "string"
}
}Node-RED stellt das Anbieten seiner Schlösser ein. Erwartet JSON-Body {"instance_id": "...", "secret": "..."}.
DELETE/api/nodered/smart_lock/register
Antworten
default
curl --request DELETE \
--url https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'DELETE', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.delete(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Delete,
RequestUri = new Uri("https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register")
.delete(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart mit package:http (kein Controller im Package iw_erp_api)
import 'package:http/http.dart' as http;
final response = await http.delete(
Uri.parse('https://eure-instanz.iw-erp.de/api/nodered/smart_lock/register'),
headers: {'x-iw-jwt-token': '<TOKEN>'},
);
print(response.body);Ergebnis eines Befehls, den Node-RED über MQTT erhalten hat. Erwartet JSON-Body {"instance_id": "...", "secret": "...", "success": true, "state": "unlocked", "message": "..."}.
POST/api/nodered/smart_lock/commands/{identifier}/result
Pfad-Parameter
identifierPflichtstring |
Antworten
default
curl --request POST \
--url https://eure-instanz.iw-erp.de/api/nodered/smart_lock/commands/42/result \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'POST', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://eure-instanz.iw-erp.de/api/nodered/smart_lock/commands/42/result', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://eure-instanz.iw-erp.de/api/nodered/smart_lock/commands/42/result"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.post(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://eure-instanz.iw-erp.de/api/nodered/smart_lock/commands/42/result', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://eure-instanz.iw-erp.de/api/nodered/smart_lock/commands/42/result"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://eure-instanz.iw-erp.de/api/nodered/smart_lock/commands/42/result")
.post(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://eure-instanz.iw-erp.de/api/nodered/smart_lock/commands/42/result"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart mit package:http (kein Controller im Package iw_erp_api)
import 'package:http/http.dart' as http;
final response = await http.post(
Uri.parse('https://eure-instanz.iw-erp.de/api/nodered/smart_lock/commands/42/result'),
headers: {'x-iw-jwt-token': '<TOKEN>'},
);
print(response.body);Darf ein Berechtigungsnachweis, den ein Leser bei Node-RED liest (App-QR-Code des Schlosses, QR der Mitgliedskarte, RFID-Kartennummer), das Schloss öffnen? Schreibt das Smart-Lock-Protokoll.
POST/api/nodered/smart_lock/check_access
Erwartet JSON-Body: { "instance_id": "...", "lock_id": "front_door", // ein Schloss dieser Node-RED-Instanz "smart_lock_id": 12, // oder ein beliebiges ERP-Smart-Lock "credential": "04A1B2C3D4", "credential_type": "auto", // auto, access_code, member_card oder card "open": false // die ERP öffnet ein Schloss eines anderen Anbieters selbst }
Antworten
200Zugriffsentscheidungobject
Felder anzeigen (6)
grantedbooleanreasonstringgranted, unknown_credential, no_access, invalid_code or code_expired
credential_typestringsmart_lockobjectFelder anzeigen (2)
idintegernamestring
personobjectFelder anzeigen (2)
idintegernamestring
openedboolean
curl --request POST \
--url https://eure-instanz.iw-erp.de/api/nodered/smart_lock/check_access \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'POST', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://eure-instanz.iw-erp.de/api/nodered/smart_lock/check_access', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://eure-instanz.iw-erp.de/api/nodered/smart_lock/check_access"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.post(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://eure-instanz.iw-erp.de/api/nodered/smart_lock/check_access', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://eure-instanz.iw-erp.de/api/nodered/smart_lock/check_access"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://eure-instanz.iw-erp.de/api/nodered/smart_lock/check_access")
.post(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://eure-instanz.iw-erp.de/api/nodered/smart_lock/check_access"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart mit package:http (kein Controller im Package iw_erp_api)
import 'package:http/http.dart' as http;
final response = await http.post(
Uri.parse('https://eure-instanz.iw-erp.de/api/nodered/smart_lock/check_access'),
headers: {'x-iw-jwt-token': '<TOKEN>'},
);
print(response.body);{
"granted": true,
"reason": "string",
"credential_type": "string",
"smart_lock": {
"id": 42,
"name": "Beispiel"
},
"person": {
"id": 42,
"name": "Beispiel"
},
"opened": true
}