feat(hosts): driver diagnostics channel on /hosts, S7 negotiated PDU size first (#640)

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 16:57:38 -04:00
parent a8b07ae12d
commit c2bdb7d5de
23 changed files with 469 additions and 20 deletions
@@ -32,7 +32,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.S7;
/// </para>
/// </remarks>
public sealed class S7Driver
: IDriver, ITagDiscovery, IReadable, IWritable, IBatchSubscribable, IHostConnectivityProbe, ISkippedTagReporter, IDisposable, IAsyncDisposable
: IDriver, ITagDiscovery, IReadable, IWritable, IBatchSubscribable, IHostConnectivityProbe, ISkippedTagReporter, IDriverDiagnostics, IDisposable, IAsyncDisposable
{
/// <summary>Authored tags this driver could not build into its poll table (Gitea #541).</summary>
private readonly SkippedTagLedger _skippedTags = new();
@@ -463,6 +463,19 @@ public sealed class S7Driver
["S7.NegotiatedPduSize"] = NegotiatedPduSize,
};
/// <summary>
/// <see cref="IDriverDiagnostics"/> view of the same facts, as strings, for the <c>/hosts</c> page
/// (Gitea #640). Empty before the first connect (PDU size 0 is "not negotiated yet", not a size).
/// </summary>
/// <returns>The diagnostics bag.</returns>
IReadOnlyDictionary<string, string> IDriverDiagnostics.GetDiagnostics()
{
var pdu = NegotiatedPduSize;
return pdu > 0
? new Dictionary<string, string> { ["S7.NegotiatedPduSize"] = pdu.ToString(System.Globalization.CultureInfo.InvariantCulture) }
: new Dictionary<string, string>();
}
private static readonly HashSet<S7DataType> ByteAnchoredDataTypes = new()
{
S7DataType.Int64,