Eddys Rückmeldung nach dem ersten Einsatz auf dem Handy: das zweite Diagramm
ergibt keinen Sinn, Zahlen überlappen, und die Signalstärke ist in den
Diagrammen nirgends ablesbar. Alle drei Punkte bestätigt und behoben.
Ursache (nachgerechnet, nicht geraten): die 745 MHz des 5-GHz-Bandes wurden
in dieselbe Breite gequetscht wie die 80 MHz des 2,4-GHz-Bandes — 9,3-fach
schlechtere Auflösung, 8,6 statt 80 Einheiten je 20-MHz-Kanal. Bei 8,6
Einheiten Tick-Abstand und 12,6 Einheiten Breite einer dreistelligen Zahl ist
Überlappung unvermeidbar ("3640444852566064"). Der vorhandene Tick-Filter
filterte nachweislich 0 von 25 Ticks weg, weil er nur gegen den
Frequenzbereich prüfte, in dem ohnehin alle Kanäle liegen.
Kanalgraph:
- 5 GHz in die regulatorischen Blöcke geteilt (UNII-1/2A, UNII-2C, UNII-3),
ein gemeinsamer Maßstab je Band -> 20-MHz-Kanal jetzt ~24 statt 8,6
Einheiten breit, alle Kanalzahlen einzeln lesbar.
- Leere Blöcke werden gezeichnet ("frei — keine Netze") statt weggelassen.
Weglassen ließe das Band voller aussehen als es ist und versteckt genau
die gesuchte Antwort: wo ist noch Platz.
- Trapez statt Parabel — die Fläche zeigt den tatsächlich belegten
Frequenzbereich. Bei der Parabel lag nur die Spitze auf dem Messwert; mit
dBm-Achse wäre alles außer der Bogenmitte falsch abgelesen worden.
- Kanalbreite über centerFreq0 statt Primärfrequenz: ein 80-MHz-Netz auf
Kanal 36 wurde sonst um 5180 statt 5210 gezeichnet, Nachbarkanäle sahen
fälschlich frei aus.
- Farbe je Netz (stabil über BSSID-Hash), gleiche Farbe in Graph, Zeitverlauf
und Netzliste. Vorher verschmolzen überlappende graue Blöcke zu einer Fläche.
- Belegte Kanalnummern hell, freie gedämpft; SSID von hinten gekürzt (sonst
heißen alle FRITZ!Box-Netze gleich); gekappte Blöcke werden markiert.
dBm-Achse (neue gemeinsame Komponente RssiAxis, für Kanalgraph UND
Zeitverlauf — damit sie konstruktiv nicht auseinanderlaufen können):
- feste Skala -95..-30 dBm, 2,0 Einheiten je dB (glatte Rasterlinien),
beschriftet -30/-50/-70/-90, Einheit "dBm", Praxiszonen grün/rot.
- Bewusst "Empfangspegel", nicht "Sendestärke": die Achse zeigt den Pegel am
Standort des Handys, nicht die Leistung des Routers.
- Schrift 7 -> 9/10 (war ~7,6 CSS-px, unter der Lesegrenze), Kontrast der
Achsenbeschriftung von zinc-600 (2,29:1, unter WCAG-Minimum) auf zinc-200/300.
Momentaufnahme wird jetzt synchronisiert: sie lag bisher nur lokal und kam nie
im Protokoll auf dem Server an, obwohl sie genau dafür gemacht wird. Landet
jetzt zusätzlich als Messung (tool='wifikanal') in Sync und PDF.
Klartext-Fazit über dem Diagramm ("Dein Netz: Kanal 6 · -48 dBm (sehr gut) ·
2,4 GHz freister Kanal: 1") — unter Zeitdruck schneller als jedes Diagramm.
Neu: tools/render-chart.mjs rendert die echten Svelte-Komponenten
serverseitig zu SVG/PNG, inklusive Randfällen (1 Netz, 25 Netze, 5 Netze auf
einem Kanal, Bandränder, leeres Band, Zeitverlauf mit Aussetzer). Das ist die
Lehre aus dem Fehler: in Phase 4 wurde die Chart-Mathematik nur durchgerechnet
(keine NaN, nichts außerhalb des Zeichenbereichs) und daraus geschlossen, das
genüge. Rechnerisch korrekt heißt nicht lesbar — ein Diagramm muss man ansehen.
Weiterhin offen: der Emulator hat keine WLAN-Hardware und liefert immer 0
Netze. Alle Diagramme sind mit realistischen Testdaten gerendert und geprüft,
aber nicht mit echtem Empfang auf dem Handy.
Details: ROADMAP_UMSETZUNG.md Phase 4 / Nachbesserung
77 lines
2.1 KiB
Svelte
77 lines
2.1 KiB
Svelte
<script lang="ts">
|
||
/**
|
||
* dBm-Achse (Empfangspegel) samt Rasterlinien und Praxis-Zonen.
|
||
*
|
||
* Bewusst eine eigene Komponente statt nur gemeinsamer Konstanten: so
|
||
* benutzen Kanalgraph und Zeitverlauf zwangsläufig dieselbe Achse. Vorher
|
||
* hatte keines der beiden Diagramme überhaupt eine Achse — die Höhe kodierte
|
||
* die Signalstärke, ohne dass man einen Wert ablesen konnte.
|
||
*
|
||
* Wichtig zur Beschriftung: das ist der EMPFANGSPEGEL am Standort des
|
||
* Handys, nicht die Sendeleistung des Routers. Ein und derselbe Router
|
||
* liefert je nach Entfernung und Wand −45 oder −85 dBm.
|
||
*/
|
||
import {
|
||
W,
|
||
PAD_L,
|
||
PAD_R,
|
||
BASELINE,
|
||
PLOT_TOP,
|
||
DB_GRID,
|
||
DB_LABELED,
|
||
RSSI_GOOD,
|
||
RSSI_WEAK,
|
||
FS_AXIS,
|
||
rssiToY,
|
||
} from '$lib/wifi/chart';
|
||
|
||
let { zonen = true }: { zonen?: boolean } = $props();
|
||
|
||
const yGood = rssiToY(RSSI_GOOD);
|
||
const yWeak = rssiToY(RSSI_WEAK);
|
||
</script>
|
||
|
||
{#if zonen}
|
||
<!-- Praxis-Zonen: oberhalb -67 dBm zuverlässig, unterhalb -75 dBm kritisch.
|
||
Beantwortet "reicht das hier?" ohne Kopfrechnen. -->
|
||
<rect x={PAD_L} y={PLOT_TOP} width={W - PAD_L - PAD_R} height={yGood - PLOT_TOP} class="fill-emerald-500/[0.07]" />
|
||
<rect x={PAD_L} y={yWeak} width={W - PAD_L - PAD_R} height={BASELINE - yWeak} class="fill-red-500/[0.07]" />
|
||
{/if}
|
||
|
||
{#each DB_GRID as db (db)}
|
||
{@const y = rssiToY(db)}
|
||
<line
|
||
x1={PAD_L}
|
||
y1={y}
|
||
x2={W - PAD_R}
|
||
y2={y}
|
||
stroke="currentColor"
|
||
class={DB_LABELED.has(db) ? 'text-zinc-700' : 'text-zinc-800'}
|
||
stroke-width="0.5"
|
||
/>
|
||
{#if DB_LABELED.has(db)}
|
||
<text
|
||
x={PAD_L - 4}
|
||
y={y + 3.5}
|
||
text-anchor="end"
|
||
class="fill-zinc-300"
|
||
style="font-size: {FS_AXIS}px"
|
||
>
|
||
{db}
|
||
</text>
|
||
{/if}
|
||
{/each}
|
||
|
||
<!-- Achseneinheit — ohne sie ist nicht klar, was die Zahlen bedeuten -->
|
||
<text
|
||
x={PAD_L - 4}
|
||
y={PLOT_TOP - 5}
|
||
text-anchor="end"
|
||
class="fill-zinc-500"
|
||
style="font-size: {FS_AXIS - 1}px"
|
||
>
|
||
dBm
|
||
</text>
|
||
|
||
<!-- Grundlinie -->
|
||
<line x1={PAD_L} y1={BASELINE} x2={W - PAD_R} y2={BASELINE} stroke="currentColor" class="text-zinc-600" stroke-width="1" />
|