C#实现数据采集系统-数据反写(2)消息内容处理和写入通信类队列

server/2024/9/19 0:51:33/ 标签: c#, .netcore, mqtt

C#实现数据采集系统-数据反写

实现步骤

  1. MQTT订阅,接收消息 链接-MQTT订阅接收消息
  2. 反写内容写入通信类,添加到写入队列中
  3. 实现Modbustcp通信写入

具体实现

2. 消息内容写入通信类,添加到写入队列中

在服务类DAqService中添加通信集合_modbusTcps用于存储每个设备的通信类,使用键值对Dictionary存储设备ID和通信类,用于快速查找

然后在启动的时候,订阅各个设备ID的写入主题,添加控制方法DeviceControl

    public class DAqService{public static string MainTopic = "DTSDAQ/";private Dictionary<string, ModbusTcp> _modbusTcps;public DAqService(DAqOption option){_modbusTcps = new Dictionary<string, ModbusTcp>();//...}/// <summary>/// 启动服务/// </summary>public void Start(){MqttControllor = new MqttControllor(_option.MqttConfig);foreach (var item in _deviceLinks){ModbusTcp modbusTcp = new ModbusTcp(item);modbusTcp.DoMonitor();modbusTcp.ValueUpdated += ModbusTcp_ValueUpdated;//将_modbusTcps.Add(item.UID, modbusTcp);MqttControllor.SubscribeTopic($"{MainTopic}{item.UID}/write", DeviceControl);}if (_serviceConfig.IsPushScheduled){timer.Start();}}}

实现消息订阅方法-设备控制DeviceControl

处理消息,将消息转换成对应点位和值,然后调用modbustcp的写入方法

 <summary>
/// 设备控制,反写
/// </summary>
/// <param name="topic"></param>
/// <param name="msg"></param>
private void DeviceControl(string topic, string msg)
{var message = JsonSerializer.Deserialize<DeviceMessage>(msg);//如果消息不为null,则通过设备id找到对应的modbustcp对象,并写入值if (message != null){var link = _deviceLinks.FirstOrDefault(x => x.UID == message.DeviceId); //通过设备id找到对应的modbustcp对象if (link != null){var modbusTcp = _modbusTcps[link.UID]; //通过设备id找到对应的modbustcp对象//循环消息中的数据对象,然后再设备link对象点位中找到对应的点位对象,并写入值foreach (var item in message.Data){var point = link.Points.FirstOrDefault(x => x.UID == item.Key); //通过点位id找到对应的点位对象if (point != null){var parseMethod = point.Type.GetMethod("Parse",BindingFlags.Public | BindingFlags.Static,new[] { typeof(string) });point.WriteValue = parseMethod.Invoke(null,new object[] { item.Value.ToString() }); //通过点位id找到对应的点位对象}modbusTcp.Write(point);}}}
}

在ModbusTcp通信类中,添加一个写入队列和写入方法,写入点位先添加在队列中,然后再读数据间隙中,实现写入

 public class ModbusTcp{/// <summary>/// 写入队列/// </summary>private Queue<RegisterPoint> _writeQueue = new Queue<RegisterPoint>();·//写入值先加入一个队列public void Write(RegisterPoint point){_writeQueue.Enqueue(point);}}

完整代码

public class DAqService
{public static string MainTopic = "DTSDAQ/";private MqttControllor MqttControllor;private Dictionary<string, ModbusTcp> _modbusTcps;private DAqOption _option;private List<DeviceLink> _deviceLinks;private ServiceConfig _serviceConfig;private System.Timers.Timer timer;public DAqService(DAqOption option){_modbusTcps = new Dictionary<string, ModbusTcp>();_option = option;_deviceLinks = option.DeviceLinks;_serviceConfig = option.ServiceConfig;timer = new System.Timers.Timer(_serviceConfig.PushTimeSpan * 1000);timer.Elapsed += Timer_Elapsed;}/// <summary>/// 启动服务/// </summary>public void Start(){MqttControllor = new MqttControllor(_option.MqttConfig);foreach (var item in _deviceLinks){ModbusTcp modbusTcp = new ModbusTcp(item);modbusTcp.DoMonitor();modbusTcp.ValueUpdated += ModbusTcp_ValueUpdated;_modbusTcps.Add(item.UID, modbusTcp);MqttControllor.SubscribeTopic($"{MainTopic}{item.UID}/write", DeviceControl);}if (_serviceConfig.IsPushScheduled){timer.Start();}}/// <summary>/// 设备控制,反写/// </summary>/// <param name="topic"></param>/// <param name="msg"></param>private void DeviceControl(string topic, string msg){var message = JsonSerializer.Deserialize<DeviceMessage>(msg);//如果消息不为null,则通过设备id找到对应的modbustcp对象,并写入值if (message != null){var link = _deviceLinks.FirstOrDefault(x => x.UID == message.DeviceId); //通过设备id找到对应的modbustcp对象if (link != null){var modbusTcp = _modbusTcps[link.UID]; //通过设备id找到对应的modbustcp对象//循环消息中的数据对象,然后再设备link对象点位中找到对应的点位对象,并写入值foreach (var item in message.Data){var point = link.Points.FirstOrDefault(x => x.UID == item.Key); //通过点位id找到对应的点位对象if (point != null){var parseMethod = point.Type.GetMethod("Parse",BindingFlags.Public | BindingFlags.Static,new[] { typeof(string) });point.WriteValue = parseMethod.Invoke(null,new object[] { item.Value.ToString() }); //通过点位id找到对应的点位对象}modbusTcp.Write(point);}}}}private void Timer_Elapsed(object? sender, ElapsedEventArgs e){foreach (var link in _deviceLinks){try{DeviceMessage device = new DeviceMessage { DeviceId = link.UID };foreach (RegisterPoint point in link.Points){// Console.WriteLine($"Point:{point.UID}-->Value:{point.Value}");device.Data.Add(point.UID, point.Value);}var data = JsonSerializer.Serialize(device);MqttControllor.Publish($"{MainTopic}{link.UID}/Time", data); //定时推送}catch (Exception ex){Console.WriteLine(ex.Message);}}}private void ModbusTcp_ValueUpdated(RegisterPoint point, object value){if (_serviceConfig.IsPushChanged){try{DeviceMessage device = new DeviceMessage { DeviceId = point.DeviceId };device.Data.Add(point.UID, value);var data = JsonSerializer.Serialize(device);MqttControllor.Publish($"{MainTopic}{point.DeviceId}/Update", data); //采集立刻推送}catch (Exception ex){Console.WriteLine(ex.Message);}}Console.WriteLine($"Point:{point.UID}-->Value:{value}");}
}

http://www.ppmy.cn/server/106553.html

相关文章

MyBatis框架学习

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程&#xff1a;封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

NRC-SIM:基于Node-RED的多级多核缓存模拟器

整理自&#xff1a; 《NRC-SIM: A NODE-RED Based Multi-Level, Many-Core Cache Simulator》&#xff0c;由 Ezequiel Trevio 撰写&#xff0c;作为他在德克萨斯大学里奥格兰德河谷分校攻读电气工程硕士学位的部分成果。以下是论文的详细主要内容&#xff1a; 摘要(Abstract…

day41.动态规划

一.动态规划 121.买卖股票的最佳时机I 思路:dp[i][1] 表示第i天不持有股票所得最多现金 dp[i][0] 表示第i天持有股票所得最多现金 class Solution { public:int maxProfit(vector<int>& prices) {int len prices.size();if (len 0) return 0;vector<vector&…

强化学习第九章:策略梯度方法

强化学习第九章&#xff1a;策略梯度方法 思路优化函数优化函数的梯度求解 Monte Carlo policy gradient (REINFORCE)总结参考资料 思路 与上一章的思路类似&#xff0c; 状态-动作 对下标索引获取概率π(s, a)的方式转换为状态-动作对 或者状态输入到神经网络中&#xff0c;两…

DevOps实现CI/CD实战(三)- 集成Sonar Qube

七、集成Sonar Qube 1. SonarQube介绍 Sonar Qube是一个开源的代码分析平台&#xff0c;支持Java、Python、PHP、JavaScript、CSS等25种以上的语言&#xff0c;可以检测出重复代码、代码漏洞、代码规范和安全性漏洞的问题。 Sonar Qube可以与多种软件整合进行代码扫描&#…

TCP keepalive和HTTP keepalive区别

TCP 的 Keepalive 在传输层 是内核态实现的&#xff0c;是TCP的保活机制 当两端的TCP连接一直没有数据交互&#xff0c;就达到了触发TCP保活机制的条件&#xff0c;那么内核里的TCP协议栈就会发送探测报文。 如果对端程序是正常工作的&#xff0c;当TCP保活的探测报文发送到对…

wp-autopost-pro 3.7.8最新完美版

插件简介&#xff1a; 插件是wp-autopost-pro 3.7.8最新版本。 采集插件适用对象 1、刚建的wordpress站点内容比较少&#xff0c;希望尽快有比较丰富的内容&#xff1b; 2、热点内容自动采集并自动发布&#xff1b; 3、定时采集&#xff0c;手动采集发布或保存到草稿&#xff…

mysql数据表管理

数据表管理 如果将数据库管理系统与之前的文件管理系统做类比的话&#xff1a; 数据库管理系统文件管理系统数据库文件夹数据表文件夹下的文件 数据表的常见操作指令 进入数据库use 数据库&#xff0c;查看当前所有表:show tables 创建表结构 idnameemailage创建表的基础语…

Leetcode面试经典150题-13.罗马数字转整数

解法都在代码里&#xff0c;不懂就留言或者私信&#xff0c;这个是相对简单点的&#xff0c;感觉会在低职级面试的时候考 class Solution {/**罗马数字转整数还是比较简单的&#xff0c;基本思路&#xff1a;把罗马数字字符串转成字符数组同时创建一个int型数组&#xff0c;遍…

「C#」EF Core的“迁移”(Migration)

1、“迁移”是什么 “迁移”&#xff08;Migration&#xff09;我觉得可以理解为将实体类的变化 转换为对数据库修改的方案&#xff0c;应用迁移就是将这个修改方案应用到数据库。其次&#xff0c;迁移也记录了数据库的版本历史等信息。 2、添加迁移 2.1、dotnet cli tool …

设计模式之简单工厂模式

一 、定义 简单工厂模式是一种创建型设计模式&#xff0c;它提供一个统一的接口来创建对象&#xff0c;而不需要客户端直接实例化对象。简单工厂模式通过封装创建对象的逻辑&#xff0c;简化了对象的创建过程&#xff0c;同时也提高了代码的可维护性和扩展性。缺点是&#xff…

浅谈【数据结构】图-图的存储

目录 1、图的存储 2、邻接表 3、十字链表 谢谢帅气美丽且优秀的你看完我的文章还要点赞、收藏加关注 没错&#xff0c;说的就是你&#xff0c;不用再怀疑&#xff01;&#xff01;&#xff01; 希望我的文章内容能对你有帮助&#xff0c;一起努力吧&#xff01;&#xff01;…

计算机毕业设计pyspark+django+scrapy租房推荐系统 租房大屏可视化 租房爬虫 hadoop 58同城租房爬虫 房源推荐系统

用到的技术: 1. python 2. django后端框架 3. django-simpleui&#xff0c;Django后台 4. vue前端 5. element-plus&#xff0c;vue的前端组件库 6. echarts前端可视化库 7. scrapy爬虫框架 基于大数据的租房信息推荐系统包括以下功能&#xff1a…

选择排序【详解】

本期介绍&#x1f356; 主要介绍&#xff1a;排序中的选择排序。 文章目录 1. 前言2. 选择排序3. 优化选择排序 1. 前言 相信只要接触过C语言的同学都或多或少了解排序问题&#xff0c;其中最基本&#xff0c;且最为人所熟知的排序是&#xff1a;选择排序。下面我会带着大家重新…

JAVA后端程序拉取私人仓库的npm包并将该程序打包成jar包

当前有一个系统用于导出项目&#xff0c;而每次导出的项目并不可以直接使用&#xff0c;需要手动从npm私人仓库中获取一个npm包然后将他们整合到一起它才是一个完整的项目&#xff0c;所以目前我的任务就是编写一个java程序可以自动地从npm私人仓库中拉取下来那个模板代码到指定…

C语言文件操作

目录 文件指针 文件的打开和关闭 文件路径&#xff1a; 相对路径 绝对路径 文件的顺序读写 所有输出流&#xff1a; fputc&#xff1a; fgetc&#xff1a; fputs&#xff1a; fgets&#xff1a; fprintf&#xff1a; fscanf&#xff1a; fwrite&#xff1a; fre…

MVVM框架对比

框架名称 MvvmLigth CommunityToolkit.Mvvm Prism Caliburn.Micro 通知属性 ObservableObject ObservableObject BindableBase PropertyChangedBase ViewModel基类 ViewModelBase 无 无 Screen/Conductor 命令对象 RelayCommand RelayCommand DelegateComman…

人工智能-TensorFlow

TensorFlow 是一个非常流行的开源机器学习框架&#xff0c;它支持广泛的机器学习和深度学习任务。以下是使用 TensorFlow 完成机器学习和深度学习任务的基本步骤&#xff1a; 1. 安装 TensorFlow 首先需要安装 TensorFlow。可以通过 pip 命令来安装 TensorFlow&#xff1a; …

Day05-Unity Time类

&#x1f3c6; 个人愚见&#xff0c;没事写写笔记 &#x1f3c6;《博客内容》&#xff1a;Unity3D开发内容 &#x1f3c6;&#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f50e;目标&#xff1a;Unity Time类 ☀️实现&#xff1a; Time相关内容主要用作游戏中参与位…

如何使用ssm实现模具制造企业订单跟踪管理系统+vue

TOC ssm256模具制造企业订单跟踪管理系统vue 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;…