关于go:如何扩展Shifu的西门子PLC驱动能力

70次阅读

共计 7472 个字符,预计需要花费 19 分钟才能阅读完成。

在上篇中咱们分享了《如何利用 Shifu 接入公有驱动的设施》。Shifu 内置了几个罕用的驱动,像是西门子 S7 系列的 PLC,RTSP 协定的摄像头等。物联网上的需要因人而异。在这次的文章中咱们将介绍如何扩大 Shifu 自带驱动的能力。

简介
本文是一个应用 Shifu Framework 的西门子 PLC 驱动的扩大指南,其中蕴含 Linux, Python, Shifu Framework, Docker, Kubernetes 的基本操作,任何开发者都能够浏览本文来学习 Shifu Framework 的开发方法。
本文中的 Shifu Framework 架构如下
北向通过 ”deviceshifu-http-http”容器向上凋谢 HTTP API 接口,南向通过 ”siemens-plc-driver”容器来和理论设施交互

指标

  1. 在本地运行 K8s 集群并装置 Shifu Framework
  2. 批改西门子 PLC 的驱动增加一个性能
  3. 打包驱动,生成容器镜像
  4. 在 Shifu 中部署 PLC 的数字孪生
  5. 实现扩大西门子 PLC 的能力

本次分享中用到的设施

  1. 开发环境(本文中为运行在 Windows 11 Pro 上面的 WSL 子系统,零碎为 Ubuntu 20.04)
  2. 西门子 PLC(反对 S7 协定即可,本文中用到的型号为西门子 S7-1200 系列)

须要的基本知识
- 根本的 Python
-Linux 命令行基本操作(创立文件,装置利用,运行程序)
-Docker/containerd 基本操作
-K8s 基本操作

步骤
第一步:在本地运行 Kubernetes(如果已装置 Shifu Framework,请间接跳到第三步)
为了运行 Shifu,咱们须要一个 Kubernetes 的集群,这里不限度用户应用的版本,本文中应用的是利用 kind 建设的测试 Kubernetes 集群。如果资源受限的话也能够思考应用 k3d 或者 microk8s。
kind 的装置教程:
https://kind.sigs.k8s.io/docs…
具体装置步骤本文将不再赘述。
kind 装置结束后能够通过“kind version”来查看以后版本,本文中的版本为”v0.12.0”:

$ kind version 
kind v0.12.0 go1.17.8 linux/amd64

接下来应用“kind create cluster”创立集群,整个过程会继续几分钟,因网速而异:

$ kind create cluster 
Creating cluster "kind" ... 
 ✓ Ensuring node image (kindest/node:v1.23.4) 🖼 
 ✓ Preparing nodes 📦 
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
Set kubectl context to "kind-kind" 
You can now use your cluster with: 
 kubectl cluster-info --context kind-kind 
Not sure what to do next? 😅  Check out https://kind.sigs.k8s.io/docs/user/quick-start/

创立实现后咱们能够通过“kubectl get nodes”查看集群状态,当显示“Ready”即可:

$ kubectl get nodes 
NAME                 STATUS   ROLES                  AGE    VERSION 
kind-control-plane   Ready    control-plane,master   119s   v1.23.4 

至此,运行 K8s 步骤结束。

第二步:装置 Shifu
首先将 Shifu 我的项目克隆到本地,我的项目地址为:
https://github.com/Edgenesis/…
执行命令为:
git clone https://github.com/Edgenesis/shifu.git

上面通过“kubectl apply -f shifu/k8s/crd/install/shifu_install.yml”即可一键将 Shifu 部署到 k3s 集群中:

$ kubectl apply -f k8s/crd/install/shifu_install.yml 
namespace/shifu-crd-system created 
customresourcedefinition.apiextensions.k8s.io/edgedevices.shifu.edgenesis.io created 
serviceaccount/shifu-crd-controller-manager created 
role.rbac.authorization.k8s.io/shifu-crd-leader-election-role created 
clusterrole.rbac.authorization.k8s.io/shifu-crd-manager-role created 
clusterrole.rbac.authorization.k8s.io/shifu-crd-metrics-reader created 
clusterrole.rbac.authorization.k8s.io/shifu-crd-proxy-role created 
rolebinding.rbac.authorization.k8s.io/shifu-crd-leader-election-rolebinding created 
clusterrolebinding.rbac.authorization.k8s.io/shifu-crd-manager-rolebinding created 
clusterrolebinding.rbac.authorization.k8s.io/shifu-crd-proxy-rolebinding created 
configmap/shifu-crd-manager-config created 
service/shifu-crd-controller-manager-metrics-service created 
deployment.apps/shifu-crd-controller-manager created 
namespace/devices created 
serviceaccount/edgedevice-sa created 
clusterrole.rbac.authorization.k8s.io/edgedevice-clusterrole created 
clusterrolebinding.rbac.authorization.k8s.io/edgedevice-clusterrolebinding created

至此,Shifu 装置结束。

第三步:批改西门子 PLC 驱动来增加新的性能
在 IDE 中关上 Shifu 文件夹,本文应用的是 VS Code。在 ”examples/siemensPLCDeviceShifu”目录下关上 ”siemens-plc.py”:

驱动内容如下(因长度问题只截取了一部分):

import os 
import sys 
import snap7 
from flask import Flask, request 
client = snap7.client.Client() 
app = Flask(__name__) 
ip = os.environ.get("PLC_ADDRESS") 
port = os.environ.get("PLC_CONTAINER_PORT") 
rack = os.environ.get("PLC_RACK") 
slot = os.environ.get("PLC_SLOT") 
def edit_single_bit(originalbyte, digitvalue, isset): 
    if digitvalue > 7: 
        digitvalue -= 8 
        changebyte = originalbyte[1] 
        if isset == 0: 
            return bytes([originalbyte[0]]) + bytes([changebyte & ~(1 << digitvalue)]) 
        else: 
            return bytes([originalbyte[0]]) + bytes([changebyte | (1 << digitvalue)])
    else: 
        changebyte = originalbyte[0] 
        if isset == 0: 
            return bytes([changebyte & ~(1 << digitvalue)]) + bytes([originalbyte[1]]) 
        else: 
            return bytes([changebyte | (1 << digitvalue)]) + bytes([originalbyte[1]]) 
@app.route('/sendsinglebit') 
def send_single_bit(): 
print("Changing single bit...") 

能够看到这个西门子 PLC 驱动是一个 Python 程序,通过调用”snap7”这个 API 来实现和西门子 PLC 的通信,向上通过 Flask 凋谢了若干个 HTTP 接口来供 Shifu 调用。

咱们次要看一下对于批改 PLC 内存值的“send_single_bit”这个函数,首先,是这个 API 接管的参数:

 rootaddress = request.args.get('rootaddress') 
 address = request.args.get('address', default=0, type=int) 
 start = request.args.get('start', default=0, type=int) 
 digit = request.args.get('digit', default=0, type=int) 
 value = request.args.get('value', default=0, type=int)

“rootaddress”定义了驱动写入的类型,目前承受的类型如下:

if rootaddress == 'M': 
        area = snap7.types.Areas.MK 
elif rootaddress == 'Q': 
        area = snap7.types.Areas.PA 
elif rootaddress == 'C': 
        area = snap7.types.Areas.CT 
elif rootaddress == 'T': 
        area = snap7.types.Areas.TM

能够看到目前反对的”M”,“Q”,“C”,“T”四种类型,除了这四种以外,S7 还反对”PE”,“DB”这两种。明天咱们就来增加”DB”的反对。

首先增加一个新的”rootaddress”的查看,当值为”DB”的时候将”area”变量设为”snap7.types.Areas.DB”:

代码如下:


 elif rootaddress == 'DB': 
        area = snap7.types.Areas.DB

至此,驱动批改结束

第四步:打包驱动并运行 PLC 的数字孪生(deviceShifu)

接下来咱们对这个驱动进行打包,在“siemensPLCDeviceShifu”中有一个现成的 Dockerfile,咱们间接利用它来对驱动进行打包,只需执行“docker build . -t edgenesis/plc-device:v0.0.1”即可:

shifu/examples/siemensPLCDeviceShifu$ docker build . -t edgenesis/plc-device:v0.0.1 
[+] Building 65.0s (10/10) FINISHED                                                                                                                                                             
 => [internal] load build definition from Dockerfile                                                                                                                                      0.0s 
 => => transferring dockerfile: 298B                                                                                                                                                      0.0s 
 => [internal] load .dockerignore                                                                                                                                                         0.0s 
 => => transferring context: 2B                                                                                                                                                           0.0s 
 => [internal] load metadata for docker.io/library/python:3.9-slim-bullseye                                                                                                              11.4s 
 => [auth] library/python:pull token for registry-1.docker.io                                                                                                                             0.0s 
 => [1/4] FROM docker.io/library/python:3.9-slim-bullseye@sha256:dea558731860898a00ac0d004fcd67fff6a0a0d420af15d7ec4289fac5ab3df5                                                         8.5s 
 => => resolve docker.io/library/python:3.9-slim-bullseye@sha256:dea558731860898a00ac0d004fcd67fff6a0a0d420af15d7ec4289fac5ab3df5                                                         0.0s 
 => => sha256:1078a59cbb2c5273b0f18e6ad6b78aa01298be2b3a54365ed7ddf3b5d68f5c54 1.37kB / 1.37kB                                                                                            0.0s 
………………………………………. 
 => => extracting sha256:8c7a905e65a9f4baafcf16861113440e68c6144d7c3a7e701482086992492f70                                                                                                 0.2s 
 => [internal] load build context                                                                                                                                                         0.0s 
 => => transferring context: 3.91kB                                                                                                                                                       0.0s 
 => [2/4] COPY requirements.txt .                                                                                                                                                         0.2s 
 => [3/4] RUN pip install --no-cache-dir -r requirements.txt                                                                                                                             44.5s 
 => [4/4] COPY siemens-plc.py .                                                                                                                                                           0.0s 
 => exporting to image                                                                                                                                                                    0.2s 
 => => exporting layers                                                                                                                                                                   0.2s 
 => => writing image sha256:9c5802b3e55e0b9b498dc05be642b4aff1c60098531156af747469cc795a7120                                                                                              0.0s 
 => => naming to docker.io/edgenesis/plc-device:v0.0.1 

因为是在本地执行的,所以让咱们将这个驱动的镜像载入到 kind 集群中,命令为“kind load docker-image edgenesis/plc-device:v0.0.1”:

$ kind load docker-image edgenesis/plc-device:v0.0.1 
Image: "edgenesis/plc-device:v0.0.1" with ID "sha256:9c5802b3e55e0b9b498dc05be642b4aff1c60098531156af747469cc795a7120" not yet present on node "kind-control-plane", loading

在“examples/siemensPLCDeviceShifu/plc-deployment”文件夹中咱们提供了四个文件,能够将 PLC 的数字孪生一键部署到 Kubernetes 集群中:

├── plc-deviceshifu-configmap.yaml 
├── plc-deviceshifu-deployment.yaml 
├── plc-deviceshifu-service.yaml 
└── plc-edgedevice.yaml

首先咱们要批改 PLC 设施的地址,本教程中的 PLC 设施地址在“192.168.0.1”,咱们须要批改“plc-deviceshifu-deployment.yaml”中的”PLC_ADDR”环境变量来让咱们的容器应用这个 IP 来进行连贯:

- name: PLC_ADDR 
 value: "192.168.0.1" 

改好后,咱们就能够通过“Kubectl apply -f examples/siemensPLCDeviceShifu/plc-deployment”来部署

$ kubectl apply -f examples/siemensPLCDeviceShifu/plc-deployment/ 
configmap/plc-configmap-0.0.1 created 
deployment.apps/edgedevice-plc-deployment created 
service/edgedevice-plc created 
edgedevice.shifu.edgenesis.io/edgedevice-plc created

接下来让咱们运行一个 nginx 利用来演示如何与 PLC 进行交互,命令为:

curl "edgedevice-plc/sendsinglebit?rootaddress=DB&address=<address>&start=<start>&digit=<digit>&value=<0/1>" 

最初一步:运行成果

root@nginx:/# curl "edgedevice-plc/sendsinglebit?rootaddress=DB&address=0&start=0&digit=0&value=1";echo 
Changed from bytearray(b’\x00\x00’) to bytearray(b’\x01x00’) 
root@nginx:/# curl edgedevice-plc/getcontent?rootaddress=Q;echo 
0b0000000000000001 

至此,教程完结

总结

在此篇文章中,咱们通过扩大 Shifu 的西门子 PLC 驱动的能力,实现了近程操纵改写 PLC 中 DB 的值。

能够看到,通过对驱动能力的减少也减少了 Shifu 的能力。

本文中的更改并没有提交到 GitHub 中,如果是您须要的需要,或者您刚好看到,无妨来咱们的 GitHub 提交一个 PR😊第一个提交的人咱们将会给您筹备一份小礼物以示感激

十分感谢您看到了这里,咱们期待您的反馈,如果感觉文章写得不错或者有任何倡议请毫不犹豫地留言。

本文由博客群发一文多发等经营工具平台 OpenWrite 公布

正文完
 0