当前位置: 首页 > news >正文

docker版jxTMS使用指南:使用jxTMS采集数据之二

本文是如何用jxTMS进行数据采集的第二部分,整个系列的文章请查看:docker版jxTMS使用指南:4.4版升级内容

docker版本的使用,请查看:docker版jxTMS使用指南

4.0版jxTMS的说明,请查看:4.0版升级内容

4.2版jxTMS的说明,请查看:4.2版升级内容

设备对数据的处理

设备接收到站点递交的消息后,会依次完成如下的工作:

1、根据配置用相应的策略来解析所接收到的消息

不同的设备有自己独特的编码方式,所以相应的解码工作单独抽离出来由该设备的策略来实现。当然,有的解码工作已经由站点在提取设备标识时就已经完成了,如使用自定义协议包传送数据的站点。

解析策略一般单独编写,然后注册到系统中。代码文件应放到app的相应目录中,并依次在各目录的__init.py__文件中引用。

main.py文件的加载顺序是先import app和module,然后再执行站点的初始化【加载站点和设备】,这就可以在站点加载时正确引用到相应的策略了。

2、触发数据接收事件来对数据做需要的处理

这里所说的处理主要指数据的转换、修正等针对数据本身的处理,如潮位仪收到测得的潮位数据后,要根据潮位仪安装点的标高换算成潮水的实时水位。

在业务上,很多时候我们还需要利用设备数据来启动业务处理。但笔者认为,为了提高系统的稳定性,最好将业务处理与此处所说的数据处理分隔开来,以最大化的降低代码的耦合度。

那么,不在此处启动业务处理,那在什么时候呢?!请参考之前的【本地数据总线】一文,笔者就是基于此种考虑,才增加了数据总线机制。

在需要执行业务处理时,通过向数据总线注册一个兴趣点来抄收设备接收并处理好的数据,然后完成需要的业务操作,从而将业务处理代码从整个设备数据处理流中分离出来,不会对设备的数据处理与保存过程产生任何干扰与影响。

尤其是在业务频繁变动的场景中,此种方案更具稳定性与可靠性。

3、设备数据的保存

接收并处理完毕的设备数据会被保存到数据库中,而这就需要完成两个动作:

  • 根据配置将处理后的设备数据保存到数据库中的哪个数据表中

  • 由于设备数据的采集频率可能会很高,如果数据的短期变化又不太重要,可以必要综合考虑是实时保存所有设备数据,还是周期性保存最新的设备数据

当给出了设备数据的保存间隔【saveDataInterval】参数时,该设备的数据将以saveDataInterval【单位:分钟】为间隔进行保存,如果该参数为0,则实时保存每一个新数据。

此外,由于设备的数据采集频次一般都很高,所以大多数情况下,都需要进行分表。如果需要分表的话,对于启动了jxTMS主系统的主站来说,只要在data文件中相应的数据类定义时指定rename属性即可。

注:如果是不启动jxTMS主系统的从站,如用于现场modbus设备采集,这些数据如果也需要保存到现场的数据库中,并同样需要分表,也很简单,一是【app/data/DieselGenerator.py】中展示的,提供一个_sql_createTable建表语句【通过查询主站所创建的该表的建表语句获得】;二是将此建表语句注册到jxTMS中:

ORM.registerSQL_createTable('DieselGenerator',_sql_createTable,renameType='day')

最后,在main.py中调用:

#启动创建需要分表的调度器
ORM.startRenameTableScheduler()

从站即会同样完成所有注册建表语句时指定了renameType的分表工作。

原则上,我们建议尽可能的使用jxTMS主系统来完成分表工作,原因很简单,风险有点高。python侧来执行分表工作,就意味着,真有需要调整data中的数据类定义的时候,必须同时完成:

  • 修改data文件中的数据类定义,否则java的jxTMS主系统在管理时会出错

  • 修改mysql中该数据库表的定义【新的表会自动更新】

  • 修改python侧的建表语句,并重启python侧的代码

前两者都比较简单,尤其是mysql比较熟悉的情况下;但后者,必须进行相关的全业务测试,尤其是还需要重启服务器,所以风险高了很多。

分表数据的查询,可以利用前面文章中讲解过的query对象【参考:数据查询】,非常的简便。

4、站点综合

一般情况下,站点都是管理方面的作用大于数据处理方面的作用,如开通、停运、对设备的管理/配置等。但有时也确实需要站点综合下属所有设备的数据以提供业务上的支撑。

如,配电系统的告警处理,管理方关心的是母线电压、储电系统的SOC等配电系统的综合性健康指标。但这些指标却是分别采集自下属的各个设备的某几个数据点。

这种情况下,以站点来统一过滤并综合这些关键指标就是必然的选择了。

因此,站点在接收并提取出设备信息后,调用distribute函数来将接收到的数据分发给相应的设备:

def distribute(self, d, data):

其使用一般是在站点的receive中,如site_multiDev_push类型的站点:

def receive(self, bsMsg):s = str(bsMsg,"utf8")js = json.loads(s)dn = js.get('dn')if not dn is None:d = self.getDev(dn)if not d is None:self.distribute(d,js)

distribute在向下属设备分发数据后,会将设备回传的数据回传给站点内部的receiveData函数,以完成站点的数据综合处理框架。该框架完成:

  • 设备对站点的通知,目前主要是跟踪状态改变以完成相应的告警处理

  • 站点触发onReceive事件来对设备回送的数据进行必要的综合

  • 如果必要【重载newOrmData函数并返回站点数据对象】,保存【实时或周期性】站点综合后的数据

5、数据联动

数据处理完毕,设备会通过数据总线发送自己接收并处理完毕的数据,所有对该设备的数据感兴趣者,都可以注册到数据总线上,接收到此新收数据事件并执行自己的处理。

前文说过,jxTMS以此种方式实现数据处理与业务处理的隔离,以提供更好的灵活性、弹性。比如,不停机重启的动态升级业务功能。

所以,使用jxTMS时应尽可能的将数据方面的处理与业务方面的处理区分出来,在设备与站点的onReceive事件【需要的话】中只完成数据转换、调整、综合、加工等工作。和业务相关的处理则通过监听数据总线的方式放到另外的代码模块中完成。

这种方式虽然看起来比较繁琐,而且效率有些低,但由于充分的隔离了数据处理与业务处理,所以业务的变动不会干扰到数据处理框架的正常工作,使得不管什么样情况下,总能稳定而可靠的接收、处理并保存正确的数据。

目前,数据总线还只是本地的数据总线,有需要的话,数据总线可以基于MQ实现异机联动,就如jxTMS的java侧管控平台那样,从而进一步的提高数据处理的稳定性与可靠性。

6、告警

目前主要是针对超时未接收到设备数据发出告警。

现版本是将告警放到了设备处,考虑到收不到数据一是设备故障、二是线路故障,所以新版本会将告警收到站点处进行,以兼顾这二者。

新版本的故障告警机制是:

  • 某站点处于正常状态时【刚开机或当下属所有设备都正常工作时】第一次收到失联,则发送故障告警

  • 当出现失联后,每半个小时发送一次当前的故障综述,即当前失联设备的列表与第一次故障的时间点

  • 当所有失联设备都恢复正常后,发送一个全站恢复的通知

目前,jxTMS只有一个默认的钉钉告警策略,但如果服务器网络中断,则依然无法发出告警,所以如果对告警非常敏感,还应增加一个网络之外的告警通道或机制。

参考资料:

jxTMS设计思想

jxTMS编程手册

下面的系列文章讲述了如何用jxTMS开发一个实用的业务功能:

如何用jxTMS开发一个功能

下面的系列文章讲述了jxTMS的一些基本开发能力:

jxTMS的HelloWorld

相关文章:

docker版jxTMS使用指南:使用jxTMS采集数据之二

本文是如何用jxTMS进行数据采集的第二部分,整个系列的文章请查看:docker版jxTMS使用指南:4.4版升级内容 docker版本的使用,请查看:docker版jxTMS使用指南 4.0版jxTMS的说明,请查看:4.0版升级内…...

系列六、Springboot操作RocketMQ

一、同步消息 1.1、发送&接收简单消息 1.1.1、发送简单消息 /*** 测试发送简单消息*/ Test public void sendSimpleMessage() {SendResult result rocketMQTemplate.syncSend("BOOT_TOPIC_SIMPLE", "我是一个简单消息");// 往[BOOT_TOPIC_SIMPLE]主…...

【jupyter异常错误】Kernel started:No module named ipykernel_launcher

尝试过的方案 pip install ipykernel 执行之后提示已经安装,但是执行代码依然报错 解决方案 python -m pip install ipykernel -U --force-reinstall 相当于是强制重新安装 安装成功后没有报错 注:根本原因应该是原来安装的包存在问题,虽然检测出来已经存在&#xf…...

使用langchain与你自己的数据对话(五):聊天机器人

之前我已经完成了使用langchain与你自己的数据对话的前四篇博客,还没有阅读这四篇博客的朋友可以先阅读一下: 使用langchain与你自己的数据对话(一):文档加载与切割使用langchain与你自己的数据对话(二):向量存储与嵌入使用langc…...

爬虫与搜索引擎优化:通过Python爬虫提升网站搜索排名

作为一名专业的爬虫程序员,我深知网站的搜索排名对于业务的重要性。在如今竞争激烈的网络世界中,如何让自己的网站在搜索引擎结果中脱颖而出,成为关键。今天,和大家分享一些关于如何通过Python爬虫来提升网站的搜索排名的技巧和实…...

2024软考系统架构设计师论文写作要点

一、写作注意事项 系统架构设计师的论文题目对于考生来说,是相对较难的题目。一方面,考生需要掌握论文题目中的系统架构设计的专业知识;另一方面,论文的撰写需要结合考生自身的项目经历。因此,如何将自己的项目经历和专业知识有机…...

【Maven】依赖范围、依赖传递、依赖排除、依赖原则、依赖继承

【Maven】依赖范围、依赖传递、依赖排除、依赖原则、依赖继承 依赖范围 依赖传递 依赖排除 依赖原则 依赖继承 依赖范围 在Maven中,依赖范围(Dependency Scope)用于控制依赖项在编译、测试和运行时的可见性和可用性。通过指定适当的依赖…...

数组slice、splice字符串substr、split

一、定义 这篇文章主要对数组操作的两种方法进行介绍和使用,包括:slice、splice。对字符串操作的两种方法进行介绍和使用,包括:substr、split (一)、数组 slice:可以操作的数据类型有:数组字符串 splice:数组 操作数组…...

程序漏洞:安全威胁的隐患

在当今数字化时代,计算机程序是现代社会的核心基石。然而,随着技术的进步,程序漏洞也成为了一个不可忽视的问题。程序漏洞可能导致数据泄露、系统崩溃、恶意攻击和经济损失等一系列问题。本文将深入探讨程序漏洞的定义、分类、影响和预防措施…...

0基础学C#笔记09:希尔排序法

文章目录 前言一、希尔排序的思想二、使用步骤总结 前言 希尔排序可以说是插入排序的一种变种。无论是插入排序还是冒泡排序,如果数组的最大值刚好是在第一位,要将它挪到正确的位置就需要 n - 1 次移动。也就是说,原数组的一个元素如果距离它…...

DOCKER的容器

1. 什么是Container(容器) 要有Container首先要有Image,也就是说Container是通过image创建的。 Container是在原先的Image之上新加的一层,称作Container layer,这一层是可读可写的(Image是只读的&#xff0…...

跳跃游戏——力扣55

文章目录 题目描述解法一 贪心题目描述 解法一 贪心 bool canJump(vector<int>& nums){int n=nums....

将本地项目上传至gitee的详细步骤

将本地项目上传至gitee的详细步骤 1.在gitee上创建以自己项目名称命名的空项目2.进入想上传的项目的文件夹&#xff0c;然后右键点击3. 初始化本地环境&#xff0c;把该项目变成可被git管理的仓库4.添加该项目下的所有文件5.使用如下命令将文件添加到仓库中去6.将本地代码库与远…...

iOS开发-导航栏UINavigationBar隐藏底部线及透明度

iOS 导航栏UINavigationBar隐藏底部线及透明度 苹果官方给出的解释&#xff1a; 如果你不调用方法设置一张背景图片的话&#xff0c;那就给你默认一张&#xff0c;然后同时还有一张阴影图片被默认设置上去&#xff0c;这就是导航栏上1px黑线的由来。 解决办法&#xff1a; 方…...

题目:2520.统计能整除数字的位数

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;2520. 统计能整除数字的位数 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 逐位判断即可。 解题代码&#xff1a; class Solution {public int countDigits(int num) {int res0;int ori…...

matplotlib 笔记 注释annotate

在图中的特定位置添加文本注释、箭头和连接线&#xff0c;以便更清晰地解释图形中的数据或信息 主要参数 text文本内容xy箭头指向的目标点的坐标xytext注释文本的坐标arrowprops 一个字典&#xff0c;指定注释箭头的属性&#xff0c;如颜色、箭头样式等 没有arrowprops的时候…...

Windows 无法安装到这个硬盘。选中的磁盘具有MBR分区。在EFI系统上,Windows只能安装到GPT磁盘

Windows无法安装到这个磁盘,选中的磁盘具有MBR分区表的解决方法 - 知乎 (zhihu.com) Windows无法安装到这个磁盘 选中的磁盘具有MBR分区表 - 知乎 (zhihu.com) 选中的磁盘具有MBR分区表&#xff0c;在EFI系统上&#xff0c;windows只能安装到GPT磁盘_选中的磁盘具有mbr分区表…...

学C的第三十三天【C语言文件操作】

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 学C的第三十二天【动态内存管理】_高高的胖子的博客-CSDN博客 1 . 为什么要使用文件 以前面写的通讯录为例&#xff0c;当通讯录运行起来的时候&#xff0c;可以给通讯录中增加、删…...

线性表的基本操作及在顺序存储及链式存储的实现

目录 线性表的基本操作&#xff1a;线性表的在顺序存储上的实现 线性表的基本操作&#xff1a; 一个数据结构的基本操作是指其最核心、最基本的操作。其他较复杂的操作可通过其基本操作来实现。线性表的主要操作如下 - InitList(&L):初始化表。构造一个空的线性表- Length…...

合宙Air724UG LuatOS-Air script lib API--nvm

nvm Table of Contents nvm nvm.init(defaultCfgFile, burnSave) nvm.set(k, v, r, s) nvm.sett(k, kk, v, r, s) nvm.flush() nvm.get(k) nvm.gett(k, kk) nvm.restore() nvm.remove() nvm 模块功能&#xff1a;参数管理 nvm.init(defaultCfgFile, burnSave) 初始化参数存储管…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...