C#实现数据采集系统-多设备采集

系统功能升级-多设备采集

数据采集系统在网络环境下,性能足够,可以实现1对多采集,需要支持多个设备进行同时采集功能,现在就开发多设备采集功能

修改多设备配置

设备配置

  1. DeviceLink 改成List集合的DeviceLinks
  2. 删掉Points,将点位集合放到对应的设备中去
    public class DaqOption{//单设备//public DeviceLink DeviceLink { get; set; }//多设备public List<DeviceLink> DeviceLinks { get; set; }public MqttConfig MqttConfig { get; set; }public ServiceConfig ServiceConfig { get; set; }//public List<RegisterPoint> Points { get; set; }public DaqOption() { }}/// <summary>/// 设备链路类/// </summary>public class DeviceLink{public string UID { get; set; }public string Ip { get; set; }public int Port { get; set; }public int SlaveId { get; set; } = 1;/// <summary>/// 采集周期 单位:S   200ms 0.2s/// </summary>public double AcqTimeSpan { get; set; }//增加public List<RegisterPoint> Points { get; set; }public DeviceLink(){Points = new List<RegisterPoint>();}}

同时配置文件也跟着变化,DeviceLinks改成数组形式,变成两个设备的配置

{"DeviceLinks": [{"UID": "device01","Ip": "127.0.0.1","Port": 502,"SlaveId": 1,"AcqTimeSpan": 1},{"UID": "device02","Ip": "127.0.0.1","Port": 503,"SlaveId": 1,"AcqTimeSpan": 1}],"MqttConfig": {//...},"ServiceConfig": {//...}
}

数据点位配置

RegisterPoint中增加设备Id的属性,用于区分,这个数据点位属于哪个设备

    public class RegisterPoint{//...public string DeviceId { get; set; }}

配置加载

DaqOptionBuilder修改配置加载,主要就是点位的加载,多设备配置的加载,按上面的配置修改后,自动反序列化加载。

点位的加载,需要读入新加的设备Id,然后根据设备id在DeviceLinks中查找到对应的设备,然后将点位加入到对应设备的点位集合Points中去。

 public class DaqOptionBuilder{//...public DaqOption Build(){var str = File.ReadAllText(_path + "\\Config.json");var option = JsonSerializer.Deserialize<DaqOption>(str);List<RegisterPoint> points = new List<RegisterPoint>();var lines = File.ReadAllLines(_path + "\\AllPoint.csv").ToList();lines.RemoveAt(0);foreach (var line in lines){var values = line.Split(',');var point = new RegisterPoint{UID = values[0],Name = values[1],Type = Type.GetType("System." + values[2]),RegisterType = values[3],Address = int.Parse(values[4]),Length = int.Parse(values[5]),DeviceId = values[6] //读入点位对应的设备ID};//查找对应的设备,将点位加入进去option.DeviceLinks.FirstOrDefault(x => x.UID == point.DeviceId)?.Points.Add(point);}return option;}}

主服务修改

多设备属性修改

修改DaqService服务类中,原来设备对象_deviceLink_points,改成设备集合_deviceLinks,然后对应的服务类中同步修改

 public class DaqService{// 原来// private DeviceLink _deviceLink;// private List<RegisterPoint> _points;//新private List<DeviceLink> _deviceLinks;public DaqService(DaqOption option){//...//修改_deviceLinks = option.DeviceLinks;//...}}

功能修改

在启动和定时推送中,都改成循环_deviceLinks来实现功能

 public void Start(){foreach (var item in _deviceLinks){ModbusTcp modbusTcp = new ModbusTcp(item);modbusTcp.ValueUpdated += ModbusTcp_ValueUpdated;modbusTcp.DoMitor();}mqttControllor = new MqttControllor(_option.MqttConfig);mqttControllor.MqttConnect();if (_serviceConfig.IsPushScheduled){_timer.Start();}}private void Timer_Elapsed(object? sender, ElapsedEventArgs e){foreach (var link in _deviceLinks){try{DeviceMessage deviceMessage = new DeviceMessage() { DeviceId = link.UID };foreach (var point in link.Points){Console.WriteLine($"Point:{point.UID}-->Value:{point.Value}");deviceMessage.Data.Add(point.UID, point.Value);}var str1 = JsonSerializer.Serialize(deviceMessage);mqttControllor.Publish("Device/" + link.UID + "/Time", str1);}catch (Exception ex){Console.WriteLine(ex.Message);}}}

在变化推送中,可以直接使用点位中DeviceId 替代原设备ID(_deviceLink.UID

 //事件方法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($"Device/{point.DeviceId}/Update", data); //采集立刻推送}catch (Exception ex){Console.WriteLine(ex.Message);}Console.WriteLine($"Point:{point.UID}-->Value:{value}");}}

完整的服务代码

 public class DaqService{private DaqOption _option;private List<DeviceLink> _deviceLinks;private ServiceConfig _serviceConfig;MqttControllor mqttControllor { get; set; }private Timer _timer;public DaqService(DaqOption option){_option = option;_deviceLinks = option.DeviceLinks;_serviceConfig = option.ServiceConfig;if (_serviceConfig.IsPushScheduled){_timer = new Timer(_serviceConfig.PushTimeSpan * 1000);_timer.Elapsed += Timer_Elapsed;}}public void Start(){foreach (var item in _deviceLinks){ModbusTcp modbusTcp = new ModbusTcp(item);modbusTcp.ValueUpdated += ModbusTcp_ValueUpdated;modbusTcp.DoMitor();}mqttControllor = new MqttControllor(_option.MqttConfig);mqttControllor.MqttConnect();if (_serviceConfig.IsPushScheduled){_timer.Start();}}private void Timer_Elapsed(object? sender, ElapsedEventArgs e){foreach (var link in _deviceLinks){try{DeviceMessage deviceMessage = new DeviceMessage() { DeviceId = link.UID };foreach (var point in link.Points){Console.WriteLine($"Point:{point.UID}-->Value:{point.Value}");deviceMessage.Data.Add(point.UID, point.Value);}var str1 = JsonSerializer.Serialize(deviceMessage);mqttControllor.Publish("Device/" + link.UID + "/Time", str1);}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($"Device/{point.DeviceId}/Update", data); //采集立刻推送}catch (Exception ex){Console.WriteLine(ex.Message);}Console.WriteLine($"Point:{point.UID}-->Value:{value}");}}}

最终实现效果

在这里插入图片描述

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

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

相关文章

运维开发——局域网SSH访问服务器与应用

摘要 本博文主要介绍局域网SSH访问登陆虚拟机和及其应用相关配置操作。 1. 局域网SSH访问登陆虚拟机 目标&#xff1a;在局域网内A电脑使用SSH登陆B电脑上虚拟机的服务器。 前提条件:B电脑为宿主机&#xff0c;可以正常使用ssh访问虚拟机服务器&#xff0c;虚拟机网络连接方…

数学强化| 李林880重点题速刷计划

快9月了&#xff0c;有的同学还没开始强化&#xff0c;进度确实有点慢了&#xff0c;有同学问&#xff1a; 刚开始强化&#xff0c;880题该如何快速刷完&#xff1f; 听我说&#xff0c;别急&#xff01;越是强化开始的晚&#xff0c;就越不能急&#xff0c;因为强化的作用有两…

【Datawhale AI 夏令营】第四期 基于2B源大模型 微调

定位&#xff1a;代码复现贴 教程&#xff1a;https://datawhaler.feishu.cn/wiki/PLCHwQ8pai12rEkPzDqcufWKnDd 模型加载 model AutoModelForCausalLM.from_pretrained(path, device_map"auto", torch_dtypetorch.bfloat16, trust_remote_codeTrue )AutoModelForC…

AI学习记录 - 如何快速构造一个简单的token词汇表

创作不易&#xff0c;有用的话点个赞 先直接贴代码&#xff0c;我们再慢慢分析&#xff0c;代码来自openai的图像分类模型的一小段 def bytes_to_unicode():"""Returns list of utf-8 byte and a corresponding list of unicode strings.The reversible bpe c…

压测工具哪个好?LoadRunner、Jmeter、Locust、Wrk 全方位对比....

当你想做性能测试的时候&#xff0c;你会选择什么样的测试工具呢&#xff1f;是会选择wrk&#xff1f;jmeter&#xff1f;locust&#xff1f;还是loadrunner呢&#xff1f;今天&#xff0c;笔者将根据自己使用经验&#xff0c;针对jmeter、locust、wrk和loadrunner常用的性能测…

前后端部署-服务器linux中部署Node.js环境

一.安装分布式版本管理系统Git (Alibaba Cloud Linux 3/2、CentOS 7.x) sudo yum install git -y 二.使用Git将NVM的源码克隆到本地的~/.nvm目录下&#xff0c;并检查最新版本。 git clone https://gitee.com/mirrors/nvm.git ~/.nvm && cd ~/.nvm && gi…

RVG29;狂犬病病毒肽;狂犬病病毒糖蛋白;115136-25-9;YTIWMPENPRPGTPCDIFTNSRGKRASNG

【RVG29 简介】 RVG29&#xff08;狂犬病病毒肽&#xff09;是一种由29个氨基酸组成的细胞穿透肽&#xff0c;它来源于狂犬病病毒糖蛋白。RVG肽能够特异性识别并结合中枢神经系统中普遍存在的烟碱型乙酰胆碱受体&#xff08;nAChR&#xff09;&#xff0c;并通过受体介导的转胞…

AR 眼镜之-系统应用音效-实现方案

目录 &#x1f4c2; 前言 AR 眼镜系统版本 系统应用音效 1. &#x1f531; 技术方案 1.1 技术方案概述 1.2 实现方案 1&#xff09;初始化 2&#xff09;播放音效 3&#xff09;释放资源 2. &#x1f4a0; 播放音效 2.1 静音不播放 2.2 获取音效默认音量 3. ⚛️ …

2.初识springcloud

文章目录 1.什么是SpringCloud1.1版本的介绍 2.Spring Cloud实现方案3.环境搭建4.服务拆分原则5.数据准备5.1订单服务5.2商品服务 大家好&#xff0c;我是晓星航。今天为大家带来的是 初识springcloud 相关的讲解&#xff01;&#x1f600; 1.什么是SpringCloud 简单来说&…

【算法基础实验】图论-最小生成树-Prim的即时实现

理论知识 Prim算法是一种用于计算加权无向图的最小生成树&#xff08;MST, Minimum Spanning Tree&#xff09;的贪心算法。最小生成树是一个连通的无向图的子图&#xff0c;它包含所有的顶点且总权重最小。Prim算法从一个起始顶点开始&#xff0c;不断将权重最小的边加入生成…

Excel表格添加趋势线_数据拟合

一个曲线通过补偿算法拟合为另一个曲线&#xff0c;通常可以通过多种数学和计算技术实现。这里也可以通过Excel表格添加趋势线&#xff0c;然后对趋势线进行拟合&#xff0c;得到趋势预测公式来达到数据补偿。 通过把你需要的数据导入到Excel表格中。 通过 “ 插入 ” --> “…

谷歌云AI新作:CROME,跨模态适配器高效多模态大语言模型

CROME: Cross-Modal Adapters for Efficient Multimodal LLM https://arxiv.org/pdf/2408.06610 Abstract 研究对象&#xff1a;Multimodal Large Language Models (MLLMs) demonstrate remarkable imagelanguage capabilities, but their widespread use faces challenges in…

论坛 推荐

畅议论坛&#xff1a;http://udbbs.top/http://udbbs.top/

查看U盘的具体信息,分区表格式、实际容量和分区状态

查看U盘的具体信息&#xff0c;分区表格式、实际容量和分区状态 前言&#xff1a; 利用windows自带的命令行窗口就可以 1、使用命令提示符查看MBR和GPT分区类型 &#xff08;1&#xff09;按“Windows R”键&#xff0c;在弹出的运行对话框中输入“diskpart”&#xff0c;并按…

游戏开发设计模式之工厂模式

目录 简单工厂模式&#xff08;Simple Factory Pattern&#xff09; 应用场景&#xff1a; 优缺点&#xff1a; 工厂方法模式&#xff08;Factory Method Pattern&#xff09; 应用场景&#xff1a; 优缺点&#xff1a; 抽象工厂模式&#xff08;Abstract Factory Patte…

碰撞检测 | 基于ROS Rviz插件的多边形碰撞检测仿真平台

目录 0 专栏介绍1 基于多边形的碰撞检测2 碰撞检测仿真平台搭建2.1 多边形实例2.2 外部服务接口2.3 Rviz插件化 3 案例演示3.1 功能介绍3.2 绘制多边形 0 专栏介绍 &#x1f525;课设、毕设、创新竞赛必备&#xff01;&#x1f525;本专栏涉及更高阶的运动规划算法轨迹优化实战…

Debian12安装tomcat8

jdk安装 安装Tomcat前需要先安装JDK&#xff0c;JDK安装参见&#xff1a; https://zhengshaoshaolin.blog.csdn.net/article/details/141407600 tomcat安装 1、下载安装 Apache Tomcat 访问官方 Apache Tomcat 下载页面&#xff0c;获取最新的二进制文件 或者使用如下的 wg…

Spring DI 数据类型—— set 方法注入

首先新建项目&#xff0c;可参考 初识IDEA、模拟三层--控制层、业务层和数据访问层 一、spring 环境搭建 &#xff08;一&#xff09;pom.xml 导相关坐标 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.or…

【Win开发环境搭建】Redis与可视化工具详细安装与配置过程

&#x1f3af;导读&#xff1a;本文档提供了Redis的简介、安装指南、配置教程及常见操作方法。包括了安装包的选择与配置环境变量的过程&#xff0c;详细说明了如何通过修改配置文件来设置密码和端口等内容。同时&#xff0c;文档还介绍了如何使用命令行工具连接Redis&#xff…

ArcGIS如何将投影坐标系转回为地理坐标系

有时候两个数据&#xff0c;一个为投影坐标系&#xff0c;另一个为地理坐标系时&#xff0c;在GIS软件中位置无法叠加到一起&#xff0c;这需要将两个或多个数据的坐标系统一&#xff0c;可以直接将地理坐标系的数据进行投影&#xff0c;或将投影坐标系转为地理坐标系。下面介绍…