From 39072042092391c2fd34b29cedf84fc4da8a8c68 Mon Sep 17 00:00:00 2001 From: TanerUslu Date: Wed, 29 Jul 2026 14:50:24 +0200 Subject: [PATCH] Change QR-Code function label from "2D-Code" back to "QR-Code" The function keeps reading all 2D-code types (QR-Code, MicroQRCode, RMQRCode, DataMatrix, Aztec, PDF417) as requested. The label is now "QR-Code" per the client's preference for their terminology. Added clarifying comments explaining the intentional mismatch between the name and the supported formats, since the hardware labels use DataMatrix (not QR). Updated README and test accordingly. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 49 ++++++++++++++++++++--------------------- src/scan-modes.js | 5 ++++- test/scan-modes.test.js | 4 ++-- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 46c0406..3453a11 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ beim physischen Sortieren am Tisch anleitet: Modul vor die Kamera halten, die App nennt den Stapel. Vor dem Scannen wählt der Nutzer eine von drei Funktionen — Strichcode, -2D-Code oder Text erkennen (siehe „Funktionsweise" unten). Jede Funktion nutzt +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. @@ -65,21 +65,20 @@ keine Daten verlassen das Gerät. | Funktion | Liest | Laufende Suche | Texterkennung | |---|---|---|---| | **Strichcode** | Code128, Code39, Code93, ITF, EAN-13, EAN-8, UPC-A, UPC-E, Codabar | ja | nein | - | **2D-Code** | QRCode, MicroQRCode, RMQRCode, DataMatrix, Aztec, PDF417 | ja | nein | + | **QR-Code** | QRCode, MicroQRCode, RMQRCode, DataMatrix, Aztec, PDF417 | ja | nein | | **Text erkennen** | keine Codes | nein | ja, auf Knopfdruck | - „2D-Code" liest neben den QR-Varianten auch DataMatrix, Aztec und PDF417. - Ursprünglich war die Funktion (damals „QR-Code" beschriftet) auf QR - beschränkt; am Gerät zeigte sich, dass sie damit auf der eigenen Ware nichts - fand, weil die 2D-Codes auf den RAM-Etiketten DataMatrix sind. Die - Beschriftung wurde daraufhin auf „2D-Code" geändert, damit sie nicht mehr - verspricht, was sie nicht meint. Die interne Kennung heißt weiterhin - `qrcode` (aus historischen Gründen, siehe `src/scan-modes.js`) — daran - ändert die Erweiterung nichts. + „QR-Code" heißt auf Wunsch des Auftraggebers „QR-Code", liest aber bewusst + nicht nur QR-Varianten, sondern auch DataMatrix, Aztec und PDF417. Der + Grund: Die 2D-Codes auf den RAM-Etiketten sind DataMatrix, nicht QR — eine + auf QR beschränkte Funktion fände auf dieser Ware nichts. Die interne + Kennung heißt weiterhin `qrcode` (aus historischen Gründen, siehe + `src/scan-modes.js`), und der Name ist Absicht — es ist der Wunsch des + Auftraggebers für seinen Sprachgebrauch. „Modul scannen" erscheint nur in „Text erkennen" — in „Strichcode" und - „2D-Code" sucht die App ohnehin laufend, ein Knopf ohne Texterkennung hätte - dort nichts zu tun. Der Zielrahmen hebt sich in „Strichcode" und „2D-Code" + „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 @@ -89,7 +88,7 @@ keine Daten verlassen das Gerät. 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 „2D-Code" eine Texterkennung + 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 @@ -97,7 +96,7 @@ keine Daten verlassen das Gerät. 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 „2D-Code"). Die zur +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 @@ -106,7 +105,7 @@ keine Daten verlassen das Gerät. 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"/„2D-Code" — „Text +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. @@ -137,7 +136,7 @@ keine Daten verlassen das Gerät. 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"/ - „2D-Code", wo meist die exakte Teilenummer trägt. + „QR-Code", wo meist die exakte Teilenummer trägt. 4. **Stapel-Zuweisung.** Grün (Barcode) und Gelb (OCR) laufen ohne Eingabe durch; nur bei roter Konfidenz (nichts Eindeutiges erkannt, widersprüchliche Barcodes oder widersprüchliche unbekannte Barcodes ohne jede OCR-Kapazität) @@ -194,9 +193,9 @@ und toleranter Vergleich, OCR-Bildaufbereitung (Otsu-Schwellwert) und -Feldextraktion, Stapel-Zuweisung, die Erkennungs-Pipeline samt Zeitgrenzen und Mehrdeutigkeitsbehandlung, die Sitzungssicherung samt Prüfung eines wiederhergestellten Zustands, die drei Scan-Funktionen (`scan-modes.js` — -Codearten je Funktion, DataMatrix/Aztec/PDF417 in „2D-Code") sowie die je Funktion +Codearten je Funktion, DataMatrix/Aztec/PDF417 in „QR-Code") sowie die je Funktion tatsächlich aufgerufenen Adapter (`scan-recognition.js` — Texterkennung läuft -nachweislich nie in „Strichcode"/„2D-Code", Barcode-Dekodierung nachweislich +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" @@ -265,8 +264,8 @@ worauf du bei der Veröffentlichung achten solltest. | `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/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, 2D-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"/„2D-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/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/camera.js` | Kamerastart, Einzelbildaufnahme, Bilddatei-Ersatzweg | | `src/barcode.js` | Adapter zu `zxing-wasm`; `decodeBarcodes(imageData, formats)` bekommt die Codearten übergeben, ohne Angabe wie bisher (Code128 + DataMatrix) | @@ -392,14 +391,14 @@ werden: **Funktionswahl (neu)** - Erster Start ohne gesicherte Sitzung: Auswahl mit drei großen Flächen - („Strichcode", „2D-Code", „Text erkennen") erscheint, *bevor* die Kamera + („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. -- „2D-Code" wählen und ein Etikett mit dem eigenen DataMatrix-Code vor die +- „QR-Code" wählen und ein Etikett mit dem eigenen DataMatrix-Code vor die Kamera halten: Rahmen hebt sich hervor, Treffer wird gebucht (DataMatrix liest diese Funktion jetzt mit). Einen echten QR-Code vor dieselbe Funktion halten: ebenfalls Treffer. @@ -421,7 +420,7 @@ werden: Etikettenfoto tatsächlich brauchbaren Text (bisher nur an synthetischen Testbildern geprüft, nie an einem echten Foto). - Ladezeit des WASM-Barcode-Moduls (`zxing-wasm`) beim allerersten Scan einer - Sitzung in Funktion „Strichcode" oder „2D-Code" beobachten — bleibt sie + Sitzung in Funktion „Strichcode" oder „QR-Code" beobachten — bleibt sie deutlich unter der 10-Sekunden-Zeitgrenze der Pipeline, und braucht ein zweiter, schnell nachfolgender Scan nicht erneut die volle Ladezeit (Beleg, dass die Vorbereitung tatsächlich nur einmal läuft)? In Funktion „Text @@ -434,7 +433,7 @@ werden: - Ladezeit des Tesseract-Arbeiters beim ersten Antippen von „Modul scannen" in Funktion „Text erkennen" beobachten — bleibt sie auf einem normalen Handy deutlich unter der 20-Sekunden-Zeitgrenze der Pipeline? In den - Funktionen „Strichcode"/„2D-Code" darf dieses Laden nie anlaufen, auch + 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 @@ -443,7 +442,7 @@ werden: darauf zurück? - Stichprobe, ob die feste Zeichen-Whitelist der Texterkennung auf echten Etiketten keine tatsächlich benötigten Zeichen ausschließt. -- Funktion „Strichcode"/„2D-Code": kein passender Code im Bild führt zu +- Funktion „Strichcode"/„QR-Code": kein passender Code im Bild führt zu Rot-Dialog (statt Fehler oder Absturz) — hier ohne jeden OCR-Versuch. Funktion „Text erkennen": kein verwertbarer OCR-Text führt ebenfalls zu Rot, hier ohne jeden Barcode-Versuch. diff --git a/src/scan-modes.js b/src/scan-modes.js index 2f7a59f..dddb5bd 100644 --- a/src/scan-modes.js +++ b/src/scan-modes.js @@ -38,8 +38,11 @@ export const SCAN_MODES = [ // Kennung bleibt aus historischen Gruenden `qrcode`, obwohl die Funktion // inzwischen alle 2D-Codearten liest (nicht mehr nur QR) - Umbenennung // nicht vorgenommen, da `qrcode` an mehreren Stellen durchgereicht wird. + // Label heisst auf Wunsch des Auftraggebers "QR-Code", obwohl die Funktion + // bewusst auch DataMatrix, Aztec und PDF417 liest - die RAM-Etiketten + // tragen DataMatrix, nicht QR. id: 'qrcode', - label: '2D-Code', + label: 'QR-Code', // QR-Varianten plus DataMatrix, Aztec, PDF417 - siehe Kommentar am Kopf. barcodeFormats: ['QRCode', 'MicroQRCode', 'RMQRCode', 'DataMatrix', 'Aztec', 'PDF417'], continuousSearch: true, diff --git a/test/scan-modes.test.js b/test/scan-modes.test.js index feb63c5..4206d64 100644 --- a/test/scan-modes.test.js +++ b/test/scan-modes.test.js @@ -17,9 +17,9 @@ test('Funktion 1 (Strichcode): eindimensionale Codearten, laufende Suche, keine assert.equal(mode.useOcr, false); }); -test('Funktion 2 (2D-Code): QR-Varianten und DataMatrix, Aztec, PDF417', () => { +test('Funktion 2 (QR-Code): QR-Varianten und DataMatrix, Aztec, PDF417', () => { const mode = getScanMode('qrcode'); - assert.equal(mode.label, '2D-Code'); + assert.equal(mode.label, 'QR-Code'); assert.deepEqual(mode.barcodeFormats, [ 'QRCode', 'MicroQRCode', 'RMQRCode', 'DataMatrix', 'Aztec', 'PDF417', ]);