Tutorial: Aprovisionamiento del edificio y supervisión de las condiciones de trabajo con Azure Digital TwinsTutorial: Provision your building and monitor working conditions with Azure Digital Twins

En este tutorial se muestra cómo usar Azure Digital Twins para supervisar las condiciones de temperatura y el nivel de comodidad deseados en los distintos espacios.This tutorial demonstrates how to use Azure Digital Twins to monitor your spaces for desired temperature conditions and comfort level. Una vez que haya configurado el edificio de ejemplo, use los pasos de este tutorial para aprovisionarlo y ejecutar funciones personalizadas en los datos de los sensores.After you configure your sample building, you can provision your building and run custom functions on your sensor data by using the steps in this tutorial.

En este tutorial, aprenderá a:In this tutorial, you learn how to:

  • Definir las condiciones que se van a supervisarDefine conditions to monitor.
  • Crear una función definida por el usuario (UDF)Create a user-defined function (UDF).
  • Simular los datos de los sensoresSimulate sensor data.
  • Obtener los resultados de una función definida por el usuarioGet results of a user-defined function.

Requisitos previosPrerequisites

En este tutorial se supone que ha terminado de configurar Azure Digital Twins.This tutorial assumes that you have finished your Azure Digital Twins setup. Antes de continuar, asegúrese de que:Before proceeding, make sure that you have:

Definición de las condiciones que se van a supervisarDefine conditions to monitor

Puede definir un conjunto de condiciones específicas para supervisar en los datos del dispositivo o del sensor, llamado buscador de coincidencias.You can define a set of specific conditions to monitor in the device or sensor data, called matchers. Luego, puede definir funciones llamadas funciones definidas por el usuario.You can then define functions called user-defined functions. Las funciones definidas por el usuario ejecutan lógica personalizada en los datos que proceden de los espacios y los dispositivos, cuando se producen las condiciones especificadas por los buscadores de coincidencias.User-defined functions execute custom logic on data that comes from your spaces and devices, when the conditions specified by the matchers occur. Para más información, lea Procesamiento de datos y funciones definidas por el usuario.For more information, read Data processing and user-defined functions.

En el proyecto de ejemplo occupancy-quickstart, abra el archivo src\actions\provisionSample.yaml en Visual Studio Code.From the occupancy-quickstart sample project, open the file src\actions\provisionSample.yaml in Visual Studio Code. Observe la sección que comienza con el tipo matchers.Note the section that begins with the type matchers. Cada entrada con este tipo crea un buscador de coincidencias con el nombre especificado.Each entry under this type creates a matcher with the specified Name. El buscador de coincidencias supervisará un sensor de tipo dataTypeValue.The matcher will monitor a sensor of type dataTypeValue. Observe cómo se relaciona con el espacio denominado Focus Room A1, que tiene un nodo devices, que contiene algunos sensores.Notice how it relates to the space named Focus Room A1, which has a devices node that contains a few sensors. Para aprovisionar un buscador de coincidencias que realice el seguimiento de uno de estos sensores, asegúrese de que su valor de dataTypeValue coincida con el valor de dataType del sensor.To provision a matcher that will track one of these sensors, make sure that its dataTypeValue matches the sensor's dataType.

Agregue el siguiente buscador de coincidencias debajo de los buscadores de coincidencias existentes.Add the following matcher below the existing matchers. Asegúrese de que las claves estén alineadas y que los espacios no se reemplacen por pestañas.Make sure the keys are aligned and spaces are not replaced by tabs.

      - name: Matcher Temperature
        dataTypeValue: Temperature

Este buscador de coincidencias realizará el seguimiento del sensor SAMPLE_SENSOR_TEMPERATURE que agregó en el primer tutorial.This matcher will track the SAMPLE_SENSOR_TEMPERATURE sensor that you added in the first tutorial. Estas líneas también están presentes en el archivo provisionSample.yaml como líneas con comentarios.These lines are also present in the provisionSample.yaml file as commented-out lines. Para quitarles la marca de comentario, elimine el carácter # delante de cada línea.You can uncomment them by removing the # character in front of each line.

Creación de una función definida por el usuarioCreate a user-defined function

Puede usar funciones definidas por el usuario para personalizar el procesamiento de los datos de los sensores.You can use user-defined functions to customize the processing of your sensor data. Estas funciones son código JavaScript personalizado que se puede ejecutar en la instancia de Azure Digital Twins cuando se producen determinadas condiciones que describen los buscadores de coincidencias.They're custom JavaScript code that can run within your Azure Digital Twins instance, when specific conditions as described by the matchers occur. Se pueden crear buscadores de coincidencias y funciones definidas por el usuario para todos los sensores que quiera supervisar.You can create matchers and user-defined functions for each sensor that you want to monitor. Para más información, lea Procesamiento de datos y funciones definidas por el usuario.For more information, read Data processing and user-defined functions.

En el archivo provisionSample.yaml de ejemplo, busque una sección que comience por el tipo userdefinedfunctions.In the sample provisionSample.yaml file, look for a section that begins with the type userdefinedfunctions. En esta sección se proporciona una función definida por el usuario con un nombre determinado.This section provisions a user-defined function with a given Name. Dicha función actúa sobre la lista de buscadores de coincidencias en matcherNames.This UDF acts on the list of matchers under matcherNames. Tenga en cuenta que puede especificar su propio archivo de JavaScript para la UDF como script.Notice how you can provide your own JavaScript file for the UDF as the script.

Fíjese también en la sección denominada roleassignments.Also note the section named roleassignments. Esta sección asigna el rol Administrador de espacios a la función definida por el usuario yIt assigns the Space Administrator role to the user-defined function. le permite acceder a los eventos que proceden de cualquiera de los espacios aprovisionados.This role allows it to access the events that come from any of the provisioned spaces.

  1. Configure la función definida por el usuario para incluir el buscador de coincidencias de temperatura; para ello, debe agregar o quitar el comentario de la línea siguiente del nodo matcherNames del archivo provisionSample.yaml:Configure the UDF to include the temperature matcher by adding or uncommenting the following line in the matcherNames node of the provisionSample.yaml file:

            - Matcher Temperature
    
  2. Abra el archivo src\actions\userDefinedFunctions\availability.js en el editor.Open the file src\actions\userDefinedFunctions\availability.js in your editor. Este es el archivo al que se hace referencia en el elemento script de provisionSample.yaml.This is the file referenced in the script element of provisionSample.yaml. La función definida por el usuario en este archivo busca condiciones cuando no se detecta movimiento en la sala, así como cuando los niveles de dióxido de carbono están por debajo de 1000 ppm.The user-defined function in this file looks for conditions when no motion is detected in the room and carbon dioxide levels are below 1,000 ppm.

    Modifique el archivo de JavaScript para supervisar la temperatura y otras condiciones.Modify the JavaScript file to monitor temperature and other conditions. Agregue las siguientes líneas de código para buscar condiciones cuando no se detecte movimiento en la sala, los niveles de dióxido de carbono no lleguen a 1000 ppm y la temperatura sea inferior a 78 ºF.Add the following lines of code to look for conditions when no motion is detected in the room, carbon dioxide levels are below 1,000 ppm, and temperature is below 78 degrees Fahrenheit.

    Nota

    En esta sección se modifica el archivo src\actions\userDefinedFunctions\availability.js para explicar detalladamente una manera de escribir una función definida por el usuario.This section modifies the file src\actions\userDefinedFunctions\availability.js so you can learn in detail one way to write a user-defined function. Sin embargo, puede elegir usar directamente el archivo src\actions\userDefinedFunctions\availabilityForTutorial.js en su configuración.However, you can choose to directly use the file src\actions\userDefinedFunctions\availabilityForTutorial.js in your setup. Dicho archivo contiene todos los cambios necesarios para este tutorial.This file has all the changes required for this tutorial. Si lo usa, asegúrese de utilizar el nombre de archivo correcto para la clave del script en src\actions\provisionSample.yaml.If you use this file instead, make sure to use the correct file name for the script key in src\actions\provisionSample.yaml.

    a.a. Al principio del archivo, agregue las siguientes líneas para la temperatura debajo del comentario // Add your sensor type here:At the top of the file, add the following lines for temperature below the comment // Add your sensor type here:

        var temperatureType = "Temperature";
        var temperatureThreshold = 78;
    

    b.b. Agregue las líneas siguientes después de la instrucción que define var motionSensor, debajo del comentario // Add your sensor variable here:Add the following lines after the statement that defines var motionSensor, below the comment // Add your sensor variable here:

       var temperatureSensor = otherSensors.find(function(element) {
           return element.DataType === temperatureType;
       });
    

    c.c. Agregue la línea siguiente después de la instrucción que define var carbonDioxideValue, debajo del comentario // Add your sensor latest value here:Add the following line after the statement that defines var carbonDioxideValue, below the comment // Add your sensor latest value here:

        var temperatureValue = getFloatValue(temperatureSensor.Value().Value);
    

    d.d. Quite las siguientes líneas de código de debajo del comentario // Modify this line to monitor your sensor value:Remove the following lines of code from below the comment // Modify this line to monitor your sensor value:

       if(carbonDioxideValue === null || motionValue === null) {
           sendNotification(telemetry.SensorId, "Sensor", "Error: Carbon dioxide or motion are null, returning");
           return;
       }
    

    Reemplácelas por estas:Replace them with the following lines:

        if(carbonDioxideValue === null || motionValue === null || temperatureValue === null){
            sendNotification(telemetry.SensorId, "Sensor", "Error: Carbon dioxide, motion, or temperature are null, returning");
            return;
        }
    

    e.e. Quite las siguientes líneas de código de debajo del comentario // Modify these lines as per your sensor:Remove the following lines of code from below the comment // Modify these lines as per your sensor:

        var availableFresh = "Room is available and air is fresh";
        var noAvailableOrFresh = "Room is not available or air quality is poor";
    

    Reemplácelas por estas:Replace them with the following lines:

        var alert = "Room with fresh air and comfortable temperature is available.";
        var noAlert = "Either room is occupied, or working conditions are not right.";
    

    f.f. Quite el siguiente bloque de código if-else después del comentario // Modify this code block for your sensor:Remove the following if-else code block after the comment // Modify this code block for your sensor:

        // If carbonDioxide less than threshold and no presence in the room => log, notify and set parent space computed value
        if(carbonDioxideValue < carbonDioxideThreshold && !presence) {
            log(`${availableFresh}. Carbon Dioxide: ${carbonDioxideValue}. Presence: ${presence}.`);
            setSpaceValue(parentSpace.Id, spaceAvailFresh, availableFresh);
    
            // Set up custom notification for air quality
            parentSpace.Notify(JSON.stringify(availableFresh));
        }
        else {
            log(`${noAvailableOrFresh}. Carbon Dioxide: ${carbonDioxideValue}. Presence: ${presence}.`);
            setSpaceValue(parentSpace.Id, spaceAvailFresh, noAvailableOrFresh);
    
            // Set up custom notification for air quality
            parentSpace.Notify(JSON.stringify(noAvailableOrFresh));
        }
    

    Y sustitúyala por el siguiente bloque if-else:And replace it with the following if-else block:

        // If sensor values are within range and room is available
        if(carbonDioxideValue < carbonDioxideThreshold && temperatureValue < temperatureThreshold && !presence) {
            log(`${alert}. Carbon Dioxide: ${carbonDioxideValue}. Temperature: ${temperatureValue}. Presence: ${presence}.`);
    
            // log, notify and set parent space computed value
            setSpaceValue(parentSpace.Id, spaceAvailFresh, alert);
    
            // Set up notification for this alert
            parentSpace.Notify(JSON.stringify(alert));
        }
        else {
            log(`${noAlert}. Carbon Dioxide: ${carbonDioxideValue}. Temperature: ${temperatureValue}. Presence: ${presence}.`);
    
            // log, notify and set parent space computed value
            setSpaceValue(parentSpace.Id, spaceAvailFresh, noAlert);
        }
    

    La UDF modificada buscará una condición en la que una sala esté disponible y tenga el dióxido de carbono y la temperatura dentro de unos límites tolerables.The modified UDF will look for a condition where a room becomes available and has the carbon dioxide and temperature within tolerable limits. Cuando dicha condición se cumpla, generará una notificación con la instrucción parentSpace.Notify(JSON.stringify(alert));.It will generate a notification with the statement parentSpace.Notify(JSON.stringify(alert)); when this condition is met. Establece el valor del espacio supervisado, independientemente de si se cumple la condición, con el mensaje correspondiente.It will set the value of the monitored space regardless of whether the condition is met, with the corresponding message.

    g.g. Guarde el archivo.Save the file.

  3. Abra una ventana de comandos y vaya a la carpeta occupancy-quickstart\src. Ejecute el siguiente comando para aprovisionar el grafo de inteligencia espacial y la función definida por el usuario:Open a command window, and go to the folder occupancy-quickstart\src. Run the following command to provision your spatial intelligence graph and user-defined function:

    dotnet run ProvisionSample
    

    Importante

    Para evitar el acceso no autorizado a Management API de Digital Twins, la aplicación occupancy-quickstart le exige que inicie sesión con las credenciales de su cuenta de Azure.To prevent unauthorized access to your Digital Twins Management API, the occupancy-quickstart application requires you to sign in with your Azure account credentials. Como las credenciales se guardan durante un breve periodo, es posible que no tenga que iniciar sesión cada vez que lo ejecute.It saves your credentials for a brief period, so you might not need to sign in every time you run it. La primera vez que se ejecuta este programa y, luego, cuándo expiran las credenciales guardadas, la aplicación le dirige a una página de inicio de sesión y le proporciona un código específico de la sesión para entrar en la página.The first time this program runs, and when your saved credentials expire after that, the application directs you to a sign-in page and gives a session-specific code to enter on that page. Siga las indicaciones para iniciar sesión con su cuenta de Azure.Follow the prompts to sign in with your Azure account.

  4. Después de que se autentica la cuenta, la aplicación empieza a crear un grafo espacial de ejemplo como se ha configurado en provisionSample.yaml.After your account is authenticated, the application starts creating a sample spatial graph as configured in provisionSample.yaml. Espere hasta que finalice el aprovisionamiento.Wait until the provisioning finishes. Esta operación puede tardar unos minutos.It will take a few minutes. Cuando se haya completado, observe los mensajes de la ventana de comandos y vea cómo se crea el grafo espacial.After that, observe the messages in the command window and notice how your spatial graph is created. Observe cómo la aplicación crea una instancia de IoT Hub en el nodo raíz o en Venue.Notice how the application creates an IoT hub at the root node or the Venue.

  5. En la salida de la ventana de comandos, copie el valor de ConnectionString, que aparece en la sección Devices, en el Portapapeles.From the output in the command window, copy the value of ConnectionString, under the Devices section, to your clipboard. Necesitará este valor para simular la conexión del dispositivo en la sección siguiente.You'll need this value to simulate the device connection in the next section.

    Ejemplo de aprovisionamiento

Sugerencia

Si recibe un mensaje de error que dice algo como que la operación de E/S se anuló debido a una salida de subproceso o una solicitud de aplicación en medio del aprovisionamiento, pruebe a volver a ejecutar el comando.If you get an error message similar to "The I/O operation has been aborted because of either a thread exit or an application request" in the middle of the provisioning, try running the command again. Esto puede ocurrir si el cliente HTTP ha agotado el tiempo de espera debido a algún problema en la red.This might happen if the HTTP client timed out from a network issue.

Simulación de los datos de los sensoresSimulate sensor data

En esta sección, usará el proyecto denominado device-connectivity en el ejemplo.In this section, you'll use the project named device-connectivity in the sample. Simulará los datos de los sensores para la detección de movimiento, temperatura y dióxido de carbono.You'll simulate sensor data for detecting motion, temperature, and carbon dioxide. Este proyecto genera valores aleatorios para los sensores y los envía a la instancia de IoT Hub mediante la cadena de conexión del dispositivo.This project generates random values for the sensors, and sends them to the IoT hub by using the device connection string.

  1. En otra ventana de comandos, vaya al ejemplo de Azure Digital Twins y, después, a la carpeta device-connectivity.In a separate command window, go to the Azure Digital Twins sample and then to the device-connectivity folder.

  2. Ejecute este comando para asegurarse de que las dependencias del proyecto son correctas:Run this command to make sure the dependencies for the project are correct:

    dotnet restore
    
  3. Abra el archivo appSettings.json en el editor y edite los valores siguientes:Open the appsettings.json file in your editor, and edit the following values:

    a.a. DeviceConnectionString: asigne el valor de ConnectionString en la ventana de salida de la sección anterior.DeviceConnectionString: Assign the value of ConnectionString in the output window from the previous section. Copie esta cadena completamente, entre comillas, para que el simulador se conecte correctamente con la instancia de IoT Hub.Copy this string completely, within the quotes, so the simulator can connect properly with the IoT hub.

    b.b. HardwareId en la matriz Sensors: dado que va a simular eventos procedentes de sensores aprovisionados en una instancia de Azure Digital Twins, tanto el identificador de hardware como los nombres de los sensores de este archivo deben coincidir con el nodo sensors del archivo provisionSample.yaml.HardwareId within the Sensors array: Because you're simulating events from sensors provisioned to your Azure Digital Twins instance, the hardware ID and the names of the sensors in this file should match the sensors node of the provisionSample.yaml file.

    Agregue una nueva entrada para el sensor de temperatura.Add a new entry for the temperature sensor. El nodo Sensors de appSettings.json debe parecerse a este:The Sensors node in appsettings.json should look like the following:

    "Sensors": [{
      "DataType": "Motion",
      "HardwareId": "SAMPLE_SENSOR_MOTION"
    },{
      "DataType": "CarbonDioxide",
      "HardwareId": "SAMPLE_SENSOR_CARBONDIOXIDE"
    },{
      "DataType": "Temperature",
      "HardwareId": "SAMPLE_SENSOR_TEMPERATURE"
    }]
    
  4. Ejecute este comando para iniciar la simulación de eventos de temperatura, movimiento y dióxido de carbono del de dispositivo:Run this command to start simulating device events for temperature, motion, and carbon dioxide:

    dotnet run
    

    Nota

    Como el ejemplo de simulación no se comunica directamente con la instancia de Digital Twin, no requiere autenticación.Because the simulation sample does not directly communicate with your Digital Twins instance, it does not require you to authenticate.

Obtención de los resultados de la función definida por el usuarioGet results of the user-defined function

La función definida por el usuario se ejecuta cada vez que una instancia recibe datos del dispositivo y de los sensores.The user-defined function runs every time your instance receives device and sensor data. En esta sección se consulta su instancia de Azure Digital Twins para obtener los resultados de la función definida por el usuario.This section queries your Azure Digital Twins instance to get the results of the user-defined function. Verá casi en tiempo real cuando una sala está disponible, el aire es puro y la temperatura es la adecuada.You'll see in near real time, when a room is available, that the air is fresh and temperature is right.

  1. Abra la ventana de comandos que usó para aprovisionar el ejemplo, o una nueva, y vaya otra vez a la carpeta occupancy-quickstart\src del ejemplo.Open the command window that you used to provision the sample, or a new command window, and go to the occupancy-quickstart\src folder of the sample again.

  2. Ejecute el comando siguiente e inicie sesión cuando se le solicite:Run the following command and sign in when prompted:

    dotnet run GetAvailableAndFreshSpaces
    

La ventana de salida muestra cómo se ejecuta la función definida por el usuario e intercepta los eventos de la simulación de dispositivos.The output window shows how the user-defined function runs and intercepts events from the device simulation.

Salida de la función definida por el usuario

Si se cumple la condición supervisada, la función definida por el usuario establece el valor del espacio con el mensaje pertinente, como se ha visto anteriormente.If the monitored condition is met, the user-defined function sets the value of the space with the relevant message, as we saw earlier. La función GetAvailableAndFreshSpaces imprime el mensaje en la consola.The GetAvailableAndFreshSpaces function prints out the message on the console.

Limpieza de recursosClean up resources

Si quiere dejar de explorar Azure Digital Twins en este punto, elimine los recursos creados en este tutorial:If you want to stop exploring Azure Digital Twins at this point, feel free to delete resources created in this tutorial:

  1. En el menú izquierdo de Azure Portal, seleccione Todos los recursos, seleccione el grupo de recurso de Digital Twins y haga clic en Eliminar.From the left menu in the Azure portal, select All resources, select your Digital Twins resource group, and select Delete.

    Sugerencia

    Si tiene problemas al eliminar una instancia de Digital Twins, se ha incorporado una actualización del servicio con la corrección.If you experienced trouble deleting your Digital Twins instance, a service update has been rolled out with the fix. Vuelva a intentar eliminar la instancia.Please retry deleting your instance.

  2. Si es necesario, elimine las aplicaciones de ejemplo en la máquina de trabajo.If necessary, delete the sample applications on your work machine.

Pasos siguientesNext steps

Ahora que ha aprovisionado los espacios y ha creado una plataforma para desencadenar notificaciones personalizadas, puede continuar con cualquiera de los siguientes tutoriales:Now that you have provisioned your spaces and created a framework to trigger custom notifications, you can go to either of the following tutorials: