物聯網時代 跟着Thingsboard學IOT架構-CoAP設備協議


thingsboard官網: https://thingsboard.io/html

thingsboard GitHub: https://github.com/thingsboard/thingsboardjava

thingsboard提供的體驗地址: http://demo.thingsboard.io/node

 

BY Thingsboard teamgit

如下內容是在原文基礎上演繹的譯文。除非另行註明,頁面上全部內容採用知識共享-署名(CC BY 2.5 AU)協議共享。github

原文地址: ThingsBoard API參考:CoAP設備APIweb


 

CoAP

協議介紹

CoAP是一種在物聯網世界的類web協議,它的詳細規範定義在RFC 7252。COAP名字翻譯來就是「受限應用協議」,顧名思義,使用在資源受限的物聯網設備上。物聯網設備的ram,rom都一般很是小,運行TCP和HTTP是不能夠接受的。npm

 

協議特色

  1. CoAP協議網絡傳輸層由TCP改成UDP。api

  2. 它基於REST,server的資源地址和互聯網同樣也有相似url的格式,客戶端一樣有POST,GET,PUT,DELETE方法來訪問server,對HTTP作了簡化。安全

  3. COAP是二進制格式的,HTTP是文本格式的,COAP比HTTP更加緊湊。服務器

  4. 輕量化,COAP最小長度僅僅4B,一個HTTP的頭都幾十個B了。

  5. 支持可靠傳輸,數據重傳,塊傳輸。 確保數據可靠到達。

  6. 支持IP多播, 便可以同時向多個設備發送請求。

  7. 非長鏈接通訊,適用於低功耗物聯網場景。

客戶端庫設置

安裝

安裝node.js,而後執行如下命令:

 npm install coap-cli -g

 

用法

 Usage: coap [command] [options] url
 ​
 ​
   Commands:
 ​
     get      performs a GET request
     put      performs a PUT request
     post     performs a POST request
     delete   performs a DELETE request
 ​
   Options:
 ​
     -h, --help                    output usage information
     -V, --version                 output the version number
     -o, --observe                 Observe the given resource
     -n, --no-new-line             No new line at the end of the stream
     -p, --payload <payload>       The payload for POST and PUT requests
     -b, --block2 <option>         set the block2 size option
     -q, --quiet                   Do not print status codes of received packets
     -c, --non-confirmable         non-confirmable
     -t, --timeout <seconds>       The maximum send time in seconds
     -T, --show-timing             Print request time, handy for simple performance tests
     -O, --coap-option <key,value> Add COAP-Option to the request (repeatable)

 

PUT和POST

PUT和POST請求以下例所示

 echo -n 'hello world' | coap post coap://localhost/message

 


 

Thingsboard的CoAP傳輸協議架構

由於Thingsboard最新release,是基於微服務架構,不利用單獨理解代碼。

Thingsboard CoAP設備傳輸協議源代碼:https://github.com/thingsboard/thingsboard/tree/release-2.0/transport/coap

本文基於上面源代碼後,剔除相關的安全驗證和處理以後搭建簡易的講解項目:

https://github.com/sanshengshui/IOT-Technical-Guide/tree/master/IOT-Guide-Coap

 


CoAP框架

Thingsboard的CoAP設備傳輸協議是基於Californium。Californium 是一款基於Java實現的Coap技術框架,該項目實現了Coap協議的各類請求響應定義,支持CON/NON不一樣的可靠性傳輸模式。 Californium 基於分層設計且高度可擴展,其內部模塊設計及接口定義存在許多學習之處;

值得一提的是,在同類型的 Coap技術實現中,Californium的性能表現是比較突出的,以下圖:

更多的數據能夠參考Californium-可擴展雲服務白皮書 本文以框架的源碼分析爲主,其餘內容不作展開。

 

項目結構

 .
 └── main
     └── java
         ├── com
         │   └── sanshengshui
         │       └── coap
         │           ├── adaptors
         │           │   └── JsonCoapAdaptor.java
         │           ├── CoapTransportResource.java
         │           ├── common
         │           │   └── FeatureType.java
         │           └── session
         │               └── SessionMsgType.java
         └── IOTCoapServer.java
 

 

 

代碼講解

IOTCoapServer

 1  public class IOTCoapServer {
 2  3      private static final String V1 = "v1";
 4      private static final String API = "api";
 5  6  7      private static String host = "127.0.0.1";
 8      private static Integer port = 5683;
 9      private static long timeout = 10000;
10 11      public static void main(String[] args) throws UnknownHostException {
12          CoapServer coapServer = new CoapServer();
13          CoapResource api = new CoapResource(API);
14          api.add(new CoapTransportResource(V1,timeout));
15          coapServer.add(api);
16          InetAddress addr = InetAddress.getByName(host);
17          InetSocketAddress sockAddr = new InetSocketAddress(addr, port);
18          coapServer.addEndpoint(new CoapEndpoint(sockAddr));
19          coapServer.start();
20 21      }
22 23  }

 

  • 第12行代碼: CoapServer用做建立服務端。

  • 第12-15行: CoapResourceresource的基本實現,擴展這個類來編寫您本身的資源。經過向資源添加「v1」、"api"和超時時間的設置,則coap的基礎url爲:coap://localhost:port/api/v1/

  • 第16-18行: Endpoint負責與網絡進行通訊, 若是沒有一個Endpoint與CoapServer進行綁定,那就建立一個默認的Endpoint,默認就是ucp實現傳輸層。

  • 第19行,啓動CoAP服務。

 

如下圖片展現服務端的基礎架構:


 

CoapTransportResource

此類負責處理請求

GET
 
 @Override
     public void handleGET(CoapExchange exchange) {
         Optional<FeatureType> featureType = getFeatureType(exchange.advanced().getRequest());
         if (!featureType.isPresent()) {
         } else if (featureType.get() == FeatureType.TELEMETRY) {
             exchange.respond(CoAP.ResponseCode.BAD_REQUEST);
         }  else if (featureType.get() == FeatureType.ATTRIBUTES) {
             processRequest(exchange, SessionMsgType.GET_ATTRIBUTES_REQUEST);
         } else {
             exchange.respond(CoAP.ResponseCode.BAD_REQUEST);
         }
     }

 

  • 若是咱們客戶端發起的是GET請求,那麼將會進入到handleGET(CoapExchange exchange)方法。

  • getFeatureType(Request request)判斷coap協議長度是否大於3。當大於等於3,獲取/api/v1/${param}param元素。

 public static final int FEATURE_TYPE_POSITION = 3;
 ​
 private Optional<FeatureType> getFeatureType(Request request) {
         List<String> uriPath = request.getOptions().getUriPath();
         try {
             if (uriPath.size() >= FEATURE_TYPE_POSITION) {
                 return Optional.of(FeatureType.valueOf(uriPath.get(FEATURE_TYPE_POSITION - 1).toUpperCase()));
             }
         } catch (RuntimeException e) {
         }
         return Optional.empty();
     }

 

  • 經過判斷param是不是temperature仍是attributes進行相關的邏輯操做。

  • 當不是上述類型,回覆狀態爲BAD_REQUEST的狀態碼。

 

POST
 
@Override
     public void handlePOST(CoapExchange exchange) {
         Optional<FeatureType> featureType = getFeatureType(exchange.advanced().getRequest());
         if (!featureType.isPresent()) {
             exchange.respond(CoAP.ResponseCode.BAD_REQUEST);
         } else {
             switch (featureType.get()) {
                 case ATTRIBUTES:
                     processRequest(exchange, SessionMsgType.POST_ATTRIBUTES_REQUEST);
                     break;
                 case TELEMETRY:
                     processRequest(exchange, SessionMsgType.POST_TELEMETRY_REQUEST);
                     break;
             }
         }
     }

 

  • 若是咱們客戶端發起的是POST請求,那麼將會進入到handlePOST(CoapExchange exchange)方法。

  • 對獲取的uri的類型是temperature仍是attributes來作相關的邏輯操做。

 

邏輯處理
 
private void processRequest(CoapExchange exchange, SessionMsgType type) {
         exchange.accept();
         Exchange advanced = exchange.advanced();
         Request request = advanced.getRequest();
 ​
         try {
             switch (type) {
                 case GET_ATTRIBUTES_REQUEST:
                 case POST_TELEMETRY_REQUEST:
                 case POST_ATTRIBUTES_REQUEST:
                     //這個類在以前的物模型博文中有所講解,你們能夠翻看!
                     JsonCoapAdaptor.convertToMsg(type,request);
                     break;
                 default:
                     throw new IllegalArgumentException("Unsupported msg type: " + type);
             }
             exchange.respond("Data has been received");
         } catch (AdaptorException e){
             exchange.respond(CoAP.ResponseCode.BAD_REQUEST, e.getMessage());
         } catch (IllegalArgumentException  e) {
             exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR, e.getMessage());
         }
     }

 


 

項目演示

遙測上傳API

要將遙測數據發佈到服務器節點,請將POST請求發送到如下URL:

 
coap://host/api/v1/telemetry

 

最簡單的支持數據格式是:

 
{"key1":"value1", "key2":"value2"}

 

要麼

 
[{"key1":"value1"}, {"key2":"value2"}]

 

請注意,在這種狀況下,服務器端時間戳將分配給上傳的數據!

若是您的設備可以獲取客戶端時間戳,您可使用如下格式:

 {"ts":1451649600512, "values":{"key1":"value1", "key2":"value2"}}

 

在上面的示例中,咱們假設「1451649600512」是具備毫秒精度的unix時間戳。例如,值'1451649600512'對應於'Fri,2016年1月1日12:00:00.512 GMT'

例子:

 echo -n '{"size":21,"type":"device"}' | coap post coap://demo.thingsboard.io/api/v1/telemetry

 

結果:
 key= 1564105084015
 屬性名=size 屬性值=21
 屬性名=type 屬性值=device

 

屬性API

屬性API容許設備

  • 將客戶端設備屬性上載到服務器。

  • 從服務器請求客戶端和共享設備屬性。

將屬性更新發布到服務器

要將客戶端設備屬性發布到ThingsBoard服務器節點,請將POST請求發送到如下URL:

 coap://host/api/v1/attributes

 

例子:

 echo -n '{"size":21,"type":"device","status":true}' | coap post coap://localhost:5683/api/v1/attributes

結果:

 
key= 1564105158573
 屬性名=size 屬性值=21
 屬性名=type 屬性值=device
 屬性名=status 屬性值=true
 
從服務器請求屬性值

要向ThingsBoard服務器節點請求客戶端或共享設備屬性,請將GET請求發送到如下URL:

 
coap://host/api/v1/attributes?clientKeys=attribute1,attribute2&sharedKeys=shared1,shared2

 

例子:

 coap get coap://localhost:5683/api/v1/attributes?clientKeys=attribute1,attribute2&sharedKeys=shared1,shared2

 

結果:

 (2.05)  Data has been received

 

到此,物聯網時代,相信你們對IOT架構下的CoAP協議有所瞭解了,感謝你們的閱讀!

相關文章
相關標籤/搜索