# π Diagram Alur Kerja Printer Niimbot
## π Alur Lengkap: Dari UI ke Printer
```mermaid
graph TD
A[User buka halaman Brankas] --> B{Printer sudah
terhubung?}
B -->|Tidak| C[Klik 'Hubungkan Printer']
B -->|Ya| D[Status: Terhubung]
C --> E[Modal NiimbotConnector muncul]
E --> F{Pilih metode koneksi}
F -->|Bluetooth| G[Klik 'Hubungkan Printer']
F -->|USB/Serial| G
G --> H[Browser: Dialog pairing muncul]
H --> I[User pilih Niimbot device]
I --> J[Library: initClient & connect]
J --> K{Koneksi
berhasil?}
K -->|Tidak| L[Tampilkan error]
K -->|Ya| M[Fetch printer info]
M --> N[Status: Terhubung β]
N --> D
D --> O[User klik item di Brankas]
O --> P[Modal item muncul]
P --> Q[Generate QR Code URL]
Q --> R[Tampilkan preview QR]
R --> S[User klik 'Cetak ke Niimbot']
S --> T{Printer
terhubung?}
T -->|Tidak| U[Alert: Hubungkan printer]
U --> C
T -->|Ya| V[createQRLabelCanvas]
V --> W[Load QR image]
W --> X[Draw ke canvas:
QR + Kode + Nama + Berat]
X --> Y[Convert canvas to DataURL]
Y --> Z[printQRCode composable]
Z --> AA[Stop heartbeat]
AA --> AB[Create PrintTask]
AB --> AC[ImageEncoder.encodeCanvas]
AC --> AD[printTask.printInit]
AD --> AE[printTask.printPage]
AE --> AF{Print
sukses?}
AF -->|Tidak| AG[Tampilkan error]
AF -->|Ya| AH[printTask.printEnd]
AH --> AI[Start heartbeat]
AI --> AJ[Alert: Berhasil dicetak!]
AJ --> AK[Printer cetak label]
```
---
## ποΈ Arsitektur Komponen
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BrankasList.vue β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β UI Layer β β
β β - Tombol "Hubungkan Printer" β β
β β - Tombol "Cetak ke Niimbot" β β
β β - Modal item dengan QR Code β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Logic Layer β β
β β - printQR() β Trigger print β β
β β - createQRLabelCanvas() β Generate canvas dengan QR β β
β β - handlePrinterConnected() β Event handler β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β useNiimbotPrinter.js (Composable) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β State Management β β
β β - printerClient (reactive) β β
β β - connectionState β β
β β - isPrinting, printProgress β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Methods β β
β β - initClient() β Buat NiimbotClient β β
β β - connect() β Hubungkan ke printer β β
β β - disconnect() β Putuskan koneksi β β
β β - printQRCode() β Print image ke printer β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β @mmote/niimbluelib (Library) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β NiimbotBluetoothClient / NiimbotSerialClient β β
β β - connect() β Web Bluetooth/Serial API β β
β β - fetchPrinterInfo() β Get printer metadata β β
β β - startHeartbeat() β Maintain connection β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β PrintTask β β
β β - newPrintTask() β Buat task print β β
β β - printInit() β Inisialisasi print β β
β β - printPage() β Kirim data gambar β β
β β - waitForFinished() β Tunggu selesai β β
β β - printEnd() β Akhiri print β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β ImageEncoder β β
β β - encodeCanvas() β Encode canvas ke binary β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Browser Web APIs β
β - Web Bluetooth API (navigator.bluetooth) β
β - Web Serial API (navigator.serial) β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Printer Niimbot (Hardware) β
β - Terima perintah via BLE/USB β
β - Decode binary image data β
β - Print ke label thermal β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
---
## π‘ Sequence Diagram: Proses Print
```
User BrankasList useNiimbot niimbluelib Browser API Printer
β β β β β β
β Klik item β β β β β
ββββββββββββββββ>β β β β β
β β β β β β
β Modal muncul β β β β β
β<ββββββββββββββββ€ β β β β
β β β β β β
β Klik 'Cetak' β β β β β
ββββββββββββββββ>β β β β β
β β β β β β
β β printQRCode()β β β β
β ββββββββββββββ>β β β β
β β β β β β
β β β stopHeartbeat() β β
β β ββββββββββββββ>β β β
β β β β β β
β β β newPrintTask() β β
β β ββββββββββββββ>β β β
β β β β β β
β β β encodeCanvas() β β
β β ββββββββββββββ>β β β
β β β β β β
β β β β BLE/Serial β β
β β β β Write Data β β
β β β ββββββββββββββ>β β
β β β β β β
β β β β β Send Data β
β β β β ββββββββββββ>β
β β β β β β
β β β β β Printing β
β β β β β ........ β
β β β β β β
β β β β Status ACK β β
β β β β<ββββββββββββββ€ β
β β β β β β
β β β printEnd() β β β
β β ββββββββββββββ>β β β
β β β β β β
β β β startHeartbeat() β β
β β ββββββββββββββ>β β β
β β β β β β
β β Alert sukses β β β β
β β<ββββββββββββββ€ β β β
β β β β β β
β Label tercetakβ β β β β
β<ββββββββββββββββ΄βββββββββββββββ΄βββββββββββββββ΄βββββββββββββββ΄βββββββββββββ€
β β
```
---
## π Connection Flow Detail
### Bluetooth Connection
```
1. User Action
ββ> Klik "Hubungkan Printer"
2. initClient('bluetooth')
ββ> new NiimbotBluetoothClient()
3. connect()
ββ> navigator.bluetooth.requestDevice({
filters: [{ namePrefix: 'Niimbot' }],
optionalServices: [SERVICE_UUID]
})
4. Browser Dialog
ββ> User pilih device "Niimbot-XXXX"
5. device.gatt.connect()
ββ> Establish BLE connection
6. getPrimaryService(SERVICE_UUID)
ββ> getCharacteristic(TX_CHAR, RX_CHAR)
7. Event: 'connect' triggered
ββ> connectionState = 'connected'
8. fetchPrinterInfo()
ββ> Send command: GET_INFO
ββ> Receive: model, serial, firmware version
9. startHeartbeat()
ββ> Kirim ping setiap 1 detik
ββ> Cek printer masih hidup
```
### USB/Serial Connection
```
1. User Action
ββ> Klik "Hubungkan Printer"
2. initClient('serial')
ββ> new NiimbotSerialClient()
3. connect()
ββ> navigator.serial.requestPort({
filters: [{ usbVendorId: 0xXXXX }]
})
4. Browser Dialog
ββ> User pilih USB device
5. port.open({ baudRate: 9600 })
ββ> Establish serial connection
6. Setup reader/writer streams
ββ> readable.getReader()
ββ> writable.getWriter()
7. Event: 'connect' triggered
ββ> connectionState = 'connected'
8. fetchPrinterInfo() & startHeartbeat()
ββ> (sama dengan Bluetooth)
```
---
## πΌοΈ Image Processing Pipeline
```
QR Code URL (dari API)
β
βΌ
new Image()
β
βΌ
img.onload
β
βΌ
Create Canvas (384x384)
β
ββ> Fill white background
β
ββ> drawImage(qr, x, y, size, size)
β
ββ> fillText(kode_item)
β
ββ> fillText(nama_produk)
β
ββ> fillText(berat)
β
βΌ
canvas.toDataURL('image/png')
β
βΌ
loadImageToCanvas(dataUrl)
β
βΌ
[Optional] applyThreshold(canvas, 140)
β
ββ> getImageData()
β
ββ> for each pixel:
β avg = (r+g+b)/3
β if avg < 140: black
β else: white
β
ββ> putImageData()
β
βΌ
ImageEncoder.encodeCanvas(canvas, 'top')
β
ββ> Convert to 1-bit bitmap
β
ββ> Rotate if needed (printDirection)
β
ββ> Pack bits: 8 pixels = 1 byte
β
βΌ
Binary Data (EncodedImage)
β
βΌ
printTask.printPage(encoded, quantity)
β
βΌ
Send to Printer via BLE/Serial
```
---
## π State Machine Diagram
```
βββββββββββββββββββ
β DISCONNECTED βββββββββββ
ββββββββββ¬βββββββββ β
β β
β connect() β disconnect()
β β
βΌ β
βββββββββββββββββββ β
β CONNECTING β β
ββββββββββ¬βββββββββ β
β β
β success β error
β β
βΌ β
βββββββββββββββββββ β
β CONNECTED βββββββββββ€
ββββββββββ¬βββββββββ β
β β
β printQRCode() β
β β
βΌ β
βββββββββββββββββββ β
β PRINTING β β
β [progress: X%] β β
ββββββββββ¬βββββββββ β
β β
β finished β
β β
βΌ β
βββββββββββββββββββ β
β CONNECTED βββββββββββ
β (heartbeat) β
βββββββββββββββββββ
```
---
## π― Data Flow: QR Code β Printed Label
```
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. DATA SOURCE β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β selectedItem = { β
β kode_item: "BRN-001", β
β produk: { β
β nama: "Cincin Emas 24K", β
β berat: 5.2 β
β } β
β } β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. QR CODE GENERATION (External API) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β URL: https://api.qrserver.com/v1/create-qr-code/ β
β ?size=150x150&data=BRN-001 β
β β
β Returns: image/png (base64 or URL) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. CANVAS CREATION β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β createQRLabelCanvas(qrUrl, item) β
β β
β Canvas 384x384px: β
β ββββββββββββββββββββββββ β
β β β β
β β ββββββββββββ β β QR Code (200x200) β
β β β ββ βββββ β β
β β ββ ββ β β β β
β β β βββ ββββ β β
β β ββββββββββββ β β
β β β β
β β BRN-001 β β Kode Item (bold 18px) β
β β Cincin Emas 24K β β Nama Produk (14px) β
β β 5.2g β β Berat (12px) β
β β β β
β ββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. IMAGE ENCODING β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ImageEncoder.encodeCanvas(canvas, 'top') β
β β
β Process: β
β - Convert RGB to grayscale β
β - Apply threshold (< 140 = black, >= 140 = white) β
β - Pack 8 pixels into 1 byte (1-bit bitmap) β
β - Width: 384px = 48 bytes per row β
β - Height: 384 rows β
β - Total: 48 Γ 384 = 18,432 bytes β
β β
β Output: Uint8Array(18432) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. PRINT PROTOCOL β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β printTask.printInit() β
β ββ> Send: [CMD_INIT, density, labelType, ...] β
β β
β printTask.printPage(encoded, quantity) β
β ββ> Send in chunks: β
β [CMD_IMAGE_HEADER, width, height] β
β [CMD_IMAGE_DATA, chunk1...] β
β [CMD_IMAGE_DATA, chunk2...] β
β ... β
β [CMD_IMAGE_END] β
β β
β printTask.waitForFinished() β
β ββ> Poll status every 100ms β
β until status = FINISHED β
β β
β printTask.printEnd() β
β ββ> Send: [CMD_PRINT_END] β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 6. PHYSICAL OUTPUT β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Printer Niimbot: β
β - Receives binary data via BLE/USB β
β - Thermal head heats selected pixels β
β - Paper feeds forward β
β - Label printed with QR + text β
β - Cut (automatic or manual) β
β β
β Result: Physical label 40x40mm dengan QR code β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
---
## π§© Component Interaction Map
```
ββββββββββββββββββββββββ
β App.vue / Router β
ββββββββββββ¬ββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β BrankasList.vue β
β β
β ββββββββββββββββββ β
β β Header β β
β β - Printer Btn ββββΌβββ
β ββββββββββββββββββ β β
β β β
β ββββββββββββββββββ β β
β β Item List β β β
β β - Click item ββββΌβββΌβββ
β ββββββββββββββββββ β β β
β β β β
β ββββββββββββββββββ β β β
β β Item Modal β β β β
β β - QR Preview β β β β
β β - Print Btn ββββΌβββΌβββΌβββ
β ββββββββββββββββββ β β β β
ββββββββββββββββββββββββ β β β
β β β
βββββββββββββββββββββββββββββββββββββββ β β
β β β
βΌ β β
ββββββββββββββββββββ β β
β NiimbotConnector β β β
β .vue β β β
β β β β
β - Connect UI ββββββββββββββββββββββββββββββ β
β - Status display β β
β - Printer info β β
ββββββββββ¬ββββββββββ β
β β
β uses β
β β
βΌ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββΌββββ
β useNiimbotPrinter.js (Composable) β β
β β β
β - State: printerClient, connectionState, etc βββββ
β - Methods: connect(), disconnect(), printQR() β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β Event Listeners Setup β β
β β - on('connect') β β
β β - on('disconnect') β β
β β - on('printprogress') β β
β β - on('heartbeat') β β
β βββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β imports
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β @mmote/niimbluelib β
β β
β - NiimbotBluetoothClient β
β - NiimbotSerialClient β
β - ImageEncoder β
β - PrintTask abstraction β
β - Utils β
ββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β uses
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Browser APIs β
β - navigator.bluetooth (Web Bluetooth API) β
β - navigator.serial (Web Serial API) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
---
## β‘ Performance Timeline
```
Event Timeline (typical print job):
0ms β User clicks "Cetak ke Niimbot"
β
10ms β Check printer connection
β ββ> Already connected β
β
20ms β createQRLabelCanvas() start
β ββ> Load QR image
β
150ms β Image loaded, draw to canvas
β ββ> Draw QR, text, etc
β
170ms β canvas.toDataURL()
β
200ms β printQRCode() called
β ββ> stopHeartbeat()
β
220ms β newPrintTask()
β
240ms β ImageEncoder.encodeCanvas()
β ββ> RGB β grayscale
β ββ> Threshold
β ββ> Pack to 1-bit
β
450ms β Encoding complete (18KB data)
β
470ms β printTask.printInit()
β ββ> Send init command
β
490ms β ACK received
β
500ms β printTask.printPage()
β ββ> Send image header
β
520ms β Send data chunk 1/10
540ms β Send data chunk 2/10
... β ...
740ms β Send data chunk 10/10
β
750ms β All data sent
β
780ms β waitForFinished() polling start
β
800ms β Status: PRINTING (0%)
900ms β Status: PRINTING (25%)
1000ms β Status: PRINTING (50%)
1100ms β Status: PRINTING (75%)
1200ms β Status: PRINTING (100%)
β
1220ms β Status: FINISHED
β
1230ms β printTask.printEnd()
β
1250ms β startHeartbeat()
β
1260ms β Alert: "QR Code berhasil dicetak!"
β
Total: ~1.3 seconds dari klik hingga selesai
```
---
## π Security & Privacy
```
Data Flow Security:
ββββββββββββββββββββ
β User's Browser β
ββββββββββ¬ββββββββββ
β
β HTTPS (encrypted)
β
βΌ
ββββββββββββββββββββ
β QR API Server β β External: api.qrserver.com
ββββββββββ¬ββββββββββ (Kirim kode_item only)
β
β Returns image URL
β
βΌ
ββββββββββββββββββββ
β User's Browser β
β - Generate β
β canvas β
β - Encode image β
ββββββββββ¬ββββββββββ
β
β BLE/USB (direct, tidak via internet)
β Encrypted jika BLE
β
βΌ
ββββββββββββββββββββ
β Niimbot Printer β β Local device, tidak terkoneksi internet
ββββββββββββββββββββ
Privacy Notes:
- Data tidak lewat server backend aplikasi
- QR Code dibuat real-time di browser
- Gambar langsung dikirim ke printer lokal
- Tidak ada logging data item ke cloud
```
---
## π Error Handling Flow
```
ββββββββββββββββββββ
β User Action β
ββββββββββ¬ββββββββββ
β
βΌ
ββββββββββββββββββββ
β Try: connect() β
ββββββββββ¬ββββββββββ
β
ββββββββββββββ΄βββββββββββββ
β β
ββββββββΌβββββββ ββββββββΌβββββββ
β Success β β Error β
ββββββββ¬βββββββ ββββββββ¬βββββββ
β β
β βΌ
β ββββββββββββββββββ
β β Catch error β
β β - Log to β
β β console β
β β - Set error β
β β message β
β β - Alert user β
β ββββββββββ¬ββββββββ
β β
β βΌ
β ββββββββββββββββββ
β β connectionStateβ
β β = 'disconnectedβ
β ββββββββββββββββββ
β
βΌ
ββββββββββββββββββ
β fetchPrinterInfoβ
ββββββββββ¬βββββββββ
β
ββββββββ΄βββββββ
β β
βββββββΌββββββ ββββββΌβββββ
β Success β β Error β
βββββββ¬ββββββ ββββββ¬βββββ
β β
β βββ> Log & continue (non-critical)
β
βΌ
βββββββββββββββββββ
β startHeartbeat()β
βββββββββββ¬ββββββββ
β
βββ> Connected & Ready
```
---
Semua diagram ini membantu memahami bagaimana sistem bekerja end-to-end! π