2018年8月6日 星期一

當 ESP8266 遇上中華電信 IoT 智慧聯網大平台 { 入門 - 01 } - 如何使用 ESP8266 利用 AT 指令取回中華電信 IoT 智慧聯網大平台上的設備感測器數據

網頁最後修改時間:2018/08/06

前段時間找資料的時候,無意間找到中華電信 IoT 智慧聯網大平台 (下面簡稱為 CHT IoT SP ),當時倒是沒很用心深入的去看裡面的內容,只知道大致上跟 ThingSpeak 類似 (部落格上面很多應用的網頁),不想太多且又是中華電信的會員的條件之下,就馬上申請了一個使用帳號。

這幾天發表了兩篇關於 ESP8266 AT 指令下透傳通訊的網頁 ( [1], [2] ) 的同時,就想著接下來怎麼讓它實際用到物聯網上去。ThingSpeak 相關應用的網頁在部落格上太多了,所以既然台灣自己有物聯網平台,怎能捨近求遠呢?那就決定是 "你" 了!

入門系列最終的目的很簡單:設定與取回 CHT IoT SP 上的資料。而這一篇將先簡單介紹 CHT IoT SP 的帳號申請、範例專案建立以及使用 ESP8266 AT 指令取回裝置感測器數據。

或許有人會說「AT 指令?老套了!我都直接用 Arduino IDE 開發」,不可諱言地,我也是!

「既然是這樣,為什麼還要用它呢 ?」因為這是最快速能夠直接驗證與 CHT IoT SP 通訊格式正確性的方式,能得到最完整的 HTTP 的回覆;直接用 Arduino IDE 去撰寫的話,無疑就像是瞎子摸象,即便 CHT IoT SP 網站 API 文件說 "象" 是 "象",出錯時難道不懷疑 "象" 不是 "象" 嗎 ?

使用 AT 指令驗證 WiFi 通訊的好處就是能馬上做修改,不管是指令還是傳輸資料;尤其是像這種交互式的,馬上就能知道資料格式對不對,而且也能馬上做修改馬上得到驗證,非常方便!想像一下,若上述的東西直接用寫程式來做,這部份要搞多久才能真正上傳與取回一組數據回來 ? 所以,AT 指令還老套嗎 ?

中華電信 IoT 大平台帳號申請與專案建立介紹:

中華電信 IoT 智慧聯網大平台網址
 CHT IoT SP / 服務說明 / 如何開始

這部分說是介紹,就不深入說明怎麼做, CHT IoT SP 網站裡面有申請的說明網頁和 PDF 文件(都是中文的),所以這裡只做引導的動作,將 CHT IoT SP 裡相關網頁與資料依順序整理出來,讓帳號申請方便一些!

要使用 CHT IoT SP 第一個步驟就是成為該平台會員。最方便的方法是進入到中華電信的會員中心網頁去註冊。

進入該網頁之後,按下 "註冊" 進入下一個加入會員的網頁;輸入手機號碼 圖形驗證碼,按下 "發送簡訊驗證碼" ,等待一下子手機就會收到簡訊。簡訊裡面會有驗證碼,將其輸入到 簡訊認證碼 欄位中,勾選下面 會員條款,最後按下 "確認資料正確,送出",就會跳到接下去的畫面 (不過後面我就沒畫面了,應該是郵箱與密碼之類的資料輸入) 完成就能註冊成功。
中華電信會員中心 - 加入會員網頁
完成會員註冊之後,回到 CHT IoT SP 網頁,點擊右上角的 "登入" 按鈕進入到會員登入網頁。在會員登入頁輸入剛剛用手機號碼註冊的帳號密碼,按下下方"登入" 按鈕,成功就能進入 CHT IoT SP 專案管理頁面。
CHT IoT SP 會員登入
下圖是 CHT IoT SP 專案建立的架構圖,依 CHT IoT SP 網頁原文的解釋:
五階層式架構
裝置管理為五階層式的結構,由上到下分別為 (1)帳號、(2)專案、(3)裝置、(4)感測器、(5)資料,且彼此之間的主從關係為一對多,即同一個帳號底下可擁有多個專案,一個專案之下可以擁有多個裝置,且一個裝置上又可能裝載多種感測器,而需特別注意的是,一個感測器只能選擇單一種類的資料型式,即儲存數據(Rawdata)或是圖像(Snapshot)

CHT IoT SP 專案管理架構, source: https://iot.cht.com.tw/iot/developer/dmp
依照這樣的架構,專案建立的流程就不難理解。

第一次進入到 CHT IoT SP 專案管理頁面是沒有任何東西的,但是我已經事先先建立了一個做測試,所以我以這個專案來做說明:
  • 專案名稱:ESP8266 中華電信物聯網平台連線測試專案
按下 "+建立專案"專案管理 / 基本資料頁面下 (紅色框是必填)
CHT IoT SP 專案管理 / 基本資料
切換到專案管理 / 權限資料頁面;在這頁面用戶可以自由建立三種存取此專案權限的 ApiKey ( 就是之後協定裏面會用到的 $({PROJECT_KEY} )。其中,第一個 ApiKey 是建立專案的時候就有,是管理者權限;第二個是我額外新增,下面測試時會用的唯獨 (read_only) 的 ApiKey

這些 ApiKey 很重要,尤其是 admin 的權限!用戶可根據 ApiKey 所賦予的權限對專案做不同程度的控制與存取,因此不要隨便將它給出去!

完成之後按下 "儲存" 就完成專案的建立。
CHT IoT SP 專案管理 / 權限資料
建立完成的專案,會以資料夾的圖示,出現在專案管理的頁面下。接著,就可以建立與設置專案所使用的設備以及設備裡所用到的感測器。

將滑鼠移至資料夾名稱上,名稱下方會出現底線 (這是一個連結),按下滑鼠右鍵,就會進入到另一個叫設備管理的頁面裡
CHT IoT SP 專案管理 - 專案建立完成
第一次進入設備管理的頁面下,也是完全沒有東西的,但因為撰寫網頁前已經做過測試的關係,已經事先建立好一組。

專案裝置的設想是這樣的:從 CHT IoT SP 上傳和取回 SHT31 的溫度與濕度;要達到這個目的,裝置可以使用 Arduino UNO + ESP8266 (WiFi) 二合一開發板,然後在該裝置下建立兩個感測器元件,分別代表 SHT31 的溫度值與濕度值 (一個感測器代表一個數值,所以 SHT31 要建立兩個感測器元件)。

按下 "增加設備" ,設備管理 / 基本頁面內,紅色框是必填;設備名稱,輸入一個容易了解的名字,是一個好的選擇;設備描述,可填可不填;設備類型有三種可以選擇 (通用設備 (general) / Modbus 工業設備 (modbus) / UDP (udp) ),後面兩個適用於其他地方,這裡用不到!所以選擇通用設備,之後再開啟時,該欄位會顯示 general 且不能再做修改;精度緯度是可代表設備所處的地點;URI 可不填,系統會自動產生一個給你(妳);設備金鑰 ( ${DEVICE_KEY} )是自動產生的,控制與存取設備和感測器用,不能修改。其他頁面現在不需要再做新增與修改,直接按 "下一頁""儲存" 就完成設備增加的動作。
CHT IoT SP 設備管理 / 基本資料
完成設備新增後,新加入的設備就會出現在列表裡;其中,設備編號 ( ${device_id} ) 是自動產生的,而這個編號代表的就是二合一開發板設備,控制與存取設備和感測器都需要它。

接著,按下 "增加感測器" 按鈕,準備建立兩組感測器。
CHT IoT SP 設備管理 - 設備建立完成,準備增加感測器
不像 ThingSpeak 網站上的 Channel 可以同時設定多個 Field;在 CHT IoT SP 每個感測器就代表一個 ThingSpeak Channel 下面的一個 Filed,因此處理 SHT31 就需要兩個感測器元件。

因為兩個感測器欄位名稱都相同,故一起說明;紅色框必填。識別標號 (ID) ( ${sensor_id} ) 作為控制與存取感測器資料用,所以要唯一且容易記;顯示名稱可設與識別編號一樣,這樣在使用的時候可以不必再點選感測器看識別編號;描述只顯示在基本資料頁面裡面,外面設備管理網頁列表也看不到,不填也沒關係;類型決定存取的方式,這裡選數值即可;單位強烈建議填寫,才不會微秒跟秒搞不清楚。

其他頁面現在不需要再做新增與修改,直接按 "下一頁" 和 "儲存" 就完成加入感測器的動作。
CHT IoT SP 感測器管理 / 基本資料 - 建立 SHT31 溫度項
CHT IoT SP 感測器管理 / 基本資料 - 建立 SHT31 濕度項
到這裡基本上就完成專案的設定,不過此時感測器還未有任何的數值。為了方便接下來的測試,點擊感測器左上角的圖示,手動輸入數據給感測器
CHT IoT SP 感測器管理 - 新建感測器 (沒有數據)
  • SHT31 Temperature 手動輸入 33.6
CHT IoT SP 感測器管理 - SHT31 Temperature 數據手動輸入
  • SHT31 Humidity 手動輸入 70
CHT IoT SP 感測器管理 - SHT31 Humidity 數據手動輸入
感測器手動數值輸入,完成後如下圖所示。
CHT IoT SP 感測器管理 - 新建感測器 (已手動輸入數據)
到此完成 CHT IoT SP 帳號的申請以及第一個專案的設置。

RESTRful API (HTTP Get) 取回資料:

CHT IoT SP 支援三種傳輸協定: (1)RESTful、(2) MQTT、(3) WebSocket;控制或是存取其中的專案、設備和感測器時,在通訊溝通上都是以 HTTP 作為網路傳輸的基礎。
CHT IoT SP 依三大協定而分類API,source: https://iot.cht.com.tw/iot/developer/api
在 CHT IoT SP / 服務說明 / 如何開始 網頁裡面,有展示怎麼使用 Postman ( RESTful API )、MQTTLens ( MQTT API ) 和 Simple WebSocket ( WebSocket API) 這些軟體上傳與取回數據的方法 (API 的使用與說明可看 CHT IoT SP / API 文件 網頁裡各小節的說明),每一個 API 協定都以 HTTP 作為網路傳輸的基礎,協定的功能動作在網頁上寫的也很詳細,還蠻容易理解的。

接下來可以想想,若要用 MCU 要怎麼做?

首先第一部分,想辦法取回  CHT IoT SP  設備的感測器資料;再來,取回的資料哪裡才是感測器資料,要怎麼分析 ?

要解決這個問題,需要到 CHT IoT SP / API 文件 / 核心服務 - 感測資料 網頁裡尋找所需功能的說明。

以剛剛所建立的專案來說,就是查詢單一感測器的數據以及一次查詢設備所有感測器的數據 (這裡限定感興趣的數據是最後一筆);查詢網頁上的說明可以找到兩個 RESTful API 可以用,協定名稱 ( Protocol Name ) 分別是:
  • 讀取設備所有感測器最新一筆感測資料 (RESTful API, HTTP GET)
    https://iot.cht.com.tw/iot/v1/device/${device_id}/rawdata
讀取設備所有感測器最新一筆感測資料 (RESTful API, HTTP GET)
  • 讀取最新一筆感測資料 (RESTful API, HTTP GET)
    https://iot.cht.com.tw/iot/v1/device/${device_id}/sensor/${sensor_id}/rawdata
讀取最新一筆感測資料 (RESTful API, HTTP GET)
在 CHT IoT SP / 服務說明 / 如何開始 網頁裡,已說明了如何使用 Postman 來取回感測器的資料,而且在 API 文件中也清楚的交代說明了 HTTP Request 和 Response 的格式,有了這些資料作參考就可以實際照著再測試一次,並且比較待會兒用 ESP8266 做的結果。

還記得剛剛所建立的專案,設備 (二合一開發板) 有兩個感測器已分別給予了數值。下面將以此為例一次 "讀取設備所有感測器最新一筆感測資料"
  • URI:https://iot.cht.com.tw/iot/v1/device/${device_id}/rawdata
  • headers:CK: ${PROJECT_KEY} 或 CK: ${DEVICE_KEY}
其中,專案建立的同時,額外多建立了一個 read-only 的 ApiKey,這個就是代表唯讀的 ${PROJECT_KEY};${device)id} 在前面小節可以找到。
read_only ${PROJECT_KEY} 在哪裡 ?
開啟 Postman (網頁用的是舊版本的,現在 chrome 上面的軟體是新版本的,使用方式一樣,不同之處會特別說明);照著下圖數字 1 ~ 6 輸入與選擇,然後點擊 B "Preview"
Postman 操作 - 01
下面紅框看到是 API 文件中 Request 格式範例 裡的 headers: 部分,雖然比較之下少了 User-Agent:,但裡面的那幾個是不可或缺的部分。

關於 HTTP 1.1: Request 的詳細格式說明,請自行點連結。
Postman 操作 - 02B - 01
新版本的 Postman (就是 CHT IoT SP / 服務說明 / 如何開始 網頁裡用的),要點擊右方橘色字 "Code" 才會出現傳送出去的 HTTP Request headers 的資料;對照之後應該不難發現,三者內容都不相同,但是都產生相同結果。所以只要保留不可或缺的 headers 部分就能用。
Postman 操作 - 02B - 02
所以若是按下 A "Send" 就是傳送上面的資料出去,然後就會收到回應的資料。對照 API 文件上的 Response 格式範例,回應分為 headers:body: 兩部分,這是同一時間一起收到的,只不過軟體把它個別區分開而已,對於終端用戶來說,body: 裡面的資料才是他們要的。
Postman 操作 - 02A
如果仔細翻閱過 CHT IoT SP / API 文件 網頁裡各小節裡的各個協定,不難發現!上面所使用的資料都是採用 JSON 格式來發送或是接收;所以建議繼續之前,先花一些時間去了解 JSON 的形成以及格式,會很有幫助!這部分就留待用戶自己去學習,不再贅述!

能藉由軟體快速的了解 CHT IoT SP 各 API 協定實際的運作是一件很好的事,但實際上的使用卻不是直接由 "人" 操作來完成的,而是設備 (微控制器;μC;MCU) 裡面的程式(或韌體)!

設備的思維是很純粹的,上面所看到的東西是不能直接拿來用的,因為它是經過包裝過的,只有反璞歸真過的數據設備才能處理。

/*--*//**---/*///**---*-*////***--*/*///***----*///--*/*///**--*/*//**--**/*//
* ESP8266 連線 CHT IoT SP 取回數據:

接下來的部分已詳細說明在下面兩個網頁,如有問題請先自行爬文
  1. ESP8266 AT 指令下的透傳模式
  2. 如何使用 MCU 建立與其他 ESP8266 的 UDP 透傳通訊
要取回數據,先了解一下下面架構圖,接著準備好 ESP8266 (ESP-01S) 與 UART 通訊底板連接到電腦上 (其他的只要能接受 AT 指令的 ESP8266 無線模組都可以用)
ESP8266 (softap mode), TCP Client 透傳模式建立架構圖
*********************************************************************************
此處所用的材料可自行準備,或選用新版本的升級套件
更多 ESP8266 相關商品,請至分類賣場
*********************************************************************************

將上面的資訊填入到建立 ESP8266 的 TCP Client 透傳模式的 AT 指令集,完成的結果如下表所示。
AT 指令集 - ESP8266 (station mode), TCP Client 透傳模式
當使用上面的 AT 指令建立 TCP Client 的透傳通訊後,表示已和 CHT IoT SP 建立連線,正等待 ESP8266 接下來再輸入 HTTP Request 的部分即可;由於 RESTful API 協定 "讀取設備所有感測器最新一筆感測資料" body: 部分是空白的,所以只需要輸入 headers: 的部分。

RESTful API HTTP GET "讀取設備所有感測器最新一筆感測資料" Request 格式範例
headers:
GET /iot/v1/device/271734761/rawdata HTTP/1.1\r\n
CK: DKH5T40KG55AWAA9U4\r\n
User-Agent: Jakarta Commons-HttpClient/3.1\r\n
Host: iot.cht.com.tw\r\n
body:
""
當然,也可使用在 Postman 取回數據所輸出的 headers:,將其作為下一個輸出即可;但不管是直接複製上面或是 Postman 的 headers,將不會得到任何回覆,因為它不符合 HTTP/1.1:Request 的格式規定,缺少了一個換行!

上面所講述的部分,下面將以影片實際操作驗證,步驟會是:
  1. 建立 ESP8266 與 CHT IoT SP 的透傳通訊
  2. 從 Postman 和 CHT IoT SP / API 文件 / 核心服務 - 感測資料 複製 "讀取設備所有感測器最新一筆感測資料" 協定的 headers 部分輸入,但無法得到回覆的測試
  3. 和成功的輸入與取回兩個感測器最新一筆數據以及分別單獨取回單一感測器最新一筆數據測試,CHT IoT SP 回應是什麼樣子

從影片中可以看到,成功的 Request 輸出後會得到一長串來自 CHT IoT SP 的回傳字串。對照 CHT IoT SP / API 文件 / 核心服務 - 感測資料  "讀取設備所有感測器最新一筆感測資料" 協定的 Response 格式範例可以發現 (已列在下方),回傳的資料合成了 headers 和 body 這兩部分,中間以換行符號分隔兩個部分;不過深入仔細比較回傳的字串與 HTTP/1.1:Request 規格之後會看到,API 文件中的 Request 格式範例的 headers 部分依舊少了換行符號。

下面是實際的輸出擷取,若有不清楚之處,可以將下面直接轉換成 16 進制去看。
HTTP/1.1 200 
Server: nginx/1.13.12
Date: Sun, 05 Aug 2018 03:17:58 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 200
Connection: keep-alive
X-Application-Context: iotapi:production:80
Access-Control-Allow-Origin: *
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

[{"id":"SHT31_Temperature","deviceId":"6945661182","time":"2018-08-01T08:20:33.361Z","value":["33.6"]},{"id":"SHT31_Humidity","deviceId":"6945661182","time":"2018-08-01T08:20:34.526Z","value":["70"]}]

RESTful API HTTP GET "讀取設備所有感測器最新一筆感測資料" Response 格式範例:
headers:
HTTP/1.1 200 OK\r\n
Server: nginx/1.9.11\r\n
Date: Fri, 04 Aug 2017 10:47:10 GMT\r\n
Content-Type: application/json;charset=UTF-8\r\n
Content-Length: 203\r\n
Connection: keep-alive\r\n
Access-Control-Allow-Origin: *\r\n
body:
[{"id":"temperature","deviceId":"271734761","time":"2017-08-04T10:46:58","lat":24.95,"lon":121.16,"value":["26.9"]},{"id":"humidity","time":"2017-08-04T10:43:58","lat":24.95,"lon":121.16,"value":["33"]}]
結論:

雖然只是簡單的一個例子,但是相信聰明的各位一定能夠瞭解,並將其觸類旁通的用到其他的協定去,在此就不再繼續贅述了!

到此,就成功完成利用 AT 指令控制 ESP8266 取回中華電信 IoT 智慧聯網大平台上的設備感測器數據的目的。

接下來的一篇,將延續這裡所得到的結果,實際撰寫程式抓取回傳的字串,並拆解出 body 裡面的 JSON 字串以得出感測器的數據。


<< 部落格相關文章 >>

沒有留言:

張貼留言