io板卡兼容优化

This commit is contained in:
hsc
2026-07-20 15:45:36 +08:00
parent 48492973c3
commit 7f2721ab11
6 changed files with 224 additions and 36 deletions

View File

@@ -11,7 +11,7 @@ using System.Threading.Tasks;
namespace DeviceCommand.Device
{
[ADPCommand]
//[ADPCommand]
public class IOBoard : ModbusTcp
{

View File

@@ -0,0 +1,160 @@
using Common.Attributes;
using Model.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
using DeviceCommand.Base;
using DeviceCommand.Device;
using System.ComponentModel;
namespace DeviceCommand.Devices
{
/// <summary>
/// 系统控制功能类型枚举 (中文)
/// </summary>
public enum : byte
{
,
,
,
}
/// <summary>
/// 精简后的 IO 端口信息结构体
/// </summary>
public struct IoPortInfo
{
public int ModuleIndex { get; set; } // IO板卡/模块序号 (1 或 2)
public ushort Address { get; set; } // 转换为 Modbus 的线圈相对偏移地址 (Y1->0, Y2->1)
public IoPortInfo(int moduleIndex, ushort address)
{
ModuleIndex = moduleIndex;
Address = address;
}
}
[ADPCommand]
public class IOBoardGroup
{
// 声明底层的 2 个 IO 板卡实例
public IOBoard Board1 { get; private set; }
public IOBoard Board2 { get; private set; }
private readonly byte _slaveAddress = 1; // 默认 Modbus 从站号为 1
// 核心:严格对齐图片数据的双层嵌套配置字典 (2个模块1-8台架)
private static readonly Dictionary<int, Dictionary<, IoPortInfo>> IoMapping
= new Dictionary<int, Dictionary<, IoPortInfo>>()
{
{ 1, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(1, 5) }, // Y6 -> 5
{ ., new IoPortInfo(1, 0) }, // Y1 -> 0
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1
{ ., new IoPortInfo(2, 8) } // Y9 -> 8
}},
{ 2, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(1, 6) }, // Y7 -> 6
{ ., new IoPortInfo(1, 2) }, // Y3 -> 2
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1
{ ., new IoPortInfo(2, 9) } // Y10 -> 9
}},
{ 3, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(1, 7) }, // Y8 -> 7
{ ., new IoPortInfo(1, 3) }, // Y4 -> 3
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1
{ ., new IoPortInfo(2, 10) } // Y11 -> 10
}},
{ 4, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(1, 8) }, // Y9 -> 8
{ ., new IoPortInfo(1, 4) }, // Y5 -> 4
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1
{ ., new IoPortInfo(2, 11) } // Y12 -> 11
}},
{ 5, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(2, 4) }, // Y5 -> 4
{ ., new IoPortInfo(2, 0) }, // Y1 -> 0
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1
{ ., new IoPortInfo(2, 12) } // Y13 -> 12
}},
{ 6, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(2, 5) }, // Y6 -> 5
{ ., new IoPortInfo(2, 1) }, // Y2 -> 1
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1
{ ., new IoPortInfo(2, 13) } // Y14 -> 13
}},
{ 7, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(2, 6) }, // Y7 -> 6
{ ., new IoPortInfo(2, 2) }, // Y3 -> 2
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1
{ ., new IoPortInfo(2, 14) } // Y15 -> 14
}},
{ 8, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(2, 7) }, // Y8 -> 7
{ ., new IoPortInfo(2, 3) }, // Y4 -> 3
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1
{ ., new IoPortInfo(2, 15) } // Y16 -> 15
}}
};
public IOBoardGroup(IOBoard board1, IOBoard board2)
{
Board1 = board1 ?? throw new ArgumentNullException(nameof(board1), "IOBoard Board1 实例不能为空。");
Board2 = board2 ?? throw new ArgumentNullException(nameof(board2), "IOBoard Board2 实例不能为空。");
}
/// <summary>
/// 执行指定台架的功能动作控制(带高低电平开关及底层安全互锁)
/// </summary>
/// <param name="台架序号">台架/工位序号 (1 - 8)</param>
/// <param name="动作">控制功能类型 (单相充电, 抛负载, 短路测试, 蜂鸣器报警)</param>
/// <param name="开关状态">开关状态 (true: 开启吸合, false: 关闭断开)</param>
/// <param name="取消令牌">异步取消令牌</param>
public async Task Async(int , , bool , CancellationToken = default)
{
// 1. 根据传入的台架序号和动作检索字典映射关系
if (!IoMapping.TryGetValue(, out var ) || !.TryGetValue(, out var io信息))
{
throw new ArgumentException($"未找到台架 [{台架序号}] 对应功能 [{动作}] 的 IO 点位映射配置。");
}
// 2. 软件防错高危互锁逻辑
if ()
{
if ( == .)
{
var = IoMapping[][.];
await GetBoardInstance(.ModuleIndex).(_slaveAddress, .Address, false);
}
else if ( == .)
{
var = IoMapping[][.];
await GetBoardInstance(.ModuleIndex).(_slaveAddress, .Address, false);
}
}
// 3. 动态获取目标板卡实例并直接驱动开关端口
IOBoard = GetBoardInstance(io信息.ModuleIndex);
await .(_slaveAddress, io信息.Address, );
}
/// <summary>
/// 内部路由辅助方法:根据板卡索引安全获取当前连接的实例对象
/// </summary>
private IOBoard GetBoardInstance(int moduleIndex)
{
IOBoard board = moduleIndex switch
{
1 => Board1,
2 => Board2,
_ => throw new ArgumentOutOfRangeException(nameof(moduleIndex), "非法的板卡序号,系统仅支持 1# 和 2# 模块。")
};
return board ?? throw new InvalidOperationException($"IO板卡模块 [{moduleIndex}#] 尚未完成初始化,无法建立总线通信。");
}
}
}