This commit is contained in:
parent
a61838bdb7
commit
c39d21b67a
|
@ -4,6 +4,7 @@
|
|||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
*.idea
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
|
16
README.md
16
README.md
|
@ -605,6 +605,22 @@ device.ReportDeviceInfo("1.0", "2.0")
|
|||
|
||||
设备可以调用`ReportLogs(logs []DeviceLogEntry) bool` 函数主动上报日志。
|
||||
|
||||
### HTTP协议上报消息和属性
|
||||
|
||||
华为云IoT物联网平台支持使用HTTP协议上报消息和属性(该功能目前处于α阶段,尚未对外开放,具体开放时间参考华为云IoT物联网平台公告)。使用HTTP协议上报消息和属性非常简单方便,SDK对接口进行了封装,接口使用的对象和MQTT协议一致。使用HTTP协议的设备接口定义如下:
|
||||
|
||||
~~~go
|
||||
type HttpDevice interface {
|
||||
SendMessage(message Message) bool
|
||||
ReportProperties(properties DeviceProperties) bool
|
||||
}
|
||||
~~~
|
||||
|
||||
使用样例参考:http_device_samples.go
|
||||
|
||||
~~~
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
## 报告bugs
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
package iot
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 使用HTTP协议的设备,当前使用HTTP协议的设备只支持上报消息和上报属性
|
||||
type HttpDevice interface {
|
||||
|
||||
// 上报消息
|
||||
SendMessage(message Message) bool
|
||||
|
||||
// 上报属性
|
||||
ReportProperties(properties DeviceProperties) bool
|
||||
}
|
||||
|
||||
type restyHttpDevice struct {
|
||||
Id string
|
||||
Password string
|
||||
Servers string
|
||||
client *resty.Client
|
||||
|
||||
lock sync.RWMutex
|
||||
accessToken string
|
||||
}
|
||||
|
||||
func (device *restyHttpDevice) SendMessage(message Message) bool {
|
||||
resp, err := device.client.R().
|
||||
SetBody(message).
|
||||
Post(fmt.Sprintf("%s/v5/devices/%s/sys/messages/up", device.Servers, device.Id))
|
||||
if err != nil {
|
||||
fmt.Printf("send message failed %s\n", err)
|
||||
}
|
||||
return err == nil && resp.StatusCode() == http.StatusOK
|
||||
}
|
||||
|
||||
func (device *restyHttpDevice) ReportProperties(properties DeviceProperties) bool {
|
||||
response, err := device.client.R().
|
||||
SetBody(properties).
|
||||
Post(fmt.Sprintf("%s/v5/devices/%s/sys/properties/report", device.Servers, device.Id))
|
||||
if err != nil {
|
||||
fmt.Printf("report properties failed %s\n", err)
|
||||
}
|
||||
return err == nil && response.StatusCode() == http.StatusOK
|
||||
}
|
||||
|
||||
func (device *restyHttpDevice) init() {
|
||||
accessTokenBody := accessTokenRequest{
|
||||
DeviceId: device.Id,
|
||||
SignType: 0,
|
||||
Timestamp: "2019120219",
|
||||
Password: hmacSha256(device.Password, "2019120219"),
|
||||
}
|
||||
|
||||
response, err := device.client.R().
|
||||
SetBody(accessTokenBody).
|
||||
Post(fmt.Sprintf("%s%s", device.Servers, "/v5/device-auth"))
|
||||
if err != nil {
|
||||
fmt.Printf("get device access token failed %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
tokenResponse := &accessTokenResponse{}
|
||||
err = json.Unmarshal(response.Body(), tokenResponse)
|
||||
if err != nil {
|
||||
fmt.Println("json unmarshal failed")
|
||||
return
|
||||
}
|
||||
|
||||
device.lock.Lock()
|
||||
device.accessToken = tokenResponse.AccessToken
|
||||
device.lock.Unlock()
|
||||
}
|
||||
|
||||
type accessTokenResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
}
|
||||
|
||||
type accessTokenRequest struct {
|
||||
DeviceId string `json:"device_id"`
|
||||
SignType int `json:"sign_type"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
func CreateHttpDevice(id, password, server string) HttpDevice {
|
||||
c := resty.New()
|
||||
c.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
|
||||
c.SetTimeout(30 * time.Second)
|
||||
c.SetRetryCount(3)
|
||||
c.SetRetryWaitTime(10 * time.Second)
|
||||
c.AddRetryCondition(func(response *resty.Response, err error) bool {
|
||||
return response.StatusCode() == http.StatusForbidden
|
||||
})
|
||||
|
||||
device := &restyHttpDevice{
|
||||
Id: id,
|
||||
Password: password,
|
||||
Servers: server,
|
||||
client: c,
|
||||
lock: sync.RWMutex{},
|
||||
}
|
||||
|
||||
device.init()
|
||||
device.client.OnBeforeRequest(func(client *resty.Client, request *resty.Request) error {
|
||||
device.lock.RLock()
|
||||
request.SetHeader("access_token", device.accessToken)
|
||||
device.lock.RUnlock()
|
||||
request.SetHeader("Content-Type", "application/json")
|
||||
return nil
|
||||
})
|
||||
device.client.OnAfterResponse(func(client *resty.Client, response *resty.Response) error {
|
||||
if response.StatusCode() == http.StatusForbidden {
|
||||
device.init()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return device
|
||||
}
|
|
@ -17,3 +17,8 @@ func CreateDevice() iot.Device {
|
|||
|
||||
return device
|
||||
}
|
||||
|
||||
func CreateHttpDevice() iot.HttpDevice{
|
||||
return iot.CreateHttpDevice(deviceId, devicePassword, "https://iot-mqtts.cn-north-4.myhuaweicloud.com:443")
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
iot "github.com/ctlove0523/huaweicloud-iot-device-sdk-go"
|
||||
"github.com/ctlove0523/huaweicloud-iot-device-sdk-go/samples"
|
||||
)
|
||||
|
||||
func main() {
|
||||
httpDevice := samples.CreateHttpDevice()
|
||||
|
||||
s := SelfHttpResponse{
|
||||
HttpCode: 404,
|
||||
HttpMessage: "test http device",
|
||||
ReportTime: iot.GetEventTimeStamp(),
|
||||
}
|
||||
entry := iot.DevicePropertyEntry{
|
||||
ServiceId: "http_api",
|
||||
Properties: s,
|
||||
EventTime: iot.GetEventTimeStamp(),
|
||||
}
|
||||
|
||||
var entries []iot.DevicePropertyEntry
|
||||
entries = append(entries, entry)
|
||||
properties := iot.DeviceProperties{
|
||||
Services: entries,
|
||||
}
|
||||
|
||||
fmt.Println(httpDevice.ReportProperties(properties))
|
||||
}
|
||||
|
||||
type SelfHttpResponse struct {
|
||||
HttpCode int `json:"http_code"`
|
||||
HttpMessage string `json:"http_message"`
|
||||
ReportTime string `json:"report_time"`
|
||||
}
|
Loading…
Reference in New Issue