全部网关代码添加详细中文注释

This commit is contained in:
2026-05-17 04:53:03 +08:00
parent df0c4cc4b2
commit 73d47cb470
26 changed files with 597 additions and 79 deletions

View File

@@ -6,19 +6,38 @@ using System.Text.Json;
namespace IntegrationGateway.Adapters.MC4;
/// <summary>
/// MC4.0 动环监控子系统适配器。
///
/// 实现的能力接口:
/// - IHasOwnDeviceTree对象树区域→设备层级
/// - IHasPoints实时点位值读取 + 反向控制写值
/// - IHasAlarms告警查询、确认、结束
///
/// 限流2 QPSMC4.0 API 推荐值)
/// 分页转换:网关 page/size ↔ MC4.0 skip/limit
/// </summary>
public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
{
private readonly HttpClient _http;
private readonly Mc4AuthHelper _auth;
/// <summary>令牌桶限流器2 QPS</summary>
private readonly RateLimiter _limiter = new(2);
/// <summary>适配器编码,格式 "MC4:实例名"</summary>
public string AdapterCode { get; }
/// <summary>人类可读的适配器名称</summary>
public string DisplayName => $"MC4 ({AdapterCode})";
/// <summary>适配器能力声明</summary>
public AdapterCapabilities Capabilities => new()
{
HasObjectTree = true, HasPoints = true, HasAlarms = true, AcceptsControl = true
};
/// <summary>创建 Mc4Adapter 实例</summary>
/// <param name="adapterCode">适配器编码</param>
/// <param name="http">HttpClient 实例</param>
/// <param name="baseUrl">MC4.0 服务地址</param>
public Mc4Adapter(string adapterCode, HttpClient http, string baseUrl)
{
AdapterCode = adapterCode;
@@ -26,8 +45,10 @@ public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
_auth = new Mc4AuthHelper(http, baseUrl);
}
/// <summary>初始化适配器:获取 MC4.0 Token</summary>
public async Task InitializeAsync() => await _auth.GetTokenAsync();
/// <summary>健康检查:尝试调用 MC4.0 认证接口确认可达性</summary>
public async Task<bool> HealthCheckAsync()
{
try
@@ -39,7 +60,14 @@ public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
catch { return false; }
}
// ─── IHasOwnDeviceTree ───
// ═══════════════════════════════════════════
// IHasOwnDeviceTree 实现
// ═══════════════════════════════════════════
/// <summary>
/// 获取 MC4.0 完整对象树。
/// Type=1 的节点为区域Type=2 的节点为设备。
/// </summary>
public async Task<List<DeviceTreeNode>> GetObjectTreeAsync()
{
await _limiter.WaitAsync();
@@ -51,15 +79,24 @@ public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
return tree.Select(MapNode).ToList();
}
/// <summary>MC4.0 树节点 → DeviceTreeNode 映射</summary>
private static DeviceTreeNode MapNode(Mc4TreeNode n) => new()
{
Id = n.Id, SourceId = n.Id.ToString(), Name = n.Name ?? n.Id.ToString(),
Type = n.Type, ObjectType = n.ObjectType, Tag = n.Tag,
Id = n.Id,
SourceId = n.Id.ToString(),
Name = n.Name ?? n.Id.ToString(),
Type = n.Type,
ObjectType = n.ObjectType,
Tag = n.Tag,
Option = n.Option ?? new Dictionary<string, object?>(),
Children = n.Children?.Select(MapNode).ToList() ?? new()
};
// ─── IHasPoints ───
// ═══════════════════════════════════════════
// IHasPoints 实现
// ═══════════════════════════════════════════
/// <summary>获取指定设备的所有实时点位值</summary>
public async Task<List<PointValue>> GetRealtimeValuesAsync(string sourceDeviceId)
{
await _limiter.WaitAsync();
@@ -72,11 +109,15 @@ public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
var values = JsonSerializer.Deserialize<List<Mc4PointValue>>(json)!;
return values.Select(v => new PointValue
{
SourceDeviceId = sourceDeviceId, PointIndex = v.Index,
Value = v.Value, UpdateTime = v.Time != null ? DateTime.Parse(v.Time) : null, Interval = v.Interval
SourceDeviceId = sourceDeviceId,
PointIndex = v.Index,
Value = v.Value,
UpdateTime = v.Time != null ? DateTime.Parse(v.Time) : null,
Interval = v.Interval
}).ToList();
}
/// <summary>向指定设备的指定点位写入控制值</summary>
public async Task SetPointValueAsync(string sourceDeviceId, int pointIndex, double value)
{
await _limiter.WaitAsync();
@@ -86,7 +127,14 @@ public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
new StringContent(body, Encoding.UTF8, "application/json"));
}
// ─── IHasAlarms ───
// ═══════════════════════════════════════════
// IHasAlarms 实现
// ═══════════════════════════════════════════
/// <summary>
/// 分页查询告警列表。
/// 内部完成 page/size → skip/limit 转换。
/// </summary>
public async Task<PagedResult<StandardAlarm>> GetAlarmsAsync(int page, int size, DateTime from, DateTime to,
string? level = null, string? state = null)
{
@@ -98,7 +146,7 @@ public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
To = to.ToString("yyyy-MM-dd HH:mm:ss"),
Skip = (page - 1) * size,
Limit = size,
Sort = 1
Sort = 1 // 按时间降序
});
var resp = await client.PostAsync("/api/central/alarm/query",
new StringContent(body, Encoding.UTF8, "application/json"));
@@ -109,17 +157,21 @@ public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
{
Items = result.List?.Select(a => new StandardAlarm
{
AlarmId = a.Id ?? "", DeviceId = a.Sid?.ToString(),
AlarmId = a.Id ?? "",
DeviceId = a.Sid?.ToString(),
AdapterCode = AdapterCode,
Level = MapAlarmLevel(a.Level), Title = a.Desc ?? "",
Level = MapAlarmLevel(a.Level),
Title = a.Desc ?? "",
OccurTime = DateTime.TryParse(a.Stime, out var st) ? st : DateTime.MinValue,
Status = MapAlarmState(a.State),
ActualValue = a.Soption?.Value, ThresholdValue = a.Eoption?.Value
ActualValue = a.Soption?.Value,
ThresholdValue = a.Eoption?.Value
}).ToList() ?? new(),
Total = result.Total
};
}
/// <summary>确认告警(同时写回 MC4.0</summary>
public async Task ConfirmAlarmAsync(string alarmId)
{
await _limiter.WaitAsync();
@@ -129,6 +181,7 @@ public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
new StringContent(body, Encoding.UTF8, "application/json"));
}
/// <summary>结束告警(同时写回 MC4.0</summary>
public async Task EndAlarmAsync(string alarmId)
{
await _limiter.WaitAsync();
@@ -138,15 +191,29 @@ public class Mc4Adapter : IHasOwnDeviceTree, IHasPoints, IHasAlarms
new StringContent(body, Encoding.UTF8, "application/json"));
}
private static string MapAlarmLevel(int level) => level switch { 1 => "提示", 2 => "普通", 3 => "重要", 4 => "紧急", _ => "提示" };
private static string MapAlarmState(int state) => state switch { 1 => "未确认", 2 => "已确认", 3 => "已结束", _ => "未确认" };
/// <summary>MC4.0 告警等级数字 → 中文映射</summary>
private static string MapAlarmLevel(int level) => level switch
{
1 => "提示", 2 => "普通", 3 => "重要", 4 => "紧急", _ => "提示"
};
/// <summary>MC4.0 告警状态数字 → 中文映射</summary>
private static string MapAlarmState(int state) => state switch
{
1 => "未确认", 2 => "已确认", 3 => "已结束", _ => "未确认"
};
}
// ─── MC4 JSON Models ───
// ═══════════════════════════════════════════
// MC4.0 JSON 反序列化模型(内部使用)
// ═══════════════════════════════════════════
/// <summary>MC4.0 对象树节点</summary>
public class Mc4TreeNode
{
public int Id { get; set; }
public string? Name { get; set; }
/// <summary>节点类型1=区域2=设备</summary>
public int Type { get; set; }
public int ObjectType { get; set; }
public string? Tag { get; set; }
@@ -154,6 +221,7 @@ public class Mc4TreeNode
public List<Mc4TreeNode>? Children { get; set; }
}
/// <summary>MC4.0 点位值</summary>
public class Mc4PointValue
{
public int Id { get; set; }
@@ -163,25 +231,32 @@ public class Mc4PointValue
public int Interval { get; set; }
}
/// <summary>MC4.0 告警查询请求体</summary>
public class Mc4AlarmQuery
{
public string? Sid { get; set; }
public string From { get; set; } = "";
public string To { get; set; } = "";
/// <summary>跳过的记录数(= (page-1)*size</summary>
public int Skip { get; set; }
/// <summary>每页条数</summary>
public int Limit { get; set; }
/// <summary>排序方式1=时间降序</summary>
public int Sort { get; set; }
}
/// <summary>MC4.0 告警查询响应</summary>
public class Mc4AlarmQueryResult
{
public int Total { get; set; }
public List<Mc4AlarmItem>? List { get; set; }
}
/// <summary>MC4.0 告警条目</summary>
public class Mc4AlarmItem
{
public string? Id { get; set; }
/// <summary>设备 SID</summary>
public int? Sid { get; set; }
public string? Desc { get; set; }
public string? EngDesc { get; set; }
@@ -192,10 +267,13 @@ public class Mc4AlarmItem
public string? Ctime { get; set; }
public string? Cuser { get; set; }
public int Type { get; set; }
/// <summary>告警触发时阈值信息</summary>
public Mc4Option? Soption { get; set; }
/// <summary>告警结束时阈值信息</summary>
public Mc4Option? Eoption { get; set; }
}
/// <summary>MC4.0 告警阈值信息</summary>
public class Mc4Option
{
public double? Value { get; set; }