Python + OPCUA + s7-1200 + MySql + Grafana实现工业数据可视化看板开发

“电气自动化搬砖打工人的IT探索之路”

        随着工业技术的发展,近年来越来越多的数字化、IOT、IT&OT融合等等各种高大上的字眼越来越多的出现在制造业领域。作为一个自动化从业者在眼花缭乱的同时,也确实看到了数字化在工业场景的应用, 未来IT在工业领域中的应用也将越来越多。为了跟上时代不掉队准备开始IT的探索之路,目标是桌面应用及WEB的全栈开发;

        本期内容将介绍如何使用Python通过OPCUA获取西门子S7-1200获取工业数据,并将数据写入到Mysql数据库中,作为Grafana的数据源。选择Python,是因为对于IT小白来讲这个容易上手,Mysql不用说是因为开源&免费,前端选择Grafana是因为兄弟的推荐,就尝试着做一做,基础较弱自己也不会选;先看完成后的效果图,并开启正式的介绍:

开发环境:

工具: Visual Studio Code

Python: 3.10.6

MySql:8.0.32

Grafana: 10.0.3

OPC Server: 西门子S7-1200(熟悉自动化行业的都应该知道,这里不过多解释)

第一章: python 通过OPC UA获取到S7-1200 PLC数据

        OPC UA是一种通信协议,全称为Open Platform Communications Unified Architecture。它是一种面向服务的架构,提供了一种标准化的方式来实现不同设备、系统、平台之间的相互通信和数据交换。在工业领域中应用非常广泛,本次使用西门子S7-1200 PLC内置的OPC UA功能,作为OPC UA服务器,python作为OPC UA 客户端获取服务器数据;

        本次直接使用opcua-python库实现python与opcua的通讯,虽然这个库已经停止更新,但是完成当前的工作已经绰绰有余了,当然还有一个高级的异步库opcua-asyncio,但是我尝试过不怎么会用,只能留着已有再说了;

opcua-python说明文档:https://python-opcua.readthedocs.io/en/latest/

opcua-python 安装:

直接使用PIP安装:

pip install opcua

等待完成后,可通过查看opcua信息查看是否安装完成:

C:\Users\Administrator>pip show opcua
Name: opcua
Version: 0.98.13
Summary: Pure Python OPC-UA client and server library
Home-page: http://freeopcua.github.io/
Author: Olivier Roulet-Dubonnet
Author-email: olivier.roulet@gmail.com
License: GNU Lesser General Public License v3 or later
Location: c:\users\administrator\appdata\local\programs\python\python310\lib\site-packages
Requires: lxml, python-dateutil, pytz
Required-by:

代码实现:

 1. 打开VS CODE新建一个.py文件,由于只是作为客户端适用,仅需从opcua库中导入client即可

from opcua import Client

2. 实例化opcua Client,这一步需要写入访问的opcua server的url,如果访问需要账号密码还需要添加账号密码到实例化客户端,由于链接过程中容易出代码参考如下:

while (True):
    try:
        # 实例化客户端,需要URL参数,timeout可以默认;
        client = Client(url="opc.tcp://192.168.0.80:4840", timeout=60000)
        # 账号秘密以实际为准
        client.set_user(opcParams['username'])
        client.set_password(opcParams['password'])
        # 客户端链接
        client.connect()
        # 链接成功后跳出循环,准备执行数据读取
        break
    except:
        logger.error("OPCUA链接失败,将在20S后重连;")
        time.sleep(20)

 3. 数据读取,opcua是通过NodeID(节点标识)来识别变量的读取,可以通过轮询获取该opc server下的所有节点数据,这个位置我也咩有整明白,暂时留着待以后再研究。这里推荐一个取巧的办法,可以通过UaExpert软件作为OPC Server的测试软件,链接成功后即可看到能访问到的节点信息;鼠标点击节点,即可看到节点对应的名称,有赢取同学可以看看,此处不再赘述;

节点再opcua库中是以列表的形式存在,由于我读取数据是连贯的,因此可以提前将面部分相同的节点提前配置完成,需要读取数据时再加上相对应的节点信息即可;参考代码如下

            for tag in dataParams:
                # 获取震动节点
                vibrateNode = []
                vibrateNode = vibrateNode + \
                    opcParams['rootnode']+["5:Vibrate_Data"]
                vibrateNode.append(f"5:{dataParams[tag]['vibrate']}")
                vibrateValue = client.get_root_node().get_child(vibrateNode).get_value()
                tagValues[f"{dataParams[tag]['vibrate']}"] = round(
                    vibrateValue, 3)

至此,opc ua数据读写完成;(代码中 dataparams是通过json作为配置文件,在python中读取获得),下一篇文章将分享,如何将获取数据写入到数据库,由于代码能力有限,文中表达有不合适的地方请见谅。、

完整代码:

def opcconnect(opcParams):
    while (True):
        try:
            client = Client(url=opcParams['url'], timeout=60000)
            client.set_user(opcParams['username'])
            client.set_password(opcParams['password'])
            client.connect()
            break
        except:
            logger.error("OPCUA链接失败,将在20S后重连;")
            time.sleep(20)
    return client
# 创建OPC 读取数据


def opcclient(opcParams, dataParams):
    client = opcconnect(opcParams)
    while (True):
        try:
            for tag in dataParams:
                # 获取震动节点
                vibrateNode = []
                vibrateNode = vibrateNode + \
                    opcParams['rootnode']+["5:Vibrate_Data"]
                vibrateNode.append(f"5:{dataParams[tag]['vibrate']}")
                vibrateValue = client.get_root_node().get_child(vibrateNode).get_value()
                tagValues[f"{dataParams[tag]['vibrate']}"] = round(
                    vibrateValue, 3)
                # 获取电流节点
                currentNode = []
                currentNode = currentNode + \
                    opcParams['rootnode']+["5:Current_Data"]
                currentNode.append(f"5:{dataParams[tag]['current']}")
                currentValue = client.get_root_node().get_child(currentNode).get_value()
                tagValues[f"{dataParams[tag]['current']}"] = round(
                    currentValue, 3)
        except:
            logger.error("OPCUA数据读取失败,将在10S后重试;")
            time.sleep(10)
            break
        logger.mylog('读取数据完成')
        logger.mylog(tagValues)
        time.sleep(opcParams['cycletime'])

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值