當前位置:
首頁 > 科技 > 使用 Azure IoT 套件推動 IoT 開發

使用 Azure IoT 套件推動 IoT 開發

物聯網 (IoT) 解決方案包括遠程遙測設備、Web 門戶、雲存儲和實時處理功能。結構如此複雜,你就更不願意開始進行 IoT 開發了。為了簡化工作,Microsoft Azure IoT 套件提供了以下兩個預配置解決方案:遠程監視和預測性維護。

本文將介紹如何創建遠程監視解決方案,從而收集和分析 Windows 10 IoT 核心版控制的遠程 IoT 設備中的數據。此 Raspberry Pi 設備將通過 USB 攝像頭採集圖像。隨後,圖像亮度會在 IoT 設備上進行計算,然後流式傳輸到雲中,並在雲中進行存儲、處理和顯示(見圖 1)。

此外,最終用戶不僅可以查看通過遠程設備採集的信息,還能遠程控制相應設備。有關輔助此論述的完整源代碼,請訪問 msdn.com/magazine/0617magcode

使用 Azure IoT 套件推動 IoT 開發

圖 1:Azure IoT 套件預配置解決方案門戶,以及用於採集並處理視頻流的遠程通用 Windows 平台應用

遠程設備

Frank LaVigne (msdn.com/magazine/mt694090) 和 Bruno Sonnino (msdn.com/magazine/mt808503) 已在本雜誌中介紹過在安裝了 Windows 10 IoT 核心版的 Raspberry Pi 上進行編程的基礎知識。

LaVigne 和 Sonnino 介紹了如何設置開發環境和 IoT 開發板、如何在瀏覽器中使用設備門戶配置 IoT 單元,以及如何使用 Windows 10 IoT 核心版控制 GPIO 埠。此外,LaVigne 還在他的文章中提到,可以使用 IoT 對遠程攝像頭進行編程和控制。

在本文中,我擴展了這一想法,並明確介紹了如何將 Raspberry Pi 變成這樣的設備。

為此,我使用空白應用(通用 Windows)Visual C# 項目模板創建了 RemoteCamera 通用 Windows 平台 (UWP) 應用,然後將目標和最低 API 版本設置為 Windows 10 周年版本(10.0;生成號 14393)。我使用此 API 版本是為了能夠綁定到方法,從而直接將視圖模型的方法與可視控制項觸發的事件相關聯:

接下來,我聲明了 UI,如圖 1 所示。有兩個選項卡: 「攝像頭捕捉」和「雲」。第一個選項卡中的控制項可用於啟動或停止攝像頭預覽、顯示視頻流並呈現圖像亮度(標籤和進度欄)。第二個選項卡中有兩個按鈕,分別用於將設備連入雲中,以及在 IoT 門戶中註冊設備。「雲」選項卡還包含一個複選框,用於啟用流式傳輸遙測數據。

與 UI 相關聯的大部分邏輯是在 RemoteCameraViewModel 類(見 RemoteCamera 項目的 ViewModels 子文件夾)中實現。除了實現一些與 UI 綁定的屬性之外,此類還負責處理視頻採集、圖像處理和雲交互。

這些子功能分別是在以下各個類中實現: CameraCapture、ImageProcessor 和 CloudHelper。我很快將會介紹 CameraCapture 和 ImageProcessor,而 CloudHelper 及相關幫助程序類則稍後將在 Azure IoT 預配置解決方案上下文中進行介紹。

相機捕捉

攝像頭捕捉(見 Helpers 文件夾下的 CameraCapture.cs)是在以下兩個元素的基礎之上生成: Windows.Media.Capture.MediaCapture class 和 Windows.UI.Xaml.Controls.CaptureElement。

前者用於採集視頻,而後者則用於顯示採集的視頻流。由於使用攝像頭採集視頻,因此必須在 Package.appxmanifest 中聲明相應的設備功能。

若要初始化 MediaCapture 類,請調用 InitializeAsync 方法。最終,可以向此方法傳遞 MediaCaptureInitializationSettings 類的實例,從而指定捕捉選項。

可以選擇是流式傳輸視頻還是音頻,並選擇捕捉硬體。在本文中,我僅通過默認攝像頭採集視頻(見圖 2)。

圖 2:攝像頭捕捉初始化

publicMediaCapture { get; privateset; } = newMediaCapture; publicboolIsInitialized { get; privateset; } = false; publicasyncTask Initialize(CaptureElement captureElement){ if(!IsInitialized) { varsettings = newMediaCaptureInitializationSettings { StreamingCaptureMode = StreamingCaptureMode.Video }; try{ awaitMediaCapture.InitializeAsync(settings); GetVideoProperties; captureElement.Source = MediaCapture; IsInitialized = true; } catch(Exception ex) { Debug.WriteLine(ex.Message); IsInitialized = false; } }}

接下來,使用 CaptureElement 類實例的 Source 屬性,將此對象與 MediaCapture 控制項相關聯,以顯示視頻流。

我還調用了幫助程序方法 GetVideoProperties,用於讀取並存儲視頻幀的大小。稍後會使用此信息來獲取預覽幀以供處理。

最後,為了能夠真正啟動和停止視頻採集,我調用了 MediaCapture 類的 StartPreviewAsync 和 StopPreviewAsync。在 CameraCapture 中,我使用其他邏輯包裝了這些方法,同時驗證了初始化和預覽狀態:

publicasyncTask Start{ if(IsInitialized) { if(!IsPreviewActive) { awaitMediaCapture.StartPreviewAsync; IsPreviewActive = true; } }}

運行應用時,可以按「開始預覽」按鈕來配置攝像頭採集,之後不久就可以看到攝像頭圖像。請注意,由於 RemoteCamera 應用是通用應用,因此無需進行任何更改,即可部署到開發 PC、智能手機、平板電腦或 Raspberry Pi。

如果使用 Windows 10 PC 測試 RemoteCamera 應用,需要確保應用可使用攝像頭。可以使用「設置」應用(「隱私」/「攝像頭」)來配置此設置。為了使用 Raspberry Pi 測試此應用,我使用了預算較低的 Microsoft Life Cam HD-3000。由於這是一個 USB 攝像頭,因此,當我將它連到四個 Raspberry Pi USB 埠之一後,Windows 10 IoT 核心版可以自動檢測到攝像頭。

有關與 Windows 10 IoT 核心版兼容的攝像頭的完整列表,請訪問 bit.ly/2p1ZHGD。將攝像頭與 Rasbperry Pi 相連後,它顯示在「設備門戶」的「設備」選項卡下。

圖像處理器

ImageProcessor 類在後台計算當前幀的亮度。為了執行後台操作,我使用基於任務的非同步模式創建了線程,如圖 3 所示。

圖 3:在後台計算亮度

publiceventEventHandler ProcessingDone; privatevoidInitializeProcessingTask{ processingCancellationTokenSource = newCancellationTokenSource; processingTask = newTask( async => { while(!processingCancellationTokenSource.IsCancellationRequested) { if(IsActive) { varbrightness = awaitGetBrightness; ProcessingDone( this, newImageProcessorEventArgs(brightness)); Task.Delay(delay).Wait; } } }, processingCancellationTokenSource.Token);}

在 while 循環中,我確定了圖像亮度,然後將此值傳遞給 ProcessingDone 事件的偵聽器。系統向此事件饋送 ImageProcessorEventArgs 類的實例,其中只有一個公共屬性 Brightness。在收到取消信號前,處理任務會一直運行。圖像處理的關鍵元素是 GetBrightness 方法,如圖 4 所示。

圖 4:GetBrightness 方法

privateasyncTask< byte> GetBrightness{ varbrightness = newbyte; if(cameraCapture.IsPreviewActive) { // Get current preview bitmapvarpreviewBitmap = awaitcameraCapture.GetPreviewBitmap; // Get underlying pixel datavarpixelBuffer = GetPixelBuffer(previewBitmap); // Process buffer to determine mean gray value (brightness)brightness = CalculateMeanGrayValue(pixelBuffer); } returnbrightness;}

我使用 CameraCapture 類實例的 GetPreviewBitmap 來獲取預覽幀。在內部,GetPreviewBitmap 使用 MediaCapture 類的 GetPreviewFrameAsync。

GetPreviewFrameAsync 有兩個版本。第一個版本是無參數方法,返回的是 VideoFrame 類的實例。

在這種情況下,可以通過讀取 Direct3DSurface 屬性來獲取實際的像素數據。第二個版本接受 Video-Frame 類的實例,並將像素數據複製到其 SoftwareBitmap 屬性中。在本文中,我使用第二個選項(見 CameraCapture 類的 GetPreviewBitmap 方法),然後通過 SoftwareBitmap 類實例的 CopyToBuffer 方法訪問像素數據(如圖 5 所示)。

圖 5:訪問像素數據

privatebyte GetPixelBuffer(SoftwareBitmap softwareBitmap){ // Ensure bitmap pixel format is Bgra8if(softwareBitmap.BitmapPixelFormat != CameraCapture.BitmapPixelFormat) { SoftwareBitmap.Convert(softwareBitmap, CameraCapture.BitmapPixelFormat); } // Lock underlying bitmap buffervarbitmapBuffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode.Read); // Use plane deion to determine bitmap height// and stride (the actual buffer width)varplaneDeion = bitmapBuffer.GetPlaneDeion(0); varpixelBuffer = newbyte[planeDeion.Height * planeDeion.Stride]; // Copy pixel data to a buffersoftwareBitmap.CopyToBuffer(pixelBuffer.AsBuffer); returnpixelBuffer;}

首先,我將確認像素格式是否為 BGRA8。此像素格式表示圖像使用四個 8 位通道:三個通道分別用於表示藍色、綠色和紅色,另外一個通道用於表示 alpha 或透明度。如果輸入點陣圖採用其他像素格式,我會執行相應的轉換。

接下來,我將把像素數據複製到位元組數組中,其大小由圖像高度與圖像步幅的乘積決定 (bit.ly/2om8Ny9)。我從 BitmapPlaneDeion 實例中讀取這兩個值,此實例是通過 SoftwareBitmap.LockBuffer 方法返回的 BitmapBuffer 對象獲取而來。

鑒於位元組數組包含像素數據,只需計算所有像素的平均值即可。因此,我循環訪問了像素緩存(見圖 6)。

圖 6:計算像素的平均值

privatebyteCalculateMeanGrayValue( byte[] pixelBuffer){ // Loop index increases by four since// there are four channels (blue, green, red and alpha).// Alpha is ignored for brightness calculationconstintstep = 4; doublemean = 0.0; for( uinti = 0; i < pixelBuffer.Length; i += step) { mean += GetGrayscaleValue(pixelBuffer, i); } mean /= (pixelBuffer.Length / step); returnConvert.ToByte(mean);}

然後,每次循環訪問時,我會計算所有顏色通道的平均值,將給定像素轉換成灰度:

privatestaticbyteGetGrayscaleValue( byte[] pixelBuffer, uintstartIndex){ vargrayValue = (pixelBuffer[startIndex] + pixelBuffer[startIndex + 1] + pixelBuffer[startIndex + 2]) / 3.0; returnConvert.ToByte(grayValue);}

Brightness 通過 ProcessingDone 事件傳遞給視圖。

此事件的處理位置為 MainPage 類 (MainPage.xaml.cs),我在其中通過標籤和進度欄顯示亮度。兩個控制項均綁定到 RemoteCameraViewModel 的 Brightness 屬性。

請注意,ProcessingDone 是由後台線程觸發。因此,我使用 Dispatcher 類通過 UI 線程修改 RemoteCameraViewModel.Brightness,如圖 7 所示。

圖 7:使用 Dispatcher 類通過 UI 線程修改 RemoteCameraViewModel.Brightness

privateasyncvoidDisplayBrightness( bytebrightness){ if(Dispatcher.HasThreadAccess) { remoteCameraViewModel.Brightness = brightness; } else{ awaitDispatcher.RunAsync(CoreDispatcherPriority.Normal, => { DisplayBrightness(brightness); }); }}

預配遠程監視解決方案

若要預配解決方案,可以使用專用門戶 (azureiotsuite.com)。登錄並選擇 Azure 訂閱後,便會重定向到一個頁面,可以在其中按「創建新的解決方案」矩形框。

這會打開一個網站,可以在其中選擇兩個預配置解決方案之一:預測性維護或遠程監視(見圖 8)。選擇解決方案後,將會看到另一個窗體,可以在其中設置 Azure 資源的解決方案名稱和區域。

在本文中,我將解決方案名稱和區域分別設置為「RemoteCameraMonitoring」和「美國西部」。

使用 Azure IoT 套件推動 IoT 開發

圖 8:Azure IoT 套件預配置解決方案(上)和遠程監視解決方案配置(下)

預配遠程監視解決方案時,Azure IoT 套件門戶會創建以下多個 Azure 資源: IoT 中心、流分析作業、存儲和 App Service。IoT 中心可實現雲和遠程設備之間的雙向通信。流分析作業會轉換遠程設備流式傳輸的數據,通常是篩選掉不必要的數據。篩選後的數據會進行存儲或定向,以供將來分析時使用。

最後,App Service 用於託管 Web 門戶。

也可以通過命令行完成解決方案預配。

為此,可以從 bit.ly/2osI4RW克隆或下載解決方案源代碼,然後按照 bit.ly/2p7MPPc中的說明操作。也可以視需要在本地部署解決方案,如 bit.ly/2nEePNi 所述。

在這種情況下,不會創建 Azure App Service,因為解決方案門戶是在本地計算機上運行。若要進行開發和調試或修改預配置解決方案,就會發現此類方法特別有用。

完成預配後,可以啟動解決方案,它的門戶顯示在默認瀏覽器中(再次見圖 1)。此門戶包含多個選項卡。

在本文中,我將僅關注其中兩個選項卡,即「儀錶板」和「設備」。「儀錶板」顯示遠程設備及其流式傳輸的遙測數據的映射。「設備」選項卡顯示遠程設備列表,包括設備的狀態、功能和說明。默認情況下,有多個模擬設備。我將介紹如何註冊新的非模擬硬體。

註冊設備

若要註冊設備,請按解決方案門戶中左下角的「添加設備」超鏈接。然後,選擇添加模擬設備還是自定義設備。選取第二個選項,然後按「添加新設備」按鈕。現在,可以定義「設備 ID」了。我將此值設置為「RemoteCamera」。

此後,「添加自定義設備」窗體中顯示設備憑據(見圖 9),稍後用它將 IoT 設備連入 IoT 中心。

使用 Azure IoT 套件推動 IoT 開發

圖 9:設備註冊摘要

設備元數據和雲通信

添加的設備顯示在設備列表中,然後便可以發送設備元數據或設備信息。設備信息包括描述遠程設備的 JSON 對象。此對象可告知雲終結點設備功能,並包含硬體描述以及設備接受的遠程命令列表。最終用戶可通過 IoT 解決方案門戶向設備發送這些命令。

在 RemoteCamera 應用中,設備信息表示為 DeviceInfo 類(位於 AzureHelpers 子文件夾中):

publicclassDeviceInfo{ publicboolIsSimulatedDevice { get; set; } publicstringVersion { get; set; } publicstringObjectType { get; set; } publicDeviceProperties DeviceProperties { get; set; } publicCommand Commands { get; set; }}

DeviceInfo 的前兩個屬性指定了是否為模擬設備,並定義了 DeviceInfo 對象的版本。稍後可以看到,第三個屬性 ObjectType 被設置為字元串常數 DeviceInfo。

雲(特別是 Azure 流分析作業)使用此字元串從遙測數據中篩選出設備信息。接下來,DeviceProperties(見 AzureHelpers 子文件夾)包含一系列描述設備的屬性(如序列號、內存、平台、RAM)。最後,Commands 屬性包含設備識別的一系列遠程命令。

通過指定名稱和參數列表(分別由 Command 和 CommandParameter 類表示,見 AzureHelpersCommand.cs),可定義每個命令。

若要在 IoT 設備和 IoT 中心之間建立通信,請使用 Microsoft.Azure.Devices.Client NuGet 包。此包提供 DeviceClient 類,可用於向雲發送消息和接收雲消息。可以使用 Create 或 CreateFromConnectionString 靜態方法,創建 DeviceClient 實例。

在本文中,我使用第一個選項(見 AzureHelpers 文件夾中的 CloudHelper.cs):

publicasyncTask Initialize{ if(!IsInitialized) { deviceClient = DeviceClient.Create( Configuration.Hostname, Configuration.AuthenticationKey); awaitdeviceClient.OpenAsync; IsInitialized = true; BeginRemoteCommandHandling; }}

可以看到,若要使用 DeviceClient.Create 方法,需要提供 IoT 中心的主機名和設備憑據(標識符和密鑰)。這些值是在設備預配期間從解決方案門戶獲取(再次見圖 9)。在 RemoteCamera 應用中,我在 Configuration 靜態類中存儲了主機名、設備 ID 和密鑰:

publicstaticclassConfiguration{ publicstaticstringHostname { get; } = ".azure-devices.net"; publicstaticstringDeviceId { get; } = "RemoteCamera"; publicstaticstringDeviceKey { get; } = ""; publicstaticDeviceAuthenticationWithRegistrySymmetricKey AuthenticationKey { returnnewDeviceAuthenticationWithRegistrySymmetricKey(DeviceId, DeviceKey); }}

此外,Configuration 類還會實現靜態方法 AuthenticationKey,從而將設備憑據包裝到 DeviceAuthenticationWithRegistrySymmetricKey 類的實例中。我藉此來簡化 DeviceClient 類實例的創建工作。

連接建立後,只需發送 DeviceInfo 即可,如圖 10 所示。

圖 10:發送設備信息

publicasyncTask SendDeviceInfo{ vardeviceInfo = newDeviceInfo { IsSimulatedDevice = false, ObjectType = "DeviceInfo", Version = "1.0", DeviceProperties = newDeviceProperties(Configuration.DeviceId), // Commands collectionCommands = newCommand { CommandHelper.CreateCameraPreviewStatusCommand } }; awaitSendMessage(deviceInfo);}

RemoteCamera 應用可發送描述實際硬體的設備信息,因此 IsSimulatedDevice 屬性設置為 false。

如上所述,ObjectType 設置為 DeviceInfo。此外,我還將 Version 屬性設置為 1.0。對於 DeviceProperties,我使用的是任意值,主要包括靜態字元串(見 DeviceProperties 類的 SetDefaultValues 方法)。

我還定義了遠程命令「更新攝像頭預覽」,以便能夠遠程控制攝像頭預覽。此命令包含一個布爾參數 IsPreviewActive,用於指定應啟動還是停止攝像頭預覽(見 AzureHelpers 文件夾下的 CommandHelper.cs 文件)。

為了能夠真正將數據發送到雲中,我實現了 SendMessage 方法:

privateasyncTask SendMessage(Object message){ varserializedMessage = MessageHelper.Serialize(message); awaitdeviceClient.SendEventAsync(serializedMessage);}

一般來說,需要將 C# 對象序列化成包含 JSON 格式對象的位元組數組(見 AzureHelpers 子文件夾中的 MessageHelper 靜態類):

publicstaticMessage Serialize( objectobj){ ArgumentCheck.IsNull(obj, "obj"); varjsonData = JsonConvert.SerializeObject(obj); returnnewMessage(Encoding.UTF8.GetBytes(jsonData));}

然後,將生成的數組包裝到 Message 類中,以使用 DeviceClient 類實例的 SendEventAsync 方法將其發送到雲中。

Message 類是對象,為原始數據(傳輸的 JSON 對象)補充了其他屬性。這些屬性用於跟蹤設備與 IoT 中心之間發送的消息。

在 RemoteCamera 應用中,與雲建立連接和發送設備信息是通過「雲」選項卡上的兩個按鈕觸發的: 「連接和初始化」和「發送設備信息」。第一個按鈕的 click 事件處理程序綁定到 RemoteCameraViewModel 的 Connect 方法:

publicasyncTask Connect{ awaitCloudHelper.Initialize; IsConnected = true;}

第二個按鈕的 click 事件處理程序與 CloudHelper 類實例的 SendDeviceInfo 方法相關聯。此方法前面介紹過。

連入雲後,還可以開始發送遙測數據,與發送設備信息相似。也就是說,可以使用 SendMessage 方法,向其傳遞遙測對象。在本文中,此對象是 Telemetry-Data 類的實例,只有一個屬性 Brightness。

下面的完整示例展示了如何將遙測數據發送到雲中,具體是在 CloudHelper 類的 SendBrightness 方法內實現:

publicasyncvoidSendBrightness( bytebrightness){ if(IsInitialized) { // Construct TelemetryDatavartelemetryData = newTelemetryData { Brightness = brightness }; // Serialize TelemetryData and send it to the cloudawaitSendMessage(telemetryData); }}

在獲取 ImageProcessor 計算的亮度後,便會立即調用 SendBrightness。ProcessingDone 事件處理程序負責執行此操作:

privatevoidImageProcessor_ProcessingDone( objectsender, ImageProcessorEventArgs e){ // Update display through dispatcherDisplayBrightness(e.Brightness); // Send telemetryif(remoteCameraViewModel.IsTelemetryActive) { remoteCameraViewModel.CloudHelper.SendBrightness(e.Brightness); }}

因此,如果現在運行 RemoteCamera 應用,然後開始預覽並連接雲,將會看到亮度值顯示

在相應圖表中,如圖 1 所示。請注意,儘管預配置解決方案的模擬設備旨在以遙測數據形式發送溫度和濕度,但也可以發送其他值。在本文中,我將發送亮度,它會自動顯示在相應圖表中。

處理遠程命令

CloudHelper 類還實現方法來處理從雲中收到的遠程命令。同樣,與 ImageProcessor 一樣,我是在後台處理命令(見 CloudHelper 類的 BeginRemoteCommandHandling)。

我將再次使用基於任務的非同步模式:

privatevoidBeginRemoteCommandHandling{ Task.Run( async => { while( true) { varmessage = awaitdeviceClient.ReceiveAsync; if(message != null) { awaitHandleIncomingMessage(message); } } });}

此方法負責創建任務來持續分析從雲終結點收到的消息。若要接收遠程消息,請調用 DeviceClient 類的 ReceiveAsync 方法。

ReceiveAsync 返回 Message 類的實例,可用於獲取包含 JSON 格式遠程命令數據的原始位元組數組。

然後,將此數組反序列化成 RemoteCommand 對象(見 AzureHelpers 文件夾中的 RemoteCommand.cs),具體是在 MessageHelper 類(見 AzureHelpers 子文件夾)中進行實現:

publicstaticRemoteCommand Deserialize(Message message){ ArgumentCheck.IsNull(message, "message"); varjsonData = Encoding.UTF8.GetString(message.GetBytes); returnJsonConvert.DeserializeObject( jsonData);}

雖然 RemoteCommand 包含多個屬性,但通常只使用以下兩個:名稱和參數(其中包含命令名稱和命令參數)。在 RemoteCamera 應用中,我使用這些值來確定是否按預期接收到了命令(見圖 11)。

如果收到,我會觸發 UpdateCameraPreviewCommandReceived 事件,將相應信息傳遞給偵聽器,然後我會使用 DeviceClient 類的 CompleteAsync 方法,通知雲已收到命令。

如果命令無法識別,我會使用 RejectAsync 方法拒絕接收。

圖 11:遠程消息反序列化和分析

privateasyncTask HandleIncomingMessage(Message message){ try{ // Deserialize message to remote commandvarremoteCommand = MessageHelper.Deserialize(message); // Parse commandParseCommand(remoteCommand); // Send confirmation to the cloudawaitdeviceClient.CompleteAsync(message); } catch(Exception ex) { Debug.WriteLine(ex.Message); // Reject message, if it was not parsed correctlyawaitdeviceClient.RejectAsync(message); }} privatevoidParseCommand(RemoteCommand remoteCommand){ // Verify remote command nameif( string.Compare(remoteCommand.Name, CommandHelper.CameraPreviewCommandName) == 0) { // Raise an event, when the valid command was receivedUpdateCameraPreviewCommandReceived( this, newUpdateCameraPreviewCommandEventArgs( remoteCommand.Parameters.IsPreviewActive)); }}

UpdateCameraPreviewCommandReceived 事件是在 MainPage 類中進行處理。我會停止或啟動本地攝像頭預覽,具體視我通過遠程命令獲取的參數值而定。此操作會再次分派給 UI 線程,如圖 12 所示。

圖 12:更新攝像頭預覽

privateasyncvoidCloudHelper_UpdateCameraPreviewCommandReceived( objectsender, UpdateCameraPreviewCommandEventArgs e){ if(Dispatcher.HasThreadAccess) { if(e.IsPreviewActive) { awaitremoteCameraViewModel.PreviewStart; } else{ awaitremoteCameraViewModel.PreviewStop; } } else{ awaitDispatcher.RunAsync(CoreDispatcherPriority.Normal, => { CloudHelper_UpdateCameraPreviewCommandReceived(sender, e); }); }}

從雲發送命令

最後,我將介紹可用於遠程控制 IoT 設備的解決方案門戶。為此,請使用「設備」選項卡,需要在其中查找並單擊相應設備(見圖 13)。

使用 Azure IoT 套件推動 IoT 開發

圖 13:顯示 RemoteCamera 詳細信息的 IoT 門戶「設備」選項卡

這會激活設備詳細信息窗格,可以在其中單擊「命令」超鏈接。然後,將看到另一個窗體,用於選擇並發送遠程命令。

此窗體的具體布局取決於所選擇的命令。在本文中,我只有一個參數命令,因此只有一個複選框。如果取消選中此複選框並發送命令,RemoteCamera 應用便會停止預覽。發送的所有命令及其狀態顯示在命令歷史記錄中,如圖 14 所示。

使用 Azure IoT 套件推動 IoT 開發

圖 14:用於向 IoT 設備發送遠程命令的窗體

總結

我介紹了如何設置遠程監視 Azure IoT 套件預配置解決方案。此解決方案可收集並顯示與遠程設備連接的攝像頭採集的圖像相關信息,並能遠程控制 IoT 設備。

隨附的源代碼可以在任意 UWP 設備上運行,因此無需真正將它部署到 Raspberry Pi。本文以及遠程監視解決方案的聯機文檔和源代碼將有助於快速啟動綜合 IoT 開發,以實現實用的遠程監視。可以看到,藉助 Windows 10 IoT 核心版,可實現的遠不止讓 LED 燈閃爍那麼簡單。

Dawid Borycki 是軟體工程師、生物醫學研究員、作家和會議演講者。他喜歡學習有關軟體實驗和原型設計的新技術。

衷心感謝以下 Microsoft 技術專家對本文的審閱: Rachel Appel

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 TechWeb 的精彩文章:

風口上的「享睡」經濟:共享睡眠倉能走多遠?
樂視重要的是應欠債還錢
Google光纖CEO上任五個月後離職
顏色太單一?微軟SurfaceBook馬上要迎來更多配色
外媒:三星Note 8預計8月底推出

TAG:TechWeb |

您可能感興趣

iPhone繼續用 Intel:5G發展將推動
《Apex Construct》開發商:PS VR推動銷量
浪潮發布新的AI品牌TensorServer 推動建立AI生態
推動TTF電場技術發明與膠質瘤臨床應用的Novo Cure執行主席Doyle
Facebook重組Oculus部門 推動AR/VR領域的長期發展
RegenHU聯合Wako Automation在美國推動藥物發現和生物3D列印
微軟收購Semantic Machines,推動會話式AI發展
Mercia宣布與Digital Catapult合作推動下一代VR/AR業務
CenturyLink擴大與Google雲端合作推動公司數碼轉型
微軟加入OpenChain Project推動開源軟體許可標準
Snap宣布Lens Creative Partners計劃,推動AR濾鏡商業化
Facebook和Snap在積極推動VRAR廣告創新
Google 開源 robots.txt 解析器,推動 REP 標準化
智慧展館端倪漸顯,LUCI攜手Nokia和Intel推動5G+VR商用
KubeCon大會:商業化加速推動Kubernetes開源項目日趨成熟
Unity升級引擎推動開發大眾化 確認參展2018 ChinaJoy BTOB
HTC 持續推動 VR 業務,Vive Focus 正式全國發貨
4.16 VR掃描:Facebook、Snap積極推動VR/AR廣告創新;SteamVR更新HTC Vive固件
Mercia技術公司宣布與數字Catapult建立夥伴關係 推動VR/AR業務
Breathe Architecture | 推動積極變革的設計