This commit is contained in:
ctlove0523 2021-08-20 22:00:53 +08:00
parent a61838bdb7
commit c39d21b67a
5 changed files with 184 additions and 0 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@
*.dll
*.so
*.dylib
*.idea
# Test binary, built with `go test -c`
*.test

View File

@ -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

126
http_device.go Normal file
View File

@ -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
}

View File

@ -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")
}

View File

@ -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"`
}