Doku: drei Scan-Funktionen statt automatischem Barcode/OCR-Ausweichen
Funktionsweise-Abschnitt, Technik- und Aufbau-Tabelle sowie die Geraete-Checkliste auf die neue Funktionswahl gebracht. Haelt fest, dass in "Text erkennen" mangels Barcode-Teilenummer allein die technischen Angaben ueber die Stapelzuordnung entscheiden, und dass "QR-Code" bewusst kein DataMatrix liest. Testanzahl auf 143 aktualisiert.
This commit is contained in:
@@ -4,6 +4,11 @@ Browser-App, die per Handykamera gebrauchte Server-RAM-Module erkennt und
|
|||||||
beim physischen Sortieren am Tisch anleitet: Modul vor die Kamera halten, die
|
beim physischen Sortieren am Tisch anleitet: Modul vor die Kamera halten, die
|
||||||
App nennt den Stapel.
|
App nennt den Stapel.
|
||||||
|
|
||||||
|
Vor dem Scannen wählt der Nutzer eine von drei Funktionen — Strichcode,
|
||||||
|
QR-Code oder Text erkennen (siehe „Funktionsweise" unten). Jede Funktion nutzt
|
||||||
|
ausschließlich ihre eigene Quelle; anders als früher weicht die App nicht mehr
|
||||||
|
automatisch auf Texterkennung aus, wenn kein Code gefunden wird.
|
||||||
|
|
||||||
Zwei Module gelten als zusammengehörig, wenn sie denselben Barcode-Inhalt
|
Zwei Module gelten als zusammengehörig, wenn sie denselben Barcode-Inhalt
|
||||||
tragen — ein Barcode ist exakt gelesen, das ist der zuverlässigste Maßstab.
|
tragen — ein Barcode ist exakt gelesen, das ist der zuverlässigste Maßstab.
|
||||||
Jeder Stapel führt dafür die Menge der Barcode-Zeichenketten, die bei seinen
|
Jeder Stapel führt dafür die Menge der Barcode-Zeichenketten, die bei seinen
|
||||||
@@ -51,16 +56,57 @@ keine Daten verlassen das Gerät.
|
|||||||
|
|
||||||
## Funktionsweise
|
## Funktionsweise
|
||||||
|
|
||||||
1. **Barcode zuerst.** Code-128 und DataMatrix werden aus dem Kamerabild
|
0. **Funktion wählen.** Vor dem ersten Scan (und jederzeit erneut über die
|
||||||
dekodiert (`zxing-wasm`). Das ist exakt, im Gegensatz zu Texterkennung.
|
antippbare Anzeige in der Scan-Ansicht) wählt der Nutzer eine von drei
|
||||||
Werden mehrere Barcodes im Bild gefunden, die sich widersprechen (nicht
|
Funktionen. Kennung, Beschriftung, gelesene Codearten und Verhalten stehen
|
||||||
dieselbe Teilenummer), gilt das als mehrdeutig — die App rät nicht,
|
ausschließlich in `src/scan-modes.js` — es gibt keine zweite Stelle, an der
|
||||||
sondern fragt nach. Das gilt nur für Barcodes mit einem bekannten
|
das steht:
|
||||||
Nummernschema; widersprechen sich mehrere Barcodes mit unbekanntem
|
|
||||||
Nummernschema, wird keine ihrer Teilenummern übernommen.
|
| Funktion | Liest | Laufende Suche | Texterkennung |
|
||||||
2. **Teilenummer-Decoder.** Aus einer Hersteller-PN wie `M386A8K40BM1-CRC4Y`
|
|---|---|---|---|
|
||||||
werden Kapazität, Bauform und Geschwindigkeit tabellengesteuert
|
| **Strichcode** | Code128, Code39, Code93, ITF, EAN-13, EAN-8, UPC-A, UPC-E, Codabar | ja | nein |
|
||||||
abgeleitet. Gelingt das, entfällt OCR vollständig, das Ergebnis ist grün.
|
| **QR-Code** | ausschließlich QRCode, MicroQRCode, RMQRCode | ja | nein |
|
||||||
|
| **Text erkennen** | keine Codes | nein | ja, auf Knopfdruck |
|
||||||
|
|
||||||
|
„QR-Code" liest bewusst **kein** DataMatrix — auch wenn die 2D-Codes auf
|
||||||
|
eigenen RAM-Etiketten DataMatrix sind. Der reguläre Arbeitsablauf läuft über
|
||||||
|
„Strichcode", weil dort die Teilenummer im Strichcode steht; „QR-Code" ist
|
||||||
|
für andere Ware gedacht. Diese Beschränkung ist eine ausdrückliche
|
||||||
|
Entscheidung, keine Lücke.
|
||||||
|
|
||||||
|
„Modul scannen" erscheint nur in „Text erkennen" — in „Strichcode" und
|
||||||
|
„QR-Code" sucht die App ohnehin laufend, ein Knopf ohne Texterkennung hätte
|
||||||
|
dort nichts zu tun. Der Zielrahmen hebt sich in „Strichcode" und „QR-Code"
|
||||||
|
hervor, sobald ein passender Code im Bild ist; in „Text erkennen" bleibt er
|
||||||
|
schlicht, weil dort nichts laufend erkannt wird. Ein Wechsel der Funktion
|
||||||
|
während des Sortierens (z. B. bei gemischter Ware) gilt sofort: laufende
|
||||||
|
Suche startet oder stoppt, der Knopf erscheint oder verschwindet.
|
||||||
|
|
||||||
|
Liegt beim Start eine gesicherte Sitzung vor, erscheint zuerst die Frage
|
||||||
|
nach dem Fortsetzen (siehe Punkt 5 unten) und erst danach die Funktionswahl
|
||||||
|
— die Kamera startet in jedem Fall erst, nachdem beides geklärt ist.
|
||||||
|
|
||||||
|
Technisch bekommen „Strichcode" und „QR-Code" eine Texterkennung
|
||||||
|
hineingereicht, die sofort leeren Text liefert, ohne Tesseract anzustoßen;
|
||||||
|
„Text erkennen" bekommt eine Barcode-Dekodierung hineingereicht, die sofort
|
||||||
|
eine leere Liste liefert (`buildRecognitionAdapters` in
|
||||||
|
`src/scan-recognition.js`). Die Erkennungs-Pipeline selbst (`src/pipeline.js`,
|
||||||
|
Punkte 1–4 unten) bleibt dabei unverändert und kennt keine Funktionen — die
|
||||||
|
drei Funktionen unterscheiden sich ausschließlich darin, welche Adapter ihr
|
||||||
|
übergeben werden.
|
||||||
|
1. **Barcode-Dekodierung** (nur in „Strichcode" und „QR-Code"). Die zur
|
||||||
|
Funktion gehörenden Codearten werden laufend aus dem Kamerabild dekodiert
|
||||||
|
(`zxing-wasm`, `decodeBarcodes` in `src/barcode.js` bekommt die Codearten
|
||||||
|
der gewählten Funktion übergeben). Das ist exakt, im Gegensatz zu
|
||||||
|
Texterkennung. Werden mehrere Barcodes im Bild gefunden, die sich
|
||||||
|
widersprechen (nicht dieselbe Teilenummer), gilt das als mehrdeutig — die
|
||||||
|
App rät nicht, sondern fragt nach. Das gilt nur für Barcodes mit einem
|
||||||
|
bekannten Nummernschema; widersprechen sich mehrere Barcodes mit
|
||||||
|
unbekanntem Nummernschema, wird keine ihrer Teilenummern übernommen.
|
||||||
|
2. **Teilenummer-Decoder** (nur relevant in „Strichcode"/„QR-Code" — „Text
|
||||||
|
erkennen" liest nie einen Barcode, siehe Punkt 0). Aus einer Hersteller-PN
|
||||||
|
wie `M386A8K40BM1-CRC4Y` werden Kapazität, Bauform und Geschwindigkeit
|
||||||
|
tabellengesteuert abgeleitet. Gelingt das, entfällt OCR vollständig, das Ergebnis ist grün.
|
||||||
Kennt der Decoder das Nummernschema nicht (siehe „Grenzen“ unten), ist das
|
Kennt der Decoder das Nummernschema nicht (siehe „Grenzen“ unten), ist das
|
||||||
allein noch kein Grund für Rot: Zum Sortieren muss keine Kapazität bekannt
|
allein noch kein Grund für Rot: Zum Sortieren muss keine Kapazität bekannt
|
||||||
sein, eine exakt gelesene Teilenummer genügt, um ein Modul wiederzuerkennen
|
sein, eine exakt gelesene Teilenummer genügt, um ein Modul wiederzuerkennen
|
||||||
@@ -72,17 +118,23 @@ keine Daten verlassen das Gerät.
|
|||||||
könnte, das über die Zuordnung entscheidet. Bei einem tatsächlich neuen
|
könnte, das über die Zuordnung entscheidet. Bei einem tatsächlich neuen
|
||||||
Modul läuft sie dagegen wie gehabt, denn dort liefert sie die lesbare
|
Modul läuft sie dagegen wie gehabt, denn dort liefert sie die lesbare
|
||||||
Beschriftung des neuen Stapels.
|
Beschriftung des neuen Stapels.
|
||||||
3. **OCR als Rückfallebene.** Nur wenn kein Barcode eindeutig lesbar war oder
|
3. **Texterkennung** (ausschließlich in „Text erkennen", ausgelöst durch
|
||||||
sein Nummernschema unbekannt ist (z. B. überklebtes/beschädigtes Etikett
|
„Modul scannen"). Anders als früher ist das kein automatischer Rückfall
|
||||||
oder ein noch nicht in `src/pn-tables.js` hinterlegter Hersteller). Das
|
vom Barcode-Weg mehr, sondern die einzige Quelle dieser Funktion — sie
|
||||||
Kamerabild wird dafür in Graustufen gewandelt und mit einem
|
liest ohnehin nie einen Barcode (siehe Punkt 0). Das Kamerabild wird dafür
|
||||||
**Otsu-Schwellwert** in Schwarz/Weiß aufbereitet: Der Schwellwert wird aus
|
in Graustufen gewandelt und mit einem **Otsu-Schwellwert** in Schwarz/Weiß
|
||||||
der Helligkeitsverteilung des gesamten Bildes bestimmt, nicht aus einer
|
aufbereitet: Der Schwellwert wird aus der Helligkeitsverteilung des
|
||||||
festen Kontrastspreizung zwischen hellstem und dunkelstem Pixel. Das macht
|
gesamten Bildes bestimmt, nicht aus einer festen Kontrastspreizung
|
||||||
die Aufbereitung robust gegen einzelne Lichtreflexe auf glänzenden
|
zwischen hellstem und dunkelstem Pixel. Das macht die Aufbereitung robust
|
||||||
Metalletiketten, die eine reine Min/Max-Spreizung leicht kippen würden.
|
gegen einzelne Lichtreflexe auf glänzenden Metalletiketten, die eine reine
|
||||||
Das OCR-Ergebnis wird anschließend gegen die bekannten Spec-Werte
|
Min/Max-Spreizung leicht kippen würden. Das OCR-Ergebnis wird anschließend
|
||||||
abgeglichen, was die typischen Verwechslungen (0/O, 1/I, 8/B, …) auflöst.
|
gegen die bekannten Spec-Werte abgeglichen, was die typischen
|
||||||
|
Verwechslungen (0/O, 1/I, 8/B, …) auflöst. Da in dieser Funktion nie eine
|
||||||
|
per Barcode gelesene Teilenummer vorliegt, entscheiden hier ausschließlich
|
||||||
|
die aus dem erkannten Text abgeleiteten technischen Angaben (Kapazität,
|
||||||
|
Bauform, Rank, Geschwindigkeit) über die Stapelzuordnung
|
||||||
|
(`specsCompatible` in `src/spec.js`) — anders als in „Strichcode"/
|
||||||
|
„QR-Code", wo meist die exakte Teilenummer trägt.
|
||||||
4. **Stapel-Zuweisung.** Grün (Barcode) und Gelb (OCR) laufen ohne Eingabe
|
4. **Stapel-Zuweisung.** Grün (Barcode) und Gelb (OCR) laufen ohne Eingabe
|
||||||
durch; nur bei roter Konfidenz (nichts Eindeutiges erkannt, widersprüchliche
|
durch; nur bei roter Konfidenz (nichts Eindeutiges erkannt, widersprüchliche
|
||||||
Barcodes oder widersprüchliche unbekannte Barcodes ohne jede OCR-Kapazität)
|
Barcodes oder widersprüchliche unbekannte Barcodes ohne jede OCR-Kapazität)
|
||||||
@@ -133,14 +185,19 @@ korrekt funktioniert.
|
|||||||
npm test
|
npm test
|
||||||
```
|
```
|
||||||
|
|
||||||
124 Tests, alle grün (Stand dieses Dokuments). Getestet werden ausschließlich
|
143 Tests, alle grün (Stand dieses Dokuments). Getestet werden ausschließlich
|
||||||
die reinen Module ohne Browser-Zugriff: Teilenummer-Decoder, Spec-Normalisierung
|
die reinen Module ohne Browser-Zugriff: Teilenummer-Decoder, Spec-Normalisierung
|
||||||
und toleranter Vergleich, OCR-Bildaufbereitung (Otsu-Schwellwert) und
|
und toleranter Vergleich, OCR-Bildaufbereitung (Otsu-Schwellwert) und
|
||||||
-Feldextraktion, Stapel-Zuweisung, die Erkennungs-Pipeline samt Zeitgrenzen
|
-Feldextraktion, Stapel-Zuweisung, die Erkennungs-Pipeline samt Zeitgrenzen
|
||||||
und Mehrdeutigkeitsbehandlung, sowie die Sitzungssicherung samt Prüfung eines
|
und Mehrdeutigkeitsbehandlung, die Sitzungssicherung samt Prüfung eines
|
||||||
wiederhergestellten Zustands. Kamera, Barcode-/OCR-Adapter selbst und
|
wiederhergestellten Zustands, die drei Scan-Funktionen (`scan-modes.js` —
|
||||||
Oberfläche laufen nur im echten Browser und werden dort manuell geprüft
|
Codearten je Funktion, kein DataMatrix in „QR-Code") sowie die je Funktion
|
||||||
(siehe „Am Gerät noch zu prüfen" unten) — `node --test` kennt kein DOM.
|
tatsächlich aufgerufenen Adapter (`scan-recognition.js` — Texterkennung läuft
|
||||||
|
nachweislich nie in „Strichcode"/„QR-Code", Barcode-Dekodierung nachweislich
|
||||||
|
nie in „Text erkennen"). Kamera, Barcode-/OCR-Adapter selbst, die
|
||||||
|
Auswahl-Oberfläche und die Verdrahtung in `main.js` laufen nur im echten
|
||||||
|
Browser und werden dort manuell geprüft (siehe „Am Gerät noch zu prüfen"
|
||||||
|
unten) — `node --test` kennt kein DOM.
|
||||||
|
|
||||||
## Produktion
|
## Produktion
|
||||||
|
|
||||||
@@ -189,7 +246,9 @@ worauf du bei der Veröffentlichung achten solltest.
|
|||||||
|
|
||||||
- Vanilla JavaScript (ES Modules), kein Framework
|
- Vanilla JavaScript (ES Modules), kein Framework
|
||||||
- [Vite](https://vite.dev/) als Entwicklungsserver und Bündler
|
- [Vite](https://vite.dev/) als Entwicklungsserver und Bündler
|
||||||
- [`zxing-wasm`](https://github.com/Sec-ant/zxing-wasm) für Code-128 und DataMatrix
|
- [`zxing-wasm`](https://github.com/Sec-ant/zxing-wasm) zur Barcode-Dekodierung;
|
||||||
|
welche Codearten gesucht werden, gibt die gewählte Funktion vor
|
||||||
|
(`src/scan-modes.js`)
|
||||||
- [`tesseract.js`](https://tesseract.projectnaptha.com/) für Texterkennung
|
- [`tesseract.js`](https://tesseract.projectnaptha.com/) für Texterkennung
|
||||||
- `node:test` für Tests, ohne zusätzliche Test-Bibliothek
|
- `node:test` für Tests, ohne zusätzliche Test-Bibliothek
|
||||||
|
|
||||||
@@ -202,15 +261,18 @@ worauf du bei der Veröffentlichung achten solltest.
|
|||||||
| `src/pn-decoder.js` | Teilenummer → Spec-Felder |
|
| `src/pn-decoder.js` | Teilenummer → Spec-Felder |
|
||||||
| `src/ocr-extract.js` | OCR-Rohtext → Spec-Felder |
|
| `src/ocr-extract.js` | OCR-Rohtext → Spec-Felder |
|
||||||
| `src/session.js` | Stapel halten, vorschlagen, buchen, umsortieren, zurücknehmen — inklusive der aus den Einträgen abgeleiteten, je Stapel bekannten Barcode-Inhalte (`stack.codes`), die vor dem Vergleich der technischen Angaben über die Zuordnung entscheiden, sofern diese Angaben nicht widersprechen |
|
| `src/session.js` | Stapel halten, vorschlagen, buchen, umsortieren, zurücknehmen — inklusive der aus den Einträgen abgeleiteten, je Stapel bekannten Barcode-Inhalte (`stack.codes`), die vor dem Vergleich der technischen Angaben über die Zuordnung entscheiden, sofern diese Angaben nicht widersprechen |
|
||||||
| `src/pipeline.js` | Barcode → Teilenummer → OCR → Ampelfarbe, inkl. Zeitgrenzen, Mehrdeutigkeitsbehandlung und Kurzschluss über einen bereits bekannten Barcode-Inhalt (`deps.isKnownCode`) |
|
| `src/pipeline.js` | Barcode → Teilenummer → OCR → Ampelfarbe, inkl. Zeitgrenzen, Mehrdeutigkeitsbehandlung und Kurzschluss über einen bereits bekannten Barcode-Inhalt (`deps.isKnownCode`) — unverändert; kennt keine Scan-Funktionen |
|
||||||
|
| `src/scan-modes.js` | Die drei Scan-Funktionen (Strichcode, QR-Code, Text erkennen): Kennung, deutsche Beschriftung, gelesene Codearten, laufende Suche ja/nein, Texterkennung ja/nein — einzige Quelle, sowohl für die Auswahl-Oberfläche als auch für `main.js` |
|
||||||
|
| `src/scan-recognition.js` | Baut die an `recognize()` übergebenen Adapter anhand der gewählten Funktion: in „Strichcode"/„QR-Code" liefert die Texterkennung sofort leeren Text ohne Tesseract anzustoßen, in „Text erkennen" liefert die Barcode-Dekodierung sofort eine leere Liste ohne `zxing-wasm` anzustoßen |
|
||||||
| `src/storage.js` | Absturzschutz der laufenden Sitzung: sichert und lädt aus `localStorage`, verwirft beim Laden jeden in sich unstimmigen Zustand vollständig (siehe unten) |
|
| `src/storage.js` | Absturzschutz der laufenden Sitzung: sichert und lädt aus `localStorage`, verwirft beim Laden jeden in sich unstimmigen Zustand vollständig (siehe unten) |
|
||||||
| `src/camera.js` | Kamerastart, Einzelbildaufnahme, Bilddatei-Ersatzweg |
|
| `src/camera.js` | Kamerastart, Einzelbildaufnahme, Bilddatei-Ersatzweg |
|
||||||
| `src/barcode.js` | Adapter zu `zxing-wasm` |
|
| `src/barcode.js` | Adapter zu `zxing-wasm`; `decodeBarcodes(imageData, formats)` bekommt die Codearten übergeben, ohne Angabe wie bisher (Code128 + DataMatrix) |
|
||||||
| `src/ocr.js` | Bildaufbereitung (Otsu) und Adapter zu `tesseract.js` |
|
| `src/ocr.js` | Bildaufbereitung (Otsu) und Adapter zu `tesseract.js` |
|
||||||
| `src/ui/scan-view.js` | Scan-Ansicht: Kamera-Vorschau, Scan-Knopf, Stapel-Leiste, „Zuletzt"-Zeile, Ersatzweg-Schaltfläche bei fehlender Kamera |
|
| `src/ui/scan-view.js` | Scan-Ansicht: Kamera-Vorschau, antippbare Anzeige der gewählten Funktion (Wechsel), Scan-Knopf (nur in „Text erkennen" sichtbar), Stapel-Leiste, „Zuletzt"-Zeile, Ersatzweg-Schaltfläche bei fehlender Kamera |
|
||||||
|
| `src/ui/mode-dialog.js` | Vollbild-Auswahl der Scan-Funktion vor dem Start und beim Wechsel: drei große Flächen, eine je Funktion aus `src/scan-modes.js` |
|
||||||
| `src/ui/result-overlay.js` | Kurze Treffer-Rückmeldung (grün/gelb), blendet sich nach kurzer Zeit selbst wieder aus |
|
| `src/ui/result-overlay.js` | Kurze Treffer-Rückmeldung (grün/gelb), blendet sich nach kurzer Zeit selbst wieder aus |
|
||||||
| `src/ui/ambiguous-dialog.js` | Rot-Dialog bei roter Konfidenz oder mehrdeutiger Stapelzuordnung |
|
| `src/ui/ambiguous-dialog.js` | Rot-Dialog bei roter Konfidenz oder mehrdeutiger Stapelzuordnung |
|
||||||
| `src/ui/resume-dialog.js` | Dialog beim Start: gesicherte Sitzung fortsetzen oder verwerfen |
|
| `src/ui/resume-dialog.js` | Dialog beim Start: gesicherte Sitzung fortsetzen oder verwerfen — läuft vor der Funktionswahl |
|
||||||
| `src/ui/session-list.js` | Sitzungsliste: Stapel-Übersicht, Umsortieren, Entfernen, Sitzung beenden |
|
| `src/ui/session-list.js` | Sitzungsliste: Stapel-Übersicht, Umsortieren, Entfernen, Sitzung beenden |
|
||||||
| `src/ui/describe-spec.js` | Gemeinsame Kurzbeschreibung eines Specs (Kapazität, Rank, Geschwindigkeit, Bauform), wahlweise mit Platzhaltern für fehlende Felder; von Treffer-Rückmeldung, „Zuletzt"-Zeile und Sitzungsliste gemeinsam genutzt |
|
| `src/ui/describe-spec.js` | Gemeinsame Kurzbeschreibung eines Specs (Kapazität, Rank, Geschwindigkeit, Bauform), wahlweise mit Platzhaltern für fehlende Felder; von Treffer-Rückmeldung, „Zuletzt"-Zeile und Sitzungsliste gemeinsam genutzt |
|
||||||
| `src/main.js` | Verdrahtung aller Module zur lauffähigen App |
|
| `src/main.js` | Verdrahtung aller Module zur lauffähigen App |
|
||||||
@@ -218,11 +280,11 @@ worauf du bei der Veröffentlichung achten solltest.
|
|||||||
| `server.py` | Auslieferung im Betrieb: statischer Server für `dist/` mit Passwortabfrage vor jeder Datei, plus passwortfreier Gesundheitspfad `/healthz`. Nur Python-Standardbibliothek, keine zusätzliche Abhängigkeit |
|
| `server.py` | Auslieferung im Betrieb: statischer Server für `dist/` mit Passwortabfrage vor jeder Datei, plus passwortfreier Gesundheitspfad `/healthz`. Nur Python-Standardbibliothek, keine zusätzliche Abhängigkeit |
|
||||||
| `.vch/deploy.yaml` | Bau- und Startbefehl sowie Gesundheitspfad für die Hosting-Umgebung |
|
| `.vch/deploy.yaml` | Bau- und Startbefehl sowie Gesundheitspfad für die Hosting-Umgebung |
|
||||||
|
|
||||||
`spec`, `pn-decoder`, `ocr-extract`, `session`, `pipeline` und `storage` sind
|
`spec`, `pn-decoder`, `ocr-extract`, `session`, `pipeline`, `storage`,
|
||||||
reine Funktionen ohne Browser-Zugriff (kein `window`, `document` oder
|
`scan-modes` und `scan-recognition` sind reine Funktionen ohne Browser-Zugriff
|
||||||
`localStorage` direkt) und deshalb vollständig mit `node:test` prüfbar.
|
(kein `window`, `document` oder `localStorage` direkt) und deshalb vollständig
|
||||||
`camera.js`, `barcode.js`, `ocr.js` und `src/ui/` brauchen einen echten
|
mit `node:test` prüfbar. `camera.js`, `barcode.js`, `ocr.js` und `src/ui/`
|
||||||
Browser und werden nur manuell geprüft.
|
brauchen einen echten Browser und werden nur manuell geprüft.
|
||||||
|
|
||||||
### Sitzungssicherung im Detail
|
### Sitzungssicherung im Detail
|
||||||
|
|
||||||
@@ -325,40 +387,68 @@ werden:
|
|||||||
- Datei-Auswahl als Ersatzweg (ohne Kamera) öffnet den nativen Dialog und
|
- Datei-Auswahl als Ersatzweg (ohne Kamera) öffnet den nativen Dialog und
|
||||||
hinterlässt keine leere Fläche im Layout.
|
hinterlässt keine leere Fläche im Layout.
|
||||||
|
|
||||||
|
**Funktionswahl (neu)**
|
||||||
|
- Erster Start ohne gesicherte Sitzung: Auswahl mit drei großen Flächen
|
||||||
|
(„Strichcode", „QR-Code", „Text erkennen") erscheint, *bevor* die Kamera
|
||||||
|
startet — kein Kamerabild sichtbar, solange keine Funktion gewählt ist.
|
||||||
|
- Erster Start *mit* gesicherter Sitzung: erst die Frage „Gesicherte Sitzung
|
||||||
|
gefunden" (fortsetzen/verwerfen), erst danach die Funktionswahl.
|
||||||
|
- „Strichcode" wählen: laufende Suche erkennt Code-128/Code-39/EAN/UPC/…,
|
||||||
|
kein „Modul scannen"-Knopf sichtbar, Zielrahmen hebt sich bei erkanntem
|
||||||
|
Code hervor.
|
||||||
|
- „QR-Code" wählen und ein Etikett mit dem eigenen DataMatrix-Code vor die
|
||||||
|
Kamera halten: **bewusst kein Treffer** (kein DataMatrix in dieser
|
||||||
|
Funktion) — Rahmen bleibt neutral. Einen echten QR-Code vor dieselbe
|
||||||
|
Funktion halten: Rahmen hebt sich hervor, Treffer wird gebucht.
|
||||||
|
- „Text erkennen" wählen: kein automatisches Hervorheben des Rahmens (er
|
||||||
|
bleibt durchgehend schlicht), „Modul scannen"-Knopf sichtbar und löst die
|
||||||
|
Texterkennung aus.
|
||||||
|
- Anzeige der gewählten Funktion in der Scan-Ansicht antippen: Auswahl
|
||||||
|
erscheint erneut, nach der Wahl gilt der Wechsel sofort — laufende Suche
|
||||||
|
startet/stoppt, Knopf erscheint/verschwindet, **ohne** die Seite neu zu
|
||||||
|
laden.
|
||||||
|
- Anzeige der gewählten Funktion aus rund einem Meter Entfernung lesbar.
|
||||||
|
|
||||||
**Barcode- und OCR-Erkennung**
|
**Barcode- und OCR-Erkennung**
|
||||||
- Samsung-Referenzmodul scannen: Code-128 *und* DataMatrix werden erkannt,
|
- Samsung-Referenzmodul in Funktion „Strichcode" scannen:
|
||||||
`M386A8K40BM1-CRC4Y` wird korrekt als Teilenummer übernommen, grüne
|
`M386A8K40BM1-CRC4Y` wird korrekt als Teilenummer übernommen, grüne
|
||||||
Rückmeldung mit `STAPEL A`, `64GB 4DRx4 PC4-2400 LRDIMM`.
|
Rückmeldung mit `STAPEL A`, `64GB 4DRx4 PC4-2400 LRDIMM`.
|
||||||
- Etikett ohne lesbaren Barcode fotografieren: OCR-Weg greift, die
|
- In Funktion „Text erkennen" ein Etikett fotografieren und „Modul scannen"
|
||||||
Otsu-Aufbereitung liefert auf einem echten, glänzenden Etikettenfoto
|
antippen: die Otsu-Aufbereitung liefert auf einem echten, glänzenden
|
||||||
tatsächlich brauchbaren Text (bisher nur an synthetischen Testbildern
|
Etikettenfoto tatsächlich brauchbaren Text (bisher nur an synthetischen
|
||||||
geprüft, nie an einem echten Foto).
|
Testbildern geprüft, nie an einem echten Foto).
|
||||||
- Ladezeit des WASM-Barcode-Moduls (`zxing-wasm`) beim allerersten Scan einer
|
- Ladezeit des WASM-Barcode-Moduls (`zxing-wasm`) beim allerersten Scan einer
|
||||||
Sitzung beobachten — bleibt sie deutlich unter der 10-Sekunden-Zeitgrenze
|
Sitzung in Funktion „Strichcode" oder „QR-Code" beobachten — bleibt sie
|
||||||
der Pipeline, und braucht ein zweiter, schnell nachfolgender Scan nicht
|
deutlich unter der 10-Sekunden-Zeitgrenze der Pipeline, und braucht ein
|
||||||
erneut die volle Ladezeit (Beleg, dass die Vorbereitung tatsächlich nur
|
zweiter, schnell nachfolgender Scan nicht erneut die volle Ladezeit (Beleg,
|
||||||
einmal läuft)?
|
dass die Vorbereitung tatsächlich nur einmal läuft)? In Funktion „Text
|
||||||
|
erkennen" darf dieses Laden dagegen gar nicht erst anlaufen, da dort nie
|
||||||
|
`decodeBarcodes` aufgerufen wird.
|
||||||
- Verbindung während des allerersten Scans einer Sitzung unterbrechen (WASM
|
- Verbindung während des allerersten Scans einer Sitzung unterbrechen (WASM
|
||||||
lädt per CDN), danach mit wiederhergestellter Verbindung erneut scannen:
|
lädt per CDN), danach mit wiederhergestellter Verbindung erneut scannen:
|
||||||
Das muss einen echten neuen Ladeversuch auslösen statt dauerhaft mit
|
Das muss einen echten neuen Ladeversuch auslösen statt dauerhaft mit
|
||||||
demselben Fehler zu scheitern.
|
demselben Fehler zu scheitern.
|
||||||
- Ladezeit des Tesseract-Arbeiters beim allerersten Scan einer Sitzung
|
- Ladezeit des Tesseract-Arbeiters beim ersten Antippen von „Modul scannen"
|
||||||
beobachten — bleibt sie auf einem normalen Handy deutlich unter der
|
in Funktion „Text erkennen" beobachten — bleibt sie auf einem normalen
|
||||||
20-Sekunden-Zeitgrenze der Pipeline?
|
Handy deutlich unter der 20-Sekunden-Zeitgrenze der Pipeline? In den
|
||||||
|
Funktionen „Strichcode"/„QR-Code" darf dieses Laden nie anlaufen, auch
|
||||||
|
nicht bei einem gänzlich unbekannten Etikett, da `runOcr` dort nie
|
||||||
|
aufgerufen wird.
|
||||||
- Verfügbarkeitsanzeige der Texterkennung: bleibt nach einem erfolgreichen
|
- Verfügbarkeitsanzeige der Texterkennung: bleibt nach einem erfolgreichen
|
||||||
Ladevorgang dauerhaft "verfügbar", springt nach einem erzwungenen
|
Ladevorgang dauerhaft "verfügbar", springt nach einem erzwungenen
|
||||||
Fehlschlag (z. B. Flugmodus beim ersten Laden) beim nächsten Erfolg wieder
|
Fehlschlag (z. B. Flugmodus beim ersten Laden) beim nächsten Erfolg wieder
|
||||||
darauf zurück?
|
darauf zurück?
|
||||||
- Stichprobe, ob die feste Zeichen-Whitelist der Texterkennung auf echten
|
- Stichprobe, ob die feste Zeichen-Whitelist der Texterkennung auf echten
|
||||||
Etiketten keine tatsächlich benötigten Zeichen ausschließt.
|
Etiketten keine tatsächlich benötigten Zeichen ausschließt.
|
||||||
- Bild ohne lesbaren Barcode und ohne verwertbaren OCR-Text: Rot-Dialog
|
- Funktion „Strichcode"/„QR-Code": kein passender Code im Bild führt zu
|
||||||
erscheint statt Fehler oder Absturz.
|
Rot-Dialog (statt Fehler oder Absturz) — hier ohne jeden OCR-Versuch.
|
||||||
- Modul mit unbekanntem Nummernschema (z. B. ein Hynix-Modul) scannen: grüne
|
Funktion „Text erkennen": kein verwertbarer OCR-Text führt ebenfalls zu
|
||||||
Rückmeldung statt Rot, auch wenn keine Kapazität abgeleitet werden kann.
|
Rot, hier ohne jeden Barcode-Versuch.
|
||||||
Dasselbe Modul ein zweites Mal scannen: landet auf demselben Stapel — und
|
- In Funktion „Strichcode" ein Modul mit unbekanntem Nummernschema (z. B. ein
|
||||||
die Rückmeldung erscheint spürbar schneller als beim ersten Scan, weil die
|
Hynix-Modul) scannen: grüne Rückmeldung statt Rot, auch wenn keine
|
||||||
Texterkennung diesmal übersprungen wird (nur am Gerät beobachtbar, da
|
Kapazität abgeleitet werden kann (die Texterkennung ist in dieser Funktion
|
||||||
`node --test` keine echte Ladezeit misst).
|
ohnehin stumm geschaltet und liefert nie eine Kapazität nach). Dasselbe
|
||||||
|
Modul ein zweites Mal scannen: landet auf demselben Stapel.
|
||||||
- Etikett mit zwei Barcodes (Teile- *und* Seriennummer) mehrfach scannen:
|
- Etikett mit zwei Barcodes (Teile- *und* Seriennummer) mehrfach scannen:
|
||||||
beide Scans landen auf demselben Stapel, obwohl die Seriennummer bei realen
|
beide Scans landen auf demselben Stapel, obwohl die Seriennummer bei realen
|
||||||
Modulen nie identisch ist — das belegt, dass die Teilenummer und nicht die
|
Modulen nie identisch ist — das belegt, dass die Teilenummer und nicht die
|
||||||
|
|||||||
Reference in New Issue
Block a user