Speciális eszközmodell létrehozása

Ez az útmutató az egyéni eszközmodellt definiáló JSON- és JavaScript-fájlokat ismerteti. A cikk tartalmaz néhány eszközmodell-definíciós mintafájlt, és bemutatja, hogyan töltheti fel őket az eszközszimulációs példányra. Speciális eszközmodelleket hozhat létre, amelyekkel valósághűbb eszközviveleteket szimulálhat a teszteléshez.

Ha még nincs Azure-előfizetése, kezdés előtt hozzon létre egy ingyenes fiókot.

Előfeltételek

Az útmutató lépéseinek követéséhez az Azure-előfizetésben üzembe helyezett eszközszimulációs példányra van szükség.

Ha még nem telepítette az eszközszimulációt, tekintse meg az Eszközszimuláció üzembe helyezését a GitHubon.

Eszközszimuláció megnyitása

Ha még nem telepítette az eszközszimulációt, tekintse meg az Eszközszimuláció üzembe helyezését a GitHubon.

Eszközmodellek

Minden szimulált eszköz egy adott eszközmodellhez tartozik, amely meghatározza a szimuláció viselkedését. Ez a viselkedés magában foglalja a telemetriai adatok küldésének gyakoriságát, a küldendő üzenetek típusát és a támogatott módszereket.

Az eszközmodellt JSON-eszközdefiníciós fájllal és JavaScript-fájlok készletével határozhatja meg. Ezek a JavaScript-fájlok határozzák meg a szimuláció viselkedését, például a véletlenszerű telemetriát és a metódus logikáját.

Egy tipikus eszközmodell a következő:

  • Minden eszközmodellhez (például lift.json) egy JSON-fájl tartozik.
  • Egy JavaScript-viselkedési szkriptfájl minden eszközmodellhez (például elevator-state.js)
  • Minden eszközmetódushoz egy JavaScript-metódus szkriptfájlja (például elevator-go-down.js)

Megjegyzés

Nem minden eszközmodell határoz meg metódusokat. Ezért előfordulhat, hogy egy eszközmodell rendelkezik metódusszkriptekkel. Azonban minden eszközmodellnek rendelkeznie kell viselkedési szkripttel.

Eszközdefiníciós fájl

Minden eszközdefiníciós fájl egy szimulált eszközmodell részleteit tartalmazza, beleértve a következő információkat:

  • Eszközmodell neve: sztring.
  • Protokoll: AMQP | MQTT | HTTP.
  • A kezdeti eszközállapot.
  • Milyen gyakran kell frissíteni az eszköz állapotát.
  • Melyik JavaScript-fájlt használja az eszköz állapotának frissítéséhez.
  • A küldendő telemetriai üzenetek listája, amelyek mindegyike adott gyakorisággal szerepel.
  • A telemetriaüzenetek sémája, amelyet a háttéralkalmazás a kapott telemetria elemzéséhez használ.
  • A támogatott metódusok listája és az egyes metódusok szimulálásához használható JavaScript-fájl.

Fájlséma

A séma verziója mindig "1.0.0", és a fájl formátumára jellemző:

"SchemaVersion": "1.0.0"

Eszközmodell leírása

Az alábbi tulajdonságok az eszközmodellt írják le. Minden típus egyedi azonosítóval, szemantikai verzióval, névvel és leírással rendelkezik:

"Id": "chiller-01",
"Version": "0.0.1",
"Name": "Chiller",
"Description": "Chiller with external temperature and humidity sensors."

IoT-protokoll

Az IoT-eszközök különböző protokollokkal csatlakozhatnak. A szimuláció lehetővé teszi az AMQP, az MQTT vagy a HTTP használatát:

"Protocol": "AMQP"

Szimulált eszközállapot

Minden szimulált eszköz belső állapottal rendelkezik, amelyet meg kell határozni. Az állapot a telemetria által jelentett tulajdonságokat is meghatározza. Előfordulhat például, hogy egy hűtő kezdeti állapota a következő:

"InitialState": {
    "temperature": 50,
    "humidity": 40
},

Egy több érzékelőt tartalmazó mozgó eszköznek több tulajdonsága lehet, például:

"InitialState": {
    "latitude": 47.445301,
    "longitude": -122.296307,
    "speed": 30.0,
    "speed_unit": "mph",
    "cargotemperature": 38.0,
    "cargotemperature_unit": "F"
}

Az eszköz állapotát a szimulációs szolgáltatás a memóriában tárolja, és a JavaScript-függvény bemeneteként adja meg. A JavaScript-függvény a következőt döntheti el:

  • Az állapot figyelmen kívül hagyása és véletlenszerű adatok létrehozása.
  • Az eszköz állapotának reális frissítése egy adott forgatókönyvhöz.

Az állapotot létrehozó függvény bemenetként is megkapja a következőt:

  • Az eszköz azonosítója.
  • Az eszköz modellje.
  • Az aktuális időpont. Ez az érték lehetővé teszi, hogy különböző adatokat hozzon létre eszköz és idő szerint.

Telemetriai üzenetek létrehozása

A szimulációs szolgáltatás több telemetriatípust is küldhet minden eszközhöz. A telemetriai adatok általában az eszköz állapotából származnak. Egy szimulált helyiség például 10 másodpercenként küldhet információkat a hőmérsékletről és a páratartalomról. Jegyezze fel a következő kódrészlet helyőrzőit, amelyeket a rendszer automatikusan lecserél az eszközállapot értékeire:

"Telemetry": [
    {
        "Interval": "00:00:10",
        "MessageTemplate":
            "{\"temperature\":${temperature},\"temperature_unit\":\"${temperature_unit}\",\"humidity\":\"${humidity}\"}",
        "MessageSchema": {
            "Name": "RoomComfort;v1",
            "Format": "JSON",
            "Fields": {
                "temperature": "double",
                "temperature_unit": "text",
                "humidity": "integer"
            }
        }
    }
],

A helyőrzők a ${NAME} speciális szintaxist használják, ahol a NAME a JavaScript függvény által visszaadott eszközállapot-objektum kulcsa. A sztringeket idézni kell, míg a számokat nem.

Üzenetséma

Minden üzenettípusnak jól definiált sémával kell rendelkeznie. Az üzenetséma IoT Hub is közzé van téve, így a háttéralkalmazások újra felhasználhatják az információkat a bejövő telemetriai adatok értelmezéséhez.

A séma támogatja a JSON formátumot, amely lehetővé teszi az egyszerű elemzést, átalakítást és elemzést több rendszerben és szolgáltatásban.

A sémában felsorolt mezők a következő típusúak lehetnek:

  • Objektum – JSON használatával szerializálva
  • Bináris – base64 használatával szerializálva
  • Szöveg
  • Logikai
  • Egész szám
  • Dupla
  • DateTime

Támogatott metódusok

A szimulált eszközök reagálhatnak a metódushívásokra is, ebben az esetben valamilyen logikát hajtanak végre, és választ adnak. A szimulációhoz hasonlóan a metóduslogika egy JavaScript-fájlban van tárolva, és kommunikálhat az eszköz állapotával. Például:

"CloudToDeviceMethods": {
    "Start": {
        "Type": "JavaScript",
        "Path": "release-pressure.js"
    }
}

Eszközdefiníciós fájl létrehozása

Ebből az útmutatóból megtudhatja, hogyan hozhat létre eszközmodellt egy drónhoz. A drón véletlenszerűen repül a koordináták kezdeti készlete körül, megváltoztatva a helyet és a magasságot.

Másolja a következő JSON-t egy szövegszerkesztőbe, és mentse drone.json formátumban.

Példa eszközdefiníciós JSON-fájlra

{
  "SchemaVersion": "1.0.0",
  "Id": "drone",
  "Version": "0.0.1",
  "Name": "Drone",
  "Description": "Simple drone.",
  "Protocol": "AMQP",
  "Simulation": {
    "InitialState": {
      "velocity": 0.0,
      "velocity_unit": "mm/sec",
      "acceleration": 0.0,
      "acceleration_unit": "mm/sec^2",
      "latitude": 47.476075,
      "longitude": -122.192026,
      "altitude": 0.0
    },
    "Interval": "00:00:05",
    "Scripts": [{
      "Type": "JavaScript",
      "Path": "drone-state.js"
    }]
  },
  "Properties": {
    "Type": "Drone",
    "Firmware": "1.0",
    "Model": "P-96"
  },
  "Tags": {
    "Owner": "Contoso"
  },
  "Telemetry": [{
      "Interval": "00:00:05",
      "MessageTemplate": "{\"velocity\":\"${velocity}\",\"acceleration\":\"${acceleration}\",\"position\":\"${latitude}|${longitude}|${altitude}\"}",
      "MessageSchema": {
        "Name": "drone-event-sensor;v1",
        "Format": "JSON",
        "Fields": {
          "velocity": "double",
          "velocity_unit": "text",
          "acceleration": "double",
          "acceleration_unit": "text",
          "latitude": "double",
          "longitude": "double",
          "altitude": "double"
        }
      }
    }
  ],
    "CloudToDeviceMethods": {
        "RecallDrone": {
            "Type": "JavaScript",
            "Path": "droneRecall-method.js"
        }
    }
}

Viselkedési szkriptfájlok

A viselkedési szkriptfájlban lévő kód áthelyezi a drónt. A szkript módosítja a drón jogosultságszint-emelését és helyét az eszköz memóriaállapotának módosításával.

A JavaScript-fájloknak rendelkezniük kell egy függvénnyel, amely két paramétert fogad el:

  • Egy környezeti objektum, amely három tulajdonságot tartalmaz:
    • currentTime as a string with format yyyy-MM-dd'T'HH:mm:sszzz.
    • deviceId. Például : Simulated.Elevator.123.
    • deviceModel. Például lift.
  • Egy állapotobjektum , amely az előző hívásban a függvény által visszaadott érték. Ezt az eszközállapotot a szimulációs szolgáltatás tartja karban, és telemetriaüzenetek létrehozásához használja.

A függvény az új eszközállapotot adja vissza. Például:

function main(context, state) {

    // Use context if the simulation depends on
    // time or device details.
    // Execute some logic, updating 'state'

    return state;
}

Viselkedési szkriptfájl létrehozása

Másolja a következő JavaScriptet egy szövegszerkesztőbe, és mentse drone-state.js.

Példa eszközmodell JavaScript-szimulációra

"use strict";

// Position control
const DefaultLatitude = 47.476075;
const DefaultLongitude = -122.192026;
const DistanceVariation = 10;

// Altitude control
const DefaultAltitude = 0.0;
const AverageAltitude = 499.99;
const AltitudeVariation = 5;

// Velocity control
const AverageVelocity = 60.00;
const MinVelocity = 20.00;
const MaxVelocity = 120.00;
const VelocityVariation = 5;

// Acceleration control
const AverageAcceleration = 2.50;
const MinAcceleration = 0.01;
const MaxAcceleration = 9.99;
const AccelerationVariation = 1;

// Display control for position and other attributes
const GeoSpatialPrecision = 6;
const DecimalPrecision = 2;

// Default state
var state = {
    velocity: 0.0,
    velocity_unit: "mm/sec",
    acceleration: 0.0,
    acceleration_unit: "mm/sec^2",
    latitude: DefaultLatitude,
    longitude: DefaultLongitude,
    altitude: DefaultAltitude
};

// Default device properties
var properties = {};

/**
 * Restore the global state using data from the previous iteration.
 *
 * @param previousState device state from the previous iteration
 * @param previousProperties device properties from the previous iteration
 */
function restoreSimulation(previousState, previousProperties) {
    // If the previous state is null, force a default state
    if (previousState) {
        state = previousState;
    } else {
        log("Using default state");
    }

    if (previousProperties) {
        properties = previousProperties;
    } else {
        log("Using default properties");
    }
}

/**
 * Simple formula generating a random value around the average
 * in between min and max
 */
function vary(avg, percentage, min, max) {
    var value = avg * (1 + ((percentage / 100) * (2 * Math.random() - 1)));
    value = Math.max(value, min);
    value = Math.min(value, max);
    return value;
}

/**
 * Entry point function called by the simulation engine.
 * Returns updated simulation state.
 * Device property updates must call updateProperties() to persist.
 *
 * @param context             The context contains current time, device model and id
 * @param previousState       The device state since the last iteration
 * @param previousProperties  The device properties since the last iteration
 */
/*jslint unparam: true*/
function main(context, previousState, previousProperties) {

    // Restore the global state before generating the new telemetry, so that
    // the telemetry can apply changes using the previous function state.
    restoreSimulation(previousState, previousProperties);

    state.acceleration = vary(AverageAcceleration, AccelerationVariation, MinAcceleration, MaxAcceleration).toFixed(DecimalPrecision);
    state.velocity = vary(AverageVelocity, VelocityVariation, MinVelocity, MaxVelocity).toFixed(DecimalPrecision);

    // Use the last coordinates to calculate the next set with a given variation
    var coords = varylocation(Number(state.latitude), Number(state.longitude), DistanceVariation);
    state.latitude = Number(coords.latitude).toFixed(GeoSpatialPrecision);
    state.longitude = Number(coords.longitude).toFixed(GeoSpatialPrecision);

    // Fluctuate altitude between given variation constant by more or less
    state.altitude = vary(AverageAltitude, AltitudeVariation, AverageAltitude - AltitudeVariation, AverageAltitude + AltitudeVariation).toFixed(DecimalPrecision);

    return state;
}

/**
 * Generate a random geolocation at some distance (in miles)
 * from a given location
 */
function varylocation(latitude, longitude, distance) {
    // Convert to meters, use Earth radius, convert to radians
    var radians = (distance * 1609.344 / 6378137) * (180 / Math.PI);
    return {
        latitude: latitude + radians,
        longitude: longitude + radians / Math.cos(latitude * Math.PI / 180)
    };
}

Metódusszkriptfájl létrehozása

A metódusszkriptek hasonlóak a viselkedési szkriptekhez. Meghatározzák az eszköz viselkedését, amikor egy adott felhőből eszközmetódust hívnak meg.

A drón visszahívási szkriptje rögzített pontra állítja a drón koordinátáit a hazaérkezést szimuláló drón szimulálásához.

Másolja a következő JavaScriptet egy szövegszerkesztőbe, és mentse droneRecall-method.js.

Példa eszközmodell JavaScript-szimulációra

"use strict";

// Default state
var state = {
    velocity: 0.0,
    velocity_unit: "mm/sec",
    acceleration: 0.0,
    acceleration_unit: "mm/sec^2",
    latitude: 0.0,
    longitude: 0.0,
    altitude: 0.0
};

// Default device properties
var properties = {};

/**
 * Restore the global state using data from the previous iteration.
 *
 * @param previousState device state from the previous iteration
 * @param previousProperties device properties from the previous iteration
 */
function restoreSimulation(previousState, previousProperties) {
    // If the previous state is null, force a default state
    if (previousState) {
        state = previousState;
    } else {
        log("Using default state");
    }

    if (previousProperties) {
        properties = previousProperties;
    } else {
        log("Using default properties");
    }
}

/**
 * Entry point function called by the simulation engine.
 *
 * @param context        The context contains current time, device model and id, not used
 * @param previousState  The device state since the last iteration, not used
 * @param previousProperties  The device properties since the last iteration
 */
/*jslint unparam: true*/
function main(context, previousState, previousProperties) {

    // Restore the global device properties and the global state before
    // generating the new telemetry, so that the telemetry can apply changes
    // using the previous function state.
    restoreSimulation(previousState, previousProperties);

    //simulate the behavior of a drone when recalled
  state.latitude = 47.476075;
  state.longitude = -122.192026;
  return state;
}

Szkriptfájlok hibakeresése

Bár nem csatolhat hibakeresőt egy futó viselkedési fájlhoz, a naplófüggvény használatával adatokat írhat a szolgáltatásnaplóba. Szintaktikai hibák esetén az értelmező meghibásodik, és információkat ír a napló kivételéről.

Példa naplózásra:

function main(context, state) {

    log("This message will appear in the service logs.");

    log(context.deviceId);

    if (typeof(state) !== "undefined" && state !== null) {
        log("Previous value: " + state.temperature);
    }

    // ...

    return updateState;
}

Speciális eszközmodell üzembe helyezése

A speciális eszközmodell üzembe helyezéséhez töltse fel az eszközszimulációs példány fájljait:

A menüsávon válassza az Eszközmodellek gombot. Az Eszközmodellek lap felsorolja az eszközszimuláció jelen példányában elérhető eszközmodelleket:

Eszközmodellek

Kattintson az + Eszközmodellek hozzáadása elemre a lap jobb felső sarkában:

Eszközmodell hozzáadása

A Speciális eszközmodell lap megnyitásához kattintson a Speciális gombra:

Speciális lap

Kattintson a Tallózás gombra , és válassza ki a létrehozott JSON- és JavaScript-fájlokat. Ügyeljen arra, hogy mindhárom fájlt kijelölje. Ha egy fájl hiányzik, az ellenőrzés sikertelen:

Tallózás a fájlok között

Ha a fájlok érvényesítése sikeres, kattintson a Mentés gombra, és az eszközmodell készen áll a szimulációban való használatra. Ellenkező esetben javítsa ki a hibákat, és töltse be újra a fájlokat:

Mentés

Következő lépések

Ebben az útmutatóban megismerkedett az eszközszimulációban használt eszközmodell-fájlokkal, valamint egy speciális eszközmodell létrehozásával. A következőkben érdemes megismerkednie a Time Series Insights használatával az eszközszimulációs megoldásgyorsítóból küldött telemetriai adatok megjelenítéséhez.