Browse path online. GalaxyDriver now implements ITagDiscovery against the gateway's GalaxyRepositoryClient (PR 0.1's mxaccessgw browse RPC) and feeds the address-space builder one folder per gobject + one variable per dynamic attribute, with alarm-bearing attributes carrying all five sub-attribute refs the server-level AlarmConditionService (PR 2.2) needs. Files: - Browse/IGalaxyHierarchySource.cs — driver-side seam between the discoverer and the gateway. Test fakes return canned hierarchies so the discoverer's translation logic is exercised without a real gRPC channel. - Browse/GatewayGalaxyHierarchySource.cs — production wrapper around GalaxyRepositoryClient.DiscoverHierarchyAsync (paged internally). - Browse/GalaxyDiscoverer.cs — translates GalaxyObject → IAddressSpaceBuilder calls. Browse name = contained_name (falls back to tag_name); full reference = attr.full_tag_reference when set, else tag_name + "." + attribute_name. Skips objects/attributes with empty identity. - Browse/DataTypeMap.cs — mx_data_type → DriverDataType (port from legacy GalaxyProxyDriver.MapDataType, same fallback to String for unknown codes). - Browse/SecurityMap.cs — security_classification → SecurityClassification (port from legacy GalaxyProxyDriver.MapSecurity). - Browse/AlarmRefBuilder.cs — populates the five sub-attribute refs by Galaxy convention (.InAlarm/.Priority/.DescAttrName/.Acked/.AckMsg). The same convention the legacy GalaxyAlarmTracker hard-coded; concentrated here so PR 2.2's service receives complete AlarmConditionInfo rows. GalaxyDriver: - Added internal ctor accepting IGalaxyHierarchySource? for test injection. Default lazily builds GatewayGalaxyHierarchySource around a GalaxyRepositoryClient constructed from options on first DiscoverAsync. - Owned GalaxyRepositoryClient disposed in Dispose. - ApiKey resolution is currently a passthrough of ApiKeySecretRef — PR 4.W (or follow-up) wires DPAPI-backed secret resolution. csproj: path-based ProjectReference to mxaccessgw (the user is shipping that repo on a parallel track; both repos sit side-by-side on the dev box). Tests project also references MxGateway.Contracts directly to construct GalaxyObject / GalaxyAttribute fixtures. Tests: 10 new in Browse/GalaxyDiscovererTests.cs covering folder-per-object, variable-per-attribute, full-ref defaulting + gw-supplied override, browse- name fallback, every metadata field propagation, alarm sub-attribute ref population, non-alarm rows skip MarkAsAlarmCondition, empty-identity skips, empty-attribute-name skips, end-to-end through GalaxyDriver.DiscoverAsync. 20 total Galaxy tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
2.4 KiB
C#
52 lines
2.4 KiB
C#
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browse;
|
|
|
|
/// <summary>
|
|
/// Populates the five sub-attribute references on <see cref="AlarmConditionInfo"/>
|
|
/// by Galaxy convention. The server-level <c>AlarmConditionService</c> (PR 2.2) uses
|
|
/// these to subscribe to live alarm-state attributes and to route ack writes back to
|
|
/// the alarm tag.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Galaxy alarms expose four runtime attributes plus a write-only ack target,
|
|
/// consistently named on every alarm-bearing object:
|
|
/// <list type="bullet">
|
|
/// <item><c><tag>.<attr>.InAlarm</c></item>
|
|
/// <item><c><tag>.<attr>.Priority</c></item>
|
|
/// <item><c><tag>.<attr>.DescAttrName</c></item>
|
|
/// <item><c><tag>.<attr>.Acked</c></item>
|
|
/// <item><c><tag>.<attr>.AckMsg</c></item>
|
|
/// </list>
|
|
/// This is the same convention the legacy <c>GalaxyAlarmTracker</c> hard-coded; we
|
|
/// concentrate it here so PR 2.2's service receives complete <c>AlarmConditionInfo</c>
|
|
/// rows during discovery without the server needing to know the convention.
|
|
/// </remarks>
|
|
internal static class AlarmRefBuilder
|
|
{
|
|
private const string InAlarmSuffix = ".InAlarm";
|
|
private const string PrioritySuffix = ".Priority";
|
|
private const string DescAttrNameSuffix = ".DescAttrName";
|
|
private const string AckedSuffix = ".Acked";
|
|
private const string AckMsgSuffix = ".AckMsg";
|
|
|
|
/// <summary>
|
|
/// Build an <see cref="AlarmConditionInfo"/> for an alarm-bearing attribute with all
|
|
/// five sub-attribute references populated. <paramref name="fullReference"/> is the
|
|
/// attribute's full reference (e.g. <c>"Tank1.Level.HiHi"</c>); the convention prefixes
|
|
/// each suffix to it.
|
|
/// </summary>
|
|
public static AlarmConditionInfo Build(
|
|
string fullReference,
|
|
AlarmSeverity initialSeverity = AlarmSeverity.Medium,
|
|
string? initialDescription = null) => new(
|
|
SourceName: fullReference,
|
|
InitialSeverity: initialSeverity,
|
|
InitialDescription: initialDescription,
|
|
InAlarmRef: fullReference + InAlarmSuffix,
|
|
PriorityRef: fullReference + PrioritySuffix,
|
|
DescAttrNameRef: fullReference + DescAttrNameSuffix,
|
|
AckedRef: fullReference + AckedSuffix,
|
|
AckMsgWriteRef: fullReference + AckMsgSuffix);
|
|
}
|