Files
ACP/DeviceCommand/Devices/IOBoard.cs
T
2026-09-22 11:33:07 +08:00

100 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Common.Attributes;
using DeviceCommand.Base;
using Model.Models;
using NModbus;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DeviceCommand.Devices
{
/// <summary>
/// IO 继电器板卡(一对一控制),基于 Modbus TCP 协议通过线圈(Coil)读写控制继电器输出。
/// 由于多块板卡的点位映射不完全一致,实际业务中使用 <see cref="IOBoardGroup"/> 统一调度三块板卡。
/// </summary>
//[ACPCommand]
public class IOBoard : ModbusTcp
{
/// <summary>
/// 构造函数,初始化 Modbus TCP 连接配置。
/// </summary>
/// <param name="config">TCP 连接配置(IP、端口等)</param>
public IOBoard(TcpConfig config) : base(config)
{
}
/// <summary>
/// 写入单个输出开关(线圈)状态。
/// </summary>
/// <param name="站号">Modbus 从站站号</param>
/// <param name="开始地址">线圈地址(0 起始)</param>
/// <param name="data">开关状态(true: 吸合/开启, false: 断开/关闭)</param>
public async Task 写输出开关(byte 站号, ushort 开始地址, bool data)
{
确保已连接();
await Modbus.WriteSingleCoilAsync(站号, 开始地址, data);
}
/// <summary>
/// 批量写入输出开关状态。先读出全部 16 个线圈当前状态,
/// 在内存中修改指定偏移段的值后再整体写回,避免影响其他点位。
/// </summary>
/// <param name="站号">Modbus 从站站号</param>
/// <param name="开始地址">起始线圈地址(0 起始)</param>
/// <param name="datas">要写入的开关状态数组,按顺序从开始地址写入</param>
public async Task 批量写输出开关(byte 站号, ushort 开始地址, bool[] datas)
{
确保已连接();
var 批量写入 = await Modbus.ReadCoilsAsync(1, 0, 16);
for (int i = 0; i < datas.Length; i++)
{
if (开始地址 + i < 批量写入.Length)
{
批量写入[开始地址 + i] = datas[i];
}
}
await Modbus.WriteMultipleCoilsAsync(站号, 0, 批量写入);
}
/// <summary>
/// 读取单个输出开关(线圈)状态。
/// </summary>
/// <param name="站号">Modbus 从站站号</param>
/// <param name="开始地址">线圈地址(0 起始)</param>
public async Task 读输出开关(byte 站号, ushort 开始地址)
{
确保已连接();
await Modbus.ReadCoilsAsync(站号, 开始地址, 1);
}
/// <summary>
/// 批量读取输出开关(线圈)状态。
/// </summary>
/// <param name="站号">Modbus 从站站号</param>
/// <param name="开始地址">起始线圈地址(0 起始)</param>
/// <param name="数量">要读取的线圈数量</param>
/// <returns>线圈状态数组,true 表示吸合/开启</returns>
public async Task<bool[]> 批量读输出开关(byte 站号, ushort 开始地址,ushort 数量)
{
确保已连接();
return await Modbus.ReadCoilsAsync(站号, 开始地址, 数量);
}
/// <summary>
/// 确认 Modbus 主站已建立(设备连接成功)。
/// 未连接时抛出带明确提示的异常,替代对 null 主站的 NullReferenceException,
/// 供上层(测试步骤 / 报警蜂鸣器)捕获并记录。
/// </summary>
/// <exception cref="InvalidOperationException">Modbus 主站尚未建立时抛出</exception>
private void 确保已连接()
{
if (Modbus == null)
throw new InvalidOperationException("IO 板卡尚未连接(Modbus 主站未建立),无法执行输出控制操作,请确认设备连接状态。");
}
}
}