天天看点

使用EdgeX的functions-sdk,通过trigger调用virtual设备调用方法

作者:freewebsys

#头条创作挑战赛#

目录

  • 前言
  • 1,关于EdgeX的例子
  • 2,使用debian进行构建
  • 3,创建Dockerfile
  • 4,然后将docker镜像放到EdgeX服务中,修改res的configuration.toml 配置
  • 5,测试接口,使用post man 测试接口
  • 6,使用总结

1,关于EdgeX的例子

最新的例子放在github的

https://github.com/edgexfoundry/edgex-examples/tree/main/application-services/custom/send-command

项目使用的SDK是:

require github.com/edgexfoundry/app-functions-sdk-go/v2 v2.2.0
           

这个代码做的是对设备进行注册,同时注册两个接口,一个get 接口,一个set 接口。

然后可以通过 EdgeX 进行访问相关数据。

2,使用debian进行构建

其实本来计划使用 alpine 进行构建的,但是相关的环境和工具不太友好,没有类似 pkgconfig

这样的工具。

还需要一点点地折腾,但是换成现在 debian 之后,很多工具就有了,非常的方便。

直接上首先要编写make file 构建脚本:

需要使用 代理:https://goproxy.io/zh/ 去下载相关的依赖包。

Makefile 文件内容:

.PHONY: build clean

GO=GOPROXY=https://proxy.golang.com.cn,direct CGO_ENABLED=1 GO111MODULE=on go

build:
	$(GO) mod tidy
	$(GO) build -o edgex-app-demo.bin

clean:
	rm -f edgex-app-demo.bin
           

3,创建Dockerfile

构建拆分了编译和运行,使用golang版本的debian bullseye 进行编译,然后把二进制代码和资源文件拷贝到debian bullseye-slim 系统上。

构建的系统占资源量:

构建的时候镜像 本地有 992MB,运行的时候少很多了只需要 85MB的基础镜像起。

$ docker images | grep bullseye
golang                                    1.19-bullseye   dce494d5814b   6 days ago       992MB
debian                                    bullseye-slim   acdab49503b5   7 days ago       80.5MB
           
# 使用debian 系统进行源代码构建:
FROM golang:1.19-bullseye AS builder

# 升级debian 的源,使用 http的地址。有证书问题。
RUN echo "deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib\n"\
"deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib\n"\
"deb http://mirrors.aliyun.com/debian-security/ bullseye-security main\n"\
"deb-src http://mirrors.aliyun.com/debian-security/ bullseye-security main\n"\
"deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib\n"\
"deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib\n"\
"deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib\n"\
"deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib" > /etc/apt/sources.list

# 按照zeroMQ 开发库。
RUN apt-get update && apt-get install -y libzmq3-dev && apt-get clean

WORKDIR /go/src/edgex-app-demo

COPY . .

# 使用make 进行构建。修改make参数即可。
RUN cd /go/src/edgex-app-demo && make

# 实际运行的镜像
FROM debian:bullseye-slim

# 升级debian 的源,使用 http的地址。有证书问题。
RUN echo "deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib\n"\
"deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib\n"\
"deb http://mirrors.aliyun.com/debian-security/ bullseye-security main\n"\
"deb-src http://mirrors.aliyun.com/debian-security/ bullseye-security main\n"\
"deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib\n"\
"deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib\n"\
"deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib\n"\
"deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib" > /etc/apt/sources.list

EXPOSE 59780
RUN apt-get update && apt-get install -y libzmq5 && apt-get clean

WORKDIR /opt

COPY --from=builder /go/src/edgex-app-demo/edgex-app-demo.bin \
        /opt/edgex-app-demo.bin
COPY --from=builder /go/src/edgex-app-demo/res /opt/res

ENTRYPOINT ["/opt/edgex-app-demo.bin"]

           

开始构建Docker镜像:

docker build . -t edgex2022/edgex-app-demo:v1.0
           

复杂麻烦的地方在于为了节省磁盘空间,所以折腾得比较复杂。

有的时候这个镜像要上传到 私服上面,再下载,所以镜像越小越好。

最终镜像大小在:

docker images | grep edgex
edgex2022/edgex-app-demo              v1.0            225f61ad3d5c   5 minutes ago       145MB

           

4,然后将docker镜像放到EdgeX服务中,修改res的configuration.toml 配置

需要 EdgeX的环境才可以启动成功,然后设置启动点,这个时候特别注意一定要增加参数

app-demo:
    container_name: edgex-app-demo
    image: edgex2022/edgex-app-demo:v1.0
    networks:
      edgex-network: {}
    ports:
    - 59780:59780/tcp
    entrypoint: ["/opt/edgex-app-demo.bin", "--registry","--confdir=/opt/res"]

           

然后再配置 res 当中的 configuration.toml

[Writable]
LogLevel = "DEBUG"

  [Writable.StoreAndForward]
  Enabled = false
  RetryInterval = "5m"
  MaxRetryCount = 10

  [Writable.InsecureSecrets]
    [Writable.InsecureSecrets.DB]
    path = "redisdb"
      [Writable.InsecureSecrets.DB.Secrets]
      username = ""
      password = ""

[Service]
HealthCheckInterval = "10s"
Host = "localhost"
Port = 59780 # 设对外端口
ServerBindAddr = "0.0.0.0" # 需要设置成0.0.0.0 否则不对外提供服务 if blank, uses default Go behavior https://golang.org/pkg/net/#Listen
StartupMsg = "This is a edgex App sample Application Service to receive HTTP request as trigger"
RequestTimeout = "30s"
MaxRequestSize = 0
MaxResultCount = 0

[Registry]
Host = "edgex-core-consul"
Port = 8500
Type = "consul"

[Database]
Type = "redisdb"
Host = "edgex-redis"
Port = 6379
Timeout = "30s"

[Clients]
  [Clients.core-metadata]
  Protocol = "http"
  Host = "edgex-core-metadata"
  Port = 59881

  [Clients.core-command]
  Protocol = "http"
  Host = "edgex-core-command"
  Port = 59882

# This example expect custom type via HTTP Trigger
[Trigger]
Type="http"

[ApplicationSettings]
           

也可以设置数据源:配置Trigger的触发器。

[Trigger]
Type="edgex-messagebus"
  [Trigger.EdgexMessageBus]
  Type = "redis"
    [Trigger.EdgexMessageBus.SubscribeHost]
    Host = "edgex-redis"
    Port = 6379
    Protocol = "redis"
    SubscribeTopics="edgex/events/#"
    [Trigger.EdgexMessageBus.PublishHost]
    Host = "edgex-redis"
    Port = 6379
    Protocol = "redis"
    PublishTopic="rules-events"
           
# 接受到了相关的日志:

level=DEBUG ts=2022-11-02T13:27:55.532706951Z app=edgex-app-demo source=runtime.go:239 msg="Expecting a custom type of edgex-robot-service/functions.ActionRequest"
level=DEBUG ts=2022-11-02T13:27:55.532770833Z app=edgex-app-demo source=send_cmd.go:45 msg="Sending Command"
level=ERROR ts=2022-11-02T13:27:55.532829953Z app=edgex-app-demo source=send_cmd.go:87 msg="Invalid action requested: "
level=DEBUG ts=2022-11-02T13:27:55.532861117Z app=edgex-app-demo source=triggermessageprocessor.go:145 
	msg="trigger successfully processed message 'default-pipeline' in pipeline 3e001c04-5197-4a40-9627-118ad23a7056"
level=DEBUG ts=2022-11-02T13:27:55.533387539Z app=edgex-app-demo source=messaging.go:189 
	msg="MessageBus Trigger: Received message with 529 bytes on topic 'edgex/events/device/Random-UnsignedInteger-Device/Random-UnsignedInteger-Device/Uint32'. Content-Type=application/json"
level=DEBUG ts=2022-11-02T13:27:55.5334934Z app=edgex-app-demo source=triggermessageprocessor.go:100 
	msg="trigger attempting to find pipeline(s) for topic edgex/events/device/Random-UnsignedInteger-Device/Random-UnsignedInteger-Device/Uint32"
            

特别需要注意的时候在 service 当中的配置设置:

特别需要注意的是在 service 当中的配置设置:

Port = 59780 # 设对外端口

ServerBindAddr = “0.0.0.0” # 需要设置成0.0.0.0 否则不能对外提供服务 i

然后在服务中就可以看到 app-send-command 了:

使用EdgeX的functions-sdk,通过trigger调用virtual设备调用方法

可以进行配置修改查看:

使用EdgeX的functions-sdk,通过trigger调用virtual设备调用方法

5,测试接口,使用post man 测试接口

配置触发器:

http://127.0.0.1:59780/api/v2/trigger
POST 内容:
{    
    "action" : "get",
    "deviceName" : "Random-Integer-Device",
    "commandName" : "Int8"
}
           
使用EdgeX的functions-sdk,通过trigger调用virtual设备调用方法

可以进行 get set 设置edgex的设备值:

set 返回数据:
{
    "apiVersion": "v2",
    "statusCode": 200
}
get 返回数据:设备和 profile 都是 Random-Integer-Device 
{
    "apiVersion": "v2",
    "statusCode": 200,
    "event": {
        "apiVersion": "v2",
        "id": "2369f3f1-df20-4522-bd2a-1fbc20e7049e",
        "deviceName": "Random-Integer-Device",
        "profileName": "Random-Integer-Device",
        "sourceName": "Int8",
        "origin": 1625868240254928800,
        "readings": [
            {
                "id": "b37c67c6-1678-4d18-b07c-a6f148aeaefd",
                "origin": 1625868240254928800,
                "deviceName": "Random-Integer-Device",
                "resourceName": "Int8",
                "profileName": "Random-Integer-Device",
                "valueType": "Int8",
                "binaryValue": null,
                "mediaType": "",
                "value": "101"
            }
        ]
    }
}
           

6,使用总结

在使用的过程中,主要是环境搭建,通过docker快速构建,使用golang的代理,下载成功依赖之后。

再进行相关的构建开发,就非常的方便了。剩下的就是使用docker-compose,把服务启动。

并且增加到edgex网络中,修改core,command等微服务的地址的配置文件,修改对外暴露的端口。

通过service.SetFunctionsPipeline方法构建一个消息总线,然后在总线内,放入消息处理的方法就行了。

这个例子是通过trigger 中配置的触发,也可以通过 messagebus 获得数据源。

继续阅读