Python-opcua 编程(3)历史数据读写

        历史数据就是将opcua 信息模型中的某一些变量保存起来,以便Client 端程序能够读取历史数据,作各种数据处理。

       Opcua 标准指出历史数据的读写,主要包括:

  1.      属性 Historizing 当设置为True 时,该变量支持历史数据读写
  2.      属性 AccessLevel 设置为HistoryReadWirte

History 机制

存储方式:

  • 存储在内存
  • 存储在sqlite3 数据库中

我们重点关注Sqlite3 数据库方式。

Sqlite3

      SQLite是一种用C写的小巧的嵌入式数据库,它的数据库就是一个文件。SQLite 不需要一个单独的服务器进程或操作的系统,不需要配置,这意味着不需要安装或管理,所有的维护都来自于SQLite 软件本身。python自带的轻量级数据库模块-sqlite3.python-opcua 的历史数据存储就是采用了python自带的sqlite3 实现的。具体的就是HistorySQLite 模块实现,它是一个类。

实例1 数据存储

import sys
sys.path.insert(0, "..")
import time
import mathfrom opcua import ua, Server
from opcua.server.history_sql import HistorySQLiteif __name__ == "__main__":# setup our serverserver = Server()server.set_endpoint("opc.tcp://127.0.0.1:48401/freeopcua/server/")# setup our own namespace, not really necessary but should as specuri = "http://examples.freeopcua.github.io"idx = server.register_namespace(uri)# get Objects node, this is where we should put our custom stuffobjects = server.get_objects_node()# populating our address spacemyobj = objects.add_object(idx, "MyObject")myvar = myobj.add_variable(idx, "MyVariable", ua.Variant(0, ua.VariantType.Double))myvar.set_writable()  # Set MyVariable to be writable by clientsmyvar1 = myobj.add_variable(idx, "MyVariable1", ua.Variant(0, ua.VariantType.Double))myvar1.set_writable()# Configure server to use sqlite as history database (default is a simple memory dict)server.iserver.history_manager.set_storage(HistorySQLite("my_datavalue_history.sql"))# starting!server.start()# enable data change history for this particular node, must be called after start since it uses subscriptionserver.historize_node_data_change(myvar, period=None, count=100)server.historize_node_data_change(myvar1, period=None, count=100)try:count = 0while True:time.sleep(1)count += 0.1myvar.set_value(math.sin(count))myvar1.set_value(1-math.sin(count))finally:# close connection, remove subscriptions, etcserver.stop()

从上述的程序可见:

定义了两个变量MyVariable和MyVariable1.

配置服务器的历史存储方式

  server.iserver.history_manager.set_storage(HistorySQLite("my_datavalue_history.sql"))

       HistorySQLite就是前面提及的访问sqlite 的类。它的源代码是history_sql.py。我认为,如果我们向物使用其它的数据库,例如 influxDB,mongoDB,TD Engine 等,大概只要改写history_sql.py模块就可以了。

执行上述程序行,将在程序所在目录中打开my_datavalue_history.sql文件,如果每一这样的文件,程序将自动兴建一个my_datavalue_history.sql文件。

另外就是实现历史数据值改变的handle就可以了。

 # enable data change history for this particular node, must be called after start since it uses subscriptionserver.historize_node_data_change(myvar, period=None, count=100)server.historize_node_data_change(myvar1, period=None, count=100)

      period是历史数据的存储周期,默认为7 天。操过这个时间会自动地被删除。count是存储数据的次数。

令人惊奇的是一旦设置完成,history 数据存储是完全自动地完成的。不需要额外的程序。

sqlite3 数据库的查看

my_datavalue_history.sql是一个二进制文件,在调试阶段如果要查看存储的数据,可以使用一个sqlite3 数据库浏览器程序,我使用DB Browser  for SQLite。可以在其官网下载,安装。

这是它的界面截图

浏览数据

 

值得一提的是,数据库表的名称是变量NodeId 的名称构成的。在我的程序中 

MyVariable的NodeId 是(ns=2,i=2)和(ns=2,i=3) 所以,对应表的名称为2_2 和2_3.

历史事件的存储

if __name__ == "__main__":# setup our serverserver = Server()server.set_endpoint("opc.tcp://localhost:48410/freeopcua/server/")# setup our own namespace, not really necessary but should as specuri = "http://examples.freeopcua.github.io"idx = server.register_namespace(uri)# get Objects node, this is where we should put our custom stuffobjects = server.get_objects_node()# populating our address spacemyobj = objects.add_object(idx, "MyObject")# Creating a custom event: Approach 1# The custom event object automatically will have members from its parent (BaseEventType)etype = server.create_custom_event_type(2, 'MyFirstEvent', ua.ObjectIds.BaseEventType,[('MyNumericProperty', ua.VariantType.Float),('MyStringProperty', ua.VariantType.String)])# create second eventetype2 = server.create_custom_event_type(2, 'MySecondEvent', ua.ObjectIds.BaseEventType,[('MyOtherProperty', ua.VariantType.Float)])# get an event generator for the myobj node which generates custom eventsmyevgen = server.get_event_generator(etype, myobj)myevgen.event.Severity = 500myevgen.event.MyStringProperty = ua.Variant("hello world")myevgen.event.MyNumericProperty = ua.Variant(-456)# get another event generator for the myobj node which generates different custom eventsmyevgen2 = server.get_event_generator(etype2, myobj)myevgen2.event.Severity = 123myevgen2.event.MyOtherProperty = ua.Variant(1.337)# get an event generator for the server node which generates BaseEventTypeserverevgen = server.get_event_generator()serverevgen.event.Severity = 111# Configure server to use sqlite as history database (default is a simple in memory dict)server.iserver.history_manager.set_storage(HistorySQLite("my_event_history.sql"))# starting!server.start()# enable history for myobj events; must be called after start since it uses subscriptionserver.iserver.enable_history_event(myobj, period=None)# enable history for server events; must be called after start since it uses subscriptionserver_node = server.get_node(ua.ObjectIds.Server)server.historize_node_event(server_node, period=None)try:count = 0while True:time.sleep(1)count += 0.1# generate events for subscribed clients and historymyevgen.trigger(message="This is MyFirstEvent " + str(count))myevgen2.trigger(message="This is MySecondEvent " + str(count))serverevgen.trigger(message="Server Event Message")# read event history from sqlend_time = datetime.utcnow()server_event_history = server_node.read_event_history(None, end_time, 0)finally:# close connection, remove subscriptions, etcserver.stop()

上述两个程序均能在spyder 中运行。希望能够帮到你。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

优化成本,探索WhatsApp API发送更经济的OTP验证信息

在现代的数字化世界中,安全性和使用者验证变得至关重要。随着移动应用程序和在线服务的普及,一次性密码(OTP)验证已经成为确保使用者身份验证的主要手段之一。然而,对于许多企业来说,发送OTP验证信息可能会…

多元回归预测 | Matlab基于高斯过程回归(GPR)的数据回归预测,matlab代码,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab基于高斯过程回归(GPR)的数据回归预测,matlab代码,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码

计算机体系结构基础知识介绍之缓存性能的十大进阶优化之关键词优先和提前重启以减少失误处罚、合并写入缓冲区以减少惩罚(五)

优化五:关键词优先,提前重启,减少漏判 处理器通常一次只需要缓存块中的一个字(word)。不要等待整个块被加载,而是在请求的字到达后就立即发送给处理器,并让处理器继续执行,同时填充…

加速大模型落地!使用4-bit训练Transformer,比FP16快2.2倍,提速35.1%

点击蓝字 关注我们 关注并星标 从此不迷路 计算机视觉研究院 公众号ID|计算机视觉研究院 学习群|扫码在主页获取加入方式 论文地址:https://arxiv.org/pdf/2306.11987.pdf 项目地址:https://github.com/xijiu9/Train_Transformers…

裸机搭建k8s报错记录

安装教程参考 修复一、 cd /etc/kubernetes/manifests vim kube-scheduler.yaml注释掉 重启 systemctl restart kubelet.service问题二、 https://github.com/kubernetes/kubernetes/issues/70202 一直处于创建中状态 网络原因 cat << EOF > /run/flannel/subnet.…

对卷积和全连接之间关系的学习(1*1卷积与全连接层可以互换吗?)

1.对于卷积和全连接 首先我们看一张图&#xff0c;它是一张关于卷积的操作&#xff1a; 然后在看关于全连接的操作&#xff1a; 从上面两张图中可以看出卷积的过程和全连接的过程&#xff0c;我们利用粉色的卷积核在image上进行卷积&#xff0c;进行内积计算得到输出值3&#…

uniapp zjy-calendar日历,uni-calendar日历增强版

一、zjy-calendar简介 zjy-calendar日历是对uniapp uni-calendar日历的增强&#xff0c;支持圆点和文字自定义颜色。 二、使用方法 源使用说明&#xff1a;https://uniapp.dcloud.net.cn/component/uniui/uni-calendar.html 1、下载导入 https://ext.dcloud.net.cn/plugin?…

django框架中使用ORM设计数据库的模型

ORM关联数据的逻辑是&#xff1a; Django 中常见的模型字段类型及其含义&#xff1a; AutoField&#xff1a;一个自动递增的整型字段&#xff0c;添加记录时它会自动增长。BigAutoField&#xff1a;一个自动递增的 biginteger字段&#xff0c;添加记录时它会自动增长。CharFie…

RPC 框架架构设计

RPC 框架架构设计 RPC 又称远程过程调用&#xff08;Remote Procedure Call&#xff09;&#xff0c;用于解决分布式系统中服务之间的调用问题。通俗地讲&#xff0c;就是开发者能够像调用本地方法一样调用远程的服务。下面我们通过一幅图来说说 RPC 框架的基本架构。 RPC 框架…

Nginx学习

文章目录 Nginx什么是NginxLinux安装与配置Nginx编译安装Nginxnignx使用nginx默认首页配置案例 localtion的匹配规则Nginx虚拟主机基于多IP的虚拟主机基于多端口的虚拟主机基于域名的虚拟机主机 反向代理案例①案例② 负载均衡案例①案例②分配策略 动静分离案例 配置Nginx网关…

分布式监控之Zabbix6.0监控系统一

分布式监控之Zabbix6.0监控系统 前言一、Zabbix1、介绍2、zabbix监控原理3、Zabbix6.0版本新特性4、Zabbix6.0功能组件5、Zabbix与Prometheus对比 二、Zabbix6.0部署1、部署zabbix服务端2、添加 zabbix 客户端主机3、自定义监控内容4、zabbix 自动发现5、zabbix 自动注册 前言 …

从零搭建一台基于ROS的自动驾驶车-----4.定位

系列文章目录 北科天绘 16线3维激光雷达开发教程 基于Rplidar二维雷达使用Hector_SLAM算法在ROS中建图 Nvidia Jetson Nano学习笔记–串口通信 Nvidia Jetson Nano学习笔记–使用C语言实现GPIO 输入输出 Autolabor ROS机器人教程 从零搭建一台基于ROS的自动驾驶车-----1.整体介…