LwM2M Server


Das Modul LwM2M Server ermöglicht die Verwaltung von LwM2M-kompatiblen IoT-Geräten direkt über die Virtuellen Geräte in niotix. Es bietet einen vollständigen LwM2M-Server und ermöglicht es, Geräte nahtlos zu verwalten und zu überwachen.

Das Modul löst zentrale Herausforderungen bei der IoT-Geräteverwaltung:

  1. Kein LwM2M-Server vom NB-IoT-Anbieter: niotix stellt einen integrierten LwM2M-Server bereit, sodass unabhängig vom Konnektivitätsanbieter IoT-Geräte direkt eingebunden und verwaltet werden können.

  2. Zentrale Verwaltung von DTLS-Keys: Durch die integrierte Verwaltung der DTLS-Keys in niotix wird eine separate Plattform überflüssig, was die Automatisierung von Workflows vereinfacht und die Sicherheit erhöht.

  3. Vermeidung herstellerspezifischer Abhängigkeiten: Das Modul nutzt den offenen LwM2M-Standard und vermeidet Abhängigkeiten herstellerspezifischer Lösungen, wodurch eine flexible, herstellerunabhängige Integration möglich wird.

  4. Effizientere Alternative zu MQTT: Im Vergleich zu MQTT bietet LwM2M eine bis zu 70 % bessere Energieeffizienz, was besonders für batteriebetriebene IoT-Geräte entscheidend ist, und ermöglicht zentrale Konfiguration, Firmware-Updates und DTLS-Verschlüsselung.

Überblick Kommunikation

%%{ init: { 'theme': 'base', 'themeVariables': { 'primaryColor': '#FFFFFF', 'primaryTextColor': '#031403', 'primaryBorderColor': '#606060', 'lineColor': '#606060', 'secondaryColor': '#2fcbff', 'tertiaryColor': '#E7E6E6', 'primary_font' : 'Poppins:wght@300;400;500;600;700;800', 'primary_font_type' : 'sans-serif' } } }%% flowchart TB H([ LwM2M Gerät ]) -->| NB-IoT| A([ NB-IoT Provider])-->|"CoAP(s)"| B H <-.->|LwM2M| B subgraph niotix direction TB B([ Lwm2m Server]) <--> I([ Konnektor: LwM2M Server]) --> C([ Virtuelles Gerät]) end

Was ist LwM2M?

Lightweight Machine-to-Machine (LwM2M) ist ein Kommunikationsprotokoll, das speziell für IoT-Geräte entwickelt wurde. Es basiert auf dem CoAP-Protokoll und eignet sich für Geräte mit begrenzter Leistung und Bandbreite, wie etwa Sensoren oder Zähler. LwM2M ermöglicht die Fernverwaltung, -überwachung und -konfiguration solcher Geräte. LwM2M bietet folgende Vorteile:

  • Effizient: Reduziert Datenlast und Sendezeit, ideal für batteriebasierte Geräte.
  • Einfache Fernverwaltung: Ermöglicht Konfiguration und Firmware-Updates.
  • Sicher: Unterstützt Sicherheitsstandards wie DTLS für eine geschützte Datenübertragung.
  • Kompatibel: Nutzt standardisierte Objekt- und Ressourcenmodelle, was die Interoperabilität zwischen verschiedenen Geräten und Herstellern sicherstellt.

Funktionsübersicht

Das LwM2M-Modul in niotix bietet folgende Kernfunktionen:

1. niotix Konnektor

Folgende Funktionen stehen aus niotix bereit:

  • Geräteverwaltung und Datenempfang: Funktionen zum Erstellen, Lesen, Aktualisieren und Löschen von LwM2M-Geräten direkt über niotix und automatisierter Datenempfang
  • DTLS-Management: Zentrale Verwaltung von DTLS-Schlüsseln zur Sicherstellung der Datensicherheit.
  • Sicherheits- und Verbindungsmodi:
    • Sicherheitsmodi: Unterstützung für keine Verschlüsselung oder DTLS (Datagram Transport Layer Security).
    • Verbindungsmodi: Wahl zwischen Bootstrap Server und Management Server.

2. LwM2M Server

Folgende Funktionen bietet das LwM2M-Backend zusätzlich:

  • LwM2M-Server: Ein vollständiger LwM2M-Server, der LwM2M V1.0, V1.1 und V1.2 unterstützt.
  • Firmware-Update-Management:
    • Over-the-Air (OTA)-Updates: Erlaubt sichere, zentrale Firmware-Updates.
    • Versionskontrolle und Rollbacks: Beinhaltet eine Versionshistorie und die Möglichkeit, Firmware bei Problemen zurückzusetzen.
  • Datenmodell-Definition:
    • Unterstützung von standardisierten LwM2M-Datenmodellen.
    • Anpassbare Datenmodelle für spezifische Anforderungen, Upload als .xml-Datei.
  • Gerätekonfiguration:
    • Remote-Konfiguration und Parameterverwaltung.
    • Profilerstellung für massenhafte, einheitliche Konfiguration von Gerätegruppen.
  • Automatisierte Aufgabenverwaltung:
    • Zeitplanung für Routineaufgaben wie Geräteprüfungen oder Updates.
    • Stapeloperationen für Massenupdates oder Konfigurationen.

Gerätekonfiguration

Konfiguration des LwM2M-Gerätes

Lwm2m-Geräte bieten in der Regel unterschiedliche Konfirgurationsoptionen. Folgende Einstellungen sind zur Verbindung mit dem niotix LwM2M-Server erforderlich:

  • Verbindungstyp: Bootstrap oder Management Server. Bootstrap Server wird grundsätzlich empfohlen
  • Verschlüsselung: Auswahl zwischen Pre-Shared Key (PSK) mit DTLS-Verschlüsselung oder ohne Verschlüsselung. DTLS wird grundsätzlich empfohlen
  • Device Key: Der PSK-Schlüssel, der für die Authentifizierung des Geräts genutzt wird; dieser kann je nach Gerät als String oder im Hex-Format vorliegen

Im Gerät muss je nach gewähltem Verbindungstyp und gewählter Verschlüsselung die Serveradresse und der Port eingestellt werden:

Verbindungstyp mit DTLS ohne Verschlüsselung
Bootstrap Server coaps://lwm2m.niotix.io:5694 coap://lwm2m.niotix.io:5693
Management Server coaps://lwm2m.niotix.io:5684 coap://lwm2m.niotix.io:5683

Konfiguration des Virtuellen Gerätes in niotix

  • External ID: Der eindeutige Identifikator des Geräts, wie IMEI oder EUI, wird zur Authentifizierung am LwM2M-Server verwendet.
  • Connection Server Type: Gibt an, ob das Gerät eine Verbindung zu einem Bootstrap- oder Management-Server herstellt.
  • Security Mode: Auswahl zwischen Pre-Shared Key (PSK) und keiner Sicherheit.
  • Device Key: Der PSK-Schlüssel im Hex-Format, der für die Authentifizierung des Geräts genutzt wird.

Datenformat im Virtuellen Gerät

Eingehende Daten im Virtuellen Gerät ("_RAW"-Datenpunkt) folgen diesem Format, wenn das Default-Template im Konnektor ausgewählt ist:

  • Struktur: {LwM2M-Resource-URL: Wert}
  • Beispiel: {/3/0/3: "BC66NBR01A11"}
  • Zeitstempel-Verwaltung: Die Plattform verwendet den Zeitstempel des eingehenden LwM2M-Servers, um die Datenzeitpunkte zuzuordnen.

Wenn ein Gerät ein individuelles Datenmodell verwendet, so muss dieses zunächst dem LwM2M-Backend hinzugefügt werden und die Datenweiterleitung im LwM2M-Backend konfiguriert werden.

Verwendung der Gerätedaten im Gerätetreiber

Die Ressourcen aus dem LwM2M-Objekt können mit einem Javascript-Funktionsparsers in Datenpunkte mit sprechenden Variablennamen konvertiert werden. Je nach Gerät kann auch z.B. dort auch eine Konvertierung eine Messtelegramms erfolgen.

Beispiel eines einfachen Funktionsparsers für das LwM2M Standardobjekt 3:

// Define the URL-to-name table
const urlNameTable = {
    // Resources for LwM2M Object 3 (Device Object)
    "/3/0/0": "Manufacturer",
    "/3/0/1": "Model Number",
    "/3/0/2": "Serial Number",
    "/3/0/3": "Firmware Version",
    "/3/0/4": "Reboot",
    "/3/0/5": "Factory Reset",
    "/3/0/6": "Available Power Sources",
    "/3/0/7": "Power Source Voltage",
    "/3/0/8": "Power Source Current",
    "/3/0/9": "Battery Level",
    "/3/0/10": "Memory Free",
    "/3/0/11": "Error Code",
    "/3/0/12": "Reset Error Code",
    "/3/0/13": "Current Time",
    "/3/0/14": "UTC Offset",
    "/3/0/15": "Timezone",
    "/3/0/16": "Supported Binding and Modes",
    "/3/0/17": "Device Type",
    "/3/0/18": "Hardware Version",
    "/3/0/19": "Software Version",
    "/3/0/20": "Battery Status",
    "/3/0/21": "Memory Total",

    // Other objects and resources can be added here
};

// Function to sanitize the resource name into camel case format
function sanitizeResourceName(name) {
    return name
        .toLowerCase()
        .replace(/[^a-zA-Z0-9]+(.)/g, (match, chr) => chr.toUpperCase()); // Convert to camel case
}

// Decode function to map URL to camel-case JavaScript variable name and value
module.exports = function (payload, meta) {
    // Extract the first (and only) key-value pair from the input object
    const [url, value] = Object.entries(payload)[0];

    // Look up the human-readable name directly in the URL name table
    const resourceName = urlNameTable[url];

    // If resource is not found, throw an error or handle it (here we return an empty object)
    if (!resourceName) {
        throw new Error(`Resource with URL ${url} not found in the table.`);
    }

    // Sanitize the resource name to camel case format
    const sanitizedResourceName = sanitizeResourceName(resourceName);

    // Return the result object with the sanitized camel-case name and value
    return {
        [sanitizedResourceName]: value
    };
}