thingsboard官網: https://thingsboard.io/
thingsboard GitHub: https://github.com/thingsboard/thingsboard
thingsboard提供的體驗地址: http://demo.thingsboard.io/
BY Thingsboard team
以下內容是在原文基礎上演繹的譯文。除非另行註明,頁面上所有內容採用知識共享-署名(CC BY 2.5 AU)協議共享。
原文地址: ThingsBoard API參考:CoAP裝置API
CoAP
協議介紹
CoAP是一種在物聯網世界的類web協議,它的詳細規範定義在RFC 7252
協議特點
-
CoAP協議網路傳輸層由TCP改為UDP。
-
它基於REST,server的資源地址和網際網路一樣也有類似url的格式,客戶端同樣有POST,GET,PUT,DELETE方法來訪問server,對HTTP做了簡化。
-
COAP是二進位制格式的,HTTP是文字格式的,COAP比HTTP更加緊湊。
-
輕量化,COAP最小長度僅僅4B,一個HTTP的頭都幾十個B了。
-
支援可靠傳輸,資料重傳,塊傳輸。 確保資料可靠到達。
-
支援IP多播, 即可以同時向多個裝置傳送請求。
-
非長連線通訊,適用於低功耗物聯網場景。
客戶端庫設定
安裝
安裝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行:
CoapResource
是resource
的基本實現,擴充套件這個類來編寫您自己的資源。通過向資源新增“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