البرنامج التعليمي: تكوين أجهزتك من خدمة خلفية
كجزء من دورة حياة الجهاز، قد تحتاج إلى تكوين أجهزة IoT الخاصة بك من الخدمة الخلفية. عند إرسال التكوين المطلوب إلى أجهزتك، فإنك تريد أيضا تلقي تحديثات الحالة والتوافق من تلك الأجهزة. على سبيل المثال، يمكنك تعيين نطاق درجة حرارة تشغيل مستهدف لجهاز أو جمع معلومات إصدار البرنامج الثابت من أجهزتك.
لمزامنة معلومات الحالة بين الجهاز ومركز IoT، يمكنك استخدام Device Twins. الجهاز المزدوج هو مستند JSON، مرتبط بجهاز معين، ويتم تخزينه بواسطة IoT Hub في السحابة حيث يمكنك الاستعلام عنهم. يحتوي توأم الجهاز على الخصائص المطلوبة والخصائص المبلغ عنها والعلامات.
- يتم تعيين الخاصية المطلوبة بواسطة تطبيق خلفي وقراءتها بواسطة جهاز.
- يتم تعيين خاصية تم الإبلاغ عنها بواسطة جهاز وقراءتها بواسطة تطبيق خلفي.
- يتم تعيين العلامة بواسطة تطبيق خلفي ولا يتم إرسالها أبدا إلى جهاز. أنت تستخدم العلامات لتنظيم أجهزتك.
يوضح لك هذا البرنامج التعليمي كيفية استخدام الخصائص المطلوبة والمبلغ عنها لمزامنة معلومات الحالة.
في هذا البرنامج التعليمي، تنفذ المهام التالية:
- أنشئ مركز IoT وأضف جهاز اختبار إلى سجل الهوية.
- استخدم الخصائص المطلوبة لإرسال معلومات الحالة إلى جهازك المحاكي.
- استخدم الخصائص التي تم الإبلاغ عنها لتلقي معلومات الحالة من جهازك المحاكي.
في حال لم يكن لديك اشتراك Azure، فأنشئ حساباً مجانيّاً قبل البدء.
المتطلبات الأساسية
يستخدم هذا البرنامج التعليمي Azure CLI لإنشاء موارد سحابية. إذا كان لديك بالفعل مركز IoT مع جهاز مسجل فيه، يمكنك تخطي هذه الخطوات. هناك طريقتان لتشغيل أوامر CLI:
استخدم بيئة Bash في Azure Cloud Shell. لمزيد من المعلومات، راجع تشغيل سريع لـ Azure Cloud Shell - Bash.
إذا كنت تفضل تشغيل أوامر مرجع CLI محلياً قم بتثبيت CLI Azure. إذا كنت تعمل على نظام تشغيل Windows أو macOS، ففكر في تشغيل Azure CLI في حاوية Docker. لمزيد من المعلومات، راجع كيفية تشغيل Azure CLI في حاوية Docker.
- قم بتسجيل الدخول إلى CLI Azure باستخدام az login.
- عند مطالبتك، يوصى بتثبيت امتدادات Azure CLI عند الاستخدام الأول. لمزيد من المعلومات بشأن الامتدادات، راجع استخدام امتدادات مع Azure CLI.
- يُرجى تشغيل إصدار az للوصول إلى الإصدار والمكتبات التابعة التي تم تثبيتها. للتحديث لآخر إصدار، يُرجى تشغيل تحديث az.
تتم كتابة نموذج التطبيقين اللذين تقوم بتشغيلهما في هذا البرنامج التعليمي باستخدام Node.js. أنت بحاجة إلى Node.js v10.x.x أو إصدار أحدث على جهاز التطوير الخاص بك.
يمكنك تنزيل Node.js لأنظمة أساسية متعددة من nodejs.org.
يمكن التحقق من الإصدار الحالي من Node.js على جهاز التطوير باستخدام الأمر التالي:
node --version
قم باستنساخ نموذج مشروع Node.js أو تنزيله من نماذج Azure IoT Node.js.
تأكد من أن المنفذ 8883 مفتوح في جدار الحماية. يستخدم نموذج الجهاز في هذا البرنامج التعليمي بروتوكول MQTT، الذي يتصل عبر المنفذ 8883. قد يُحظر هذا المنفذ في بعض بيئات الشبكات التعليمية، وشبكات الشركات. لمزيد من المعلومات وطرق التغلب على هذه المشكلة، راجع الاتصال بمركز IoT (MQTT).
إعداد موارد Azure
لإكمال هذا البرنامج التعليمي، يجب أن يحتوي اشتراك Azure الخاص بك على مركز IoT مع جهاز مضاف إلى سجل هوية الجهاز. الإدخال في سجل هوية الجهاز يُمكّن الجهاز المحاكي الذي تقوم بتشغيله في هذا البرنامج التعليمي من الاتصال بالمركز الخاص بك.
إذا لم يكن لديك بالفعل مركز IoT تم إعداده في اشتراكك، فيمكنك إعداد واحد باستخدام البرنامج النصي التالي CLI. يستخدم هذا البرنامج النصي الاسم tutorial-iot-hub مع رقم عشوائي ملحق لاسم مركز IoT. يمكنك استبدال هذا الاسم باسمك الفريد عالميا عند تشغيله. ينشئ البرنامج النصي مجموعة الموارد والمحور في منطقة Central US، والتي يمكنك تغييرها إلى منطقة أقرب إليك. يسترد البرنامج النصي سلسلة اتصال خدمة مركز IoT الخاصة بك، والتي تستخدمها في نموذج النهاية الخلفية للاتصال بمركز IoT الخاص بك:
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 موجود في الملف المطلوب. 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، حصلت على جهاز سلسلة الاتصال كإخراج. يستخدم الجهاز سلسلة الاتصال الجهاز للمصادقة بهويته المسجلة في السحابة. يتصل الرمز التالي بلوحة وصل 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. على سبيل المثال، يرى هذا المعالج جميع تغييرات الخصائص المطلوبة المرسلة إلى الجهاز من تطبيق الواجهة الخلفية. يحتوي المتغير delta على الخصائص المطلوبة المرسلة من النهاية الخلفية للحل:
// 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();
}
});
معالجة عمليات الإدراج والتحديث والحذف
لا تشير الخصائص المطلوبة المرسلة من النهاية الخلفية إلى العملية التي يتم إجراؤها على خاصية معينة مطلوبة. تحتاج التعليمات البرمجية الخاصة بك إلى استنتاج العملية من المجموعة الحالية للخصائص المرغوبة المخزنة محلياً والتغييرات المرسلة من الموزع.
يوضح الجزء التالي كيف يتعامل الجهاز الذي تمت محاكاته مع عمليات الإدراج والتحديث والحذف في قائمة المكونات في الخصائص المطلوبة. يمكنك معرفة كيفية استخدام قيم فارغة للإشارة إلى أنه يجب حذف أحد المكونات:
// 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);
}
تشغيل التطبيقات
في هذا القسم، يمكنك تشغيل نموذج التطبيقين لملاحظة تطبيق خلفي يرسل تحديثات الخصائص المطلوبة إلى تطبيق جهاز محاكاة.
لتشغيل الجهاز المحاكي والتطبيقات الخلفية، تحتاج إلى سلاسل اتصال الجهاز والخدمة. لقد قمت بتدوين سلاسل الاتصال عند إنشاء الموارد في بداية هذا البرنامج التعليمي.
لتشغيل تطبيق محاكاة الجهاز، افتح shell أو نافذة موجه الأوامر وانتقل إلى المجلد iot-hub/Tutorials/Device Twins في مشروع Node.js الذي قمت بتنزيله. ثم قم بتشغيل الأوامر التالية:
npm install
node SimulatedDevice.js "{your device connection string}"
لتشغيل التطبيق الخلفي، افتح نافذة أخرى أو نافذة موجه الأوامر. ثم انتقل إلى المجلد iot-hub/Tutorials/Device Twins في مشروع Node.js الذي قمت بتنزيله. ثم قم بتشغيل الأوامر التالية:
npm install
node ServiceClient.js "{your service connection string}"
مراقبة تحديثات الخصائص المطلوبة
تُظهر لقطة الشاشة التالية الإخراج من تطبيق الجهاز الذي تمت محاكاته وتبرز كيفية تعامله مع تحديث للخاصية المطلوبة maxTemperature. يمكنك أن ترى كيف يعمل كل من معالج المستوى الأعلى ومعالجات مكونات المناخ:
تُظهر لقطة الشاشة التالية الإخراج من التطبيق الخلفي وتبرز كيفية إرساله تحديثاً إلى الخاصية المطلوبة maxTemperature:
مراقبة تحديثات الخصائص التي تم الإبلاغ عنها
تُظهر لقطة الشاشة التالية الإخراج من تطبيق الجهاز المحاكي وتسلط الضوء على كيفية إرسال تحديث خاصية تم الإبلاغ عنه إلى المركز الخاصة بك:
تُظهر لقطة الشاشة التالية الإخراج من التطبيق الخلفي وتسلط الضوء على كيفية تلقيه ومعالجة تحديث خاصية تم الإبلاغ عنه من جهاز:
تنظيف الموارد
إذا كنت تخطط لإكمال البرنامج التعليمي التالي، فاترك مجموعة الموارد ومركز IoT لإعادة استخدامها لاحقا.
إذا لم تعد بحاجة إلى مركز IoT، فاحذفه ومجموعة الموارد في المدخل. للقيام بذلك، حدد مجموعة الموارد tutorial-iot-hub-rg التي تحتوي على مركز IoT الخاص بك وحدد Delete.
بدلاً من ذلك، استخدم CLI:
# Delete your resource group and its contents
az group delete --name tutorial-iot-hub-rg
الخطوات التالية
في هذا البرنامج التعليمي، تعلمت كيفية مزامنة معلومات الحالة بين أجهزتك ومركز IoT الخاص بك. تقدم إلى البرنامج التعليمي التالي لمعرفة كيفية استخدام Device Twins لتنفيذ عملية تحديث البرامج الثابتة.