Release: WAN data usage tracking, audit improvements, and fixes#374
Merged
tvancott42 merged 4 commits intomainfrom Feb 27, 2026
Merged
Release: WAN data usage tracking, audit improvements, and fixes#374tvancott42 merged 4 commits intomainfrom
tvancott42 merged 4 commits intomainfrom
Conversation
Ports with 802.1X/RADIUS MAC-based auth legitimately need tagged VLANs for dynamic VLAN assignment. If the admin has curated a custom VLAN set, skip entirely. If "Allow All" is configured, downgrade to Informational severity with score impact 2 (instead of Recommended/6). Add overrideSeverity and overrideScoreImpact to CreateIssue base method so individual rules can downgrade specific cases without changing the rule's default severity.
…#372) NetFlow requires CPU-based packet inspection, making Hardware Acceleration incompatible. Skip the recommendation when the controller settings show NetFlow is active. Also adds [VendorSpecific] attribute to Core for tracking raw-JSON parsing spots that need strong typing and eventual vendor abstraction.
* Add WAN data usage tracking with billing cycle alerts Poll WAN byte counters every 2 minutes, store snapshots, calculate billing-cycle usage, and alert when thresholds are crossed. New Data Usage tab in Alerts page with per-WAN config (cap, warning %, billing day) and usage progress bars. Handles counter resets on gateway reboot. * Use friendly WAN names from network config and make alert rule enable atomic - Resolve WAN friendly names via ConnectionService.GetNetworksAsync() matching by network group (same pattern as WAN Speed Test and Adaptive SQM) - Move EnsureAlertRulesEnabledAsync before SaveChangesAsync so config save and alert rule enable are atomic in a single transaction * Use friendly WAN names from network config, fix ordinal formatting - Use NetworkInfo from GetNetworksAsync() as WAN source (same as speed test dropdowns) instead of device-level GatewayWanInterface - Key configs by WanNetworkgroup (WAN, WAN2) not device key (wan1, wan2) - Map device byte counters to network groups via WanKeyToNetworkGroup() - Add DisplayFormatters.FormatOrdinal() for correct ordinal suffixes (21st, 22nd, 23rd instead of 21th, 22th, 23th) - Add tests for WanKeyToNetworkGroup and FormatOrdinal * Replace inline ordinal logic in FloorPlanEditor with DisplayFormatters.FormatOrdinal * Fix FormatOrdinal for negative numbers using Math.Abs Prod-vetted FloorPlanEditor code used Math.Abs() for ordinal suffix logic. Without it, -11 would incorrectly get "st" instead of "th" because C# modulo preserves sign (-11 % 100 = -11, missing the 11/12/13 teen check). * Fix Data Usage tab: load on fresh page load, fix WAN status dots, show interface name - Add data-usage case to OnInitializedAsync so F5 loads WAN data - Fetch live WAN up/down status from device API instead of relying on summary (which only exists for enabled WANs) - Show interface name in parens next to friendly name: "Starlink (WAN)" - Fix "UniFi controller" to "UniFi Console" in user-facing text * Fix Schedule tab missing WAN interfaces when navigated to from another tab * Consolidate NormalizeWanDisplay into shared DisplayFormatters helper Move WAN -> WAN1 display normalization from inline WanSpeedTest method to DisplayFormatters.NormalizeWanDisplay(). Used by both WanSpeedTest and Data Usage tab for consistent WAN interface labels. * Show auto-managed alert rules notice with link to Rules tab * Use gateway uptime to establish baseline data usage on first snapshot When tracking is first enabled for a WAN, if the gateway booted within the current billing cycle, the cumulative byte counters represent all usage since boot (which is all within this cycle). Mark the first snapshot as IsBaseline so the usage calculation includes the raw bytes as starting usage instead of requiring deltas to accumulate from zero. * Add manual usage adjustment with explicit Save button - Consolidate migrations into single AddWanDataUsageTables migration - Add ManualAdjustmentGb to config (additive offset for known usage) - Add IsBaseline to snapshots (gateway uptime baseline detection) - Replace auto-save on every field change with explicit Save button - Lock manual adjustment field by default, click Edit to unlock - Include ManualAdjustmentGb in usage total calculation * Fix adjustment UX: rename Lock to Done, hide Save button when not dirty * Align Usage Adjustment label with other config field labels * Simplify adjustment field: readonly by default, click to unlock, locks on save/reload * Vertically center status dots with WAN name * Re-create data usage alert rules if deleted by user EnsureAlertRulesEnabledAsync only enabled existing rules but did nothing if they had been deleted. Now re-creates them as enabled. * Fix ManualAdjustmentGb not persisting and usage bar missing on fresh load SaveConfigAsync update path was missing ManualAdjustmentGb copy to existing entity. GetCurrentUsage was synchronous and returned empty list before background poll ran. Added async fallback that calculates from DB snapshots when in-memory cache is empty. * Invalidate usage cache after config save, rename adjustment to Prior Usage Bar wasn't updating after saving a manual adjustment because GetCurrentUsageAsync returned stale cached summaries. Clear cache after SaveConfigAsync so the next load recalculates from DB. Renamed "Usage Adjustment" to "Prior Usage" with clearer tooltip. * Fix prior usage field losing focus on click Single input element with toggled readonly attribute instead of swapping between two elements. Uses onfocus to unlock so the same element stays focused. * Rename Billing Cycle Day to Usage Resets On with tooltip Users don't know what day to enter - the old label was ambiguous. New label asks when the ISP resets data usage, with tooltip guidance to check the carrier renewal/due date. * Fix tooltip icon vertical alignment and prevent field label wrapping Tooltip icon-sm was sitting low on field labels - added vertical-align: text-top. Schedule field labels now use white-space: nowrap to prevent wrapping. * Fix data usage config fields layout - all 5 fields on one row Display Name gets flex:2 (wide), numeric fields (Data Cap, Warning, Prior Usage) get compact sizing with min-width 110px so all fields fit on a single row without wrapping. * Constrain compact field width to 140px max * Show Save button immediately on input, not on blur Added @oninput to mark fields dirty as the user types. The @onchange still handles the actual value commit on blur. Save Changes button now appears instantly when any field is modified. * Remove Display Name field - name comes from UniFi network config Users already set the WAN name in UniFi Console, having an editable Display Name here is redundant. The stored name is still set from the UniFi network name on creation for use in alert messages. * Stop config fields from stretching full width on desktop All 4 fields now use compact sizing so the row doesn't span 100%. Usage Resets On gets slightly wider max (180px) for the dropdown. * Auto-refresh Data Usage tab every 30 seconds The refresh timer already handled active and schedule tabs but not data-usage. Users staying on the tab now see updated usage. * Trigger immediate poll on enable and show Save button When toggling tracking on, immediately poll the device API for a first snapshot so usage is calculated right away instead of showing 0. Also marks config dirty so the Save button is visible for the user to configure cap, billing day, etc. * Always calculate usage from DB instead of using in-memory cache The cache caused stale data after toggling tracking on. The DB query is cheap (small indexed table) so just always calculate fresh.
- Add SemaphoreSlim to serialize PollAndRecordAsync (background loop + UI trigger) - Use ExecuteDeleteAsync in DeleteConfigAsync to avoid loading all snapshots into memory - Reset ManualAdjustmentGb to 0 on billing cycle rollover - Clamp DataCapGb to >= 0 server-side - Floor usedGb at 0 so negative adjustments can't produce negative display - Use Math.Ceiling for DaysRemaining so last day of cycle shows "1" not "0" - Add CancellationToken to GetCurrentUsageAsync - Only set _dataUsageLoaded on success so tab retries on console disconnect - Rename "Prior Usage" to "Usage Adjustment" and allow negative values
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan