Hoppa till huvudinnehåll

Node-RED

Node-RED Example Flow

Introduktion​

Node-RED är ett flödesbaserat, low-code-verktyg för att koppla samman hårdvara, API:er och onlinetjänster. Med IoT-plattformen fyller det flera syften:

  • Fungerar som ett utvecklingskit för att bygga och verifiera IoT-plattformens översättare och Flow-komponenter.
  • Fungerar som ett simuleringsverktyg som underlättar utbyte av data med IoT-plattformen för att utforska olika scenarier.
  • Fungerar som ett verifieringsverktyg för att simulera olika integrationsmetoder och protokoll, vilket förenklar acceptanstestning för nya versioner av IoT-plattformens programvara.
  • Fungerar som ett integrationsverktyg som gör det möjligt att koppla samman olika tredjepartstjänster och system.

Node-RED har dock sina begränsningar. Det kräver kunskaper i JavaScript-programmering och fungerar som en enda hyresgäst (single tenant), och saknar därmed skalbarhet. Dessutom erbjuder det bara ett grundläggande skydd mot obehörig åtkomst genom en enkel inloggningsskärm, vilket kräver strikt brandväggsskydd.

Vad du kan göra (och var du börjar)​

Ditt målBörja med
Simulera enheter / skicka testdata till IoT-plattformenKom igång - MQTT-exempelflödet
Läsa IoT-plattformens data via REST-API:etKom igång - REST-delen av exempelflödet
Bygga, testa och ladda upp översättareSkapa IoT-plattformens översättare med Node-RED
Bygga dataflöden mellan enheter (additionalDeviceUpdates)Dataflöden

Förutsättningar​

  • Node-RED installerat på en dator eller server (nodered.org).
  • Ett konto på IoT-plattformen med åtkomst till din servers Swagger-gränssnitt (https://staging.yggio.net/swagger) - används för att hämta en API-token och för att reservera MQTT- ämnen (topics) / skapa autentiseringsuppgifter.
  • Nätverksåtkomst från Node-RED till IoT-plattformens MQTT-broker och REST-API. Håll Node-RED bakom en brandvägg (det har bara en enkel inloggning).
  • Grundläggande JavaScript-kunskaper för REST-API:et och översättararbete.

Kom igång​

Installera Node-RED på en dator eller server enligt Node-RED-instruktionerna. Det enklaste sättet att utbyta data med IoT-plattformen är standardnoderna MQTT in / MQTT out riktade mot IoT-plattformens MQTT-broker - därifrån kan du bygga flöden och dashboards och simulera datamängder. Att istället använda IoT-plattformens REST-API är mer kraftfullt men kräver mer JavaScript.

Snabbaste vägen till första resultatet. Exempelflödet nedan är komplett (6 simulerade enheter, dubbelriktad MQTT, plus REST) - bra för lärande, men mycket på en gång. Om du bara vill se en datapunkt landa i IoT-plattformen först: reservera ett MQTT-ämne (IoT-plattformen, steg 5 nedan), lägg till en enda MQTT out-nod som pekar på det, och publicera ett litet JSON-meddelande som {"temperature": 21}. En enhet dyker upp i IoT-plattformen inom en minut. Importera därefter hela flödet för den fullständiga bilden.

För en snabb start, importera följande exempel-Node-RED-flöde till din Node-RED-installation:

Node-RED Exempel Flow JSON

Exempelflödet visar hur man använder MQTT för att publicera simulerad data och prenumerera på den från IoT-plattformens MQTT-broker. Dessutom innehåller det ett exempel på att logga in med IoT-plattformens REST-API, spara en token och utföra en GET-förfrågan till /iotnodes och en tidsserie.

Gör följande konfigurationer i IoT-plattformen:

  1. Gå till IoT-plattformens Swagger.
  2. Hämta en giltig token från IoT-plattformen genom att navigera till /auth/local-ändpunkten. Klicka på "Try it out", ange ditt användarnamn och lösenord för IoT-plattformen, klicka på "Execute" och kopiera svarstoken till urklipp.
  3. Klicka på den gröna "Authorize"-knappen längst upp till höger, klistra in token i textrutan och klicka på "Authorize". Du är nu inloggad på IoT-plattformens API i Swagger och kan testa alla API:er.
  4. Gå till /basicCredentialSet-ändpunkten och skapa en uppsättning grundläggande autentiseringsuppgifter (basic credential set) med ett lämpligt starkt användarnamn och lösenord.
  5. Gå till /reservedMqttTopic-ändpunkten, använd basicCredentialSet, och reservera 6 olika ämnen för 6 IoT-noder i IoT-plattformen. Ämnet måste följa strukturen yggio/generic/v2/[youruniquedeviceid]

Gör konfigurationerna i Node-RED:

  1. Importera exempelflödet.
  2. I 'Start'-noden längst upp till vänster, uppdatera användarnamn och lösenord så att de matchar dina autentiseringsuppgifter på IoT-plattformen för att möjliggöra användning av REST-API:et.
  3. I en av MQTT out-noderna som representerar enheter på IoT-plattformen, lägg till en ny MQTT-server med samma URL som IoT-plattformens URL, och ange ditt användarnamn och lösenord i avsnittet "Security".
  4. Lägg till ämnet för enhet 1 som skapades i steg 5 ovan.
  5. Upprepa stegen ovan för de återstående 5 MQTT out-noderna, med den MQTT-server som skapades tidigare.

Du kan nu köra (deploy) flödet och testa REST-API-integrationen GET /iotnodes genom att klicka på startknappen längst upp till vänster. Du får ett felmeddelande från tidsseriedatan men bortse från det för nu. Om du går tillbaka till ditt konto på IoT-plattformen bör det nu finnas en MQTT-nod som tar emot simulerad data med jämna mellanrum.

Gör den slutliga konfigurationen för att få dubbelriktad kommunikation:

  1. Gå till ditt konto på IoT-plattformen och klicka på den nya MQTT-noden.
  2. Gå till fliken 'Channels' och skapa en ny MQTT-kanal. Välj kanaltypen basicCredentialSet och referera till det basicCredentialSetId som skapades tidigare.
  3. Kopiera det fullständiga ämnet från MQTT-kanalen till urklipp.
  4. Gå tillbaka till Node-RED, hitta noden med namnet Device1-FromYggio och klicka på den. Detta är en MQTT in-nod.
  5. Välj din befintliga MQTT-server och klistra in ämnet som kopierades från IoT-plattformen i ämnesfältet.
  6. För att få tidsserie-API-anropet att fungera, uppdatera IoT-nodens id i den nedre av de två 'Prepare API call' till _id på fliken 'General' i enhetslistan för din nya MQTT-nod.
  7. Konfigurationen är nu klar och du kan köra (deploy) den. Inom 1 minut skapas ytterligare 5 MQTT-IoT-noder i IoT-plattformen. Du kan observera datan som genereras i Node-RED, skickas till IoT-plattformen genom att publiceras på IoT-plattformens MQTT-broker, prenumereras på från IoT-plattformens MQTT-broker, fördröjs och sedan återpubliceras på IoT-plattformens MQTT-broker. Du kommer också se att tidsserie-API:et nu börjar fungera.

För att se simuleringen i praktiken, gå till enhetslistan i IoT-plattformen. Använd 'Select many' för att välja de nya MQTT-noderna, gå till Charts och undersök de olika fälten från simuleringen. Med Node-RED och lite tekniska JavaScript-kunskaper kan du snabbt integrera IoT-plattformen med olika system, skapa och verifiera IoT-plattformens översättare och utveckla IoT-plattformens Flow-komponenter. Du kan också importera denna trevliga enhetslistvy för att se den fungera i realtid: Node-RED enhetslistvy.txt

Skapa IoT-plattformens översättare med Node-RED​

Grunderna​

Node-RED är ett utmärkt SDK för att bygga och testa IoT-plattformens översättare. Båda körs på Node.js - samma JavaScript-motor - så en översättare som fungerar i en Node-RED-simulering (och använder strikt, giltig JavaScript) beter sig likadant när den väl har laddats upp till IoT-plattformen via översättar-API:et i Swagger.

Två saker att tänka på när kod flyttas från Node-RED till IoT-plattformen.

  1. Sandlådans omfattning. En Node-RED-funktionsnod har full Node.js; IoT-plattformens översättarsandlåda är smalare - den tillhandahåller standard-JavaScript (Date, Math, JSON), lodash (_), Buffer och console.log, men inte require, timers, nätverk eller filsystem. Håll din translate inom dessa gränser.
  2. Datamodellens konsekvens. En översättares utdata måste använda IoT-plattformens kanoniska fältnamn, enheter och kvantiteter - det är det som gör att dashboards, larm och nedströms-översättare fungerar för alla enheter. Innan du skriver utdatafält, läs Utveckla översättare och fälttabellen i referensen Translator API.

Börja utveckla

Node-RED my first translator

Node-RED min första översättare JSON

Importera flödet ovan till Node-RED. Det består av:

  1. En inject-nod.
  2. En funktionsnod som genererar simulerad data.
  3. En funktionsnod som implementerar en översättare och returnerar resultatet.
  4. En debug-nod som gör datan synlig.
  5. Ett flöde för att omvandla översättaren och specifikationen till strängar, vilket skrivs ut i Node-REDs konsolloggar.
  6. En specifikation som beskriver översättaren och dess utdata. Specifikationens fältnamn och datatyper måste exakt matcha översättarens utdata; annars misslyckas valideringen och inget resultat sparas.

Detta är en fungerande översättare du kan ladda upp via API:et och koppla till vilken enhet som helst som tillhandahåller rssi och snr. Den beräknar ett signalstyrkevärde: rssi + snr när snr är negativt, annars enbart rssi. spec är ett kontrakt med slutanvändaren och måste matcha översättarens utdata exakt - varje avvikelse gör att valideringen misslyckas och resultatet kasseras. För dynamiska eller varierande resultat, returnera dem inuti ett JSON-object-fält.

För kompletta, kopieringsbara mallar (hårdvara, calculate, set-alarm, analys) och en lokal testrigg, se Utveckla översättare. Den här sidan fokuserar på det Node-RED-specifika arbetsflödet för att bygga och simulera dem.

Hårdvarudekodrar​

Om tillverkaren tillhandahåller en referensdekoder i JavaScript går det vanligtvis snabbt att bygga och verifiera översättaren. Återanvänd samma översättarflöde: klistra in tillverkarens dekoder i flödet och anropa den från translate, och skicka in hex-payloaden till den.

Behåll tillverkarens dekoder oförändrad (verbatim), och harmonisera som det sista steget: mappa dess råa utdata till IoT-plattformens kanoniska fältnamn, och skala enheter korrekt. Returnera inte den råa dekoderutdatan direkt - råa tillverkarnamn som TempC_SHT eller BatV är inga kanoniska fält. I exemplet nedan är rawTranslate tillverkarens dekoder:

function translate ({encodedData}) {
const {hexEncoded, port} = encodedData;

if (!hexEncoded || !port) {
throw new Error('Expected fields hexEncoded and/or port are missing');
}

const decoded = rawTranslate({hexEncoded, port}); // manufacturer decoder, kept verbatim

// Harmonize: rename raw vendor fields to canonical Yggio fields and scale
// units to the canonical unit (e.g. mV -> V, hPa -> Pa).
return {
result: {
temperature: decoded.TempC_SHT, // vendor name -> canonical field
relativeHumidity: decoded.Hum_SHT,
batteryVoltage: decoded.BatV / 1000, // mV -> V
},
};
}

För att verifiera översättaren behöver du verkliga payloads och förväntade resultat för varje payload. Tillverkare tillhandahåller vanligtvis exempel som kan användas för att skapa simulerad data för översättaren. Alternativt kan du sätta upp en verklig enhet i IoT-plattformen och använda de payloads som tas emot av IoT-plattformen som simulerad data för översättaren.

Om ingen referensdekoder finns tillgänglig från tillverkaren blir det en betydligt större uppgift att skriva en dekoder, vilket potentiellt kan ta allt från några timmar till veckors utvecklingsarbete. Denna process innebär ofta komplex hantering av bitar och byte, och en mängd olika payloads kommer att behövas för att uppnå en tillfredsställande verifieringsnivå.

Dataflöden​

IoT-plattformens översättarmodell gör det möjligt för en översättare att skicka översättningsresultat till andra IoT-noder via 'additionalDeviceUpdates', förutsatt att alla administratörer för en enhet har skrivbehörighet till målen. Denna funktion möjliggör hantering av mycket komplexa användningsfall och realtidsvisualisering av berikad data, eftersom målnoder kan bestämmas dynamiskt beroende på översättningen. IoT-plattformen stödjer också atomära uppdateringar av aggregeringsnoder, vilket säkerställer att resultatet alltid blir korrekt oavsett i vilken ordning data anländer. Eftersom Node-RED stödjer att skapa flöden, dock inte dynamiskt som IoT-plattformen, är det ett utmärkt verktyg för att utveckla och verifiera översättare som implementerar komplexa och dynamiska dataflöden.

Princip för att sätta upp dataflödessimuleringar

  1. Utveckla översättarna med 'additionalDeviceUpdates' med hjälp av standardmetoden beskriven ovan, genom att simulera förväntad indata och vidarebefordra den till översättarna.
  2. När översättaren är klar, ladda upp den till IoT-plattformen via översättar-API:et.
  3. Kopiera det ursprungliga flödesexemplet beskrivet högst upp på denna sida och lägg till den nyutvecklade översättaren till MQTT-noderna.
  4. Skapa alla nödvändiga 'Generic nodes' som kan användas för att dela data till.
  5. Injicera data med Node-RED i simuleringen via IoT-plattformens MQTT-broker. Om nödvändigt, skapa flera noder med översättaren och verifiera alla förväntade beteenden.
  6. Prenumerera på data från MQTT-noderna och använd den för att utveckla ytterligare nödvändiga översättare för att hantera det kompletta dataflödet.
  7. En viktig detalj är att "additionalDeviceUpdates" behöver identifieraren för målnoden; ett enkelt sätt att göra identifieraren konfigurerbar är att använda contextMap.

Exempel på additionalDeviceUpdates:

function translate(iotnode) {
const log = _.get(iotnode, 'log');
const measurementFields = _.get(iotnode, 'contextMap.measurementFields','').split(',');
const additionalDevice = _.get(iotnode,'contextMap.targetNodeSecret');
const sourceDevice = _.get(iotnode,'name','unknown').replace(/\W/g, '-');
let measurements = {};
let result = {};

// Transfer selected measurement fields to target node
if (additionalDevice != undefined && measurementFields != undefined) {
for (let i = 0; i < measurementFields.length; i++) {
measurements[measurementFields[i]] = { [sourceDevice]: _.get(iotnode, measurementFields[i]) };
}
if (log != undefined && log.message != '')
result = {
...result,
'log': {
'message': '',
'type': '',
'priority': '',
'category': ''
}
};
}
else if (log == undefined || log.message == '')
result = {
'log': {
'message': 'At least one of the 2 fields targetNodeSecret or measurementFields are missing in the contextMap.',
'type': 'Error',
'priority': 'Low',
'category': 'Status'
}
}
return {
result,
additionalDeviceUpdates:
[{
identifier: {
secret: additionalDevice
},
result: { measurements }
}],
};
}

Felsökning​

Så din översättare fungerar perfekt i Node-RED-simuleringen, men när den väl har laddats upp till IoT-plattformen verkar ingenting hända när noden den lades till på uppdateras. Utan någon tydlig handlingsbar information kanske du undrar vad du ska göra härnäst. Det finns tre potentiella typer av problem som kan orsaka detta:

Kontrollera först enhetens loggar. När en översättare kraschar, registrerar IoT-plattformen felet i enhetens loggar och behåller det i 6 timmar. Öppna loggarna och filtrera Type = Debug och Category = System för att se det, kopiera sedan den felande indatan till din Node-RED-simulering för att återskapa den. En lyckad översättning skriver ingen logg, så en tom logg innebär att den antingen körde utan problem eller aldrig utlöstes - kontrollera enhetens kolumn Senast rapporterad i enhetslistan för att avgöra vilket (om den uppdaterades körde översättaren).

  1. Validering av översättarens utdata mot specifikationen misslyckas - detta är den vanligaste orsaken och lätt att missa. Se till att:
  • Granska alla möjliga utdatafält och deras datatyper, och säkerställ en 100 % matchning mot specifikationen, inklusive versaler/gemener för varje enskilt tecken.
  • Framtvinga datatyper med funktioner som Number(), String() och Array.isArray(myArray) för att förhindra avvikelser i datatyper.
  • Bekräfta att varje utdatafält är ett kanoniskt fältnamn för IoT-plattformen (eller ett korrekt specificerat enhetsspecifikt fält) - ett felstavat eller icke-kanoniskt namn är en tyst avvikelse längre ner i kedjan.
  1. Översättaren kraschar under körning: Om översättaren kraschar beror det troligen på felaktig hantering av kombinationer av indata. Den vanligaste orsaken är att försöka tilldela eller referera till en odefinierad variabel.
  • Kopiera indatan som skickades till översättaren från IoT-plattformen och lägg till den i din Node-RED-simulering. Detta avslöjar om översättaren kraschar eller inte.
  • Kontrollera att du inte använder något utanför IoT-plattformens sandlåda (require, timers, Node-API:er) som råkar fungera i Node-RED men inte i IoT-plattformen.
  1. Översättaren misslyckas att kompilera i IoT-plattformen: Om översättaren misslyckas att kompilera i IoT-plattformen kan problemet bero på ett saknat semikolon eller andra kodproblem efter strängomvandling (stringification).
  • För att åtgärda detta, kör koden genom linters för att kontrollera att den är giltig JavaScript och JSON. Det finns gott om online-JavaScript-validerare tillgängliga genom att söka på "Javascript online linter validation".
  • Om din translate anropar hjälpfunktioner, se till att de är inkluderade i den uppladdade koden - hela kodsträngen körs i sandlådan, så en kvarglömd hjälpfunktion ger felet "X is not defined".

Se även​

  • Utveckla översättare - datamodellens regler, fullständiga översättarmallar, lokal testrigg och paketering för uppladdning.
  • Translator API - översättarobjektets schema, kontraktet för translate, kedjning och den kanoniska fälttabellen.