Microsoft Azure IoT Hub(2)
從Android裝置傳送訊息至IoT Hub
- IoT Hub 建立新device
1. 進入上一章建立的IoT Hub(IoTWorkSuccess) 點選 "IoT 裝置"
2. 點選 "新增" 進入 "建立裝置"
3. 在"裝置識別碼" 輸入 "andrid_device01"
4. 在"驗證類型" 選取"對稱金鑰"(原預設不動)
5. 在"自動產生金鑰" 選取"啟動" (原預設不動)
6. 按下"儲存", 完成新增
7. 點選新建立的"android_device01"裝置, 進入 "andrid_device01" 頁面
8. 點選"主要連接字串"後面"顯示/隱藏欄位內容" 可以顯示出此device的連線字符串
9. 點選 "copy" 待coding時使用此字串
B. 輸入下列資料 Name : DeviceToIoT Package Name: com.rdwatchworld.devicetoiot, Save Location: E:\worksapces\Azure\DeviceToIoT 後按下 "Finish"
2. Layout設定: 佈置一個"Multiline Text"及"Button":
A. 從"Android"切換至"Project"後展開以下目錄"DeviceToIoT", "app", "src", "main", "res", "layout"B. 開啟"activity_main.xml",刪除原有的"TextView:,拖拉一個"Multiline Text"拉至適當大小再拖一個"Button放至下方, 分別id設為 "Info_Text"與"Send_Button"
C. 從"Design" 切換"Code"
D. activity_main.xml程式碼如下:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText mInfo = (EditText)findViewById(R.id.Info_Text);
Button mSend = (Button)findViewById(R.id.Send_Button);
mSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
b. 連接Device ID: private final String deviceId = "andrid_device01";
d. 定義雲端Device Client端物件: private static DeviceClient client;
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:layout_editor_absoluteX="123dp"
tools:layout_editor_absoluteY="1dp"
tools:ignore="MissingConstraints">
<EditText
android:id="@+id/Info_Text"
android:layout_width="351dp"
android:layout_height="101dp"
android:ems="10"
android:gravity="start|top"
android:inputType="textMultiLine"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="42dp"
tools:layout_editor_absoluteY="30dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/Send_Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start"
tools:layout_editor_absoluteX="85dp"
tools:layout_editor_absoluteY="166dp"
tools:ignore="MissingConstraints" />
<Button
android:id="@+id/stop_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop"
tools:layout_editor_absoluteX="234dp"
tools:layout_editor_absoluteY="166dp"
tools:ignore="MissingConstraints" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
3. Android Studio Project設定(build.gradle):
A. 在"Tool Windows" 的 "Project" 中選擇"DeviceToIoT"後按右鍵, 在List中選擇"Open Module Settings ", 跳出"Project Structure"視窗.
B. 選擇"Dependencies"在"Module"中選擇"app",在"Declared Dependencies"中按下"Add Dependency"後選擇"Library Dependency", 跳出"Add Library Dependency"視窗.
C. 在"Step 1" 輸入 "azure"(全部小寫)後按"Search", List 相關的搜尋結果, 再選擇"com.microsoft.azure"
D. 在"Step 2" 選擇"Implementation"後按下"OK", 再按一次"OK".
D. 在"Step 2" 選擇"Implementation"後按下"OK", 再按一次"OK".
E. 開啟"app"下的 "build.gradle" (在專案下也有一個build.gradle)檔案在dependencies {}中加入
api ('com.microsoft.azure.sdk.iot:iot-device-client:1.28.0') {
exclude module: 'slf4j-api'
}
F. 按下右上角"try sync"將設定值設給全專案.
4. 加入Android 權限(AndroidManifest.xml)
A. 加入<uses-permission android:name="android.permission.INTERNET" />
5. 撰寫程式碼:
A. 收起"res"後展開"java"及"com.rdwatchworld.devicetoiot"後點開"MainActivity"
B, 在onCreate Function中將之前佈置的Info_Text及Send_Button分別建立mInfo與mSend二件物件
C. 將mSend建立OnClickListener以對應button事件
D. 程式碼如下:
protected void onCreate(Bundle savedInstanceState) {B, 在onCreate Function中將之前佈置的Info_Text及Send_Button分別建立mInfo與mSend二件物件
C. 將mSend建立OnClickListener以對應button事件
D. 程式碼如下:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText mInfo = (EditText)findViewById(R.id.Info_Text);
Button mSend = (Button)findViewById(R.id.Send_Button);
mSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
E. 撰寫連線雲端需要的定義:
a. 連接字串: private final String connString = "HostName=IotWorkSuccess.azure-devices.net;DeviceId=android_device01;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
b. 連接Device ID: private final String deviceId = "andrid_device01";
c. 連線的protocol: private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
d. 定義雲端Device Client端物件: private static DeviceClient client;
F. 建立一個Thread來無限發送Message(隨機產生的溫度溼度值)至IoT Hub:
private static class MessageSender implements Runnable {
public void run() {
try {
// Initialize the simulated telemetry.
double minTemperature = 20; //最小的溫度值
double minHumidity = 60; //最大的溼度值
Random rand = new Random(); //建立一個隨機產生的值的rand物件
while (true) { //無限迴圈
// Simulate telemetry.
double currentTemperature = minTemperature + rand.nextDouble() * 15;
double currentHumidity = minHumidity + rand.nextDouble() * 20;
TelemetryDataPoint telemetryDataPoint = new TelemetryDataPoint();
telemetryDataPoint.temperature = currentTemperature;//產生的隨機溫度
telemetryDataPoint.humidity = currentHumidity; //產生的隨機溼度
// Add the telemetry to the message body as JSON.
String msgStr = telemetryDataPoint.serialize();
Message msg = new Message(msgStr); //Message是com.microsoft.azure.sdk.iot.device內的Message物件
// Add a custom application property to the message.
// An IoT hub can filter on these properties without access to the message body.
msg.setProperty("temperatureAlert", (currentTemperature > 30) ? "true" : "false"); //超過30度就列為警示
System.out.println("Sending message: " + msgStr);
// Send the message.
EventCallback callback = new EventCallback();
client.sendEventAsync(msg, callback, 1);//將msg送至雲端, response 到EvenCallback
mInfo.setText("Temperature = "+ currentTemperature + " Humidity = " + currentHumidity + "\n");將溫度及溼度秀在Edit Text中
Thread.sleep(5000);//停5秒再繼續}} catch (InterruptedException e) {System.out.println("Finished.");}
}
}
G. 建立EventCallback來收取傳送Message後雲端傳回來的事件
private static class EventCallback implements IotHubEventCallback {
public void execute(IotHubStatusCode status, Object context) {
System.out.println("IoT Hub responded to message with status: " + status.name());
if (context != null) {
synchronized (context) {
context.notify();
}
}
}
} H. 在Button 的onClick事件中建立Thread來發送Message到雲端
public void onClick(View view) {
MessageSender sender = new MessageSender(); //步驟F所建立的MessageSender Thread
executor = Executors.newFixedThreadPool(1);
executor.execute(sender);//執行MessageSender Thread
}
I. 離開時記得釋出物件:
public void onDestroy() {
super.onDestroy();
try {
executor.shutdownNow();//Thread停止
client.closeNow();//關閉雲端連線
} catch (IOException e) {
e.printStackTrace();
}
}
J. 驗證雲端是否收到Message:
- 建立雲端儲存體來存放message
- 在搜尋列輸入"儲存體帳戶", 進入儲存體帳戶頁面
- 按下"新增"進入建立儲存體帳戶頁面
- 在"資源群組"選擇之前建立的"WorkSuccessRG"
- 在"儲存體帳戶名稱"輸入"storageworksuccess"(只能小寫)
- 在"位置"選擇"東南亞"(跟 WorkSuccessRG同一區會比較好)
- 其餘設定保持預設不變按下"檢閱+建立" 後再按下"建立"等待完成
- 開啟cloud shell來下command, 如開啟時需選擇一儲存體請選擇"storageworksuccess"
- 在command下輸入az iot hub monitor-events --hub-name IotWorkSuccess --device-id android_device01按下enter即可看到傳來的Message










沒有留言:
張貼留言
歡迎各方朋友針對本文議題討論~