- Driver.AbCip-007: inject an optional ILogger<AbCipDriver> / ILogger<AbCipAlarmProjection> (default NullLogger) and log around every read / write / template-fetch / probe / alarm-poll failure path. - Driver.AbCip-011: LogWarning when InitializeAsync is configured with Probe.Enabled=true but ProbeTagPath is blank — operators now see why GetHostStatuses keeps reporting Unknown. - Driver.AbCip-012: documented the LibplctagTemplateReader per-call Tag cost as accepted given libplctag's own connection pool and the low-frequency discovery use-case. - Driver.AbCip-013: per-device AllowPacking + ConnectionSize overrides on AbCipDeviceOptions, threaded through AbCipTagCreateParams; central BuildCreateParams helper replaces five ad-hoc clones; AllowPacking now reaches Tag.AllowPacking at runtime. - Driver.AbCip-015: stale-comment sweep — every PR-N forward-reference is rewritten to describe present behaviour. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
57 lines
2.5 KiB
C#
57 lines
2.5 KiB
C#
using System.Collections.Concurrent;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip;
|
|
|
|
/// <summary>
|
|
/// Cache of UDT shape descriptors keyed by <c>(deviceHostAddress, templateInstanceId)</c>.
|
|
/// Populated on demand during discovery + whole-UDT reads; flushed via
|
|
/// <see cref="AbCipDriver.FlushOptionalCachesAsync"/> and on device
|
|
/// <c>ReinitializeAsync</c>.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Templates are decoded by <see cref="CipTemplateObjectDecoder"/> (CIP Template Object
|
|
/// class 0x6C, <c>GetAttributeList</c> + <c>Read Template</c>); the live reader is
|
|
/// <see cref="LibplctagTemplateReader"/>, and <see cref="AbCipDriver.FetchUdtShapeAsync"/>
|
|
/// populates this cache on first fetch.
|
|
/// </remarks>
|
|
public sealed class AbCipTemplateCache
|
|
{
|
|
private readonly ConcurrentDictionary<(string device, uint instanceId), AbCipUdtShape> _shapes = new();
|
|
|
|
/// <summary>
|
|
/// Retrieve a cached UDT shape, or <c>null</c> if not yet read.
|
|
/// </summary>
|
|
public AbCipUdtShape? TryGet(string deviceHostAddress, uint templateInstanceId) =>
|
|
_shapes.TryGetValue((deviceHostAddress, templateInstanceId), out var shape) ? shape : null;
|
|
|
|
/// <summary>Store a freshly-decoded UDT shape.</summary>
|
|
public void Put(string deviceHostAddress, uint templateInstanceId, AbCipUdtShape shape) =>
|
|
_shapes[(deviceHostAddress, templateInstanceId)] = shape;
|
|
|
|
/// <summary>Drop every cached shape — called on <see cref="AbCipDriver.FlushOptionalCachesAsync"/>.</summary>
|
|
public void Clear() => _shapes.Clear();
|
|
|
|
/// <summary>Count of cached shapes — exposed for diagnostics + tests.</summary>
|
|
public int Count => _shapes.Count;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decoded shape of one Logix UDT — member list + each member's offset + type. Populated
|
|
/// by <see cref="CipTemplateObjectDecoder.Decode"/> from a Template Object response buffer
|
|
/// read via <see cref="LibplctagTemplateReader"/>.
|
|
/// </summary>
|
|
/// <param name="TypeName">UDT name as reported by the Template Object.</param>
|
|
/// <param name="TotalSize">Bytes the UDT occupies in a whole-UDT read buffer.</param>
|
|
/// <param name="Members">Ordered list of members, each with its byte offset + type.</param>
|
|
public sealed record AbCipUdtShape(
|
|
string TypeName,
|
|
int TotalSize,
|
|
IReadOnlyList<AbCipUdtMember> Members);
|
|
|
|
/// <summary>One member of a Logix UDT.</summary>
|
|
public sealed record AbCipUdtMember(
|
|
string Name,
|
|
int Offset,
|
|
AbCipDataType DataType,
|
|
int ArrayLength);
|