# ipc.winform **Repository Path**: LiuYGG/ipc.winform ## Basic Information - **Project Name**: ipc.winform - **Description**: 读写国内主流plc工具,对外自托管webApi,方便局域网内其他设备读写。欢迎各路大神使用修改,仿Kepserver - **Primary Language**: C# - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 3 - **Created**: 2026-06-05 - **Last Updated**: 2026-09-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: 窗体应用 ## README # IPC 使用文档 本文档面向现场调试、设备接入和上位系统调用人员,介绍 IPC 的安装、启动、项目配置、运行监视、MQTT、WebAPI、远程配置下发和常见问题。 ## 1. 软件用途 IPC 是一个 Windows 桌面 PLC 通信和边缘网关工具,用于配置设备、分组和标签,周期读取 PLC/OPC UA 数据,支持写入标签、MQTT 订阅/上报、报警预警、边缘规则、本地历史库、WebAPI 查询和远程配置下发。 当前支持的协议: - Rockwell CIP - Siemens S7 - Mitsubishi MC 3E - Mitsubishi MC 1E - Mitsubishi Serial - Mitsubishi Q/L Serial - Omron FINS - Modbus TCP - Modbus RTU - OPC UA - Virtual PLC - Plugin 插件驱动 边缘网关能力: - MQTT 订阅写值、采集值上报、心跳上报、报警/预警上报、规则事件上报。 - MQTT 断线持久缓存、PUBACK 后删除、重连补发。 - 点位统一模型:点位编码、资产路径、业务类型、数据源、精度。 - 边缘规则引擎:阈值、死区变化、变化率、条件判断、延时确认、组合条件。 - 本地历史库:最近 N 天采集值、报警记录、MQTT 上报记录。 - WebAPI 历史查询和断网期间本地追溯。 - MQTT/WebAPI 远程下发设备、分组、标签、规则、MQTT 参数和网关配置包。 - 配置版本、配置备份、失败回滚和远程回滚。 - 网站端远程运维命令:远程自检、插件刷新、配置回滚。 - 协议/驱动插件化,后续协议可通过 DLL 插件扩展。 ## 2. 启动程序 1. 进入程序目录,例如 `bin\Release\`。 2. 双击 `IPC.exe`。 3. 程序会自动加载 `Data\project.xml`。 4. 程序启动后会自动启动运行时轮询。 5. 默认会启动 WebAPI,监听 `http://+:5000/`。 程序只允许单实例运行。重复双击时会唤起已经运行的窗口。 点击窗口关闭按钮时,程序默认隐藏到系统托盘;如需完全退出,请在托盘图标右键菜单中选择退出。 如需开机后直接在右下角托盘运行,可使用启动参数: ```text IPC.exe --tray ``` ## 3. 默认项目 默认配置文件为: ```text Data\project.xml ``` 默认包含两个设备: | 设备 | 协议 | 说明 | | --- | --- | --- | | `VPLC1` | Virtual PLC | 虚拟 PLC,不需要真实设备即可测试 | | `PLC1` | Modbus TCP | 真实 PLC 示例,默认地址 `192.168.1.10:502` | 虚拟设备 `VPLC1` 默认标签: | 路径 | 地址 | 类型 | 权限 | 说明 | | --- | --- | --- | --- | --- | | `VPLC1.Speed` | `D0` | `Int16` | `ReadWrite` | 设备直属读写标签 | | `VPLC1.Switch` | `M0` | `Bool` | `ReadWrite` | 布尔标签 | | `VPLC1.Demo.Temperature` | `D10` | `Int16` | `ReadWrite` | 启用 0.1 倍率缩放 | 真实设备 `PLC1` 默认标签: | 路径 | 地址 | 类型 | 权限 | 说明 | | --- | --- | --- | --- | --- | | `PLC1.Speed` | `HR0` | `Int16` | `ReadWrite` | 设备直属示例标签 | | `PLC1.Motor.Current` | `HR1` | `Int16` | `ReadOnly` | 启用 0.1 倍率缩放 | 现场使用前,请把 `PLC1` 的 IP、端口、站号、地址和数据类型改成实际设备参数。 ## 4. 主界面操作 主界面以项目树组织数据: - 项目 - 设备 - 设备直属标签 - 分组 - 分组标签 常用操作: - 新增设备:选择项目或空白位置,点击新增设备。 - 新增分组:选择设备,点击新增分组。 - 新增标签:选择设备或分组,点击新增标签。 - 编辑:选中设备、分组或标签后点击编辑,或使用右键菜单。 - 删除:选中对象后使用删除操作。 - 复制/剪切/粘贴:支持设备、分组、标签层级内的复制和移动。 - 撤销:可撤销最近的项目编辑操作。 - 刷新:重新刷新项目树和内容列表显示。 编辑完成后注意保存项目配置。默认运行配置来自 `Data\project.xml`。 ## 5. 设备配置 新增或编辑设备时,重点确认: - 设备名称:WebAPI 查询时会使用该名称。 - 启用状态:禁用设备不会轮询。 - 协议:选择与 PLC 匹配的协议。 - 主机/IP:网络协议需要填写 PLC 地址。 - 端口:例如 Modbus TCP 常用 `502`,Rockwell CIP 常用 `44818`,Siemens S7 常用 `102`。 - Rack / Slot:部分协议需要,例如 S7、CIP 或 Modbus 站号场景。 - 超时时间:现场网络不稳定时可适当增大。 - 字节序/字序:多字数据读取异常时重点检查。 - 默认扫描周期:标签未单独配置扫描周期时使用该值。 OPC UA 设备: - 协议选择 `OpcUa`。 - 主机/IP 填 OPC UA Endpoint,例如 `opc.tcp://192.168.1.10:4840`。 - 如服务端需要账号密码,填写用户名和密码。 插件驱动设备: - 协议选择 `Plugin`。 - 驱动 ID 填插件实现的 `DriverId`。 - 驱动参数 JSON 填插件自定义参数,例如 `{"station":1,"mode":"tcp"}`。 - 插件 DLL 放在程序目录下的 `Drivers` 或 `Plugins\Drivers`。 串口协议还需要确认: - 串口号 - 波特率 - 数据位 - 校验位 - 停止位 - 站号 ## 6. 标签配置 新增或编辑标签时,重点确认: - 标签名称:WebAPI 查询和运行监视中显示的名称。 - 地址:必须符合当前协议的地址格式。 - 数据类型:必须与 PLC 实际数据一致。 - 数组长度:数组或字符串类型需要设置。 - 元素偏移:数组写入/读取指定偏移时使用。 - 启用状态:禁用标签不会读取。 - 访问权限: - `ReadWrite`:可读可写。 - `ReadOnly`:只读,禁止写入。 - `WriteOnly`:只写,运行监视中不会自动读取当前值。 - 扫描周期:填 0 时继承分组或设备扫描周期。 - 单位:用于显示。 - 点位编码:统一点位 ID,MQTT 上报和规则匹配优先使用该字段。 - 资产路径:例如 `工厂A/产线1/设备1`。 - 业务类型:例如 `temperature`、`pressure`、`speed`。 - 数据源:例如 `plc`、`opcua`、`virtual`。 - 精度:上报时的小数位控制。 - 描述:便于维护。 缩放配置: ```text 工程值 = 原始值 * Multiplier + Offset ``` 写入启用缩放的标签时,输入的是工程值;程序会反算为原始值后写入 PLC。 报警预警配置: - 可按标签启用报警。 - 当处理后的工程值高于上限或低于下限时,会通过 MQTT 上报报警。 - 当工程值进入上下限预警偏差范围时,会通过 MQTT 上报预警。 - 报警/预警信息可自定义,载荷会携带当前值、阈值、设备、分组、标签和点位信息。 ## 7. 运行监视 打开运行监视窗口后,可以按项目、设备、设备直属标签或分组查看实时值。 运行监视支持: - 实时标签值显示 - 标签质量显示 - 时间戳显示 - 搜索过滤 - 仅显示异常 - 事件列表 - 右键写入标签值 常见质量含义: | 质量 | 含义 | | --- | --- | | `Unknown` | 等待首次扫描 | | `Good` | 读取正常 | | `Disabled` | 设备、分组或标签被禁用 | | `NotConnected` | 设备未连接 | | `ReadError` | 读取失败 | | `NotFound` | 标签不存在 | | `AccessDenied` | 标签不允许读取或访问被拒绝 | 如果标签一直不是 `Good`,先检查设备连接参数、标签地址、数据类型和启用状态。 ## 8. 写入标签 可以在运行监视中右键标签写入,也可以通过 WebAPI 写入。 写入前请确认: - 标签不是 `ReadOnly`。 - 设备、分组和标签均已启用。 - 写入数据类型与标签配置一致。 - 写入值在 PLC 接受范围内。 - 启用缩放时,输入值是工程值。 写入 `WriteOnly` 标签时,程序允许下发,但不会自动读取当前值。 ## 9. WebAPI 使用 默认监听: ```text http://localhost:5000/ ``` 局域网访问时,把 `localhost` 改为本机 IP,例如: ```text http://192.168.1.20:5000/ ``` ### 健康检查 ```text GET http://localhost:5000/api/health GET http://localhost:5000/api/gateway/self-check ``` 返回示例: ```json { "success": true, "running": true, "prefix": "http://+:5000/" } ``` ### 读取设备直属标签 ```text GET http://localhost:5000/api/tags?device=VPLC1&tag=Speed ``` ### 读取分组下所有标签 ```text GET http://localhost:5000/api/tags?device=VPLC1&group=Demo ``` ### 读取分组下指定标签 ```text GET http://localhost:5000/api/tags?device=VPLC1&group=Demo&tag=Temperature ``` 查询规则: - `device + tag`:查询设备直属标签。 - `device + group`:查询该分组下所有标签。 - `device + group + tag`:查询组内指定标签。 - 只传 `device` 会返回错误。 ### 写入设备直属标签 ```powershell Invoke-RestMethod ` -Method Post ` -Uri "http://localhost:5000/api/tags/write" ` -ContentType "application/json" ` -Body '{"deviceName":"VPLC1","tagName":"Speed","dataType":"Int16","value":123}' ``` ### 写入组内标签 ```powershell Invoke-RestMethod ` -Method Post ` -Uri "http://localhost:5000/api/tags/write" ` -ContentType "application/json" ` -Body '{"channelName":"VirtualPlc","deviceName":"VPLC1","groupName":"Demo","tagName":"Temperature","dataType":"Int16","value":25.6}' ``` 写入字段说明: | 字段 | 必填 | 说明 | | --- | --- | --- | | `deviceName` | 是 | 设备名称 | | `groupName` | 否 | 分组名称,写设备直属标签时留空 | | `tagName` | 是 | 标签名称 | | `dataType` | 是 | 必须与标签配置的数据类型一致 | | `value` | 否 | 工程值 | | `valueText` | 否 | 原始文本值,优先级高于 `value` | ### 查询本地历史 ```text GET http://localhost:5000/api/history/stats GET http://localhost:5000/api/history?category=values&limit=500 GET http://localhost:5000/api/history?category=alarms&limit=500 GET http://localhost:5000/api/history?category=publishes&limit=500 ``` 历史分类: | category | 说明 | | --- | --- | | `values` | 采集值历史 | | `alarms` | 报警/预警历史 | | `publishes` | MQTT 上报历史 | 这些接口读取本机历史文件,外网或 MQTT 断开时仍可用于现场追溯。 ### 查询当前网关配置 ```text GET http://localhost:5000/api/config ``` 返回当前项目配置、MQTT 参数、网关设置、配置版本状态和配置备份列表。查询结果会对 MQTT 密码脱敏。 ### 协议插件查询 ```text GET http://localhost:5000/api/plugins/drivers POST http://localhost:5000/api/plugins/drivers/reload ``` `reload` 会重新扫描程序目录下的 `Drivers` 和 `Plugins\Drivers`。 ### 远程下发配置 ```text POST http://localhost:5000/api/config/apply Content-Type: application/json ``` 新增设备示例: ```json { "action": "upsertDevice", "requestId": "dev-001", "device": { "name": "远程设备1", "enabled": true, "protocol": "ModbusTcp", "defaultScanRateMs": 1000, "connection": { "host": "192.168.1.10", "port": 502, "rack": 1, "timeoutMilliseconds": 3000 } } } ``` 新增分组示例: ```json { "action": "upsertGroup", "requestId": "grp-001", "deviceName": "远程设备1", "group": { "name": "温控分组", "enabled": true, "scanRateMs": 1000 } } ``` 新增标签示例: ```json { "action": "upsertTag", "requestId": "tag-001", "deviceName": "远程设备1", "groupName": "温控分组", "tag": { "name": "温度", "address": "40001", "dataType": "Int16", "enabled": true, "accessMode": "ReadWrite", "scanRateMs": 1000, "unit": "℃", "pointCode": "line1.temp", "mqttPublishEnabled": true } } ``` 常用动作: | action | 说明 | | --- | --- | | `applyPackage` / `applyGatewayPackage` | 应用网关配置包 | | `replaceProject` / `applyProject` | 替换整个项目 | | `replaceDevices` | 替换设备列表 | | `upsertDevice` / `deleteDevice` | 新增/更新或删除设备 | | `replaceGroups` | 替换指定设备下的分组 | | `upsertGroup` / `deleteGroup` | 新增/更新或删除分组 | | `replaceTags` | 替换指定设备或分组下的标签 | | `upsertTag` / `deleteTag` | 新增/更新或删除标签 | | `replaceRules` | 替换规则列表 | | `upsertRule` / `deleteRule` | 新增/更新或删除边缘规则 | | `updateMqtt` / `applyMqtt` | 更新 MQTT 参数 | | `applySettings` / `updateSettings` | 更新网关设置 | 配置下发成功后会保存项目文件,并自动重启运行时、MQTT 和规则引擎。 配置回滚: ```text POST http://localhost:5000/api/config/rollback Content-Type: application/json ``` 回滚到最新备份: ```json {} ``` 回滚到指定备份: ```json { "requestId": "rollback-001", "backupFile": "gateway_config_20260614_180000_000_v3_apply.xml" } ``` 也可以通过 MQTT 向配置主题下发: ```json { "action": "rollbackConfig", "requestId": "rollback-001", "responseTopic": "ipc/config/result" } ``` ## 10. MQTT 功能 MQTT 配置入口在工具菜单的 `MQTT`。 主要能力: - 订阅写值:默认订阅 `ipc/write/#`。 - 采集值上报:按标签配置是否发布,支持主题模板和 QoS。 - 变化上报:可配置仅变化时上报,也可配置不变值心跳间隔。 - MQTT 心跳:默认主题 `ipc/heartbeat`,默认 60 秒。 - 报警/预警上报:主题在采集上报主题后追加 `/alarm` 或 `/warning`。 - 规则事件上报:边缘规则触发和恢复时发布事件。 - 持久缓存:断线时写入本地队列,连接恢复后补发。 MQTT 写标签主题示例: ```text ipc/write/VPLC1/Speed ipc/write/VPLC1/Demo/Temperature ``` payload 可直接传值: ```text 123 ``` 也可传 JSON: ```json { "value": 123, "dataType": "Int16" } ``` MQTT 远程下发配置主题: ```text ipc/write/_config ``` payload 与 WebAPI `/api/config/apply` 相同。可通过 `responseTopic` 指定回执主题,默认回执到: ```text ipc/config/result ``` 插件驱动设备的 MQTT 下发示例: ```json { "action": "upsertDevice", "requestId": "plugin-dev-001", "responseTopic": "ipc/config/result", "device": { "name": "插件设备1", "enabled": true, "protocol": "Plugin", "defaultScanRateMs": 1000, "connection": { "driverId": "custom-driver", "host": "192.168.1.30", "port": 9000, "timeoutMilliseconds": 3000, "driverOptionsJson": "{\"station\":1}" } } } ``` ## 11. 边缘规则引擎 入口在工具菜单的 `边缘规则引擎`。 支持规则类型: - 阈值 - 死区变化 - 变化率 - 条件判断 - 组合条件 规则支持延时确认,可避免瞬时抖动造成误报。组合条件支持“全部满足”和“任一满足”。规则匹配优先使用标签点位编码;点位编码为空时使用设备、分组、标签名称匹配。 规则触发后可发布 MQTT 事件,并进入现有 MQTT 持久缓存和断线补发流程。 ## 12. 网站端远程运维 网站配置管理页支持: - 保存配置包 - 下发配置 - 远程自检 - 刷新客户端协议插件 - 回滚客户端配置到最新备份 对应后端接口: ```text POST /api/gateways/{gatewayId}/config-package/apply POST /api/gateways/{gatewayId}/config-package/rollback POST /api/gateways/{gatewayId}/operations/self-check POST /api/gateways/{gatewayId}/plugins/drivers/reload ``` 这些接口需要管理员或运维账号登录。命令会进入下发记录,客户端执行后通过 MQTT 回执更新状态。 ## 13. 本地历史库 入口在工具菜单的 `本地历史库`。 历史库默认启用,默认目录: ```text Data\History ``` 默认保留 7 天,可在界面中配置。文件按天保存为 `jsonl`: - `values-YYYYMMDD.jsonl` - `alarms-YYYYMMDD.jsonl` - `publishes-YYYYMMDD.jsonl` 本地历史库用于断网期间追溯,WebAPI 历史查询也读取这些文件。 ## 14. 局域网访问授权 如果 WebAPI 配置为 `http://+:5000/`,首次部署可能需要管理员 PowerShell 执行: ```bat netsh http add urlacl url=http://+:5000/ user=Everyone netsh advfirewall firewall add rule name="IPC WebApi 5000" dir=in action=allow protocol=TCP localport=5000 ``` 中文系统如 `Everyone` 不可用,可改用当前用户或“所有人”: ```bat netsh http add urlacl url=http://+:5000/ user=所有人 ``` 如果端口不是 5000,请同步修改命令中的端口。 ## 15. 虚拟 PLC 快速测试 无需真实 PLC 的测试步骤: 1. 启动 `IPC.exe`。 2. 打开运行监视,选择 `VPLC1`。 3. 读取: ```text GET http://localhost:5000/api/tags?device=VPLC1&tag=Speed ``` 4. 写入: ```powershell Invoke-RestMethod ` -Method Post ` -Uri "http://localhost:5000/api/tags/write" ` -ContentType "application/json" ` -Body '{"deviceName":"VPLC1","tagName":"Speed","dataType":"Int16","value":456}' ``` 5. 再次读取 `Speed`,应返回新值。 6. 写入 `Temperature`: ```powershell Invoke-RestMethod ` -Method Post ` -Uri "http://localhost:5000/api/tags/write" ` -ContentType "application/json" ` -Body '{"channelName":"VirtualPlc","deviceName":"VPLC1","groupName":"Demo","tagName":"Temperature","dataType":"Int16","value":25.6}' ``` `Temperature` 启用了 `0.1` 倍率缩放,写入工程值 `25.6` 时,内部会按原始值约 `256` 写入。 ## 16. 协议插件开发和部署 后续新增协议建议使用插件方式,不必修改主程序和内置协议代码。 插件 DLL 放置目录: ```text Drivers Plugins\Drivers ``` 插件需要引用 `IPC.Plc.Communication.dll`,实现: ```csharp public interface IPlcDriverPlugin { string DriverId { get; } string DisplayName { get; } IPlcClient CreateClient(PlcConnectionOptions options); } ``` 设备选择 `Plugin` 协议后,程序会根据 `connection.driverId` 找到插件,并调用 `CreateClient()` 创建通信客户端。插件客户端仍然实现 `IPlcClient`,因此采集、写入、缩放、报警、规则和 MQTT 上报逻辑都会复用现有链路。 ## 17. 常见问题 ### 程序启动提示 WebAPI 权限错误 使用管理员 PowerShell 执行 URL ACL 授权命令,并放行防火墙端口。也可以把监听前缀改为 `http://localhost:5000/`,只允许本机访问。 ### 局域网其他电脑访问不了 检查: - 本机 IPC 程序是否正在运行。 - `IpcWebApiPrefix` 是否为 `http://+:5000/` 或绑定了正确 IP。 - Windows 防火墙是否放行 TCP 5000。 - 两台电脑是否在同一网络且能互相 ping 通。 - URL 中是否使用了 IPC 所在电脑的 IP。 ### 标签显示 `NotConnected` 检查 PLC IP、端口、站号、串口参数、网线、PLC 通信服务和防火墙。 ### 标签显示 `ReadError` 检查标签地址格式、数据类型、数组长度、偏移、PLC 地址范围和协议是否匹配。 ### 写入失败 检查标签是否 `ReadOnly`,请求中的 `dataType` 是否与配置一致,写入值是否超范围,设备是否连接。 ### 修改配置后没有生效 确认配置已保存,并重启运行时或重新启动程序。运行时启动时会克隆配置对象,已启动的轮询不会自动读取磁盘上的手工改动。