io映射修改,低压电源命令修改
This commit is contained in:
+1261
-194
File diff suppressed because it is too large
Load Diff
@@ -11,26 +11,36 @@ using System.ComponentModel;
|
|||||||
namespace DeviceCommand.Devices
|
namespace DeviceCommand.Devices
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 系统控制功能类型枚举 (根据三工位 ACP接线图 更新)
|
/// 系统控制功能类型枚举 (根据 ACP硬件接线图.xlsx 三工位系统更新)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum 功能动作 : byte
|
public enum 功能动作 : byte
|
||||||
{
|
{
|
||||||
产品充电三相,
|
/// <summary>低压电源产品唤醒通断 KL30(三工位,模块1# Y1/Y3/Y5,KA2/KA4/KA6)</summary>
|
||||||
产品放电三相,
|
|
||||||
KL30通断,
|
KL30通断,
|
||||||
|
/// <summary>低压电源产品唤醒通断 KL15(三工位,模块1# Y2/Y4/Y6,KA3/KA5/KA7)</summary>
|
||||||
KL15通断,
|
KL15通断,
|
||||||
|
/// <summary>电子锁60Ω电阻通断(三工位,模块1# Y13/Y14/Y15)</summary>
|
||||||
电子锁60欧电阻,
|
电子锁60欧电阻,
|
||||||
|
/// <summary>温度检测1KΩ电阻通断(三工位,模块3# Y1/Y2/Y3)</summary>
|
||||||
温度检测1K欧电阻,
|
温度检测1K欧电阻,
|
||||||
|
/// <summary>CC信号串1KΩ电阻(三工位,模块2# Y1/Y5/Y9)</summary>
|
||||||
CC信号串1K欧电阻,
|
CC信号串1K欧电阻,
|
||||||
|
/// <summary>CP信号串1KΩ电阻(三工位,模块2# Y13/Y14/Y15)</summary>
|
||||||
CP信号串1K欧电阻,
|
CP信号串1K欧电阻,
|
||||||
|
/// <summary>CC信号串680Ω电阻(三工位,模块2# Y2/Y6/Y10)</summary>
|
||||||
CC信号串680欧电阻,
|
CC信号串680欧电阻,
|
||||||
|
/// <summary>CC信号串220Ω电阻(三工位,模块2# Y3/Y7/Y11)</summary>
|
||||||
CC信号串220欧电阻,
|
CC信号串220欧电阻,
|
||||||
|
/// <summary>CC信号串100Ω电阻(三工位,模块2# Y4/Y8/Y12)</summary>
|
||||||
CC信号串100欧电阻,
|
CC信号串100欧电阻,
|
||||||
CC信号空载,
|
/// <summary>蜂鸣器阈值报警(三工位,模块1# Y10/Y11/Y12)</summary>
|
||||||
蜂鸣器报警,
|
蜂鸣器报警,
|
||||||
抛负载通断, // (接线图中标注于 Y14, KM8)
|
/// <summary>双向直流源(HV+)抛负载通断(仅一工位,模块1# Y7,KA8)</summary>
|
||||||
短路测试HV, // (接线图中标注于 Y15, KM9)
|
抛负载通断,
|
||||||
短路测试LV // (接线图中标注于 Y16, KM10)
|
/// <summary>双向直流源(HV)短路测试通断(仅一工位,模块1# Y8,KA9)</summary>
|
||||||
|
短路测试HV,
|
||||||
|
/// <summary>低压源载一体机(LV)短路测试通断(仅一工位,模块1# Y9,KA10)</summary>
|
||||||
|
短路测试LV
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -50,90 +60,75 @@ namespace DeviceCommand.Devices
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IO 板卡组(三工位统一调度),封装 3 块 IO 继电器板卡的访问。
|
/// IO 板卡组(三工位统一调度),封装 3 块 IO 继电器板卡的访问。
|
||||||
/// 根据 ACP 硬件接线图的点位映射字典,按台架序号路由到对应板卡的线圈地址,
|
/// 根据 ACP硬件接线图.xlsx 的点位映射字典,按台架序号路由到对应板卡的线圈地址。
|
||||||
/// 并内置充电/放电互锁保护,防止同时吸合造成短路。
|
/// 注意:模块1# 集中承载三工位的 KL30/KL15 唤醒、蜂鸣器、电子锁及一工位专属的
|
||||||
|
/// 抛负载/短路测试;模块2# 承载三工位 CC/CP 引导信号电阻;模块3# 承载三工位温度检测电阻。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ACPCommand]
|
[ACPCommand]
|
||||||
public class IOBoardGroup
|
public class IOBoardGroup
|
||||||
{
|
{
|
||||||
// 声明底层的 3 个 IO 板卡实例(对应三工位系统)
|
// 声明底层的 3 个 IO 板卡实例(对应接线图中的 IO继电器模块 1#/2#/3#)
|
||||||
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; }
|
public IOBoard Board3 { get; private set; }
|
||||||
|
|
||||||
private readonly byte _slaveAddress = 1; // 默认 Modbus 从站号为 1
|
private readonly byte _slaveAddress = 1; // 默认 Modbus 从站号为 1
|
||||||
|
|
||||||
// 核心:根据 ACP硬件接线图 严格对齐的数据字典 (3个模块独立对应1-3工位)
|
// 核心:根据 ACP硬件接线图.xlsx 严格对齐的数据字典(按工位分组,点位跨模块路由)
|
||||||
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# 工位(一工位)
|
||||||
{ 1, new Dictionary<功能动作, IoPortInfo> {
|
{ 1, new Dictionary<功能动作, IoPortInfo> {
|
||||||
{ 功能动作.产品充电三相, new IoPortInfo(1, 0) }, // Y1 -> 0 (KM2)
|
{ 功能动作.KL30通断, new IoPortInfo(1, 0) }, // 模块1# Y1 -> 0 (KA2, 低压电源KL30唤醒)
|
||||||
{ 功能动作.产品放电三相, new IoPortInfo(1, 1) }, // Y2 -> 1 (KM3)
|
{ 功能动作.KL15通断, new IoPortInfo(1, 1) }, // 模块1# Y2 -> 1 (KA3, 低压电源KL15唤醒)
|
||||||
{ 功能动作.KL30通断, new IoPortInfo(1, 2) }, // Y3 -> 2
|
{ 功能动作.抛负载通断, new IoPortInfo(1, 6) }, // 模块1# Y7 -> 6 (KA8, 双向直流源HV+抛负载)
|
||||||
{ 功能动作.KL15通断, new IoPortInfo(1, 3) }, // Y4 -> 3
|
{ 功能动作.短路测试HV, new IoPortInfo(1, 7) }, // 模块1# Y8 -> 7 (KA9, 双向直流源HV短路测试)
|
||||||
{ 功能动作.电子锁60欧电阻, new IoPortInfo(1, 4) }, // Y5 -> 4
|
{ 功能动作.短路测试LV, new IoPortInfo(1, 8) }, // 模块1# Y9 -> 8 (KA10, 低压源载一体机LV短路测试)
|
||||||
{ 功能动作.温度检测1K欧电阻, new IoPortInfo(1, 5) }, // Y6 -> 5
|
{ 功能动作.蜂鸣器报警, new IoPortInfo(1, 9) }, // 模块1# Y10 -> 9 (1#蜂鸣器)
|
||||||
{ 功能动作.CC信号串1K欧电阻, new IoPortInfo(1, 6) }, // Y7 -> 6
|
{ 功能动作.电子锁60欧电阻, new IoPortInfo(1, 12) }, // 模块1# Y13 -> 12 (1#电子锁60Ω)
|
||||||
{ 功能动作.CP信号串1K欧电阻, new IoPortInfo(1, 7) }, // Y8 -> 7
|
{ 功能动作.CC信号串1K欧电阻, new IoPortInfo(2, 0) }, // 模块2# Y1 -> 0 (CC 1KΩ)
|
||||||
{ 功能动作.CC信号串680欧电阻, new IoPortInfo(1, 8) }, // Y9 -> 8
|
{ 功能动作.CC信号串680欧电阻, new IoPortInfo(2, 1) }, // 模块2# Y2 -> 1 (CC 680Ω)
|
||||||
{ 功能动作.CC信号串220欧电阻, new IoPortInfo(1, 9) }, // Y10 -> 9
|
{ 功能动作.CC信号串220欧电阻, new IoPortInfo(2, 2) }, // 模块2# Y3 -> 2 (CC 220Ω)
|
||||||
{ 功能动作.CC信号串100欧电阻, new IoPortInfo(1, 10) }, // Y11 -> 10
|
{ 功能动作.CC信号串100欧电阻, new IoPortInfo(2, 3) }, // 模块2# Y4 -> 3 (CC 100Ω)
|
||||||
{ 功能动作.CC信号空载, new IoPortInfo(1, 11) }, // Y12 -> 11
|
{ 功能动作.CP信号串1K欧电阻, new IoPortInfo(2, 12) }, // 模块2# Y13 -> 12 (CP 1KΩ)
|
||||||
{ 功能动作.蜂鸣器报警, new IoPortInfo(1, 12) }, // Y13 -> 12
|
{ 功能动作.温度检测1K欧电阻, new IoPortInfo(3, 0) } // 模块3# Y1 -> 0 (温度检测1KΩ)
|
||||||
{ 功能动作.抛负载通断, 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# 工位(二工位)
|
||||||
{ 2, new Dictionary<功能动作, IoPortInfo> {
|
{ 2, new Dictionary<功能动作, IoPortInfo> {
|
||||||
{ 功能动作.产品充电三相, new IoPortInfo(2, 0) }, // Y1 -> 0 (KM4)
|
{ 功能动作.KL30通断, new IoPortInfo(1, 2) }, // 模块1# Y3 -> 2 (KA4, 低压电源KL30唤醒)
|
||||||
{ 功能动作.产品放电三相, new IoPortInfo(2, 1) }, // Y2 -> 1 (KM5)
|
{ 功能动作.KL15通断, new IoPortInfo(1, 3) }, // 模块1# Y4 -> 3 (KA5, 低压电源KL15唤醒)
|
||||||
{ 功能动作.KL30通断, new IoPortInfo(2, 2) }, // Y3 -> 2
|
{ 功能动作.蜂鸣器报警, new IoPortInfo(1, 10) }, // 模块1# Y11 -> 10 (2#蜂鸣器)
|
||||||
{ 功能动作.KL15通断, new IoPortInfo(2, 3) }, // Y4 -> 3
|
{ 功能动作.电子锁60欧电阻, new IoPortInfo(1, 13) }, // 模块1# Y14 -> 13 (2#电子锁60Ω)
|
||||||
{ 功能动作.电子锁60欧电阻, new IoPortInfo(2, 4) }, // Y5 -> 4
|
{ 功能动作.CC信号串1K欧电阻, new IoPortInfo(2, 4) }, // 模块2# Y5 -> 4 (CC 1KΩ)
|
||||||
{ 功能动作.温度检测1K欧电阻, new IoPortInfo(2, 5) }, // Y6 -> 5
|
{ 功能动作.CC信号串680欧电阻, new IoPortInfo(2, 5) }, // 模块2# Y6 -> 5 (CC 680Ω)
|
||||||
{ 功能动作.CC信号串1K欧电阻, new IoPortInfo(2, 6) }, // Y7 -> 6
|
{ 功能动作.CC信号串220欧电阻, new IoPortInfo(2, 6) }, // 模块2# Y7 -> 6 (CC 220Ω)
|
||||||
{ 功能动作.CP信号串1K欧电阻, new IoPortInfo(2, 7) }, // Y8 -> 7
|
{ 功能动作.CC信号串100欧电阻, new IoPortInfo(2, 7) }, // 模块2# Y8 -> 7 (CC 100Ω)
|
||||||
{ 功能动作.CC信号串680欧电阻, new IoPortInfo(2, 8) }, // Y9 -> 8
|
{ 功能动作.CP信号串1K欧电阻, new IoPortInfo(2, 13) }, // 模块2# Y14 -> 13 (CP 1KΩ)
|
||||||
{ 功能动作.CC信号串220欧电阻, new IoPortInfo(2, 9) }, // Y10 -> 9
|
{ 功能动作.温度检测1K欧电阻, new IoPortInfo(3, 1) } // 模块3# Y2 -> 1 (温度检测1KΩ)
|
||||||
{ 功能动作.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# 工位(三工位)
|
||||||
{ 3, new Dictionary<功能动作, IoPortInfo> {
|
{ 3, new Dictionary<功能动作, IoPortInfo> {
|
||||||
{ 功能动作.产品充电三相, new IoPortInfo(3, 0) }, // Y1 -> 0 (KM6)
|
{ 功能动作.KL30通断, new IoPortInfo(1, 4) }, // 模块1# Y5 -> 4 (KA6, 低压电源KL30唤醒)
|
||||||
{ 功能动作.产品放电三相, new IoPortInfo(3, 1) }, // Y2 -> 1 (KM7)
|
{ 功能动作.KL15通断, new IoPortInfo(1, 5) }, // 模块1# Y6 -> 5 (KA7, 低压电源KL15唤醒)
|
||||||
{ 功能动作.KL30通断, new IoPortInfo(3, 2) }, // Y3 -> 2
|
{ 功能动作.蜂鸣器报警, new IoPortInfo(1, 11) }, // 模块1# Y12 -> 11 (3#蜂鸣器)
|
||||||
{ 功能动作.KL15通断, new IoPortInfo(3, 3) }, // Y4 -> 3
|
{ 功能动作.电子锁60欧电阻, new IoPortInfo(1, 14) }, // 模块1# Y15 -> 14 (3#电子锁60Ω)
|
||||||
{ 功能动作.电子锁60欧电阻, new IoPortInfo(3, 4) }, // Y5 -> 4
|
{ 功能动作.CC信号串1K欧电阻, new IoPortInfo(2, 8) }, // 模块2# Y9 -> 8 (CC 1KΩ)
|
||||||
{ 功能动作.温度检测1K欧电阻, new IoPortInfo(3, 5) }, // Y6 -> 5
|
{ 功能动作.CC信号串680欧电阻, new IoPortInfo(2, 9) }, // 模块2# Y10 -> 9 (CC 680Ω)
|
||||||
{ 功能动作.CC信号串1K欧电阻, new IoPortInfo(3, 6) }, // Y7 -> 6
|
{ 功能动作.CC信号串220欧电阻, new IoPortInfo(2, 10) }, // 模块2# Y11 -> 10 (CC 220Ω)
|
||||||
{ 功能动作.CP信号串1K欧电阻, new IoPortInfo(3, 7) }, // Y8 -> 7
|
{ 功能动作.CC信号串100欧电阻, new IoPortInfo(2, 11) }, // 模块2# Y12 -> 11 (CC 100Ω)
|
||||||
{ 功能动作.CC信号串680欧电阻, new IoPortInfo(3, 8) }, // Y9 -> 8
|
{ 功能动作.CP信号串1K欧电阻, new IoPortInfo(2, 14) }, // 模块2# Y15 -> 14 (CP 1KΩ)
|
||||||
{ 功能动作.CC信号串220欧电阻, new IoPortInfo(3, 9) }, // Y10 -> 9
|
{ 功能动作.温度检测1K欧电阻, new IoPortInfo(3, 2) } // 模块3# Y3 -> 2 (温度检测1KΩ)
|
||||||
{ 功能动作.CC信号串100欧电阻, new IoPortInfo(3, 10) }, // Y11 -> 10
|
|
||||||
{ 功能动作.CC信号空载, new IoPortInfo(3, 11) }, // Y12 -> 11
|
|
||||||
{ 功能动作.蜂鸣器报警, new IoPortInfo(3, 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)
|
|
||||||
}}
|
}}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造函数,注入三个工位的 IO 板卡实例。
|
/// 构造函数,注入三个 IO 板卡实例。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="board1">1# 工位 IO 板卡实例</param>
|
/// <param name="board1">IO继电器模块 1# 板卡实例</param>
|
||||||
/// <param name="board2">2# 工位 IO 板卡实例</param>
|
/// <param name="board2">IO继电器模块 2# 板卡实例</param>
|
||||||
/// <param name="board3">3# 工位 IO 板卡实例</param>
|
/// <param name="board3">IO继电器模块 3# 板卡实例</param>
|
||||||
/// <exception cref="ArgumentNullException">任一块板卡实例为空时抛出</exception>
|
/// <exception cref="ArgumentNullException">任一块板卡实例为空时抛出</exception>
|
||||||
// 修改构造函数以支持 3 个板块
|
|
||||||
public IOBoardGroup(IOBoard board1, IOBoard board2, IOBoard board3)
|
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 实例不能为空。");
|
||||||
@@ -142,7 +137,7 @@ namespace DeviceCommand.Devices
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 执行指定台架的功能动作控制(带高低电平开关及底层安全互锁)
|
/// 执行指定台架的功能动作控制(按接线图字典跨模块路由到对应线圈地址)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="台架序号">台架/工位序号 (1 - 3)</param>
|
/// <param name="台架序号">台架/工位序号 (1 - 3)</param>
|
||||||
/// <param name="动作">控制功能类型</param>
|
/// <param name="动作">控制功能类型</param>
|
||||||
@@ -153,29 +148,10 @@ 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 点位映射配置。请注意抛负载及短路测试仅存在于 3# 工位。");
|
throw new ArgumentException($"未找到台架 [{台架序号}] 对应功能 [{动作}] 的 IO 点位映射配置。请注意抛负载及短路测试(HV/LV)仅存在于 1# 工位。");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 软件防错高危互锁逻辑:防止同时执行充电和放电
|
// 2. 动态获取目标板卡实例并直接驱动开关端口
|
||||||
if (开关状态)
|
|
||||||
{
|
|
||||||
if (动作 == 功能动作.产品充电三相)
|
|
||||||
{
|
|
||||||
if (IoMapping[台架序号].TryGetValue(功能动作.产品放电三相, out var 放电点位))
|
|
||||||
{
|
|
||||||
await GetBoardInstance(放电点位.ModuleIndex).写输出开关(_slaveAddress, 放电点位.Address, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (动作 == 功能动作.产品放电三相)
|
|
||||||
{
|
|
||||||
if (IoMapping[台架序号].TryGetValue(功能动作.产品充电三相, out var 充电点位))
|
|
||||||
{
|
|
||||||
await GetBoardInstance(充电点位.ModuleIndex).写输出开关(_slaveAddress, 充电点位.Address, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 动态获取目标板卡实例并直接驱动开关端口
|
|
||||||
IOBoard 目标板卡 = GetBoardInstance(io信息.ModuleIndex);
|
IOBoard 目标板卡 = GetBoardInstance(io信息.ModuleIndex);
|
||||||
await 目标板卡.写输出开关(_slaveAddress, io信息.Address, 开关状态);
|
await 目标板卡.写输出开关(_slaveAddress, io信息.Address, 开关状态);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,7 +236,8 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
public async Task 设置CV正向电流(double 电流, CancellationToken ct = default)
|
public async Task 设置CV正向电流(double 电流, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
await SendAsync($"CURRent:LIMit:POSitive {电流}{ScpiDelimiter}", ct);
|
await SendAsync($"VOLTage:ILIMit {电流}{ScpiDelimiter}", ct);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -247,7 +248,7 @@ namespace DeviceCommand.Devices
|
|||||||
public async Task 设置CV反向电流(double 电流, CancellationToken ct = default)
|
public async Task 设置CV反向电流(double 电流, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 载模式限制需要负数,若传入正数建议在外部转换为负值
|
// 载模式限制需要负数,若传入正数建议在外部转换为负值
|
||||||
await SendAsync($"CURRent:LIMit:NEGative {电流}{ScpiDelimiter}", ct);
|
await SendAsync($"VOLTage:ILIMit:NEGative {电流}{ScpiDelimiter}", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user