Översättar-API
Från och med Yggio version 3.4 är den nya Översättartjänsten nu aktiverad. Den gör det möjligt för utvecklare att lägga till sina egna översättare till Yggio. API-detaljer finns på Swagger. Detta dokument beskriver utförligt hur Översättartjänsten fungerar.
Alla översättare körs i en avgränsad NodeJS v16-miljö. Översättarna är begränsade i det avseendet att de endast kan använda ren JS-funktioner och kan inte komma åt Node-specifika funktioner via import
och require()
. Vi tillhandahåller även definitioner av lodash (som "_") och Buffer.
Användning av översättare
Vilka översättare som körs för en enhet väljs utifrån enhetens translatorPreferences
.
Exempel:
translatorPreferences: [
{
name: 'sensative-strips',
userId: '91698973-01ac-4879-a9f6-927611463f2e',
version: '1.0.0',
upgradePolicy: 'minor',
},
{
name: 'celsius-to-fahrenheit',
userId: '91698973-01ac-4879-a9f6-927611463f3a',
version: '1.2.0',
upgradePolicy: 'all',
},
]
Egenskaperna för en translatorPreference används för att identifiera en översättare. version
tillsammans med upgradePolicy
används för att välja versionen. upgradePolicy används för att automatiskt välja en nyare version av en översättare utan att användaren behöver uppdatera manuellt till den nya versionen.
upgradePolicy kan vara en av följande fyra:
none
Den valda versionen kommer alltid att användaspatch
Om du har valt version 1.0.0 kommer det att resultera i 1.^minor
Om du har valt version 1.0.0 kommer det att resultera i 1.0.^all
: Den absolut nyaste tillgängliga versionen kommer att användas
Val av translatorPreferences
translatorPreferences är en attribut av en enhet och kan ställas in vid skapandet eller när en enhet uppdateras.
En API-användare kan använda rutten GET /translators
för att få de tillgängliga översättarna och använda dem för att fylla i en enhets translatorPreferences. Du kan tillhandahålla deviceModelName
som en frågeparameter för att endast få översättare som är lämpliga för den deviceModelName.
Det finns också ett enklare sätt att lägga till translatorPreferences när du skapar en enhet. Om du tillhandahåller en deviceModelName, kommer Yggio automatiskt att fylla i translatorPreferences med en lämplig standardöversättare (som matchar med deviceModelName).
Körning av flera översättare
Det är möjligt att köra flera översättare. Detta kan användas för att utföra kraftfulla operationer. Till exempel, om en översättare ger temperaturen i Celsius kan en andra översättare användas för att översätta temperaturen till Fahrenheit.
Översättarna körs sedan i en sekventiell eller "kedjad" ordning. Inmatningen av en översättare är resultatet av de tidigare översättarna, sammanslagna med den ursprungliga iotnoden.
Detta kan beskrivas med följande formel:
resultat = A(x) + B(x + A(x))
där A
och B
är översättare, x
är ursprungsdata för iotnoden och +
betecknar sammanfogning.
Observera att om en översättare misslyckas med att köra avbryts loopen och de efterföljande översättarna kommer inte att köras.
Skapa en Översättare
Översättartjänsten kan köra vilken giltig JavaScript-kod som helst i en avgränsad miljö. En översättare kan endast interagera med sin miljö genom att returnera data från funktionen translate
. Översättaren körs varje gång ny data för en iotnod tas emot.
Översättarspecifikation
Översättare är JSON-objekt och har ett par obligatoriska metadatafält som definierar var, när och hur de ska tillämpas.
name
är namnet på översättaren. Får endast innehålla gemener, alfanumeriska tecken och bindestreck, måste börja med en bokstav. Regex: /[a-z][a-z0-9-]+/
version
måste vara ett korrekt semver-versionsnummer.
apiVersion
versionen av Yggio-översättarapiet som denna översättare är utformad att fungera med.
description
en användarvänlig beskrivning av översättaren.
match
ett objekt som specifierar vilka enheter översättaren är tillämplig för. Kan (för närvarande) endast innehålla fältet deviceModelName
med en sträng som värde.
spec
definierar vilken typ av data översättaren kommer att returnera. Varje f ält inuti detta objekt måste innehålla en sträng med en giltig typ, någon av array
, date
, boolean
, number
, object
, string
. Objektet kan specificera många fält.
code
är ett fält som måste innehålla en sträng med giltig JavaScript-kod (långa strängar tillåtna). Översättarens kod måste uppfylla följande krav.
Översättarkod
Översättarkoden är skriven i JavaScript och måste innehålla en funktion som heter translate
. Den körs varje gång en ny nyttolast tas emot för den relaterade IoTNode. Översättningsfunktionen (function translate(iotnode) { ... }
) kan komma åt vilket fält som helst på iotnoden som ska översättas. Om du behöver datumet då nyttolasten togs emot är det tillgängligt som iotnode.reportedAt
.
Översättaren måste returnera ett objekt eller kasta ett fel. Detta objekt kan vara tomt om översättaren inte kunde översätta några värden. Om ett fel uppstår ska översättaren throw
ett lämpligt fel.
Objektet (från och med nu kallat translated
) som returneras av översättaren kommer att hålla fält med semantiskt värde. Alla fält som inte specificeras här behandlas som ett fel. För närvarande finns det två möjliga fält för översättaren att returnera. Översättaren kan välja att returnera inget, något eller båda dessa fält.
Om översättaren returnerar ett objekt med ett fält translated.result
, måste detta fält innehålla uppdaterade värden för iotnoden. Endast fält i översättarens spec
får uppdateras. Returnerade fält som är undefined
eller null
kommer att tas bort.
Tidsserie-data kan returneras via fältet translated.timeseries
. Detta fält måste innehålla en array av objekt {timestamp, value}
där timestamp
måste vara ett giltigt JavaScript Date-objekt och value
följer samma regler som det tidigare nämnda fältet result
.
När en översättare laddas upp tillhör den uppladdaren för alltid. Detta lagras i översättarens userId
-fält.
Exempel
// This is an example translator
function translate(iotnode) { // you can access the full iotnode object for the device
/* translator code here */
return {
result: {
someValue: 13,
anotherValue: 37,
},
timeseries: [{
timestamp: new Date("2021-11-12T14:30:00Z"),
value: {
someValue: 12,
},
}, {
timestamp: new Date("2021-11-12T14:15:00Z"),
value: {
someValue: 11,
},
}],
};
}
const translator = {
name: 'my-translator',
version: '0.2.1',
apiVersion: '1.0',
description: 'A translator for ExampleCorp DemoDevice™ 9000',
match: {
deviceModelName: 'examplecorp-demodevice9000',
},
spec: {
someValue: 'number',
anotherValue: 'number',
},
code: translate.toString(),
}
/* the translator object can now be POSTed to the API */
Översättare för gateway-enheter eller enheter som agerar som gateways
En översättare kan returnera fältet translated.additionalDeviceUpdates
, som är en array med uppdateringar för andra enheter. Objekten translated.additionalDeviceUpdates
måste ha två nycklar, translated.additionalDeviceUpdates.identifier
och translated.additionalDeviceUpdates.result
. translated.additionalDeviceUpdates.[i].identifier
måste vara ett objekt med nycklar och värden som kan identifiera en specifik enhet. Ett exempel för LoRa skulle vara {devEui: '123456789012345'}
och för trådlös M-Bus skulle det vara {wMbusDeviceId: '12312312', manufacturer: 'BMT'}
. translated.additionalDeviceUpdates.[i].result
innehåller uppdateringarna för enheten. Enheten eller gatewayen kan också skicka uppdateringar för sig själv i samma payload.
Exempel
// This is an example translator
function translate(iotnode) { // you can access the full iotnode object for the device
/* translator code here */
return {
result: {
internalTemperature: 13,
anotherValue: 37,
},
additionalDeviceUpdates: [{
identifier: {
wMbusDeviceId: '12312312',
manufacturer: 'BMT'
},
result: {
someValue: 12,
},
}, {
identifier: {
devEui: '123456789012345'
},
result: {
someValue: 11,
},
}],
};
}
const translator = {
name: 'my-gateway',
version: '0.0.1',
apiVersion: '0.1',
description: 'A translator for ExampleCorp DemoGateway™ 9001',
match: {
deviceModelName: 'examplecorp-demogateway9001',
},
spec: {
someValue: 'number',
anotherValue: 'number',
},
code: translate.toString(),
}
Översättarversioner
Översättare måste ha korrekta semver-kompatibla versionsnummer: Major.Minor.Patch
. När en Iotnod uppdateras väljs automatiskt den översättare med högsta versionsnumret för att utföra översättningen.
Om det redan finns en översättare skapad av Sensative kommer den översättaren att väljas innan andra översättare övervägs.
Radera översättare
Översättare kan för närvarande inte raderas av en användare. Detta är för att undvika fall där en översättare används av en annan användare än den ursprungliga skaparen.
En översättare kan endast raderas av en Yggio-administratör under extraordinära omständigheter, som en översättare som innehåller skadlig kod.
Yggio translator-service API-versioner
Yggio 3.6 använder version 1.0 av översättartjänstens API, detta ska betraktas som grunden för alla framtida versioner.