Go to file
ctlove0523 062b25c9bd #15 support self define response 2022-04-16 22:37:58 +08:00
samples #15 support self define response 2022-04-16 22:37:58 +08:00
.gitignore #8 2021-08-20 22:00:53 +08:00
LICENSE Initial commit 2020-12-16 08:18:38 +08:00
README.md #12 支持设备发放服务 2022-02-11 20:47:39 +08:00
async.go #9 Http类型设备支持设置连接参数 2021-09-19 16:02:00 +08:00
async_device.go #15 support self define response 2022-04-16 22:37:58 +08:00
base_device.go #15 support self define response 2022-04-16 22:37:58 +08:00
base_device_test.go #15 support self define response 2022-04-16 22:37:58 +08:00
bootstrap.go #12 支持设备发放服务 2022-02-11 20:47:39 +08:00
device.go #15 support self define response 2022-04-16 22:37:58 +08:00
device_test.go #9 Http类型设备支持设置连接参数 2021-09-19 16:02:00 +08:00
gateway.go prepare for async 2021-03-30 08:49:40 +08:00
go.mod add dependency of resty 2021-03-12 14:35:46 +08:00
go.sum #3 2021-03-19 19:52:53 +08:00
http_client.go async client 2021-04-20 23:10:24 +08:00
http_device.go remove print secret 2021-12-31 22:47:30 +08:00
info.go 支持文件上传功能 2020-12-22 23:35:42 +08:00
info_test.go 更新版本信息 2022-01-23 08:25:36 +08:00
options.go #15 support self define response 2022-04-16 22:37:58 +08:00
sdk_info 更新版本信息 2022-01-23 08:25:36 +08:00
util.go #12 支持设备发放服务 2022-02-11 20:47:39 +08:00
util_test.go async client 2021-04-20 23:10:24 +08:00

README.md

huaweicloud-iot-device-sdk-go

huaweicloud-iot-device-sdk-go提供设备接入华为云IoT物联网平台的Go版本的SDK提供设备和平台之间通讯能力以及设备服务、网关服务、OTA等高级服务。IoT设备开发者使用SDK可以大大简化开发复杂度快速的接入平台。

支持如下功能:

版本说明

当前稳定版本v1.0.1

安装和构建

安装和构建的过程取决于你是使用go的 modules(推荐) 还是还是GOPATH

Modules

如果你使用 modules 只需要导入包"github.com/ctlove0523/huaweicloud-iot-device-sdk-go"即可使用。当你使用go build命令构建项目时依赖的包会自动被下载。注意使用go build命令构建时会自动下载最新版本最新版本还没有达到release的标准可能存在一些尚未修复的bug。如果想使用稳定的发布版本可以从release 获取最新稳定的版本号并在go.mod文件中指定版本号。

module example

go 1.15

require github.com/ctlove0523/huaweicloud-iot-device-sdk-go v0.0.1-alpha

GOPATH

如果你使用GOPATH下面的一条命令即可实现安装

go get github.com/ctlove0523/huaweicloud-iot-device-sdk-go

使用API

SDK提供了异步client下面所有的方法都有对应的异步方法。

设备连接鉴权

使用密钥鉴权

1、首先在华为云IoT平台创建一个设备设备的信息如下

设备ID5fdb75cccbfe2f02ce81d4bf_go-mqtt

设备密钥123456789

2、使用SDK创建一个Device对象并初始化Device。

import (
	"fmt"
	"github.com/ctlove0523/huaweicloud-iot-device-sdk-go"
	"time"
)

func main() {
	// 创建一个设备并初始化
	device := iot.CreateIotDevice("5fdb75cccbfe2f02ce81d4bf_go-mqtt", "123456789", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
	device.Init()
	if device.IsConnected() {
		fmt.Println("device connect huawei iot platform success")
	} else {
		fmt.Println("device connect huawei iot platform failed")
	}
}

iot-mqtts.cn-north-4.myhuaweicloud.com为华为IoT平台基础班在华为云北京四的访问端点如果你购买了标准版或企业版请将iot-mqtts.cn-north-4.myhuaweicloud.com更换为对应的MQTT协议接入端点。

使用x.509证书鉴权

1、根据华为云文档创建证书并注册设备

华为云文档

2、使用SDK创建一个使用x.509证书鉴权的设备并初始化

使用x.509证书鉴权需要获取平台的ca证书并已经创建获取了设备的证书具体可以参考上面的华为云文档。

caPath := "your ca path"
certFilePath := "your cert path"
certKeyFilePath := "your key path"

config := iot.DeviceConfig{
	Id:              "your device id",
	Servers:         "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883",
	AuthType:        iot.AUTH_TYPE_X509,
	ServerCaPath:    caPath,
	CertFilePath:    certFilePath,
	CertKeyFilePath: certKeyFilePath,
}

device := iot.CreateIotDeviceWitConfig(config)

res := device.Init()
fmt.Println(res)

使用x.509证书鉴权必须设置AuthType的值为1iot.AUTH_TYPE_X509否则默认使用密码进行鉴权

设备命令

1、首先在华为云IoT平台创建一个设备设备的信息如下

设备ID5fdb75cccbfe2f02ce81d4bf_go-mqtt

设备密钥123456789

2、使用SDK创建一个Device对象并初始化Device。

// 创建一个设备并初始化
device := iot.CreateIotDevice("5fdb75cccbfe2f02ce81d4bf_go-mqtt", "123456789", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
device.Init()
if device.IsConnected() {
	fmt.Println("device connect huawei iot platform success")
} else {
	fmt.Println("device connect huawei iot platform failed")
}

3、注册命令处理handler支持注册多个handler并且按照注册的顺序回调

// 添加用于处理平台下发命令的callback
device.AddCommandHandler(func(command iot.Command) bool {
	fmt.Println("First command handler begin to process command.")
	return true
})

device.AddCommandHandler(func(command iot.Command) bool {
	fmt.Println("Second command handler begin to process command.")
	return true
})

4、通过应用侧API向设备下发一个命令可以看到程序输出如下

device connect huawei iot platform success
First command handler begin to process command.
Second command handler begin to process command.

完整样例

import (
	"fmt"
	"github.com/ctlove0523/huaweicloud-iot-device-sdk-go"
	"time"
)

// 处理平台下发的同步命令
func main() {
	// 创建一个设备并初始化
	device := iot.CreateIotDevice("5fdb75cccbfe2f02ce81d4bf_go-mqtt", "123456789", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
	device.Init()
	if device.IsConnected() {
		fmt.Println("device connect huawei iot platform success")
	} else {
		fmt.Println("device connect huawei iot platform failed")
	}

	// 添加用于处理平台下发命令的callback
	device.AddCommandHandler(func(command iot.Command) bool {
		fmt.Println("First command handler begin to process command.")
		return true
	})

	device.AddCommandHandler(func(command iot.Command) bool {
		fmt.Println("Second command handler begin to process command.")
		return true
	})
	time.Sleep(1 * time.Minute)
}

设备支持的命令定义在产品中

设备消息

1、首先在华为云IoT平台创建一个设备设备的信息如下

设备ID5fdb75cccbfe2f02ce81d4bf_go-mqtt

设备密钥123456789

2、使用SDK创建一个Device对象并初始化Device。

device := iot.CreateIotDevice("5fdb75cccbfe2f02ce81d4bf_go-mqtt", "123456789", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
	device.Init()

设备消息上报

message := iot.Message{
	ObjectDeviceId: uuid.NewV4().String(),
	Name:           "Fist send message to platform",
	Id:             uuid.NewV4().String(),
	Content:        "Hello Huawei IoT Platform",
}
device.SendMessage(message)

平台消息下发

接收平台下发的消息只需注册消息处理handler支持注册多个handler并按照注册顺序回调。

// 注册平台下发消息的callback当收到平台下发的消息时调用此callback.
// 支持注册多个callback并且按照注册顺序调用
device.AddMessageHandler(func(message iot.Message) bool {
	fmt.Println("first handler called" + iot.Interface2JsonString(message))
	return true
})

device.AddMessageHandler(func(message iot.Message) bool {
	fmt.Println("second handler called" + iot.Interface2JsonString(message))
	return true
})

完整样例

import (
	"fmt"
	iot "github.com/ctlove0523/huaweicloud-iot-device-sdk-go"
	uuid "github.com/satori/go.uuid"
	"time"
)

func main() {
	// 创建一个设备并初始化
	device := iot.CreateIotDevice("5fdb75cccbfe2f02ce81d4bf_go-mqtt", "123456789", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
	device.Init()

	// 注册平台下发消息的callback当收到平台下发的消息时调用此callback.
	// 支持注册多个callback并且按照注册顺序调用
	device.AddMessageHandler(func(message iot.Message) bool {
		fmt.Println("first handler called" + iot.Interface2JsonString(message))
		return true
	})

	device.AddMessageHandler(func(message iot.Message) bool {
		fmt.Println("second handler called" + iot.Interface2JsonString(message))
		return true
	})

	//向平台发送消息
	message := iot.Message{
		ObjectDeviceId: uuid.NewV4().String(),
		Name:           "Fist send message to platform",
		Id:             uuid.NewV4().String(),
		Content:        "Hello Huawei IoT Platform",
	}
	device.SendMessage(message)
	time.Sleep(2 * time.Minute)

}

设备属性

1、首先在华为云IoT平台创建一个设备并在该设备下创建3个子设备设备及子设备的信息如下

设备ID5fdb75cccbfe2f02ce81d4bf_go-mqtt

设备密钥123456789

子设备ID5fdb75cccbfe2f02ce81d4bf_sub-device-1

子设备ID5fdb75cccbfe2f02ce81d4bf_sub-device-2

子设备ID5fdb75cccbfe2f02ce81d4bf_sub-device-3

2、使用SDK创建一个Device对象并初始化Device。

// 创建设备并初始化
device := iot.CreateIotDevice("5fdb75cccbfe2f02ce81d4bf_go-mqtt", "123456789", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
device.Init()
fmt.Printf("device connected: %v\n", device.IsConnected())

设备属性上报

使用ReportProperties(properties ServiceProperty) bool 上报设备属性

// 设备上报属性
props := iot.ServicePropertyEntry{
	ServiceId: "value",
	EventTime: iot.DataCollectionTime(),
	Properties: DemoProperties{
		Value:   "chen tong",
		MsgType: "23",
	},
}

var content []iot.ServicePropertyEntry
content = append(content, props)
services := iot.ServiceProperty{
	Services: content,
}
device.ReportProperties(services)

网关批量设备属性上报

使用BatchReportSubDevicesProperties(service DevicesService) 实现网关批量设备属性上报

// 批量上报子设备属性
subDevice1 := iot.DeviceService{
	DeviceId: "5fdb75cccbfe2f02ce81d4bf_sub-device-1",
	Services: content,
}
subDevice2 := iot.DeviceService{
	DeviceId: "5fdb75cccbfe2f02ce81d4bf_sub-device-2",
	Services: content,
}

subDevice3 := iot.DeviceService{
	DeviceId: "5fdb75cccbfe2f02ce81d4bf_sub-device-3",
	Services: content,
}

var devices []iot.DeviceService
devices = append(devices, subDevice1, subDevice2, subDevice3)

device.BatchReportSubDevicesProperties(iot.DevicesService{
	Devices: devices,
})

平台设置设备属性

使用AddPropertiesSetHandler(handler DevicePropertiesSetHandler) 注册平台设置设备属性handler当接收到平台的命令时SDK回调。

// 注册平台设置属性callback,当应用通过API设置设备属性时会调用此callback支持注册多个callback
device.AddPropertiesSetHandler(func(propertiesSetRequest iot.DevicePropertyDownRequest) bool {
	fmt.Println("I get property set command")
	fmt.Printf("request is %s", iot.Interface2JsonString(propertiesSetRequest))
	return true
})

平台查询设备属性

使用SetPropertyQueryHandler(handler DevicePropertyQueryHandler)注册平台查询设备属性handler当接收到平台的查询请求时SDK回调。

// 注册平台查询设备属性callback当平台查询设备属性时此callback被调用仅支持设置一个callback
device.SetPropertyQueryHandler(func(query iot.DevicePropertyQueryRequest) iot.ServicePropertyEntry {
	return iot.ServicePropertyEntry{
		ServiceId: "value",
		Properties: DemoProperties{
			Value:   "QUERY RESPONSE",
			MsgType: "query property",
		},
		EventTime: "2020-12-19 02:23:24",
	}
})

设备侧获取平台的设备影子数据

使用QueryDeviceShadow(query DevicePropertyQueryRequest, handler DevicePropertyQueryResponseHandler) 可以查询平台的设备影子数据当接收到平台的响应后SDK自动回调DevicePropertyQueryResponseHandler

// 设备查询设备影子数据
device.QueryDeviceShadow(iot.DevicePropertyQueryRequest{
	ServiceId: "value",
}, func(response iot.DevicePropertyQueryResponse) {
	fmt.Printf("query device shadow success.\n,device shadow data is %s\n", iot.Interface2JsonString(response))
})

完整样例

import (
	"fmt"
	iot "github.com/ctlove0523/huaweicloud-iot-device-sdk-go"
	"time"
)

func main() {
	// 创建设备并初始化
	device := iot.CreateIotDevice("5fdb75cccbfe2f02ce81d4bf_go-mqtt", "123456789", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
	device.Init()
	fmt.Printf("device connected: %v\n", device.IsConnected())

	// 注册平台设置属性callback,当应用通过API设置设备属性时会调用此callback支持注册多个callback
	device.AddPropertiesSetHandler(func(propertiesSetRequest iot.DevicePropertyDownRequest) bool {
		fmt.Println("I get property set command")
		fmt.Printf("request is %s", iot.Interface2JsonString(propertiesSetRequest))
		return true
	})

	// 注册平台查询设备属性callback当平台查询设备属性时此callback被调用仅支持设置一个callback
	device.SetPropertyQueryHandler(func(query iot.DevicePropertyQueryRequest) iot.ServicePropertyEntry {
		return iot.ServicePropertyEntry{
			ServiceId: "value",
			Properties: DemoProperties{
				Value:   "QUERY RESPONSE",
				MsgType: "query property",
			},
			EventTime: "2020-12-19 02:23:24",
		}
	})

	// 设备上报属性
	props := iot.ServicePropertyEntry{
		ServiceId: "value",
		EventTime: iot.DataCollectionTime(),
		Properties: DemoProperties{
			Value:   "chen tong",
			MsgType: "23",
		},
	}

	var content []iot.ServicePropertyEntry
	content = append(content, props)
	services := iot.ServiceProperty{
		Services: content,
	}
	device.ReportProperties(services)

	// 设备查询设备影子数据
	device.QueryDeviceShadow(iot.DevicePropertyQueryRequest{
		ServiceId: "value",
	}, func(response iot.DevicePropertyQueryResponse) {
		fmt.Printf("query device shadow success.\n,device shadow data is %s\n", iot.Interface2JsonString(response))
	})

	// 批量上报子设备属性
	subDevice1 := iot.DeviceService{
		DeviceId: "5fdb75cccbfe2f02ce81d4bf_sub-device-1",
		Services: content,
	}
	subDevice2 := iot.DeviceService{
		DeviceId: "5fdb75cccbfe2f02ce81d4bf_sub-device-2",
		Services: content,
	}

	subDevice3 := iot.DeviceService{
		DeviceId: "5fdb75cccbfe2f02ce81d4bf_sub-device-3",
		Services: content,
	}

	var devices []iot.DeviceService
	devices = append(devices, subDevice1, subDevice2, subDevice3)

	device.BatchReportSubDevicesProperties(iot.DevicesService{
		Devices: devices,
	})
	time.Sleep(1 * time.Minute)
}

type DemoProperties struct {
	Value   string `json:"value"`
	MsgType string `json:"msgType"`
}

文件上传/下载管理

文件上传

device := iot.CreateIotDevice("5fdb75cccbfe2f02ce81d4bf_go-mqtt", "xxx", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
device.Init()

device.UploadFile("D/software/mqttfx/chentong.txt")

网关与子设备管理

当前SDK没有内置mqtt broker模块对mqtt broker的支持正在开发中

网关接收子设备新增和删除通知

网关如果要处理子设备新增和删除需要注册对应的handler让SDK调用。

device := iot.CreateIotDevice("xxx", "xxx", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")

// 处理子设备添加
device.SetSubDevicesAddHandler(func(devices iot.SubDeviceInfo) {
	for _, info := range devices.Devices {
		fmt.Println("handle device add")
		fmt.Println(iot.Interface2JsonString(info))
	}
})

// 处理子设备删除
device.SetSubDevicesDeleteHandler(func(devices iot.SubDeviceInfo) {
	for _, info := range devices.Devices {
		fmt.Println("handle device delete")
		fmt.Println(iot.Interface2JsonString(info))
	}
})

device.Init()

网关同步子设备列表

  • 同步所有版本的子设备

    device := iot.CreateIotDevice("xxx", "xxx", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
    device.Init()
    device.SyncAllVersionSubDevices()
    
  • 同步指定版本的子设备

    device := iot.CreateIotDevice("xxx", "xxx", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
    device.Init()
    device.SyncSubDevices(version int)
    

网关新增子设备

device := iot.CreateIotDevice("xxx", "xxx", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
device.Init()
result:= device.AddSubDevices(deviceInfos) // deviceInfos 的类型为[]DeviceInfo

网关删除子设备

device := iot.CreateIotDevice("xxx", "xxx", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
device.Init()
result:= device.DeleteSubDevices(deviceIds) // deviceIds的类型为[]string

网关更新子设备状态

device := iot.CreateIotDevice("xxx", "xxx", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
device.Init()
result:= device.UpdateSubDeviceState(subDevicesStatus) //subDevicesStatus的类型SubDevicesStatus

设备信息上报

设备可以向平台上报SDK版本、软固件版本信息其中SDK的版本信息SDK自动填充

device := iot.CreateIotDevice("xxx", "xxx", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
device.Init()

device.ReportDeviceInfo("1.0", "2.0")

设备日志收集

设备日志功能主要包括:平台下发日志收集命令,设备上报平台指定时间段内的日志;设备调用接口主动上报日志。

  • 设备响应平台日志收集命令

    设备响应日志收集功能需要实现日志收集函数,函数的定义如下:

    // 设备状态日志收集器
    type DeviceStatusLogCollector func(endTime string) []DeviceLogEntry
    
    // 设备属性日志收集器
    type DevicePropertyLogCollector func(endTime string) []DeviceLogEntry
    
    // 设备消息日志收集器
    type DeviceMessageLogCollector func(endTime string) []DeviceLogEntry
    
    // 设备命令日志收集器
    type DeviceCommandLogCollector func(endTime string) []DeviceLogEntry
    

    函数需要返回endTime之前的所有日志DeviceLogEntry包括日志记录时间、日志类型以及日志内容。当设备收到平台下发日志收集请求后SDK会自动的上报日志直到平台关闭日志收集或endTime范围内没有任何日志内容。

    日志收集函数的设置如下:

    device := iot.CreateIotDevice("5fdb75cccbfe2f02ce81d4bf_go-mqtt", "xxx", "tls://iot-mqtts.cn-north-4.myhuaweicloud.com:8883")
    
    // 设置设备状态日志收集器
    device.SetDeviceStatusLogCollector(func(endTime string) []iot.DeviceLogEntry {
    	return []iot.DeviceLogEntry{}
    })
    device.Init()
    
  • 设备主动上报日志

    设备可以调用ReportLogs(logs []DeviceLogEntry) bool 函数主动上报日志。

HTTP协议上报消息和属性

华为云IoT物联网平台支持使用HTTP协议上报消息和属性该功能目前处于α阶段尚未对外开放具体开放时间参考华为云IoT物联网平台公告。使用HTTP协议上报消息和属性非常简单方便SDK对接口进行了封装接口使用的对象和MQTT协议一致。使用HTTP协议的设备接口定义如下

type HttpDevice interface {
	SendMessage(message Message) bool
	ReportProperties(properties DeviceProperties) bool
}

使用样例参考http_device_samples.go

使用设备发放服务

有两种方法可以使用设备发放服务动态获取设备连接平台的地址

方法1通过设备发放服务获取设备连接平台的地址然后创建设备

id := "device_id"
pwd := "your device password"

bootstrapClient, err := iot.NewBootstrapClient(id, pwd)
if err != nil {
	fmt.Printf("create bs client failed")
	return
}

server := bootstrapClient.Boot()
if len(server) == 0 {
	fmt.Println("get server address failed")
	return
}

device := iot.CreateIotDevice(id, pwd, server)
device.Init()

方法2在创建设备时启动设备发放服务

id := "device_id"
pwd := "your device password"
config := iot.DeviceConfig{
	Id:           id,
	Password:     pwd,
	UseBootstrap: true,
}
device := iot.CreateIotDeviceWitConfig(config)
initRes := device.Init()
fmt.Println(initRes)

time.Sleep(1 * time.Minute)

报告bugs

如果你在使用过程中遇到任何问题或bugs请通过issue的方式上报问题或bug我们将会在第一时间内答复。上报问题或bugs时请尽量提供以下内容

  • 使用的版本
  • 使用场景
  • 重现问题或bug的样例代码
  • 错误信息
  • ······

贡献

该项目欢迎来自所有人的pull request。