@page "/modbus/diagnostics/{DriverInstanceId}" @using Microsoft.AspNetCore.Components.Web @using ZB.MOM.WW.OtOpcUa.Admin.Services @rendermode RenderMode.InteractiveServer @inject DriverDiagnosticsClient Diagnostics @* #154 — operator-facing view of the Server's auto-prohibition state for a Modbus driver. Fetches via DriverDiagnosticsClient (HttpClient against the Server's HealthEndpointsHost). Refreshes on demand; auto-refresh is a future task once a SignalR diag channel exists. *@ Modbus diagnostics — @DriverInstanceId

Modbus auto-prohibitions

Driver instance @DriverInstanceId. Live snapshot of coalesced ranges the planner has learned to read individually (#148 / #150 / #151 / #152).

@if (_lastRefreshed is not null) { Last refreshed @_lastRefreshed.Value.ToLocalTime().ToString("HH:mm:ss") }
@if (_error is not null) {
@_error
} else if (_response is null) {

Click Refresh to load.

} else if (_response.Count == 0) {
No auto-prohibitions. The planner is coalescing freely.
} else {
Prohibited ranges
@foreach (var r in _response.Ranges.OrderBy(r => r.UnitId).ThenBy(r => r.Region).ThenBy(r => r.StartAddress)) { }
Unit Region Start End Span Status Last probed
@r.UnitId @r.Region @r.StartAddress @r.EndAddress @(r.EndAddress - r.StartAddress + 1) @if (r.BisectionPending) { BISECTING } else { ISOLATED } @FormatTimeSince(r.LastProbedUtc)
} @code { [Parameter] public string DriverInstanceId { get; set; } = string.Empty; private ModbusAutoProhibitionsResponse? _response; private string? _error; private bool _loading; private DateTime? _lastRefreshed; private async Task LoadAsync() { _loading = true; _error = null; try { _response = await Diagnostics.GetModbusAutoProhibitedRangesAsync(DriverInstanceId); _lastRefreshed = DateTime.UtcNow; if (_response is null) _error = $"Server reports driver '{DriverInstanceId}' is not present or is not a Modbus driver."; } catch (Exception ex) { _error = $"Fetch failed: {ex.Message}"; } finally { _loading = false; } } private static string FormatTimeSince(DateTime utc) { var span = DateTime.UtcNow - utc; if (span.TotalSeconds < 60) return $"{(int)span.TotalSeconds}s ago"; if (span.TotalMinutes < 60) return $"{(int)span.TotalMinutes}m ago"; if (span.TotalHours < 24) return $"{(int)span.TotalHours}h ago"; return $"{(int)span.TotalDays}d ago"; } }