Поделиться через


Руководство: Настройка ваших устройств через бэкэнд-сервис

В рамках жизненного цикла устройства вам может потребоваться настроить устройства Интернета вещей из службы бэкэнда. Когда вы отправляете желаемую конфигурацию на ваши устройства, вы также хотите получать обновления о состоянии и соответствии от этих устройств. Например, можно задать целевой диапазон температуры операционной системы для устройства или собирать сведения о версии встроенного ПО с устройств.

Чтобы синхронизировать сведения о состоянии между устройством и Центром Интернета вещей, используйте двойники устройств. Двойник устройства — это документ JSON, связанный с определенным устройством и хранящийся Центром Интернета вещей в облаке, где их можно запросить. Двойник устройства содержит требуемые свойства, сообщаемые свойства и теги.

  • требуемое свойство устанавливается серверным приложением и считывается устройством.
  • сообщаемое свойство устанавливается устройством и считывается серверным приложением.
  • Тег задается серверным приложением и никогда не отправляется на устройство. Теги используются для упорядочивания устройств.

В этом руководстве показано, как использовать требуемые и сообщаемые свойства для синхронизации сведений о состоянии.

Схема двойников устройств на устройстве и в облаке.

В этом руководстве вы выполните следующие задачи:

  • Создайте Центр Интернета вещей и добавьте тестовое устройство в реестр удостоверений.
  • Используйте требуемые свойства для отправки сведений о состоянии на имитированное устройство.
  • Используйте сообщаемые свойства для получения сведений о состоянии с имитированного устройства.

Если у вас нет подписки Azure, создайте бесплатную учетную запись, прежде чем приступить к работе.

Предпосылки

  • В этом руководстве используется Azure CLI для создания облачных ресурсов. Если у вас уже есть Центр Интернета вещей с устройством, зарегистрированным на нем, можно пропустить эти действия. Существует два способа выполнения команд CLI:

  • Два примера приложений, выполняемых в этом руководстве, написаны с помощью Node.js. Вам потребуется установить Node.js 10 x.x или более поздней версии на компьютере для разработки.

    • Node.js, предназначенный для нескольких платформ, можно скачать здесь: nodejs.org.

    • Текущую версию Node.js на компьютере, на котором ведется разработка, можно проверить, используя следующую команду:

      node --version
      
  • Клонируйте или скачайте пример проекта Node.js из примеров Интернета вещей Azure для Node.js.

  • Убедитесь, что в брандмауэре открыт порт 8883. Пример устройства в этом руководстве использует протокол MQTT, который передает данные через порт 8883. В некоторых корпоративных и академических сетях этот порт может быть заблокирован. Дополнительные сведения и способы устранения этой проблемы см. в разделе о подключении к Центру Интернета вещей по протоколу MQTT.

Настройка ресурсов Azure

Чтобы завершить этот урок, ваша подписка Azure должна содержать IoT-центр с устройством, добавленным в реестр удостоверений устройств. Запись в реестре удостоверений устройства позволяет имитированному устройству, запущенном в этом руководстве, подключиться к центру.

Если у вас еще нет центра Интернета вещей, настроенного в подписке, его можно настроить с помощью следующего скрипта CLI. Этот скрипт использует имя tutorial-iot-hub со случайным числом, добавленным для имени Центра Интернета вещей. Это имя можно заменить собственным глобально уникальным именем при запуске. Скрипт создает группу ресурсов и концентратор в регионе Центрального США , который можно изменить на регион ближе к вам. Скрипт извлекает строку подключения службы Центра Интернета вещей, которая используется в примере серверной части для подключения к вашему центру Интернета вещей.

let "randomIdentifier=$RANDOM*$RANDOM"  
hubname="tutorial-iot-hub-$randomIdentifier"
location=centralus

# Install the IoT extension if it's not already installed:
az extension add --name azure-iot

# Create a resource group:
az group create --name tutorial-iot-hub-rg --location $location

# Create your free-tier IoT hub. You can only have one free IoT hub per subscription.
# Change the sku to S1 to create a standard-tier hub if necessary.
az iot hub create --name $hubname --location $location --resource-group tutorial-iot-hub-rg --partition-count 2 --sku F1

# Make a note of the service connection string, you need it later:
az iot hub connection-string show --hub-name $hubname --policy-name service -o table

В этом руководстве используется имитированное устройство с именем MyTwinDevice. Следующий скрипт добавляет это устройство в реестр удостоверений и извлекает строку подключения:

# Create the device in the identity registry:
az iot hub device-identity create --device-id MyTwinDevice --hub-name $hubname --resource-group tutorial-iot-hub-rg

# Retrieve the device connection string, you need this later:
az iot hub device-identity connection-string show --device-id MyTwinDevice --hub-name $hubname --resource-group tutorial-iot-hub-rg -o table

Отправка сведений о состоянии на устройство

Требуемые свойства используются для отправки сведений о состоянии из серверного приложения на устройство. В этом разделе показано, как:

  • Настройте устройство для получения и обработки требуемых свойств.
  • Отправьте требуемые свойства из серверного приложения на устройство.

Пример нужных свойств

Вы можете структурировать нужные свойства любым способом, удобным для вашего приложения. В этом примере используется одно свойство верхнего уровня с именем fanOn и группирует остальные свойства в отдельные компоненты. В следующем фрагменте JSON показана структура требуемых свойств, которые используется в этом руководстве. JSON находится в файле desired.json.

{
  "fanOn": "true",
  "components": {
    "system": {
      "id": "17",
      "units": "farenheit",
      "firmwareVersion": "9.75"
    },
    "wifi" : { 
      "channel" : "6",
      "ssid": "my_network"
    },
    "climate" : {
      "minTemperature": "68",
      "maxTemperature": "76"
    }
  }
}

Получение требуемых свойств в приложении устройства

Чтобы просмотреть пример кода имитированного устройства, получающего необходимые свойства, перейдите в папку iot-hub/Tutorials/DeviceTwins в примере проекта Node.js, который вы скачали. Затем откройте файл SimulatedDevice.js в текстовом редакторе.

В следующих разделах описывается код, который выполняется на имитированном устройстве, реагирующем на изменения требуемого свойства, отправленные из серверного приложения.

Получение объекта двойника устройства

При регистрации устройства в Центре Интернета вещей вы получили строку подключения устройства в качестве выходных данных. Строка подключения устройства используется устройством для аутентификации с помощью его зарегистрированного удостоверения в облаке. Код ниже подключается к вашему IoT-хабу, используя строку подключения для устройства.

// Get the device connection string from a command line argument
var connectionString = process.argv[2];

Следующий код получает двойник из клиентского объекта:

// Get the device twin
client.getTwin(function(err, twin) {
  if (err) {
    console.error(chalk.red('Could not get device twin'));
  } else {
    console.log(chalk.green('Device twin created'));

Создайте обработчики

Вы можете создавать обработчики для обновлений требуемого свойства, которые отвечают на обновления на разных уровнях иерархии JSON. Например, этот обработчик видит все необходимые изменения свойств, отправленные на устройство из серверного приложения. Разностная переменная содержит требуемые свойства, отправляемые из внутренней части решения:

// Handle all desired property updates
twin.on('properties.desired', function(delta) {
    console.log(chalk.yellow('\nNew desired properties received in patch:'));

Следующий обработчик реагирует только на изменения, внесенные в требуемое свойство fanOn :

// Handle changes to the fanOn desired property
twin.on('properties.desired.fanOn', function(fanOn) {
    console.log(chalk.green('\nSetting fan state to ' + fanOn));

    // Update the reported property after processing the desired property
    reportedPropertiesPatch.fanOn = fanOn ? fanOn : '{unknown}';
});

Обработчики для нескольких свойств

В примере требуемых свойств JSON для этого руководства узел климата в компонентах содержит два свойства, minTemperature и maxTemperature.

Локальный объект двойника устройства сохраняет полный набор требуемых и сообщаемых свойств. Разность, отправляемая из внутренней части, может обновить только подмножество требуемых свойств. В следующем фрагменте кода, если имитированное устройство получает обновление до одного из minTemperature и maxTemperature, оно использует значение в локальном двойнике для другого значения для настройки устройства:

// Handle desired properties updates to the climate component
twin.on('properties.desired.components.climate', function(delta) {
    if (delta.minTemperature || delta.maxTemperature) {
      console.log(chalk.green('\nUpdating desired tempertures in climate component:'));
      console.log('Configuring minimum temperature: ' + twin.properties.desired.components.climate.minTemperature);
      console.log('Configuring maximum temperture: ' + twin.properties.desired.components.climate.maxTemperature);

      // Update the reported properties and send them to the hub
      reportedPropertiesPatch.minTemperature = twin.properties.desired.components.climate.minTemperature;
      reportedPropertiesPatch.maxTemperature = twin.properties.desired.components.climate.maxTemperature;
      sendReportedProperties();
    }
});

Обработка операций вставки, обновления и удаления

Требуемые свойства, отправляемые из внутренней части, не указывают, какая операция выполняется для определенного требуемого свойства. Код должен выводить операцию из текущего набора требуемых свойств, хранящихся локально, и изменения, отправленные из концентратора.

В следующем фрагменте кода показано, как имитированное устройство обрабатывает операции вставки, обновления и удаления в списке компонентов в нужных свойствах . Вы можете узнать, как использовать значения NULL , чтобы указать, что компонент должен быть удален:

// Keep track of all the components the device knows about
var componentList = {};

// Use this componentList list and compare it to the delta to infer
// if anything was added, deleted, or updated.
twin.on('properties.desired.components', function(delta) {
  if (delta === null) {
    componentList = {};
  }
  else {
    Object.keys(delta).forEach(function(key) {

      if (delta[key] === null && componentList[key]) {
        // The delta contains a null value, and the
        // device has a record of this component.
        // Must be a delete operation.
        console.log(chalk.green('\nDeleting component ' + key));
        delete componentList[key];

      } else if (delta[key]) {
        if (componentList[key]) {
          // The delta contains a component, and the
          // device has a record of it.
          // Must be an update operation.
          console.log(chalk.green('\nUpdating component ' + key + ':'));
          console.log(JSON.stringify(delta[key]));
          // Store the complete object instead of just the delta
          componentList[key] = twin.properties.desired.components[key];

        } else {
          // The delta contains a component, and the
          // device has no record of it.
          // Must be an add operation.
          console.log(chalk.green('\nAdding component ' + key + ':'));
          console.log(JSON.stringify(delta[key]));
          // Store the complete object instead of just the delta
          componentList[key] = twin.properties.desired.components[key];
        }
      }
    });
  }
});

Отправка нужных свойств из серверного приложения

Вы узнали, как устройство реализует обработчики для получения необходимых обновлений свойств. В этом разделе показано, как отправлять требуемые изменения свойств на устройство из серверного приложения.

Чтобы просмотреть пример кода имитированного устройства, получающего необходимые свойства, перейдите в папку iot-hub/Tutorials/DeviceTwins в примере проекта Node.js, который вы скачали. Затем откройте файл ServiceClient.js в текстовом редакторе.

В следующем фрагменте кода показано, как подключиться к реестру удостоверений устройства и получить доступ к двойнику для конкретного устройства:

// Create a device identity registry object
var registry = Registry.fromConnectionString(connectionString);

// Get the device twin and send desired property update patches at intervals.
// Print the reported properties after some of the desired property updates.
registry.getTwin(deviceId, async (err, twin) => {
  if (err) {
    console.error(err.message);
  } else {
    console.log('Got device twin');

В следующем фрагменте кода показано, как другое требуемое свойство исправляет серверное приложение отправляет на устройство:

// Turn the fan on
var twinPatchFanOn = {
  properties: {
    desired: {
      patchId: "Switch fan on",
      fanOn: "false",
    }
  }
};

// Set the maximum temperature for the climate component
var twinPatchSetMaxTemperature = {
  properties: {
    desired: {
      patchId: "Set maximum temperature",
      components: {
        climate: {
          maxTemperature: "92"
        }
      }
    }
  }
};

// Add a new component
var twinPatchAddWifiComponent = {
  properties: {
    desired: {
      patchId: "Add WiFi component",
      components: {
        wifi: { 
          channel: "6",
          ssid: "my_network"
        }
      }
    }
  }
};

// Update the WiFi component
var twinPatchUpdateWifiComponent = {
  properties: {
    desired: {
      patchId: "Update WiFi component",
      components: {
        wifi: { 
          channel: "13",
          ssid: "my_other_network"
        }
      }
    }
  }
};

// Delete the WiFi component
var twinPatchDeleteWifiComponent = {
  properties: {
    desired: {
      patchId: "Delete WiFi component",
      components: {
        wifi: null
      }
    }
  }
};

В следующем фрагменте кода показано, как серверное приложение отправляет требуемое обновление свойства на устройство:

// Send a desired property update patch
async function sendDesiredProperties(twin, patch) {
  twin.update(patch, (err, twin) => {
    if (err) {
      console.error(err.message);
    } else {
      console.log(chalk.green(`\nSent ${twin.properties.desired.patchId} patch:`));
      console.log(JSON.stringify(patch, null, 2));
    }
  });
}

Получение сведений о состоянии с устройства

Серверное приложение получает сведения о состоянии от устройства в виде сообщаемых свойств. Устройство задает сообщаемые свойства и отправляет их в центр. Серверное приложение может считывать текущие значения сообщаемых свойств из двойника устройства, хранящегося в центре.

Отправка сообщаемого свойства с устройства

Обновления можно отправлять в сообщаемые значения свойств в виде исправления. В следующем фрагменте кода показан шаблон для исправления, отправляемого имитированного устройства. Симулированное устройство обновляет поля в патче перед отправкой в концентратор.

// Create a patch to send to the hub
var reportedPropertiesPatch = {
  firmwareVersion:'1.2.1',
  lastPatchReceivedId: '',
  fanOn:'',
  minTemperature:'',
  maxTemperature:''
};

Имитированное устройство использует следующую функцию для отправки исправления, содержащего сообщаемые свойства в концентратор:

// Send the reported properties patch to the hub
function sendReportedProperties() {
  twin.properties.reported.update(reportedPropertiesPatch, function(err) {
    if (err) throw err;
    console.log(chalk.blue('\nTwin state reported'));
    console.log(JSON.stringify(reportedPropertiesPatch, null, 2));
  });
}

Обработка сообщённых свойств

Серверное приложение обращается к текущим значениям свойств для устройства через двойник устройства. В следующем фрагменте кода показано, как серверное приложение считывает сообщаемые значения свойств для имитированного устройства:

// Display the reported properties from the device
function printReportedProperties(twin) {
  console.log("Last received patch: " + twin.properties.reported.lastPatchReceivedId);
  console.log("Firmware version: " + twin.properties.reported.firmwareVersion);
  console.log("Fan status: " + twin.properties.reported.fanOn);
  console.log("Min temperature set: " + twin.properties.reported.minTemperature);
  console.log("Max temperature set: " + twin.properties.reported.maxTemperature);
}

Запуск приложений

В этом разделе вы запустите два примера приложений для наблюдения за тем, как серверное приложение отправляет требуемые обновления свойств в имитированное приложение устройства.

Для запуска имитированных устройств и внутренних приложений требуются строки подключения устройства и службы. Когда вы создавали ресурсы в начале этого руководства, вы сделали заметку о строках подключения.

Чтобы запустить имитированное приложение устройства, откройте окно оболочки или командной строки и перейдите в папку iot-hub/Tutorials/DeviceTwins в скачанном проекте Node.js. Затем выполните следующие команды:

npm install
node SimulatedDevice.js "{your device connection string}"

Чтобы запустить серверное приложение, откройте другую оболочку или окно командной строки. Затем перейдите в папку iot-hub/Tutorials/DeviceTwins в скачанном проекте Node.js. Затем выполните следующие команды:

npm install
node ServiceClient.js "{your service connection string}"

Наблюдайте за обновлениями желаемого свойства

На следующем снимках экрана показаны выходные данные из имитированного приложения устройства и показано, как оно обрабатывает обновление до требуемого свойства maxTemperature . Вы можете увидеть, как выполняются обработчики верхнего уровня и обработчики компонентов климата:

Снимок экрана, показывающий, как работают обработчик верхнего уровня и обработчики компонентов климата.

На следующем снимке экрана показаны выходные данные серверного приложения и выделен способ отправки обновления в требуемое свойство maxTemperature.

Снимок экрана: выходные данные серверного приложения и выделение способа отправки обновления.

Наблюдение за обновлениями сообщаемого свойства

На следующем снимке экрана показан результат работы приложения смоделированного устройства, который демонстрирует, как оно отправляет сообщение об обновлении свойств в ваш концентратор:

Снимок экрана: имитированное устройство обновляет состояние двойника.

На следующем снимках экрана показаны выходные данные серверного приложения, а также показано, как оно получает и обрабатывает сообщаемое обновление свойства с устройства:

Снимок экрана: серверное приложение, получающее сообщаемые свойства устройства.

Очистка ресурсов

Если вы планируете завершить следующее руководство, сохраните группу ресурсов и узел Интернета вещей, чтобы использовать их позже.

Если вам больше не требуется Центр Интернета вещей, удалите его и группу ресурсов на портале. Для этого выберите группу ресурсов tutorial-iot-hub-rg , содержащую центр Интернета вещей, и нажмите кнопку "Удалить".

Кроме того, используйте интерфейс командной строки:

# Delete your resource group and its contents
az group delete --name tutorial-iot-hub-rg

Дальнейшие действия

В этом руководстве вы узнали, как синхронизировать сведения о состоянии между устройствами и Центром Интернета вещей. Перейдите к следующему руководству, чтобы узнать, как использовать двойники устройств для реализации процесса обновления устройства.