代码拉取完成,页面将自动刷新
同步操作将从 zhiting-tech/smartassistant 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
此文档描述如何开发一个简单插件,面向插件开发者。
开发前先阅读插件设计概要:插件系统设计技术概要
下面展示如何快速实现一个可控的(虚拟)灯设备的插件开发
plugin
├── device
│ ├── attribute.go
│ ├── switch.go
│ └── light.go
├── lib
│ ├── protocol.go
│ └── discover.go
├── config.json
├── html
│ ├── index.html
│ └── images
...
├── Readme.md
├── .dockerignore
├── Dockerfile
└── main.go
go get github.com/zhiting-tech/smartassistant
实现前推荐先了解插件设备生命周期管理:插件设备生命周期管理
plugin/device/light.go
package device
import (
"github.com/zhiting-tech/smartassistant/pkg/plugin/sdk/v2"
"github.com/zhiting-tech/smartassistant/pkg/plugin/sdk/v2/definer"
)
type Light struct {
}
func NewLight() sdk.Device {
return &Light{}
}
func (l Light) Address() string {
// TODO implement me
panic("implement me")
}
func (l Light) Connect() error {
// TODO implement me
panic("implement me")
}
func (l Light) Disconnect(iid string) error {
// TODO implement me
panic("implement me")
}
func (l Light) Define(df *definer.Definer) error {
// TODO implement me
panic("implement me")
}
func (l Light) Info() sdk.DeviceInfo {
// TODO implement me
panic("implement me")
}
func (l Light) Online(iid string) bool {
// TODO implement me
panic("implement me")
}
plugin/device/light.go
func (l Light) Address() string {
// 该地址返回改变会导致设备断开重连
return "192.168.0.123:12345"
}
plugin/device/light.go
func (l Light) Info() sdk.DeviceInfo {
return sdk.DeviceInfo{
IID: "iid",
Model: "model",
Manufacturer: "manufacturer",
AuthRequired: false,
}
}
plugin/device/light.go
func (l Light) Connect() error {
// 此处由于是虚拟设备,所以没有连接过程
// return l.protocol.Connect()
return nil
}
func (l Light) Disconnect(iid string) error {
// 此处由于是虚拟设备,所以没有断开连接过程
// return l.protocol.Disconnect()
return nil
}
plugin/device/light.go
func (l Light) Close() error {
// 此处由于是虚拟设备,所以没有回收资源的过程
// return l.protocol.Close()
return nil
}
plugin/device/light.go
func (l Light) Online(iid string) bool {
// 此处由于是虚拟设备,所以没判断实际是否在线
// return l.protocol.IsOnline()
return true
}
plugin/device/attribute.go
package device
import "github.com/zhiting-tech/smartassistant/pkg/plugin/sdk/v2/definer"
// OnOff 开关
// 通过实现 thingmodel.IAttribute 的接口,以便sdk调用
type OnOff struct {
service *definer.BaseService
}
func (l *OnOff) Set(val interface{}) error {
// 如果有设备,则跟据已实现的通讯协议控制设备
// return l.protocol.SetSwitch(val)
// 此处仅将设置的状态同步回SA
return l.service.Notify(thingmodel.OnOff, val)
}
plugin/device/light.go
func (l Light) Define(df *definer.Definer) error {
info := df.Instance(l.Info().IID).NewInfo()
info.WithAttribute(thingmodel.Manufacturer).SetVal(l.Info().Manufacturer)
info.WithAttribute(thingmodel.Model).SetVal(l.Info().Model)
info.WithAttribute(thingmodel.Identify).SetVal(l.Info().IID)
info.WithAttribute(thingmodel.Version).SetVal("1.0.0")
light := df.Instance(l.Info().IID).NewLight()
light.Enable(thingmodel.OnOff, OnOff{light}).SetVal("on")
// 为了使得物模型属性状态和设备状态保持一致,需要开发者主动同步设备状态变化
// go func() {
// for {
// // 此处同步设备属性状态
// light.Notify(thingmodel.OnOff, "on")
// }
// }()
}
plugin/main.go
package main
import (
"context"
"log"
sdk "github.com/zhiting-tech/smartassistant/pkg/plugin/sdk/v2"
"plugin/device"
)
func main() {
p := sdk.NewPluginServer(Discover)
err := sdk.Run(p)
if err != nil {
log.Panicln(err)
}
}
// Discover 这里需要实现一个发现设备的方法,给sdk调用
func Discover(ctx context.Context, devices chan<- sdk.Device) {
l := getDevice()
devices <- l
<-ctx.Done()
}
// getDevice 发现设备,由于没有设备,所以没有实现发现设备的逻辑
func getDevice() sdk.Device {
return device.NewLight()
}
暂时仅支持以镜像方式安装插件,调试正常后,编译成镜像提供给SA
plugin/Dockerfile
FROM golang:1.16-alpine as builder
RUN apk add build-base
COPY . /app
WORKDIR /app
RUN go env -w GOPROXY="goproxy.cn,direct"
RUN go build -ldflags="-w -s" -o demo-plugin
FROM alpine
WORKDIR /app
COPY --from=builder /app/demo-plugin /app/demo-plugin
# static file
COPY ./html ./html
ENTRYPOINT ["/app/demo-plugin"]
docker build -f your_plugin_Dockerfile -t your_plugin_name
SA上通过我的-支持品牌-我的插件-创作-添加插件可以将插件安装到SA上调试
demo-plugin : 通过上文的插件实现教程实现的示例插件;这是一个模拟设备写的一个简单插件服务,不依赖硬件,实现了核心插件的功能
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。