【Python】OPC UA模拟服务器实现

目录

      • 服务器模拟
        • 1. 环境准备
        • 2. 服务器设置
        • 3. 服务器初始化
        • 4. 节点操作
        • 5. 读取CSV文件
        • 6. 运行服务器
      • 查看服务器
      • 客户端
      • 总结

 在工业自动化和物联网(IoT)领域,OPC UA(开放平台通信统一架构)已经成为一种广泛采用的数据交换标准。它提供了一种安全、可靠且独立于平台的方式来访问实时数据。在本文中,我们将探讨如何使用Python和OPC UA库来创建一个高效的数据服务器,该服务器能够从CSV文件读取数据,并允许OPC UA客户端访问这些数据。

服务器模拟

1. 环境准备

确保您的Python环境中已安装opcua库。如果未安装,请使用以下命令进行安装:

pip install opcua

导入python库

import argparse
import csv
import time
from typing import List
from opcua import Server, Node, ua
2. 服务器设置

首先,我们定义命令行参数来配置服务器地址、端口和数据源路径。

parser = argparse.ArgumentParser(description="OPCUA模拟服务器")

# 添加参数
parser.add_argument("--ip", "-i", default="0.0.0.0", help="服务器地址")
parser.add_argument("--port", "-p", default=4840, type=int, help="服务器端口")
parser.add_argument("--source", "-s", default="opcua_data.csv", help="数据源路径")
parser.add_argument("--type", "-t", default="fanuc", help="模拟类型")
# 解析命令行参数
args = parser.parse_args()

CSV_FILE = args.source
SERVER_URL = "opc.tcp://" + str(args.ip) + ":" + str(args.port)
SERVER_TYPE: str = args.type

参数:
在这里插入图片描述

3. 服务器初始化

接着,我们初始化OPC UA服务器,并设置命名空间。

# 创建服务器实例
server = Server()
# 设置服务器端口
server.set_endpoint(SERVER_URL)
# 创建一个命名空间
uri = "http://opcua.simulator.com"
idx = server.register_namespace(uri)
4. 节点操作

定义函数来处理节点信息,并添加或更新节点。

# 获取对象节点,它通常是根节点的第一个孩子
objects = server.get_objects_node()
node_cache_dict = {}


def get_node_dict(node_info: str):
    pairs = node_info.split(";")
    if len(pairs) <= 1:
        return {"ns": idx, "s": node_info}
    data = {}
    for pair in pairs:
        key, value = pair.split("=")
        data[key] = value
    return data


def add_node(parent: Node, node_name, value, node_dict: dict, node_type="obj"):
    node_path = node_dict.get("s")
    node_ns = node_dict.get("ns")
    node_id = node_dict.get("i")
    # 检查节点是否已经存在
    children: List[Node] = parent.get_children()
    for child in children:
        browse_name: ua.QualifiedName = child.get_browse_name()
        if browse_name.Name == node_name:
            return child  # 返回已存在的节点

    # 如果节点不存在,创建它
    if node_type == "var":
        if SERVER_TYPE.upper() == "FANUC":
            node_idx = f"ns={node_ns};i={node_id}" if node_id else idx
        else:
            node_idx = f"ns={node_ns};s={node_path}"
        new_node = parent.add_variable(node_idx, node_name, str(value))
    else:
        new_node: Node = parent.add_object(idx, node_name)
        # new_node.set_writable()  # 设置变量为可写
    return new_node


def set_node_value(node_info: str, value):
    node_dict = get_node_dict(node_info)
    node_path: str = node_dict.get("s")
    if node_path.startswith("/Server/"):
        return
    try:
        last_node: Node = node_cache_dict.get(node_path)
        if last_node is None:
            # 递归查找或创建节点
            parent = objects
            parts = node_path.split("/")
            for part in parts[:-1]:  # 遍历除了最后一个节点的所有节点
                if part == "":
                    continue
                parent = add_node(
                    parent, part, value, node_dict
                )  # 创建节点(如果不存在)

            # 设置或更新最后一个节点的值
            last_node_name = parts[-1]
            last_node = add_node(parent, last_node_name, value, node_dict, "var")
            node_cache_dict[node_path] = last_node
        last_node.set_value(str(value))
    except Exception as e:
        print(f"Error setting node value: {e}")
5. 读取CSV文件

使用csv模块读取CSV文件,并更新OPC UA节点的值。

csv.field_size_limit(500 * 1024 * 1024)

try:
    with open(CSV_FILE, "r") as csvfile:
        csvreader = csv.reader(csvfile)
        header = next(csvreader)
        row = next(csvreader)
        for i in range(len(header)):
            set_node_value(header[i], row[i])  # 首次创建节点

        server.start()  # 启动服务器(先创建结构再启动server)
        print(f"Server started at {SERVER_URL}")

        # 每秒读取csv中的一行,更新节点值
        while True:
            try:
                row = next(csvreader)
                for i in range(len(header)):
                    set_node_value(header[i], row[i])
                time.sleep(1)
            except StopIteration:
                csvfile.seek(0)  # 回到文件开头
                next(csvreader)  # 跳过表头
finally:
    server.stop() if server else None
6. 运行服务器

执行脚本,服务器将启动,并开始从CSV文件读取数据更新OPC UA节点。

python opcua_simulator.py --ip 0.0.0.0 --port 4840 --source opcua_data.csv

查看服务器

可以使用 UA Sample Client (下载链接)软件连接到创建的opcua服务器查看结构和数据。
在这里插入图片描述
数据监控:
请添加图片描述

客户端

【Python】OPC UA 服务器与客户端的实现

总结

 本文介绍了如何使用Python和OPC UA库创建一个模拟服务器。通过读取CSV文件,服务器能够动态更新OPC UA节点的值,这对于开发和测试OPC UA客户端应用程序非常有用。您可以按照上述步骤进行实践,并根据具体需求调整代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/555326.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用Docker部署WPS Office服务并实现无公网IP远程处理文档表格

文章目录 1. 拉取WPS Office镜像2. 运行WPS Office镜像容器3. 本地访问WPS Office4. 群晖安装Cpolar5. 配置WPS Office远程地址6. 远程访问WPS Office小结 7. 固定公网地址 wps-office是一个在Linux服务器上部署WPS Office的镜像。它基于WPS Office的Linux版本&#xff0c;通过…

【深入解析spring cloud gateway】13 Reactive Feign的使用

问题引入 在gateway中如果使用feignClient的话&#xff0c;会报如下错误 java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-3at reactor.core.publisher.BlockingSingleSubscriber.bloc…

合并区间详解

题目&#xff1a; 大体思路&#xff1a; 先排序&#xff0c;设置一个新数组&#xff0c;将原数组遍历的第一位添加到新数组&#xff0c;之后不断的将遍历原数组后的起始位置和新数组的终止位置进行比较&#xff0c;大于&#xff0c;则添加到新数组&#xff0c;不大于&#xff…

OpenHarmony轻量系统开发【13】鸿蒙小车开发

13.1 小车介绍 基于鸿蒙系统 Hi3861 的WiFi小车 首先&#xff0c;我们得有一套WiFi小车套件&#xff0c;其实也是Hi3861 加上电机、循迹模块、超声波等模块。 小车安装完大概是这样&#xff1a; 13.2 电机驱动 我们这里先只做最简单的&#xff0c;驱动小车的电机&#xff…

Simlab python二次开发1-将所有缸套内表面半径加大1mm

Simlab python二次开发1-将所有缸套内表面半径加大1mm 1、打开模型文件2、getBodiesWithSubString&#xff08;&#xff09;从名字得到Bodies3、建Body类Group3.1、定义放入Group中的Bodies3.2、建Group 4、将缸套内表面建组&#xff0c;并扩半径1mm4.1、simlab.getBodiesFromG…

【嵌入式之中断】

Cortex-M4集成了嵌套式矢量型中断控制器(Nested Vectored Interrupt Controller (NVIC))来实现高效的异常和中断处理。NVIC实现了低延迟的异常和中断处理&#xff0c;以及电源管理控制。它和内核是紧密耦合的。 凡是打断程序顺序执行的事件都称为异常&#xff08;exception&am…

Gitlab: Python项目CI/CD实践

目录 1. 说明 2. 准备工作 2.1 服务器 2.2 开发机hosts文件 2.3 项目 3. 步骤过程 3.1 建仓Fastapi T1 3.2 开发机测试构建与推送 ​编辑 3.3 在工作站添加gitlab-runner 3.4 提交代码&#xff0c;查看Pipelines结果 3.5 观察部署情况 4. 参考 1. 说明 分别以一个…

线程互斥及基于线程锁的抢票程序

我们实现一个简单的多线程抢票程序。 #include<iostream> #include<thread> #include<unistd.h> #include<functional> #include<vector> using namespace std; template<class T> using func_tfunction<void(T)>;//返回值为void,…

leetcode刷题(python)——(四)

01.02.03 练习题目&#xff08;第 04 天&#xff09; 1. 0048. 旋转图像 1.1 题目大意 描述&#xff1a;给定一个 n n n \times n nn 大小的二维矩阵&#xff08;代表图像&#xff09; m a t r i x matrix matrix。 要求&#xff1a;将二维矩阵 m a t r i x matrix matr…

点云的投影------PCL

点云的投影 /// <summary> /// 参数化模型投影点云 /// </summary> /// <param name"cloud">点云</param> /// <param name"x">投影平面x面的系数</param> /// <param name"y"></param> /// &…

【Qt-Qt Creator使用技巧】

工具-Qt Creator ■ 使用技巧■ 定义触发片段■ Qt Creator 行编辑■ 代码注释■ 代码补全■ 快速给函数添加定义■ 创建书签■ 同步列输入■ 局部替换■ 源代码阅读■ 源码调试■ 使用技巧 ■ 定义触发片段 ■ Qt Creator 行编辑 shift + alt + up / down来获得多个游标。 …

第二部分 Python提高—GUI图形用户界面编程(三)

简单组件学习 Radiobutton 单选按钮、Checkbutton 复选按钮和canvas 画布 文章目录 Radiobutton 单选按钮Checkbutton 复选按钮canvas 画布 Radiobutton 单选按钮 Radiobutton 控件用于选择同一组单选按钮中的一个。Radiobutton 可以显示文本&#xff0c;也可以显示图像。 f…

CUDA编程---线程束洗牌指令

从Kepler系列的GPU&#xff08;计算能力为3.0或更高&#xff09;开始&#xff0c;洗牌指令&#xff08;shuffle instruction&#xff09;作为一种机制被加入其中&#xff0c;只要两个线程在相同的线程束中&#xff0c;那么就允许这两个线程直接读取另一个线程的寄存器。 洗牌指…

程序员购车指南

哈喽大家好&#xff0c;我是咸鱼。 爱车可以说是大部分男人的天性&#xff0c;而我对汽车的热情却远不及对手表的钟爱&#xff08;痴迷劳力士&#xff09;。以至于我的朋友掏出车钥匙指着上面的苹果树标志跟我介绍奔驰 AMG 系列的强劲性能和马力时&#xff0c;我只能尽量假装自…

C++的继承

目录 前言 继承的概念和定义 访问权限表 基类和派生类对象的赋值转换 继承中的作用域 派生类的默认成员函数 继承与友元 继承与静态成员 复杂的菱形继承和菱形虚拟继承 菱形虚拟继承 观察内存 注意事项&#xff1a;对象在内存中的存储顺序是按声明的顺序存储的 …

Python分析之3 种空间插值方法

插值是一个非常常见的数学概念,不仅数据科学家使用它,而且各个领域的人们也使用它。然而,在处理地理空间数据时,插值变得更加复杂,因为您需要基于几个通常稀疏的观测值创建代表性网格。 在深入研究地理空间部分之前,让我们简要回顾一下线性插值。 为了演示的目的,我将使…

ansible模块实战-部署rsync服务端

目录 1、根据部署流程所用到的命令找出模块 2.实战部署 2.1 服务部署&#xff1a;yum 安装 2.2 准备好rsync服务的配置文件 &#xff0c;并将配置文件通过copy模块分发给192.168.81.136这台受控主机 2.3 创建虚拟机用户 2.4 创建密码文件和改权限 2.5 模块对应目录&…

2024百度网盘超级会员怎么购买才能最省钱且不会踩坑?我来给你分享一下

不知道百度网盘超级会员怎么买最便宜&#xff0c;我来告诉你通过百度网盘最新优惠活动最低仅需188元/年。下面就和大家详细分享百度网盘会员最便宜的购买方法&#xff0c;值得你收藏和点赞&#xff01;当我们需要选择网盘时&#xff0c;大部分同学都会选择百度网盘&#xff0c;…

2024年五一杯数学建模B题思路分析

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间&#xff1a;2024…

python聊天室

python聊天室 文章目录 python聊天室chat_serverchat_client使用方式1.局域网聊天2.公网聊天 下面是一个简单的示例&#xff0c;包含了chat_client.py和chat_server.py的代码。 chat_server chat_server.py监听指定的端口&#xff0c;并接收来自客户端的消息&#xff0c;并将消…