3878b51e97
- Rename AbLegacyEquipmentTagParser → AbLegacyTagDefinitionFactory; TryParse →
FromTagConfig(tagConfig, rawPath, out def). Drop the leading-{ heuristic and the
deviceHostAddress key; def.Name = rawPath. Add inverse ToTagConfig. Keep strict-enum
guards + Inspect.
- Options: Tags(IReadOnlyList<AbLegacyTagDefinition>) → RawTags(IReadOnlyList<RawTagEntry>).
- Driver: _tagsByRawPath (Ordinal); byName-only resolver; build table from _options.RawTags
via FromTagConfig, threading WriteIdempotent + resolving RawTagEntry.DeviceName to the
owning device host (ResolveDeviceHost; TODO(v3 WaveC) for the live Device-row host).
DiscoverAsync + family-profile validation iterate the built table. Probe picks its address
from RawTags via the mapper.
- Factory: retire the pre-declared tag DTO path; bind List<RawTagEntry>? RawTags; keep Devices.
- Cli BuildOptions: deliver typed defs as RawTagEntry via ToTagConfig.
- Tests: AbLegacyRawTags helper; migrate Tags= → RawTags; parser tests → FromTagConfig;
equipment-ref driver/ResolveHost tests re-authored as RawTagEntry + read by RawPath.
Driver+Contracts+Cli green; 213 driver + 36 Cli tests pass.
92 lines
4.3 KiB
C#
92 lines
4.3 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
using ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.PlcFamilies;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.AbLegacy;
|
|
|
|
/// <summary>
|
|
/// AB Legacy (PCCC) driver configuration. One instance supports N devices (SLC 500 /
|
|
/// MicroLogix / PLC-5 / LogixPccc). AbLegacy ships separately from
|
|
/// AbCip because PCCC's file-based addressing (<c>N7:0</c>) and Logix's symbolic addressing
|
|
/// (<c>Motor1.Speed</c>) pull the abstraction in different directions.
|
|
/// </summary>
|
|
public sealed class AbLegacyDriverOptions
|
|
{
|
|
/// <summary>Gets or sets the list of PCCC devices to connect to.</summary>
|
|
public IReadOnlyList<AbLegacyDeviceOptions> Devices { get; init; } = [];
|
|
|
|
/// <summary>
|
|
/// Authored raw tags this driver serves. The deploy artifact hands each authored raw
|
|
/// <c>Tag</c> as a <see cref="RawTagEntry"/> (RawPath identity + driver <c>TagConfig</c> blob +
|
|
/// WriteIdempotent flag + owning <see cref="RawTagEntry.DeviceName"/>); the driver maps each
|
|
/// through <see cref="AbLegacyTagDefinitionFactory.FromTagConfig"/> into its RawPath → definition
|
|
/// table, routing each to its device by <see cref="RawTagEntry.DeviceName"/>. AbLegacy has no
|
|
/// discovery protocol — the driver serves exactly these.
|
|
/// </summary>
|
|
public IReadOnlyList<RawTagEntry> RawTags { get; init; } = [];
|
|
|
|
/// <summary>Gets or sets the probe (connectivity check) options.</summary>
|
|
public AbLegacyProbeOptions Probe { get; init; } = new();
|
|
|
|
/// <summary>Gets or sets the default timeout for read/write operations.</summary>
|
|
public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(2);
|
|
|
|
/// <summary>
|
|
/// Timeout for the AdminUI Test Connect probe, in seconds. The AdminUI clamps to a
|
|
/// 60s server-side maximum; this default is what the form pre-fills for new instances.
|
|
/// </summary>
|
|
[Display(Name = "Probe timeout (seconds)", Description = "Connection test timeout. Default 5s.", GroupName = "Diagnostics")]
|
|
[Range(1, 60)]
|
|
public int ProbeTimeoutSeconds { get; init; } = 5;
|
|
}
|
|
|
|
public sealed record AbLegacyDeviceOptions(
|
|
string HostAddress,
|
|
AbLegacyPlcFamily PlcFamily = AbLegacyPlcFamily.Slc500,
|
|
string? DeviceName = null);
|
|
|
|
/// <summary>
|
|
/// One PCCC-backed OPC UA variable. <paramref name="Address"/> is the canonical PCCC
|
|
/// file-address string that parses via <c>AbLegacyAddress.TryParse</c>.
|
|
/// </summary>
|
|
/// <param name="ArrayLength">
|
|
/// Element count when the tag addresses a multi-element span of a PCCC data file (e.g. an
|
|
/// <c>N7</c> integer file is inherently up to 256 words); <see langword="null"/> for a scalar.
|
|
/// A PCCC data file holds at most <see cref="AbLegacyArray.MaxElements"/> (256) elements, so a
|
|
/// value above that is clamped where it is materialised/read. <c>1</c> is a valid one-element array exposed as a <c>[1]</c> OPC UA array node.
|
|
/// </param>
|
|
public sealed record AbLegacyTagDefinition(
|
|
string Name,
|
|
string DeviceHostAddress,
|
|
string Address,
|
|
AbLegacyDataType DataType,
|
|
bool Writable = true,
|
|
bool WriteIdempotent = false,
|
|
int? ArrayLength = null);
|
|
|
|
/// <summary>PCCC array-tag constants shared by the parser, discovery, and read paths.</summary>
|
|
public static class AbLegacyArray
|
|
{
|
|
/// <summary>
|
|
/// Maximum element count for a single PCCC data file. The PCCC/DF1 protocol addresses a
|
|
/// data file element with a single byte sub-element offset, so a file holds at most 256
|
|
/// elements (words for N/B/I/O/S/A, 32-bit elements for L/F). Array tags clamp to this.
|
|
/// </summary>
|
|
public const int MaxElements = 256;
|
|
}
|
|
|
|
public sealed class AbLegacyProbeOptions
|
|
{
|
|
/// <summary>Gets or sets a value indicating whether connectivity probing is enabled.</summary>
|
|
public bool Enabled { get; init; } = true;
|
|
|
|
/// <summary>Gets or sets the interval between probe attempts.</summary>
|
|
public TimeSpan Interval { get; init; } = TimeSpan.FromSeconds(5);
|
|
|
|
/// <summary>Gets or sets the timeout for each probe operation.</summary>
|
|
public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(2);
|
|
|
|
/// <summary>Gets or sets the probe address (defaults to <c>S:0</c> — status file, first word).</summary>
|
|
public string? ProbeAddress { get; init; } = "S:0";
|
|
}
|