將裝置連接至遠端監視預先設定方案 (Node.js)
案例概觀
在此案例中,您會建立一個裝置,此裝置會將下列遙測資料傳送給遠端監視預先設定解決方案:
- 外部溫度
- 內部溫度
- 溼度
為了簡化起見,在裝置上的程式碼會產生範例值,但我們鼓勵您將實際的感應器連接到您的裝置並傳送實際的遙測資料來擴充此範例。
此裝置同時也能夠回應從解決方案儀表板叫用的方法,以及回應解決方案儀表板中設定的所需屬性值。
若要完成此教學課程,您需要一個有效的 Azure 帳戶。 如果您沒有帳戶,只需要幾分鐘的時間就可以建立免費試用帳戶。 如需詳細資料,請參閱 Azure 免費試用。
開始之前
在您為裝置撰寫任何程式碼之前,您必須先佈建遠端監視預先設定解決方案,並在該解決方案中佈建新的自訂裝置。
佈建遠端監視預先設定解決方案
您在本教學課程中建立的裝置會將資料傳送給遠端監視預先設定解決方案的執行個體。 如果您尚未在您的 Azure 帳戶中佈建遠端監視預先設定解決方案,請依照下列步驟執行:
- 在 https://www.azureiotsolutions.com/ 頁面上,按一下 + 以建立解決方案。
- 按一下 [遠端監視] 面板上的 [選取],以建立解決方案。
- 在 [建立遠端監視解決方案] 頁面上,輸入 您選擇的 [解決方案名稱],選取您要部署的 [區域],並選取想要使用的 Azure 訂用帳戶。 按一下 [建立解決方案] 。
- 等候佈建程序完成。
警告
預先設定的解決方案使用可計費的 Azure 服務。 當您使用完預先設定的解決方案之後,請務必將它從您的訂用帳戶中移除,以避免任何不必要的費用。 您可以造訪 https://www.azureiotsolutions.com/ 頁面,以從訂用帳戶中完全移除預先設定的解決方案。
當遠端監視解決方案的佈建程序完成之後,請按一下 [啟動] ,以在瀏覽器中開啟解決方案儀表板。
在遠端監視解決方案中佈建您的裝置
注意
如果您已經在解決方案中佈建裝置,則可以略過此步驟。 建立用戶端應用程式時,您需要知道裝置認證。
對於連線到預先設定解決方案的裝置,該裝置必須使用有效的認證向 IoT 中樞識別自己。 您會從解決方案儀表板收到裝置認證。 稍後在本教學課程中,您會將您的裝置認證包含在您的用戶端應用程式中。
若要在您的遠端監視解決方案中新增裝置,請在解決方案儀表板中完成下列步驟:
在儀表板左下角,按一下 [新增裝置] 。
在 [自訂裝置] 面板中,按一下 [新增]。
選擇 [讓我定義自己的裝置識別碼]。 輸入裝置識別碼 (例如 mydevice),按一下 [檢查 ID] 以確認沒有其他裝置使用該名稱,然後按一下 [建立] 來佈建裝置。
記下裝置認證 (裝置識別碼、IoT 中樞主機名稱及裝置金鑰)。 用戶端應用程式需要這些值,才能連接到遠端監視解決方案。 然後按一下 [完成]。
從解決方案儀表板的裝置清單中選取您的裝置。 然後,在 [裝置詳細資料] 面板中,按一下 [啟用裝置]。 裝置的狀態現在會是 [正在執行]。 遠端監視解決方案現在已可從您的裝置接收遙測資料,並在該裝置上叫用方法。
建立 node.js 範例解決方案
請確定 Node.js 0.11.5 版或更新版本已經安裝在您的開發電腦上。 您可以在命令列執行 node --version
來檢查版本。
在開發電腦上建立名為 RemoteMonitoring 的資料夾。 在命令列環境中瀏覽至此資料夾。
執行下列命令,以下載並安裝完成範例應用程式所需的套件︰
npm init npm install azure-iot-device azure-iot-device-mqtt --save
在 RemoteMonitoring 資料夾中,建立名為 remote_monitoring.js 的檔案。 在文字編輯器中開啟這個檔案。
在 remote_monitoring.js 檔案中,新增下列
require
陳述式︰'use strict'; var Protocol = require('azure-iot-device-mqtt').Mqtt; var Client = require('azure-iot-device').Client; var ConnectionString = require('azure-iot-device').ConnectionString; var Message = require('azure-iot-device').Message;
在
require
陳述式之後新增下列變數宣告。 使用您在遠端監視解決方案儀表板中為裝置記下的值來取代 [Device Id] 和 [Device Key] 預留位置值。 使用解決方案儀表板中的「IoT 中樞主機名稱」來取代 [IoTHub Name]。 例如,若您的 IoT 中樞主機名稱是 contoso.azure-devices.net,請使用 contoso 取代 [IoTHub Name]:var connectionString = 'HostName=[IoTHub Name].azure-devices.net;DeviceId=[Device Id];SharedAccessKey=[Device Key]'; var deviceId = ConnectionString.parse(connectionString).DeviceId;
新增下列變數來定義一些基本遙測資料︰
var temperature = 50; var humidity = 50; var externalTemperature = 55;
新增下列協助程式來列印作業結果︰
function printErrorFor(op) { return function printError(err) { if (err) console.log(op + ' error: ' + err.toString()); }; }
新增下列協助程式函式,用來將排遙測值隨機化︰
function generateRandomIncrement() { return ((Math.random() * 2) - 1); }
針對裝置在啟動時傳送的 DeviceInfo 物件,新增下列定義︰
var deviceMetaData = { 'ObjectType': 'DeviceInfo', 'IsSimulatedDevice': 0, 'Version': '1.0', 'DeviceProperties': { 'DeviceID': deviceId, 'HubEnabledState': 1 } };
針對裝置對應項報告值新增下列定義。 此定義包含裝置支援的直接方法說明︰
var reportedProperties = { "Device": { "DeviceState": "normal", "Location": { "Latitude": 47.642877, "Longitude": -122.125497 } }, "Config": { "TemperatureMeanValue": 56.7, "TelemetryInterval": 45 }, "System": { "Manufacturer": "Contoso Inc.", "FirmwareVersion": "2.22", "InstalledRAM": "8 MB", "ModelNumber": "DB-14", "Platform": "Plat 9.75", "Processor": "i3-9", "SerialNumber": "SER99" }, "Location": { "Latitude": 47.642877, "Longitude": -122.125497 }, "SupportedMethods": { "Reboot": "Reboot the device", "InitiateFirmwareUpdate--FwPackageURI-string": "Updates device Firmware. Use parameter FwPackageURI to specifiy the URI of the firmware file" }, }
新增下列函式以處理 Reboot 直接方法呼叫:
function onReboot(request, response) { // Implement actual logic here. console.log('Simulated reboot...'); // Complete the response response.send(200, "Rebooting device", function(err) { if(!!err) { console.error('An error occurred when sending a method response:\n' + err.toString()); } else { console.log('Response to method \'' + request.methodName + '\' sent successfully.' ); } }); }
新增下列函式以處理 InitiateFirmwareUpdate 直接方法呼叫。 此直接方法使用參數來指定要下載之韌體映像的位置,並以非同步方式在裝置上啟始韌體更新︰
function onInitiateFirmwareUpdate(request, response) { console.log('Simulated firmware update initiated, using: ' + request.payload.FwPackageURI); // Complete the response response.send(200, "Firmware update initiated", function(err) { if(!!err) { console.error('An error occurred when sending a method response:\n' + err.toString()); } else { console.log('Response to method \'' + request.methodName + '\' sent successfully.' ); } }); // Add logic here to perform the firmware update asynchronously }
新增下列程式碼,以建立用戶端執行個體︰
var client = Client.fromConnectionString(connectionString, Protocol);
新增下列程式碼,以便:
- 開啟連線。
- 傳送 DeviceInfo 物件。
- 設定所需屬性的處理常式。
- 傳送報告屬性。
- 登錄直接方法的處理常式。
- 開始傳送遙測。
client.open(function (err) { if (err) { printErrorFor('open')(err); } else { console.log('Sending device metadata:\n' + JSON.stringify(deviceMetaData)); client.sendEvent(new Message(JSON.stringify(deviceMetaData)), printErrorFor('send metadata')); // Create device twin client.getTwin(function(err, twin) { if (err) { console.error('Could not get device twin'); } else { console.log('Device twin created'); twin.on('properties.desired', function(delta) { console.log('Received new desired properties:'); console.log(JSON.stringify(delta)); }); // Send reported properties twin.properties.reported.update(reportedProperties, function(err) { if (err) throw err; console.log('twin state reported'); }); // Register handlers for direct methods client.onDeviceMethod('Reboot', onReboot); client.onDeviceMethod('InitiateFirmwareUpdate', onInitiateFirmwareUpdate); } }); // Start sending telemetry var sendInterval = setInterval(function () { temperature += generateRandomIncrement(); externalTemperature += generateRandomIncrement(); humidity += generateRandomIncrement(); var data = JSON.stringify({ 'DeviceID': deviceId, 'Temperature': temperature, 'Humidity': humidity, 'ExternalTemperature': externalTemperature }); console.log('Sending device event data:\n' + data); client.sendEvent(new Message(data), printErrorFor('send event')); }, 5000); client.on('error', function (err) { printErrorFor('client')(err); if (sendInterval) clearInterval(sendInterval); client.close(printErrorFor('client.close')); }); } });
將變更儲存至 remote_monitoring.js 檔案。
在命令提示字元中執行下列命令,以啟動範例應用程式:
node remote_monitoring.js
在儀表板中檢視裝置遙測
遠端監視解決方案中的儀表板可讓您檢視裝置傳送到 IoT 中樞的遙測資料。
在瀏覽器中,返回遠端監視解決方案儀表板,按一下左面板中的 [裝置] 瀏覽至 [裝置清單]。
在 [裝置清單] 中,您應該會看到裝置的狀態是 [正在執行]。 如果不是,請按一下 [裝置詳細資料] 面板中的 [啟用裝置]。
按一下 [儀表板] 以返回儀表板,從 [要檢視的裝置] 下拉式清單中選取您的裝置,以檢視其遙測。 範例應用程式的遙測是 50 個單位的內部溫度、 55 個單位的外部溫度,以及 50 個單位的濕度。
在裝置上叫用方法
遠端監視解決方案中的儀表板可讓您透過 IoT 中樞在裝置上叫用方法。 例如,在遠端監視解決方案中,您可以叫用方法來模擬裝置重新啟動。
在遠端監視解決方案的儀表板中,按一下左面板中的 [裝置] 瀏覽至 [裝置清單]。
在 [裝置清單] 中,按一下裝置的 [裝置識別碼]。
在 [裝置詳細資料] 面板中,按一下 [方法]。
在 [方法] 下拉式清單中,選取 [InitiateFirmwareUpdate],然後在 [FWPACKAGEURI] 中輸入虛擬的 URL。 按一下 [叫用方法] 以在裝置上呼叫該方法。
當裝置處理該方法時,您可以在執行裝置程式碼的主控台中看見訊息。 該方法的結果會新增到解決方案入口網站的歷程記錄中:
後續步驟
自訂預先設定的方案一文描述可供您擴充此範例的一些方式。 可能的延伸模組包括使用真實的感應器和實作其他命令。
您可以深入了解 azureiotsuite.com 網站的權限。