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

Modbus Simulator

基于最近要进行modbus rtu/tcp的数据收集功能,测试代码放在github上,需要的友们,麻烦给个小星星⭐️:
git@github.com:feiyuluoye/mutil-modbus.git

Modbus Simulator 是一个使用 Go 实现的多模组 Modbus TCP 模拟系统,支持单实例模拟器、并发服务器管理、数据采集与文件导出等功能。项目旨在帮助快速构建 Modbus 联调、测试与演示环境。

功能概览

  • 最小 Modbus TCP 服务器,支持读 coils、discrete inputs、holding/input registers。
  • 基于 CSV 的寄存器周期写入,支持单实例与多实例并发运行。
  • 数据采集器可实时拉取点位数据,并按需落盘 JSONL/CSV。
  • 支持一次性快照导出,JSON/CSV 两种格式,便于排查和留存。

目录结构

  • cmd/server/:单服务器模拟器,读取 config.toml
  • cmd/servers/:并发服务器管理器,读取 config/config.yaml,可选快照。
  • cmd/collector/:数据采集器,支持 CLI 启用落盘功能。
  • cmd/export/:一次性快照导出 CLI。
  • internal/:核心实现(Modbus 服务、采集器、输出、模型等)。
  • config/:示例 YAML/TOML 配置。
  • data/:CSV 数据源及采集输出目录。

快速开始

  1. 安装 Go 1.20+
  2. 克隆仓库并进入目录
  3. go mod tidy
  4. 准备配置与 CSV 数据(可使用仓库自带示例)
  5. 参考下方命令运行需要的模块

运行示例

单服务器模拟器 + 客户端

RTU配置参考*.rtu.toml文件

go run ./cmd/server --config config.toml
go run ./cmd/client --config config.toml

并发服务器管理器

go run ./cmd/servers --config config/config.yaml# 仅当需要一次性导出快照时,加上 snapshot 参数
go run ./cmd/servers --config config/config.yaml \--snapshot-json out.json --snapshot-csv out.csv --snapshot-wait 5s

虚拟串口模拟

go run ./cmd/mocktty --config config/mocktty.yaml

展示效果如下:
请添加图片描述

当提供 --snapshot-json--snapshot-csv 时,程序会等待 --snapshot-wait 时长(默认 3s)以便 CSV 写入生效,随后导出快照并退出;否则常驻运行。

数据采集器

go run ./cmd/collector --config config/config.yaml# CLI 覆盖 storage 相关配置
go run ./cmd/collector --config config/config.yaml \--storage-enabled --storage-dir data --storage-queue 20000

system.storage.file_type 决定输出模式:

  • log:仅日志输出(默认 wrapHandler),不落盘。
  • csv:写入 storage-dir/collector.csv
    CSV 表头:timestamp, server_id, device_id, connection, slave_id, point_name, address, register, unit, value

JSONL 字段示例:

{"timestamp":"2025-09-29T14:45:32Z","server_id":"plc_server_1","device_id":"device_001","connection":"0.0.0.0:1502","slave_id":1,"point_name":"temperature","address":1,"register":"holding","unit":"","raw":21,"value":21}

一次性快照导出 CLI

go run ./cmd/export --config config/config.yaml \--json out.json --csv out.csv --wait 3s

cmd/export 会自启服务器,等待指定时长后导出当前快照并退出。

数据库与最新点位查询(ORM)

项目已迁移为使用 GORM(gorm.io/gorm)管理 SQLite 数据库,模型定义见 internal/model/modbus.go,ORM 辅助见 internal/db/orm.go

  • 连接与迁移:db.Open(path) 会自动创建并迁移表。
  • 采集入库:采集器通过 DB.SavePointValue() 写入 point_values

最新点位查询(去重规则变更)

DB.LatestPoints(ctx) 返回“最新点位值”列表,去重规则为复合键:server_id + device_id + name。即每个服务器-设备-点位名组合仅保留一条最新记录。

  • 返回结构(PointLatest):
    • server_id, device_id, name, address, register_type, data_type, byte_order, unit, value, timestamp

运行示例(examples/latest)

新增示例 examples/latest 用于查询并输出最新点位值(JSON):

# 全量最新点位
go run ./examples/latest -db ./data.sqlite -pretty=false# 仅过滤某个 server
go run ./examples/latest -db ./data.sqlite -server plc_server_1# 仅过滤某个 device
go run ./examples/latest -db ./data.sqlite -device device_001# 同时按 server 与 device 过滤
go run ./examples/latest -db ./data.sqlite -server plc_server_1 -device device_001

可选参数:

  • -db: SQLite 文件路径(默认 ./data.sqlite
  • -pretty: 是否美化 JSON(默认 true
  • -timeout: 查询超时(默认 5s
  • -server: 按 server_id 过滤(可选)
  • -device: 按 device_id 过滤(可选)

配置说明

TOML (config.toml, 供 cmd/server 使用)

[server]
listen_address = ":1502"[[registers]]
name = "temperature"
type = "holding"
address = 1
csv_column = "temperature"

YAML (config/config.yaml, 供 cmd/serverscmd/collector 使用)

  • servers[]: 定义每个服务器、设备与点位;points.name 需与 CSV 列名一致。
  • frequency: server_id -> duration,控制 CSV 写入周期。
  • type / devices_file: 服务器设备来源。
    • type: device(默认):从 devices 数组读取点位定义。
    • type: csvfile:通过 devices_file(相对或绝对路径)加载设备与点位,例如 data/plc_device_point.csv
  • system.storage: 控制采集器输出行为,示例:
system:storage:enabled: truefile_type: json+csv   # 支持 log | csv | json | json+csvdb_path: "data"max_workers: 0max_queue_size: 10000

CLI 参数 --storage-* 会覆盖上述配置。

CSV 数据 (data/example_data.csv)

列名需与点位名称一致,例如 temperature,humidity,pump,alarm

输出文件说明

  • 模拟器数据源:data/example_data.csv
  • 采集器输出:data/collector.jsonl, data/collector.csv(取决于 file_type
  • 服务器设备清单:data/plc_device_point.csv(示例,供 plc_server_2 使用)
  • 快照导出:按命令指定的 out.json, out.csv

CSV 行示例:

timestamp,server_id,device_id,point_name,address,register,unit,value

JSONL 行示例:

{"timestamp":"2025-09-29T13:38:00.123456789Z","server_id":"plc_server_1","device_id":"device_001","point_name":"temperature","address":1,"register":"holding","unit":"","raw":21,"value":21}

开发提示

  • internal/servermgr/manager.goSnapshot() 会按 YAML 点位读取当前寄存器值。
  • internal/collector/storage.go 使用缓冲队列异步写文件,max_queue_size 可调。
  • internal/output/exporter.go 支持 JSON/CSV 两种快照格式。

欢迎贡献更多协议扩展、输出格式或改进数据处理逻辑!

http://www.dtcms.com/a/546660.html

相关文章:

  • 网页设计网站期末作业石河子做网站
  • 温岭做网站的公司有哪些网页设计尺寸怎么测量
  • 怎么做网络乞丐网站在putty上怎样安装wordpress
  • 无锡网站建设818gx家装室内设计
  • 网站建设需要洽谈什么在centos上搭建wordpress
  • 域名代理商网站西安优秀的集团门户网站建设公司
  • 宠物出售的网站怎么做网站扁平化设计风格
  • MySQL 复合查询全解析:从单表到多表的实战进阶
  • 从0开始学Java--day7--类与对象-初
  • 用c 可以做网站吗做资讯类网站
  • 庄行网站建设免费wordpress中文主题
  • 深圳网站设计 制作wordpress评论框插件
  • 深圳培训网站开发山东省建设厅网站地址
  • 江苏网站开发建设多少钱服装公司网站多少钱
  • 网站建设进度计划表优享揭阳网站建设
  • 标准化信息网站建设与应用网站做多长时间才会成功
  • matlab示例
  • 做文案的网站有些什么建设网站人员名单
  • 公司名称 网站域名 关联常州模板网站建设价位
  • 网站3d特效源码电子商务网站建设与维护代码
  • 学生制作个人网站湖南建设监理报名网站
  • 有免费的微网站是什么上海的网站设计公司
  • 工信部网站备案注销网站广告推广怎么做的
  • Linux小课堂: 系统救援模式操作指南:修复启动问题与重置Root密码
  • 利用不坑盒子在WPS中插入网页,放映的电脑无需安装插件,直接就能显示网页!
  • 济南网络建站企业网站推广的策略有哪些
  • 南昌建网站那家好乐享黔程是什么公司
  • Vue 中 <keep-alive> 功能介绍,使用场景,完整使用示例演示
  • 上海做网站最低价做网站赚钱一般做什么
  • 《openEuler2403 与 PostgreSQL17 组合实战:搭建个人本地数据库服务》