spoko labels: etykiety drukowane prosto z przeglądarki

· 5 min czytania

Wydruk jednej etykiety z magazynu zajmował 5–10 minut: eksport, telefon, aplikacja NIIMBOT. Teraz panel drukuje ją jednym przyciskiem w mniej niż 10 sekund, bo przeglądarka rozmawia z drukarką bezpośrednio, przez Web Bluetooth. Zestaw open source, zbudowany w trzy dni.

Wydruk jednej etykiety z magazynu zajmował 5–10 minut: eksport, telefon, aplikacja NIIMBOT. Teraz panel drukuje ją jednym przyciskiem w mniej niż 10 sekund, bo przeglądarka rozmawia z drukarką bezpośrednio, przez Web Bluetooth. Zestaw open source, zbudowany w trzy dni.

W skrócie

Problem
Wydruk etykiety z magazynu szedł przez eksport, telefon i aplikację NIIMBOT. 5–10 minut, niezależnie od liczby etykiet.
Rozwiązanie
Przeglądarka rozmawia z drukarką bezpośrednio, przez Web Bluetooth. W panelu został jeden przycisk.
Efekt
Etykieta w mniej niż 10 sekund, z telefonu albo laptopa, bez eksportu.
Technologie
TypeScript, Web Bluetooth, Filament, Cloudflare Pages.
Czas
Trzy dni od pomysłu do przycisku w panelu, sprawdzonego na prawdziwej drukarce z laptopa, komputera i telefonu.

O projekcie

Każde pudło, półka i część w magazynie garażowym ma etykietę z kodem QR. Drukuje je NIIMBOT B1, budżetowa drukarka za niecałe 100 zł: Bluetooth, etykiety 50×30 mm, akumulator. Mieści się w dłoni, leży na półce między pudłami i nie ma żadnego kabla. Etykiety wychodzą dobre. Problem był z tym, ile trzeba zrobić, zanim jedna wyjdzie.

spoko labels to zestaw open source, dzięki któremu strona internetowa drukuje prosto na B1. Powstał po to, żeby panel magazynu drukował etykietę jednym przyciskiem, a przy okazji stał się publiczną aplikacją dla każdego, kto ma taką samą drukarkę.

Wyzwanie

B1 łączy się przez Bluetooth tylko z aplikacją NIIMBOT na telefon, a aplikacja na komputer obsługuje wyłącznie kabel USB. Każda etykieta musiała więc przejść przez aplikację NIIMBOT. Na początku najwięcej czasu zajmowało formatowanie: zmieścić nazwę, model, numer i kod QR na 50×30 mm tak, żeby dało się je odczytać. Kiedy był już szablon, dane trzeba było wpisywać etykieta po etykiecie. Gdy lista urosła, przyszedł import z pliku xls:

Aplikacja NIIMBOT na telefonie: edytor szablonu z etykietą narzędzia powiązaną z kolumnami arkusza i siatka etykiet narzędzi zaimportowanych z pliku
Stary sposób
  1. Krok 1

    Eksport

    Zaznaczyć rekordy w panelu i wyeksportować je do pliku xls.

  2. Krok 2

    Przeniesienie

    Przenieść plik na telefon.

  3. Krok 3

    Import

    Zaimportować go do aplikacji NIIMBOT i przypisać kolumny do szablonu.

  4. Krok 4

    Druk

    Połączyć się z drukarką w aplikacji, znaleźć etykietę i wydrukować.

Cztery kroki, dwa urządzenia i 5–10 minut, czy to była jedna etykieta, czy dwadzieścia. Do tego aplikacja ma niewiele fontów z polskimi znakami, a edycja na telefonie przy większej liczbie etykiet męczy. W praktyce etykietę drukowało się „przy okazji”, a okazji nie było. Pudła stały nieopisane, a porządkowanie magazynu stawało w miejscu.

NIIMBOT B1 z długą taśmą świeżo wydrukowanych etykiet na pudełka: kod w rodzaju KA-19, słowo Pudełko, wymiary i numer pojemnika obok kodu QRWydrukowana etykieta na ciemnym kartonowym pudełku: KA-35, Pudełko, 200×160×160, pojemnik C0049 i kod QR

Jak to rozwiązałem

Zamiast ulepszać ten proces, usunąłem go. Przeglądarka potrafi rozmawiać przez Bluetooth tak samo jak aplikacja na telefon, trzeba tylko znać język drukarki. Nikt go nie opisał, więc najpierw powstał prototyp w Pythonie, który potwierdził protokół na prawdziwej B1. Potem przeniosłem go do TypeScriptu jako cztery pakiety i aplikację, każdy do użycia osobno:

Część Co robi
labels-core
Protokół drukarki i połączenie przez Web Bluetooth: stan drukarki i baterii, gęstość, liczba kopii, kalibracja, przerwanie wydruku.
labels-render
Szablony etykiet w milimetrach (tekst, kod QR, linie) z polami z danych, renderowane do obrazu, który drukuje głowica.
labels-niimbot
Czyta szablony zaprojektowane w aplikacji NIIMBOT, więc gotowe projekty dalej działają.
labels-embed
Chip ze stanem drukarki i okno drukowania do osadzenia w dowolnej aplikacji webowej.
Aplikacja webowa
Szablon wbudowany albo zaimportowany z aplikacji NIIMBOT, plik xlsx albo JSON API, wybór wierszy, druk. Po polsku i po angielsku.
Aplikacja spoko labels: szablon narzędzia z kodem QR, lista narzędzi z magazynu wczytana z pliku xlsx z dwoma zaznaczonymi wierszami i podgląd etykiety zakrętarki 50 × 30 mm co do punktu

Podgląd to wydruk

Głowica ma 384 punkty szerokości, czyli 8 punktów na milimetr, i drukuje tylko czerń i biel. Etykieta, która ładnie wygląda na ekranie, a wychodzi z rozmazanym kodem QR, jest gorsza niż brak podglądu. Dlatego renderer liczy w punktach drukarki:

  • Szablon w milimetrach, wynik w punktach. Obraz jest zamieniany na czystą czerń i biel, a moduły kodu QR zawsze trafiają w całe punkty, więc kody skanują się nawet małe.
  • Podgląd pokazuje sprzęt. Czerwone pasy są poza głowicą i się nie wydrukują, szare rogi poza zaokrągloną etykietą, przerywana linia to bezpieczny obszar. Tekst, który się nie mieści, dostaje uwagę, zanim zmarnujesz etykietę.
  • Testy na obrazach wzorcowych. Zmiana, która przesuwa jeden punkt, jest świadomą decyzją, z obrazami przed i po w pull requeście.

Bluetooth ze strony internetowej

Web Bluetooth ma swoje zasady i projekt jest wokół nich zbudowany:

  • Połączenie zaczyna się od kliknięcia. Przeglądarka pozwala wybrać drukarkę tylko w odpowiedzi na gest użytkownika, więc chip w oknie drukowania robi to jako pierwszą rzecz.
  • Jedno polecenie naraz. Drukarka odpowiada na jedno polecenie, zanim przyjmie następne. Wszystkie idą przez jedną kolejkę, więc chip, okno i aplikacja nie mówią jednocześnie.
  • Protokół sprawdzany na sprzęcie. Pakiety 55 55 CMD LEN DATA… CHK AA AA z sumą XOR, a między nimi pakiety stanu, które drukarka wysyła sama. Każda zmiana w protokole jest sprawdzana na prawdziwej B1 przed merge.
  • Nie działa wszędzie i aplikacja to mówi. Chrome i Edge na komputerze i Androidzie działają. iOS i Firefox nie mają Web Bluetooth. Brave wymaga flagi i aplikacja podaje, której.
Ustawienia drukarki w aplikacji: przesunięcie kalibracji w poziomie i w pionie w milimetrach, z wartościami domyślnymi dla B1 i linkiem do pomocy

Jeden przycisk w panelu

Magazyn działa na Filamencie. Pakiet do osadzania zamienił drukowanie w jedną akcję: panel przekazuje szablon i zaznaczone wiersze, okno rysuje podgląd, chip trzyma połączenie. Pakiet niczego nie pobiera ani nie wysyła, więc działa pod restrykcyjnym Content Security Policy bez wyjątków. Na telefonie chip zwija się do ikony w górnym pasku. Stary widok drukowania i eksport, na którym się opierał, zostały usunięte.

Panel magazynu na produkcji: strona edycji produktu z otwartym oknem drukowania, podgląd etykiety przewodów hamulcowych z numerem OE, numerem 0035 i kodem QR, kopie i gęstość, połączona drukarka z poziomem baterii oraz przycisk Drukuj

Tak wydrukowana etykieta ląduje na części, obok naklejki producenta:

Etykieta produktu wydrukowana z panelu, naklejona na pompie ABS Bosch pod naklejką producenta: numer OE 6R0-907-379-AF pogrubiony, nazwa Pompa ABS Bosch 8.2i, numer 0019 i kod QR

Drukowanie z telefonu działa idealnie, nie muszę już eksportować plików xls. — warsztat, pierwszego dnia drukowania z panelu

Efekty

  • Etykieta w mniej niż 10 sekund zamiast 5–10 minut. Otworzyć rekord, stuknąć Drukuj etykietę, odkleić. Z telefonu w warsztacie albo z laptopa.
  • Zero eksportu. Arkusz, który był nieaktualny, gdy tylko zmieniła się nazwa, już nie istnieje. Etykieta zawsze pokazuje to, co jest w panelu.
  • Porządkowanie ruszyło. Gdy etykieta nic nie kosztuje, pudło dostaje ją od razu, a nie „przy okazji”.
  • Dane zostają w przeglądarce. Pliki xlsx są czytane na stronie, API jest pobierane bez danych logowania, nic nie trafia na żaden serwer.
  • Publiczna aplikacja. Każdy z B1 może drukować ze swojego arkusza pod adresem spoko-labels.pages.dev, a kod jest na licencji MIT. Kto ma już szablony w aplikacji NIIMBOT, wskazuje jej plik bazy: szablony wczytują się w przeglądarce, z podglądem i listą tego, co zostało uproszczone, i zostają w niej na kolejne wizyty. Tak właśnie przeszły szablony magazynu.
Aplikacja w dwóch oknach przeglądarki i na telefonie: pionowy szablon pojemnika z kodem QR po polsku, połączona drukarka ze stanem baterii i ten sam szablon na telefonie

Jak powstało

Od pomysłu do przycisku w panelu minęły trzy dni, od 12 do 14 października 2026, w około trzydziestu małych pull requestach. Przeniesienie prototypu zaplanowałem jako spisane specyfikacje, po jednej na pakiet. Każdy pakiet trafiał do repozytorium z własnymi testami, na koniec było ich 666, a wszystko, co dotykało sprzętu, sprawdzałem dodatkowo na prawdziwej drukarce, z laptopa, komputera stacjonarnego i telefonu. Bramka (typecheck, lint, testy, build) jest uruchamiana lokalnie przed każdym merge, a aplikację wdrażam ręcznie na Cloudflare Pages. W stopce widać commit, z którego została zbudowana.

Co dalej

  • Szablony z pliku. Własny szablon jako plik JSON do wczytania, a zaimportowany do pobrania, żeby przenieść go do innej aplikacji.
  • Linki bezpośrednie, żeby link otwierał aplikację z wybranym szablonem i źródłem danych.
  • Więcej drukarek. Projekt rozwijam na B1. Inne modele NIIMBOT używają podobnego protokołu, zgłoszenia są mile widziane.

Następny krok

Masz proces, który zabiera za dużo czasu?

Eksport, przepisywanie, przenoszenie plików między urządzeniami, czekanie na program. Buduję aplikacje webowe i integracje z urządzeniami, które taki krok usuwają albo automatyzują: tu 5–10 minut zamieniło się w 10 sekund. Napisz, co u Ciebie trwa najdłużej, a odpowiem, czy i jak da się to przyspieszyć.

Porozmawiajmy o Twoim procesie
Powrót do portfolio