当前位置:网站首页>树莓派4B上运行opcua协议DEMO接入kubeedge

树莓派4B上运行opcua协议DEMO接入kubeedge

2022-06-27 05:40:00 阿龙哥哥

 一、KubeEdge简介

KubeEdge是个还不错的边缘云平台。能够支持边缘设备的接入和管理。

KubeEdge由以下组件组成:

  • Edged: 在边缘节点上运行并管理容器化应用程序的代理。
  • EdgeHub: Web套接字客户端,负责与Cloud Service进行交互以进行边缘计算(例如KubeEdge体系结构中的Edge Controller)。这包括将云侧资源更新同步到边缘,并将边缘侧主机和设备状态变更报告给云。
  • CloudHub: Web套接字服务器,负责在云端缓存信息、监视变更,并向EdgeHub端发送消息。
  • EdgeController: kubernetes的扩展控制器,用于管理边缘节点和pod的元数据,以便可以将数据定位到对应的边缘节点。
  • EventBus: 一个与MQTT服务器(mosquitto)进行交互的MQTT客户端,为其他组件提供发布和订阅功能。
  • DeviceTwin: 负责存储设备状态并将设备状态同步到云端。它还为应用程序提供查询接口。
  • MetaManager: Edged端和Edgehub端之间的消息处理器。它还负责将元数据存储到轻量级数据库(SQLite)或从轻量级数据库(SQLite)检索元数据。

设备管理部分的原理如下图所示:

https://kubeedge.io/zh/docs/kubeedge_zh/

二、云端设备的数据存储

model就是设备模型。

Device Model

apiVersion: devices.kubeedge.io/v1alpha2
kind: DeviceModel
metadata:
 name: opcua-model
 namespace: default
spec:
 properties:
  - name: temperature
    description: temperature in degree celsius
    type:
      int:
        accessMode: ReadOnly
        defaultValue: 1
  - name: switcher
    description: turn on or turn off
    type:
      boolean:
        accessMode: ReadWrite

 instance就是设备实例,指某一台具体的设备。

Device Instance

apiVersion: devices.kubeedge.io/v1alpha2
kind: Device
metadata:
  name: lamp-opcua
  labels:
    model: opcua-model
spec:
  deviceModelRef:
    name: opcua-model
  protocol:
    opcua:
      url: opc.tcp://192.168.137.100:4840/
      userName: testuser
      password: ""
      password: /ca/pass
      certificate: /ca/clientcert.pem
      privateKey: /ca/clientkey.pem
      securityMode: None
      securityPolicy: ""
    common:
      customizedValues:
        remoteCertificate: /ca/servercert.pem
  nodeSelector:
    nodeSelectorTerms:
    - matchExpressions:
      - key: ''
        operator: In
        values:
        - rpi4b2.1
  propertyVisitors:
    - propertyName: temperature
      opcua:
        nodeID: ns=3;i=2002   #node1
    - propertyName: switcher
      opcua:
        nodeID: ns=3;i=2003   #node2
status:
  twins:
    - propertyName: switcher
      reported:
        metadata:
          timestamp: '1550049403598'
          type: boolean
        value: "false"
      desired:
        metadata:
          timestamp: '1550049403598'
          type: boolean
        value: "false"
    - propertyName: temperature
      reported:
        metadata:
          timestamp: '1550049403598'
          type: integer
        value: "0"

fhttps://kubeedge.io/zh/docs/developer/device_crd/

Mapper用于进行协议转换,实现Kubeedge对各类协议的支持。

Device Mapper

Mapper is an application that is used to connect and control devices. Following are the responsibilities of mapper:

1) Scan and connect to the device.

2) Report the actual state of twin-attributes of device.

3) Map the expected state of device-twin to actual state of device-twin.

4) Collect telemetry data from device.

5) Convert readings from device to format accepted by KubeEdge.

6) Schedule actions on the device.

7) Check health of the device.

总之就是读取设备数据,发送指令,与设备打交道的。

不同的设备支持不同的协议,目前实现的几种协议在这个项目中:

https://github.com/kubeedge/mappers-go

三、OPCUA DEMO 运行

下载 https://github.com/kubeedge/mappers-go

进入 mappers/opcua目录

make mapper opcua package ARM64=true

Dockfile进行了些许修改

FROM ubuntu:20.04

RUN mkdir -p kubeedge
RUN mkdir -p ca
COPY ./ca/*  /ca/
RUN ls /ca

COPY ./bin/opcua kubeedge/
COPY ./config.yaml kubeedge/

WORKDIR kubeedge
ENTRYPOINT ["/kubeedge/opcua", "--v", "5"]

 

编译并生成镜像opcua-mapper

[email protected]:~/work/mappers-go/mappers/opcua# make mapper opcua package ARM64=true
opcua package
# make mapper opcua package
downloading dependencies for mapper opcua...
tidying
vending
...done
fmt and linting mapper opcua...
...done
crossed packaging for linux/arm64
building linux/arm64
...done
packaging mapper opcua...
crossed packaging for linux/arm64
packaging opcua-mapper:v1.0-linux-arm64
Sending build context to Docker daemon  95.07MB
Step 1/9 : FROM ubuntu:20.04
 ---> d25e19480966
Step 2/9 : RUN mkdir -p kubeedge
 ---> Using cache
 ---> 184c2c6417ac
Step 3/9 : RUN mkdir -p ca
 ---> Using cache
 ---> c5eb93feeab0
Step 4/9 : COPY ./ca/*  /ca/
 ---> Using cache
 ---> 3e3c53d9c9a7
Step 5/9 : RUN ls /ca
 ---> Using cache
 ---> 3f2c57f65659
Step 6/9 : COPY ./bin/opcua kubeedge/
 ---> Using cache
 ---> d4185abacf94
Step 7/9 : COPY ./config.yaml kubeedge/
 ---> Using cache
 ---> 612e41c13320
Step 8/9 : WORKDIR kubeedge
 ---> Using cache
 ---> 125000909f46
Step 9/9 : ENTRYPOINT ["/kubeedge/opcua", "--v", "5"]
 ---> Using cache
 ---> 0811ee8d139c
Successfully built 0811ee8d139c
Successfully tagged opcua-mapper:v1.0-linux-arm64
...done

docker images 查看镜像

[email protected]:~/work/mappers-go/mappers/opcua# docker images
REPOSITORY                                        TAG                IMAGE ID       CREATED             SIZE
opcua-mapper                                      v1.0-linux-arm64   0811ee8d139c   About an hour ago   72.3MB
<none>                                            <none>             23a240215cc8   3 days ago          72.3MB
<none>                                            <none>             46b34807de81   3 days ago          72.3MB
<none>                                            <none>             72db7f8d0bb4   7 days ago          101MB

由于镜像是边缘端使用的,还要将镜像导出,传输到边缘上再导入。也可以直接在边缘上编译并生成镜像。

docker save -o opcua-mapper-arm64.tar  opcua-mapper:v1.0-linux-arm64

编写 crd/model.yaml   crd/instance.yaml

从build/crd-samples/devices这个目录下把opcua的两个Yaml文档拿出来放在crd,opcua-model.yaml作为model.yaml

opcua-device.yaml作为 instance.yaml 具体内容见上面。

我的边缘的节点名为rpi4b2.1 ,各位可以按照需求进行修改 。

用以下命令部署APP:

$ kubectl apply -f crd/model.yaml
$ kubectl apply -f crd/instance.yaml

#deploy opcua mapper
$ kubectl apply -f deploy.yaml

model.yaml

apiVersion: devices.kubeedge.io/v1alpha2
kind: DeviceModel
metadata:
 name: opcua-model
 namespace: default
spec:
 properties:
  - name: temperature
    description: temperature in degree celsius
    type:
      int:
        accessMode: ReadOnly
        defaultValue: 1
  - name: switcher
    description: turn on or turn off
    type:
      boolean:
        accessMode: ReadWrite

instance.yaml的内容:

apiVersion: devices.kubeedge.io/v1alpha2
kind: Device
metadata:
  name: lamp-opcua
  labels:
    model: opcua-model
spec:
  deviceModelRef:
    name: opcua-model
  protocol:
    opcua:
      url: opc.tcp://192.168.137.100:4840/
      userName: testuser
      password: ""
      password: /ca/pass
      certificate: /ca/clientcert.pem
      privateKey: /ca/clientkey.pem
      securityMode: None
      securityPolicy: ""
    common:
      customizedValues:
        remoteCertificate: /ca/servercert.pem
  nodeSelector:
    nodeSelectorTerms:
    - matchExpressions:
      - key: ''
        operator: In
        values:
        - rpi4b2.1
  propertyVisitors:
    - propertyName: temperature
      opcua:
        nodeID: ns=3;i=2002
    - propertyName: switcher
      opcua:
        nodeID: ns=3;i=2003
status:
  twins:
    - propertyName: switcher
      reported:
        metadata:
          timestamp: '1550049403598'
          type: boolean
        value: "false"
      desired:
        metadata:
          timestamp: '1550049403598'
          type: boolean
        value: "false"
    - propertyName: temperature
      reported:
        metadata:
          timestamp: '1550049403598'
          type: integer
        value: "0"

 deploy.yaml的内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: opcua-mapper
spec:
  replicas: 1
  selector:
    matchLabels:
      app: opcuamapper
  template:
    metadata:
      labels:
        app: opcuamapper
    spec:
      nodeName: rpi4b2.1   ## 这个地方节点名字要修改
      hostNetwork: true
      containers:
      - name: opcua-mapper-container
        image: opcua-mapper:v1.0    ## 这个我修改了一下,与我的容器名相符
        imagePullPolicy: IfNotPresent
        securityContext:
          privileged: true
        volumeMounts:
        - name: config-volume
          mountPath: /opt/kubeedge/
      nodeSelector:
        opcua: "true"
      volumes:
      - name: config-volume
        configMap:
          name: device-profile-config-rpi4b2.1   ##这个地方要注意
      restartPolicy: Always

在云端可以看到:

在边端设备上可以看到容器已经在运行了:

~ # docker ps

如果opcua-mapper没有在运行,需要查看程序运行日志,进行排错。

最常见的错误是opcua服务器连接的问题。

三、opcua server模拟器

在边缘节点上访问opcua server。

目前可用的opcua 模拟器是Prosys OPC UA模拟服务器。

http://www.prosysopc.cn/products/opc-ua-simulation-server/

这个软件对个人使用是免费的,可以在csdn上搜索并下载。

运行界面: 

具体值的模拟界面: 

目前还未解决的是Prosys OPC UA模拟服务器好像不支持数据写入,就是opcua客户端通过opcua协议修改模拟器上的数据。

前期比较容易出的问题是连接不上opcua服务器,可以在边缘端编译运行,opuca的程序,查看程序运行结果。

https://github.com/kubeedge/mappers-go/tree/main/mappers/opcua

四、在云端查看数据

用下面的命令查看device的值。

[email protected]:~/work/mappers-go/mappers/opcua# kubectl get devices lamp-opcua -o yaml
apiVersion: devices.kubeedge.io/v1alpha2
kind: Device
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"devices.kubeedge.io/v1alpha2","kind":"Device","metadata":{"annotations":{},"labels":{"model":"opcua-model"},"name":"lamp-opcua","namespace":"default"},"spec":{"deviceModelRef":{"name":"opcua-model"},"nodeSelector":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"","operator":"In","values":["rpi4b2.1"]}]}]},"propertyVisitors":[{"opcua":{"nodeID":"ns=3;i=2002"},"propertyName":"temperature"},{"opcua":{"nodeID":"ns=3;i=2003"},"propertyName":"switcher"}],"protocol":{"common":{"customizedValues":{"remoteCertificate":"/ca/servercert.pem"}},"opcua":{"certificate":"/ca/clientcert.pem","password":"/ca/pass","privateKey":"/ca/clientkey.pem","securityMode":"None","securityPolicy":"","url":"opc.tcp://192.168.137.100:4840/","userName":"testuser"}}},"status":{"twins":[{"desired":{"metadata":{"timestamp":"1550049403598","type":"boolean"},"value":"false"},"propertyName":"switcher","reported":{"metadata":{"timestamp":"1550049403598","type":"boolean"},"value":"false"}},{"propertyName":"temperature","reported":{"metadata":{"timestamp":"1550049403598","type":"integer"},"value":"0"}}]}}
  creationTimestamp: "2022-06-17T04:04:09Z"
  generation: 729
  labels:
    model: opcua-model
  managedFields:
  - apiVersion: devices.kubeedge.io/v1alpha2
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:kubectl.kubernetes.io/last-applied-configuration: {}
        f:labels:
          .: {}
          f:model: {}
      f:spec:
        .: {}
        f:deviceModelRef:
          .: {}
          f:name: {}
        f:nodeSelector:
          .: {}
          f:nodeSelectorTerms: {}
        f:propertyVisitors: {}
        f:protocol:
          .: {}
          f:common:
            .: {}
            f:customizedValues:
              .: {}
              f:remoteCertificate: {}
          f:opcua:
            .: {}
            f:certificate: {}
            f:password: {}
            f:privateKey: {}
            f:securityMode: {}
            f:securityPolicy: {}
            f:url: {}
            f:userName: {}
      f:status: {}
    manager: kubectl
    operation: Update
    time: "2022-06-21T02:29:09Z"
  - apiVersion: devices.kubeedge.io/v1alpha2
    fieldsType: FieldsV1
    fieldsV1:
      f:status:
        f:twins: {}
    manager: cloudcore
    operation: Update
    time: "2022-06-21T02:39:53Z"
  name: lamp-opcua
  namespace: default
  resourceVersion: "22666744"
  selfLink: /apis/devices.kubeedge.io/v1alpha2/namespaces/default/devices/lamp-opcua
  uid: cb57e60a-4c80-4b49-a461-2706f7fffc40
spec:
  deviceModelRef:
    name: opcua-model
  nodeSelector:
    nodeSelectorTerms:
    - matchExpressions:
      - key: ""
        operator: In
        values:
        - rpi4b2.1
  propertyVisitors:
  - opcua:
      nodeID: ns=3;i=2002
    propertyName: temperature
  - opcua:
      nodeID: ns=3;i=2003
    propertyName: switcher
  protocol:
    common:
      customizedValues:
        remoteCertificate: /ca/servercert.pem
    opcua:
      certificate: /ca/clientcert.pem
      password: /ca/pass
      privateKey: /ca/clientkey.pem
      securityMode: None
      securityPolicy: ""
      url: opc.tcp://192.168.137.100:4840/
      userName: testuser
status:
  twins:
  - desired:
      metadata:
        timestamp: "1550049403598"
        type: boolean
      value: "false"
    propertyName: switcher
    reported:
      metadata:
        timestamp: "1655779193063"
        type: boolean
      value: "true"
  - desired:
      value: ""
    propertyName: temperature
    reported:
      metadata:
        timestamp: "1655779193079"
        type: string
      value: "17"

原网站

版权声明
本文为[阿龙哥哥]所创,转载请带上原文链接,感谢
https://blog.csdn.net/v6543210/article/details/125385847