IO板卡映射修改

This commit is contained in:
“hsc”
2026-08-03 14:19:24 +08:00
parent 21cc593d3f
commit 9f8cf5f267
2 changed files with 96 additions and 69 deletions

View File

@@ -11,14 +11,26 @@ using System.ComponentModel;
namespace DeviceCommand.Devices namespace DeviceCommand.Devices
{ {
/// <summary> /// <summary>
/// 系统控制功能类型枚举 (中文) /// 系统控制功能类型枚举 (根据三工位 ACP接线图 更新)
/// </summary> /// </summary>
public enum : byte public enum : byte
{ {
, ,
, ,
, KL30通断,
KL15通断,
60,
1K欧电阻,
CC信号串1K欧电阻,
CP信号串1K欧电阻,
CC信号串680欧电阻,
CC信号串220欧电阻,
CC信号串100欧电阻,
CC信号空载,
,
, // (接线图中标注于 Y14, KM8)
HV, // (接线图中标注于 Y15, KM9)
LV // (接线图中标注于 Y16, KM10)
} }
/// <summary> /// <summary>
@@ -26,7 +38,7 @@ namespace DeviceCommand.Devices
/// </summary> /// </summary>
public struct IoPortInfo public struct IoPortInfo
{ {
public int ModuleIndex { get; set; } // IO板卡/模块序号 (1 或 2) public int ModuleIndex { get; set; } // IO板卡/模块序号 (1、23)
public ushort Address { get; set; } // 转换为 Modbus 的线圈相对偏移地址 (Y1->0, Y2->1) public ushort Address { get; set; } // 转换为 Modbus 的线圈相对偏移地址 (Y1->0, Y2->1)
public IoPortInfo(int moduleIndex, ushort address) public IoPortInfo(int moduleIndex, ushort address)
@@ -39,79 +51,89 @@ namespace DeviceCommand.Devices
[ACPCommand] [ACPCommand]
public class IOBoardGroup public class IOBoardGroup
{ {
// 声明底层的 2 个 IO 板卡实例 // 声明底层的 3 个 IO 板卡实例(对应三工位系统)
public IOBoard Board1 { get; private set; } public IOBoard Board1 { get; private set; }
public IOBoard Board2 { get; private set; } public IOBoard Board2 { get; private set; }
public IOBoard Board3 { get; private set; }
private readonly byte _slaveAddress = 1; // 默认 Modbus 从站号为 1 private readonly byte _slaveAddress = 1; // 默认 Modbus 从站号为 1
// 核心:严格对齐图片数据的双层嵌套配置字典 (2个模块1-8台架) // 核心:根据 ACP硬件接线图 严格对齐的数据字典 (3个模块独立对应1-3工位)
private static readonly Dictionary<int, Dictionary<, IoPortInfo>> IoMapping private static readonly Dictionary<int, Dictionary<, IoPortInfo>> IoMapping
= new Dictionary<int, Dictionary<, IoPortInfo>>() = new Dictionary<int, Dictionary<, IoPortInfo>>()
{ {
// 1# 工位 -> IO继电器模块 1#
{ 1, new Dictionary<, IoPortInfo> { { 1, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(1, 5) }, // Y6 -> 5 { ., new IoPortInfo(1, 0) }, // Y1 -> 0 (KM2)
{ ., new IoPortInfo(1, 0) }, // Y1 -> 0 { ., new IoPortInfo(1, 1) }, // Y2 -> 1 (KM3)
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1 { .KL30通断, new IoPortInfo(1, 2) }, // Y3 -> 2
{ ., new IoPortInfo(2, 15) } // Y9 -> 8 { .KL15通断, new IoPortInfo(1, 3) }, // Y4 -> 3
{ .60, new IoPortInfo(1, 4) }, // Y5 -> 4
{ .1K欧电阻, new IoPortInfo(1, 5) }, // Y6 -> 5
{ .CC信号串1K欧电阻, new IoPortInfo(1, 6) }, // Y7 -> 6
{ .CP信号串1K欧电阻, new IoPortInfo(1, 7) }, // Y8 -> 7
{ .CC信号串680欧电阻, new IoPortInfo(1, 8) }, // Y9 -> 8
{ .CC信号串220欧电阻, new IoPortInfo(1, 9) }, // Y10 -> 9
{ .CC信号串100欧电阻, new IoPortInfo(1, 10) }, // Y11 -> 10
{ .CC信号空载, new IoPortInfo(1, 11) }, // Y12 -> 11
{ ., new IoPortInfo(1, 12) }, // Y13 -> 12
{ ., new IoPortInfo(3, 13) }, // Y14 -> 13 (KM8)
{ .HV, new IoPortInfo(3, 14) }, // Y15 -> 14 (KM9)
{ .LV, new IoPortInfo(3, 15) } // Y16 -> 15 (KM10)
}}, }},
// 2# 工位 -> IO继电器模块 2#
{ 2, new Dictionary<, IoPortInfo> { { 2, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(1, 6) }, // Y7 -> 6 { ., new IoPortInfo(2, 0) }, // Y1 -> 0 (KM4)
{ ., new IoPortInfo(1, 2) }, // Y3 -> 2 { ., new IoPortInfo(2, 1) }, // Y2 -> 1 (KM5)
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1 { .KL30通断, new IoPortInfo(2, 2) }, // Y3 -> 2
{ ., new IoPortInfo(2, 14) } // Y10 -> 9 { .KL15通断, new IoPortInfo(2, 3) }, // Y4 -> 3
{ .60, new IoPortInfo(2, 4) }, // Y5 -> 4
{ .1K欧电阻, new IoPortInfo(2, 5) }, // Y6 -> 5
{ .CC信号串1K欧电阻, new IoPortInfo(2, 6) }, // Y7 -> 6
{ .CP信号串1K欧电阻, new IoPortInfo(2, 7) }, // Y8 -> 7
{ .CC信号串680欧电阻, new IoPortInfo(2, 8) }, // Y9 -> 8
{ .CC信号串220欧电阻, new IoPortInfo(2, 9) }, // Y10 -> 9
{ .CC信号串100欧电阻, new IoPortInfo(2, 10) }, // Y11 -> 10
{ .CC信号空载, new IoPortInfo(2, 11) }, // Y12 -> 11
{ ., new IoPortInfo(2, 12) }, // Y13 -> 12
{ ., new IoPortInfo(3, 13) }, // Y14 -> 13 (KM8)
{ .HV, new IoPortInfo(3, 14) }, // Y15 -> 14 (KM9)
{ .LV, new IoPortInfo(3, 15) } // Y16 -> 15 (KM10)
}}, }},
// 3# 工位 -> IO继电器模块 3# (包含额外的抛负载及短路测试控制)
{ 3, new Dictionary<, IoPortInfo> { { 3, new Dictionary<, IoPortInfo> {
{ ., new IoPortInfo(1, 7) }, // Y8 -> 7 { ., new IoPortInfo(3, 0) }, // Y1 -> 0 (KM6)
{ ., new IoPortInfo(1, 3) }, // Y4 -> 3 { ., new IoPortInfo(3, 1) }, // Y2 -> 1 (KM7)
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1 { .KL30通断, new IoPortInfo(3, 2) }, // Y3 -> 2
{ ., new IoPortInfo(2, 13) } // Y11 -> 10 { .KL15通断, new IoPortInfo(3, 3) }, // Y4 -> 3
}}, { .60, new IoPortInfo(3, 4) }, // Y5 -> 4
{ 4, new Dictionary<, IoPortInfo> { { .1K欧电阻, new IoPortInfo(3, 5) }, // Y6 -> 5
{ ., new IoPortInfo(1, 8) }, // Y9 -> 8 { .CC信号串1K欧电阻, new IoPortInfo(3, 6) }, // Y7 -> 6
{ ., new IoPortInfo(1, 4) }, // Y5 -> 4 { .CP信号串1K欧电阻, new IoPortInfo(3, 7) }, // Y8 -> 7
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1 { .CC信号串680欧电阻, new IoPortInfo(3, 8) }, // Y9 -> 8
{ ., new IoPortInfo(2, 12) } // Y12 -> 11 { .CC信号串220欧电阻, new IoPortInfo(3, 9) }, // Y10 -> 9
}}, { .CC信号串100欧电阻, new IoPortInfo(3, 10) }, // Y11 -> 10
{ 5, new Dictionary<, IoPortInfo> { { .CC信号空载, new IoPortInfo(3, 11) }, // Y12 -> 11
{ ., new IoPortInfo(2, 4) }, // Y5 -> 4 { ., new IoPortInfo(3, 12) }, // Y13 -> 12
{ ., new IoPortInfo(2, 0) }, // Y1 -> 0 { ., new IoPortInfo(3, 13) }, // Y14 -> 13 (KM8)
{ ., new IoPortInfo(1, 1) }, // Y2 -> 1 { .HV, new IoPortInfo(3, 14) }, // Y15 -> 14 (KM9)
{ ., new IoPortInfo(2, 11) } // Y13 -> 12 { .LV, new IoPortInfo(3, 15) } // Y16 -> 15 (KM10)
}},
{ 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, 10) } // 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, 9) } // 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, 8) } // Y16 -> 15
}} }}
}; };
public IOBoardGroup(IOBoard board1, IOBoard board2) // 修改构造函数以支持 3 个板块
public IOBoardGroup(IOBoard board1, IOBoard board2, IOBoard board3)
{ {
Board1 = board1 ?? throw new ArgumentNullException(nameof(board1), "IOBoard Board1 实例不能为空。"); Board1 = board1 ?? throw new ArgumentNullException(nameof(board1), "IOBoard Board1 实例不能为空。");
Board2 = board2 ?? throw new ArgumentNullException(nameof(board2), "IOBoard Board2 实例不能为空。"); Board2 = board2 ?? throw new ArgumentNullException(nameof(board2), "IOBoard Board2 实例不能为空。");
Board3 = board3 ?? throw new ArgumentNullException(nameof(board3), "IOBoard Board3 实例不能为空。");
} }
/// <summary> /// <summary>
/// 执行指定台架的功能动作控制(带高低电平开关及底层安全互锁) /// 执行指定台架的功能动作控制(带高低电平开关及底层安全互锁)
/// </summary> /// </summary>
/// <param name="台架序号">台架/工位序号 (1 - 8)</param> /// <param name="台架序号">台架/工位序号 (1 - 3)</param>
/// <param name="动作">控制功能类型 (单相充电, 抛负载, 短路测试, 蜂鸣器报警)</param> /// <param name="动作">控制功能类型</param>
/// <param name="开关状态">开关状态 (true: 开启吸合, false: 关闭断开)</param> /// <param name="开关状态">开关状态 (true: 开启吸合, false: 关闭断开)</param>
/// <param name="取消令牌">异步取消令牌</param> /// <param name="取消令牌">异步取消令牌</param>
public async Task Async(int , , bool , CancellationToken = default) public async Task Async(int , , bool , CancellationToken = default)
@@ -119,21 +141,25 @@ namespace DeviceCommand.Devices
// 1. 根据传入的台架序号和动作检索字典映射关系 // 1. 根据传入的台架序号和动作检索字典映射关系
if (!IoMapping.TryGetValue(, out var ) || !.TryGetValue(, out var io信息)) if (!IoMapping.TryGetValue(, out var ) || !.TryGetValue(, out var io信息))
{ {
throw new ArgumentException($"未找到台架 [{台架序号}] 对应功能 [{动作}] 的 IO 点位映射配置。"); throw new ArgumentException($"未找到台架 [{台架序号}] 对应功能 [{动作}] 的 IO 点位映射配置。请注意抛负载及短路测试仅存在于 3# 工位。");
} }
// 2. 软件防错高危互锁逻辑 // 2. 软件防错高危互锁逻辑:防止同时执行充电和放电
if () if ()
{ {
if ( == .) if ( == .)
{ {
var = IoMapping[][.]; if (IoMapping[].TryGetValue(., out var ))
await GetBoardInstance(.ModuleIndex).(_slaveAddress, .Address, false); {
await GetBoardInstance(.ModuleIndex).(_slaveAddress, .Address, false);
}
} }
else if ( == .) else if ( == .)
{ {
var = IoMapping[][.]; if (IoMapping[].TryGetValue(., out var ))
await GetBoardInstance(.ModuleIndex).(_slaveAddress, .Address, false); {
await GetBoardInstance(.ModuleIndex).(_slaveAddress, .Address, false);
}
} }
} }
@@ -151,7 +177,8 @@ namespace DeviceCommand.Devices
{ {
1 => Board1, 1 => Board1,
2 => Board2, 2 => Board2,
_ => throw new ArgumentOutOfRangeException(nameof(moduleIndex), "非法的板卡序号,系统仅支持 1# 和 2# 模块。") 3 => Board3,
_ => throw new ArgumentOutOfRangeException(nameof(moduleIndex), "非法的板卡序号,系统仅支持 1#、2# 和 3# 模块。")
}; };
return board ?? throw new InvalidOperationException($"IO板卡模块 [{moduleIndex}#] 尚未完成初始化,无法建立总线通信。"); return board ?? throw new InvalidOperationException($"IO板卡模块 [{moduleIndex}#] 尚未完成初始化,无法建立总线通信。");

View File

@@ -214,15 +214,15 @@ namespace UIShare.GlobalVariable
// IOGroup 初始化:从已实例化的设备中取出前两个 IOBoard 实例组建 IOBoardGroup // IOGroup 初始化:从已实例化的设备中取出前两个 IOBoard 实例组建 IOBoardGroup
try try
{ {
var ioBoards = DeviceMap.Values.OfType<IOBoard>().Take(2).ToList(); var ioBoards = DeviceMap.Values.OfType<IOBoard>().Take(3).ToList();
if (ioBoards.Count == 2) if (ioBoards.Count == 3)
{ {
IOGroup = new IOBoardGroup(ioBoards[0], ioBoards[1]); IOGroup = new IOBoardGroup(ioBoards[0], ioBoards[1], ioBoards[2]);
LoggerHelper.Info($"IOBoardGroup 已初始化Board1={ioBoards[0].GetType().Name}, Board2={ioBoards[1].GetType().Name}。"); LoggerHelper.Info($"IOBoardGroup 已初始化Board1={ioBoards[0].GetType().Name}, Board2={ioBoards[1].GetType().Name}, Board3={ioBoards[2].GetType().Name}。");
} }
else else
{ {
LoggerHelper.Warn($"IOBoardGroup 初始化跳过:需要 2 个 IOBoard 实例,当前仅找到 {ioBoards.Count} 个。"); LoggerHelper.Warn($"IOBoardGroup 初始化跳过:需要 3 个 IOBoard 实例,当前仅找到 {ioBoards.Count} 个。");
} }
} }
catch (Exception ex) catch (Exception ex)