Commit b95b9cb
committed
Adaptive SQM: GPON/XGS-PON profiles, congestion tuning, non-linear latency response (#528)
* Split FTTH into separate GPON and XGS-PON Adaptive SQM profiles
Rename Fiber (enum value 2) to Gpon for backwards compatibility with
existing DB values. Add XgsPon (enum value 6) at end of enum.
GPON schedule: 1.00 overnight, 0.99 morning taper, 0.975-0.97 workday,
0.965 streaming prime time, smooth taper back up through evening.
XGS-PON schedule: compressed version - 1.00 overnight, 0.995 morning,
0.9875-0.985 workday, 0.98 streaming. 10G headroom means minimal dip.
Both profiles uniform across all 7 days. Auto-detection maps "GPON",
"Fiber", "FTTH", "FTTP" to GPON and "XGS-PON"/"XGSPON" to XGS-PON.
* Expand XGS-PON auto-detection for multi-gig fiber names
Detect 10G, 5 Gig, 3 Gig, 2 Gig, XG-PON, and variants as XGS-PON
since any multi-gig fiber service implies XGS-PON infrastructure.
* Make ping script safety cap baseline-proportional
The flat safety cap (ABSOLUTE_MAX * 0.95) was clamping all hours to
the same ceiling, making the GPON/XGS-PON congestion schedule invisible.
Now scales with the baseline: cap = ABSOLUTE_MAX * SAFETY_CAP * (baseline / nominal).
At night (1.00): 1003 * 0.95 * 1.0 = 952. Streaming (0.965): 1003 * 0.95 * 0.9648 = 919.
Adds NOMINAL_SPEED to the ping script for the ratio calculation.
* Gate baseline-proportional safety cap to fiber types only
Variable connections (DOCSIS, Starlink, cellular) have wide baseline
swings (0.75-0.87) and the flat safety cap was never binding - making
it proportional would incorrectly clamp rates below actual capacity.
Only GPON and XGS-PON use the baseline ratio since their tight range
(0.965-1.00) means the flat cap was always the binding constraint.
* Remove unreachable '5G Fiber' auto-detection match
The cellular check (name.Contains("5G")) comes earlier in the
if/else chain, so '5G Fiber' would always match cellular first.
* Add user-tunable congestion severity slider
Congestion severity (0.90-1.10, default 1.0) scales the magnitude of
baseline schedule dips while keeping 1.0 hours unchanged:
effective = 1.0 - (1.0 - schedule_multiplier) * severity
UI shows a Congestion Schedule section with the effective speed range
and a severity slider. Range updates live as the slider moves.
Includes DB migration with default 1.0 for existing configs.
* Rename Speed Range to Latency Adjust Range for clarity
Distinguishes the latency-based floor/ceiling from the congestion
schedule range shown below it.
* Style severity slider to match app sliders, expand range to +/- 25%
Use wan-time-slider class for consistent blue gradient track and white
thumb. Range now 0.75-1.25 (was 0.90-1.10). Slider spans full width
of the param grid.
* Add user-tunable latency threshold, style severity slider
Latency threshold is now an editable input (like baseline latency),
persisted to DB, and restored on load. Only resets when connection
type changes, not when nominal speed changes.
Severity slider uses wan-time-slider class for consistent styling,
range expanded to 0.75-1.25 (+/- 25%).
* Fix migration split, center severity slider in param card
The LatencyThresholdMs column was added to an already-applied migration,
so it never ran on NAS. Split into separate migration (20260402110000).
Severity slider now fits within its param card (100px width, centered)
instead of spanning the full grid width.
* Consolidate migrations, fix DOCSIS congestion range display
Single migration for both CongestionSeverity and LatencyThresholdMs.
Fix congestion range for non-fiber types to show baseline * overhead
(capped at flat safety cap) instead of just the flat cap value.
* Apply safety cap before latency adjustment, not after
Moving the cap before latency logic eliminates the dead zone where
mild latency spikes were detected but produced no visible rate change.
Before: cap after latency = latency decrease from 958 to 920, then
capped back to 913. No visible effect.
After: cap MAX_DOWNLOAD_SPEED to 913 first, then latency decreases
from 913 to 876. Every deviation produces a visible change.
Post-latency ceiling still prevents the increase branch from
exceeding the schedule-derived cap.
* Change ping adjustment interval from 5 min to 1 min
* Reduce ping count to 10 at 0.5s interval for better spread
* Fix hardcoded 6 AM/6 PM in speedtest trigger description
* Add log rotation on boot: keep last 2000 lines
* Only persist latency threshold when user overrides it
Track the auto-calculated default and only save to DB when the user's
value differs. Null in DB = use profile default, so future profile
changes to the default threshold will be picked up automatically.
* Smooth GPON hour 22 from 0.97 to 0.975 for even taper
* Skip tc update when ping rate unchanged
* Non-linear latency response (n^0.7) and lower fiber thresholds
Latency decrease now uses n^0.7 exponent instead of linear n, so mild
spikes (1-2 deviations) get gentle response while sustained congestion
(4+ deviations) still triggers aggressive shaping.
GPON and XGS-PON default latency threshold lowered from 2.0/1.5 to
1.0ms - fiber latency is clean enough to detect mild congestion.
* Offset non-linear curve: (n+1)^0.7 - 1 for gentler first step1 parent 73c8b9c commit b95b9cb
10 files changed
Lines changed: 2279 additions & 54 deletions
File tree
- src
- NetworkOptimizer.Sqm
- Models
- NetworkOptimizer.Storage
- Migrations
- Models
- Repositories
- NetworkOptimizer.Web
- Components/Pages
- Services
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
15 | | - | |
| 14 | + | |
| 15 | + | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
25 | 28 | | |
26 | 29 | | |
27 | 30 | | |
| |||
142 | 145 | | |
143 | 146 | | |
144 | 147 | | |
145 | | - | |
146 | | - | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
147 | 153 | | |
148 | 154 | | |
149 | 155 | | |
| |||
171 | 177 | | |
172 | 178 | | |
173 | 179 | | |
174 | | - | |
175 | | - | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
176 | 185 | | |
177 | 186 | | |
178 | 187 | | |
| |||
200 | 209 | | |
201 | 210 | | |
202 | 211 | | |
203 | | - | |
| 212 | + | |
| 213 | + | |
204 | 214 | | |
205 | 215 | | |
206 | 216 | | |
| |||
217 | 227 | | |
218 | 228 | | |
219 | 229 | | |
220 | | - | |
221 | | - | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
222 | 235 | | |
223 | 236 | | |
224 | 237 | | |
| |||
246 | 259 | | |
247 | 260 | | |
248 | 261 | | |
249 | | - | |
| 262 | + | |
| 263 | + | |
250 | 264 | | |
251 | 265 | | |
252 | 266 | | |
| |||
263 | 277 | | |
264 | 278 | | |
265 | 279 | | |
266 | | - | |
267 | | - | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
268 | 285 | | |
269 | 286 | | |
270 | 287 | | |
| |||
292 | 309 | | |
293 | 310 | | |
294 | 311 | | |
295 | | - | |
| 312 | + | |
| 313 | + | |
296 | 314 | | |
297 | 315 | | |
298 | 316 | | |
| |||
309 | 327 | | |
310 | 328 | | |
311 | 329 | | |
312 | | - | |
| 330 | + | |
| 331 | + | |
313 | 332 | | |
314 | 333 | | |
315 | 334 | | |
| |||
327 | 346 | | |
328 | 347 | | |
329 | 348 | | |
330 | | - | |
| 349 | + | |
331 | 350 | | |
332 | 351 | | |
333 | | - | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
334 | 356 | | |
335 | 357 | | |
336 | 358 | | |
| |||
341 | 363 | | |
342 | 364 | | |
343 | 365 | | |
344 | | - | |
| 366 | + | |
345 | 367 | | |
346 | 368 | | |
347 | 369 | | |
| |||
351 | 373 | | |
352 | 374 | | |
353 | 375 | | |
354 | | - | |
355 | | - | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
356 | 385 | | |
357 | 386 | | |
358 | 387 | | |
| |||
378 | 407 | | |
379 | 408 | | |
380 | 409 | | |
381 | | - | |
382 | | - | |
| 410 | + | |
| 411 | + | |
383 | 412 | | |
384 | 413 | | |
385 | 414 | | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
386 | 420 | | |
387 | 421 | | |
388 | 422 | | |
| |||
397 | 431 | | |
398 | 432 | | |
399 | 433 | | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
400 | 439 | | |
401 | 440 | | |
402 | 441 | | |
| |||
446 | 485 | | |
447 | 486 | | |
448 | 487 | | |
449 | | - | |
450 | | - | |
451 | | - | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
452 | 499 | | |
453 | 500 | | |
454 | 501 | | |
| |||
532 | 579 | | |
533 | 580 | | |
534 | 581 | | |
535 | | - | |
| 582 | + | |
| 583 | + | |
536 | 584 | | |
537 | 585 | | |
538 | 586 | | |
| |||
549 | 597 | | |
550 | 598 | | |
551 | 599 | | |
552 | | - | |
| 600 | + | |
| 601 | + | |
553 | 602 | | |
554 | 603 | | |
555 | 604 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
115 | 115 | | |
116 | 116 | | |
117 | 117 | | |
118 | | - | |
| 118 | + | |
119 | 119 | | |
120 | 120 | | |
121 | 121 | | |
| |||
148 | 148 | | |
149 | 149 | | |
150 | 150 | | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
151 | 158 | | |
152 | 159 | | |
153 | 160 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
79 | 85 | | |
80 | 86 | | |
81 | 87 | | |
| |||
361 | 367 | | |
362 | 368 | | |
363 | 369 | | |
| 370 | + | |
364 | 371 | | |
365 | 372 | | |
366 | 373 | | |
| |||
418 | 425 | | |
419 | 426 | | |
420 | 427 | | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
421 | 453 | | |
422 | 454 | | |
423 | | - | |
| 455 | + | |
424 | 456 | | |
425 | 457 | | |
426 | 458 | | |
| |||
437 | 469 | | |
438 | 470 | | |
439 | 471 | | |
440 | | - | |
| 472 | + | |
441 | 473 | | |
442 | 474 | | |
443 | 475 | | |
444 | | - | |
445 | | - | |
446 | | - | |
| 476 | + | |
447 | 477 | | |
448 | 478 | | |
449 | 479 | | |
| |||
479 | 509 | | |
480 | 510 | | |
481 | 511 | | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
482 | 521 | | |
483 | 522 | | |
484 | 523 | | |
| |||
696 | 735 | | |
697 | 736 | | |
698 | 737 | | |
699 | | - | |
700 | | - | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
701 | 742 | | |
702 | 743 | | |
703 | 744 | | |
| |||
0 commit comments