Magazyny zasobów ochrony ludności mieszczą się często w piwnicach albo budynkach o grubych ścianach, gdzie zasięg sieci komórkowej jest słaby albo go nie ma. Aplikacja wymagająca stałego połączenia zatrzymałaby wydanie zasobu w chwili, gdy jest ono najpilniejsze.
OLiOC Mobile, aplikacja WMS OLiOC na Androida, zapisuje operacje w bazie na urządzeniu i przesyła je do serwera po odzyskaniu łączności. Takie podejście rozwiązuje problem zasięgu, ale tworzy dwa nowe: powtórzenia przy ponownej wysyłce oraz konflikty, gdy dwa urządzenia zmienią tę samą pozycję bez kontaktu z serwerem.
Tryb offline nie jest bezkonfliktowy. Dwa terminale bez łączności mogą wydać ostatnią sztukę tego samego zasobu. Synchronizacja nie zapobiegnie takiej sytuacji, może ją tylko wykryć i przekazać do wyjaśnienia, dlatego reguły rozstrzygania konfliktów trzeba ustalić przed wdrożeniem.
Zakres pracy bez połączenia
Aplikacja obsługuje bez połączenia cztery rodzaje operacji. Każda niesie inne ryzyko przy późniejszej synchronizacji.
| Operacja | Zapis na urządzeniu | Ryzyko przy synchronizacji |
|---|---|---|
| Przyjęcie zasobu | dokument z identyfikatorem nadanym na urządzeniu | ponowna wysyłka po zerwaniu połączenia |
| Wydanie kryzysowe WK-ZOL | dokument podpisany na ekranie przez odbierającego | wydanie tej samej sztuki z dwóch terminali |
| Inwentaryzacja | wynik spisu z datą oraz osobą spisującą | spis, który nie uwzględnia operacji z innego urządzenia |
| Elektroniczna lista kontrolna | wynik przeglądu sprzętu | ta sama pozycja oceniona na dwóch urządzeniach |
Przebieg wydania kryzysowego opisuje artykuł o wydawaniu zasobów pod presją czasu, a listy kontrolne - materiał o konserwacji sprzętu OC w WMS OLiOC. Inaczej działa aplikacja mobilna BioKontrol, która wymaga stałego połączenia, bo kierowca pracuje w terenie z zasięgiem, a system blokuje zrzut na podstawie danych z serwera.
Urządzenia i skanowanie
Aplikacja działa na smartfonach i tabletach z Androidem, w tym na wzmocnionych urządzeniach Zebra oraz Panasonic z serii Toughbook. Przy wyborze sprzętu warto sprawdzić cztery parametry.
- Szczelność obudowy - klasa IP65 albo IP67 według normy IEC 60529, czyli ochrona przed pyłem oraz strugą wody albo krótkim zanurzeniem.
- Odporność mechaniczna - deklaracja producenta o testach według MIL-STD-810, amerykańskiej normy metod badań; to opis przeprowadzonych prób, a nie certyfikat, więc warto sprawdzić, które testy objęły dany model.
- Skaner - wbudowany czytnik kodów kreskowych i QR; w urządzeniach Zebra wynik skanu trafia do aplikacji przez usługę DataWedge.
- Wersja systemu - materiały produktu podają Androida 8.0 jako minimum, a ta wersja od lat nie otrzymuje poprawek bezpieczeństwa, więc warto wybierać urządzenia z aktualnym systemem i deklarowanym okresem wsparcia.
Dane zapisane offline zostają na urządzeniu do czasu synchronizacji. Szyfrowanie pamięci oraz możliwość zdalnego wyczyszczenia zgubionego terminala przez system zarządzania urządzeniami chronią ewidencję przed ujawnieniem.
Synchronizacja: operacje w górę, zmiany w dół
Urządzenie nie wysyła stanów magazynowych, tylko operacje: przyjęcie o 10 sztuk, wydanie 4 sztuk. Każda operacja ma identyfikator nadany na urządzeniu oraz kolejny numer w obrębie urządzenia. Serwer zapisuje operację tylko raz, więc ponowienie wysyłki po zerwanym połączeniu nie zmienia stanu. Schemat w T-SQL ilustruje zasadę, a nie kod WMS OLiOC.
CREATE TABLE dbo.OperacjaMagazynowa (
OperacjaId uniqueidentifier NOT NULL PRIMARY KEY, -- nadany na urządzeniu
UrzadzenieId int NOT NULL,
NrKolejny int NOT NULL, -- licznik operacji urządzenia
ZasobId int NOT NULL,
Zmiana decimal(12, 3) NOT NULL, -- przyjęcie dodatnie, wydanie ujemne
CzasUrzadzenia datetime2 NOT NULL,
CzasSerwera datetime2 NOT NULL DEFAULT SYSUTCDATETIME(),
CONSTRAINT UQ_Operacja_Urzadzenie UNIQUE (UrzadzenieId, NrKolejny)
);
INSERT INTO dbo.OperacjaMagazynowa (OperacjaId, UrzadzenieId, NrKolejny, ZasobId, Zmiana, CzasUrzadzenia)
SELECT p.OperacjaId, p.UrzadzenieId, p.NrKolejny, p.ZasobId, p.Zmiana, p.CzasUrzadzenia
FROM @Paczka AS p
WHERE NOT EXISTS (SELECT 1 FROM dbo.OperacjaMagazynowa AS o WHERE o.OperacjaId = p.OperacjaId);
Jeżeli dwie kopie tej samej paczki dotrą jednocześnie, obie mogą przejść test NOT EXISTS, ale klucz główny odrzuci drugą błędem 2627, a ponowiona paczka zostanie już odfiltrowana.
Numer kolejny ujawnia operacje, które nigdy nie dotarły: luka między numerami 41 i 43 jednego urządzenia oznacza zgubioną operację 42, na przykład po resecie terminala. Zapis dwóch znaczników czasu wynika z tego, że zegar urządzenia pracującego tygodniami bez sieci może się rozjechać, a czas serwera pokazuje tylko moment przyjęcia paczki.
W drugą stronę serwer wysyła urządzeniu tylko wiersze zmienione od jego ostatniej synchronizacji. Mechanizm Change Tracking w SQL Server zwraca klucze zmienionych wierszy od podanej wersji, a odczyt w transakcji SNAPSHOT gwarantuje, że lista zmian i nowy numer wersji pochodzą z tego samego stanu bazy.
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION;
DECLARE @NowaWersja bigint = CHANGE_TRACKING_CURRENT_VERSION();
IF @OstatniaWersja < CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID(N'dbo.Zasob'))
THROW 50070, N'Historia zmian nie sięga wersji urządzenia. Wymagana pełna synchronizacja.', 1;
SELECT ct.ZasobId, ct.SYS_CHANGE_OPERATION, z.Nazwa, z.TerminWaznosci
FROM CHANGETABLE(CHANGES dbo.Zasob, @OstatniaWersja) AS ct
LEFT JOIN dbo.Zasob AS z ON z.ZasobId = ct.ZasobId;
SELECT @NowaWersja AS NowaWersja;
COMMIT;
Warunek z funkcją CHANGE_TRACKING_MIN_VALID_VERSION chroni przed cichą utratą zmian. Terminal wyłączony dłużej niż okres przechowywania historii zmian musi pobrać pełny stan, bo różnica od jego wersji nie jest już dostępna. Usunięty wiersz wraca z kolumną SYS_CHANGE_OPERATION równą 'D' i pustymi danymi, dlatego złączenie jest zewnętrzne.
Konflikt dwóch wydań tej samej pozycji
Dwa terminale bez łączności widzą stan 1 sztuki i oba ją wydają. Po synchronizacji suma operacji daje stan -1. Zapytanie sumuje operacje narastająco i wskazuje miejsca, w których stan spadł poniżej zera.
SELECT x.ZasobId, x.OperacjaId, x.UrzadzenieId, x.CzasUrzadzenia, x.StanPo
FROM (SELECT o.ZasobId, o.OperacjaId, o.UrzadzenieId, o.CzasUrzadzenia,
SUM(o.Zmiana) OVER (PARTITION BY o.ZasobId
ORDER BY o.CzasUrzadzenia, o.OperacjaId
ROWS UNBOUNDED PRECEDING) AS StanPo
FROM dbo.OperacjaMagazynowa AS o) AS x
WHERE x.StanPo < 0;
Kolejność według czasu urządzenia jest przybliżona z powodu dryfu zegarów, więc wynik wskazuje pozycje do wyjaśnienia, a nie winnego. Przy wydaniu kryzysowym pierwszeństwo ma wydanie, a konflikt staje się zadaniem uzgodnienia po zdarzeniu. Przy planowanych dystrybucjach można mu zapobiec przydziałem ilości: przed wyjazdem każde urządzenie dostaje limit, którego suma nie przekracza stanu, i wydaje offline tylko w jego granicach. Zasady prowadzenia stanów opisuje artykuł o magazynie zasobów ochrony ludności.
Interfejs do pracy w rękawicach
Materiały produktu podają minimalny rozmiar przycisku 80 px. Na Androidzie rozmiar trzeba jednak określać w dp, czyli pikselach niezależnych od gęstości ekranu. Na ekranie o gęstości 3x 80 fizycznych pikseli to około 27 dp, mniej niż 48 dp, które dokumentacja dostępności aplikacji na Androida zaleca jako minimum dla każdego elementu dotykowego. Do pracy w grubych rękawicach przyciski powinny być wyraźnie większe od tego minimum.
| Kryterium WCAG 2.2 | Poziom | Wymaganie |
|---|---|---|
| 1.4.3 Kontrast (minimum) | AA | 4,5:1 dla zwykłego tekstu |
| 1.4.6 Kontrast (wzmocniony) | AAA | 7:1 dla zwykłego tekstu |
| 2.5.8 Rozmiar celu (minimum) | AA | 24 na 24 piksele CSS |
| 2.5.5 Rozmiar celu (wzmocniony) | AAA | 44 na 44 piksele CSS |
Źródło deklaruje zgodność trybu alarmowego z poziomem AAA. Specyfikacja WCAG 2.2 zaznacza, że nie zaleca wymagania poziomu AAA dla całych serwisów, bo części kryteriów nie da się spełnić dla niektórych treści. Precyzyjniejsza deklaracja wskazuje konkretne kryteria spełnione w trybie alarmowym, na przykład kontrast 7:1 oraz rozmiar celu co najmniej 44 na 44.
Wskazanie lokalizacji przy kompletacji
Klasyczny system put-to-light używa modułów świetlnych zamontowanych przy lokalizacjach magazynowych: lampka zapala się przy półce, na którą trzeba odłożyć albo z której trzeba pobrać zasób. OLiOC Mobile wyświetla lokalizację oraz ilość na ekranie urządzenia, więc nie wymaga instalacji na regałach. Ceną jest konieczność patrzenia na ekran przy każdej pozycji, co przy masowym wydaniu dla wielu formacji wydłuża kompletację w porównaniu z sygnalizacją świetlną.
Operacje zsynchronizowane z terminali trafiają do zestawienia zmian dla ewidencji centralnej, co opisuje artykuł o ewidencji zasobów i CEZOLOC. Stan po synchronizacji jest też podstawą raportu pokrycia normy 3-dniowej, a partie z terminem ważności, spisywane w magazynie z terminala, omawia materiał o kontroli terminów ważności w magazynie ochrony ludności. Pełny opis systemu zawiera strona WMS OLiOC.
Pytania i odpowiedzi
Czy aplikacja działa w magazynie bez zasięgu
Tak. Operacje są zapisywane w bazie na urządzeniu, a aplikacja przesyła je do serwera WMS OLiOC po odzyskaniu łączności, bez udziału magazyniera.
Co się stanie, gdy ta sama operacja zostanie wysłana dwa razy
Nic. Każda operacja ma identyfikator nadany na urządzeniu, a serwer pomija operację o identyfikatorze, który już zapisał. Ponowna wysyłka po zerwaniu połączenia nie tworzy duplikatu.
Co jeśli dwa terminale bez łączności wydadzą ten sam zasób
Po synchronizacji stan pozycji spadnie poniżej zera, a system wskaże operacje, które do tego doprowadziły. Synchronizacja wykrywa taki konflikt, ale nie może mu zapobiec, dlatego przy planowanych wydaniach warto przydzielić urządzeniom ilości z góry.
Na jakich urządzeniach działa OLiOC Mobile
Na smartfonach i tabletach z Androidem, w tym na wzmocnionych urządzeniach Zebra oraz Panasonic z wbudowanym skanerem kodów. Warto wybierać urządzenia z aktualną wersją systemu i deklarowanym okresem wsparcia producenta.
Czy przyciski o wielkości 80 px wystarczą do pracy w rękawicach
To zależy od gęstości ekranu. Na ekranie o gęstości 3x 80 fizycznych pikseli to około 27 dp, czyli mniej niż zalecane przez Google 48 dp. Rozmiar przycisków trzeba określać w dp, a nie w pikselach.
Słownik pojęć
- Offline-first
- Architektura, w której aplikacja zapisuje dane najpierw na urządzeniu i traktuje brak połączenia jako stan normalny. Synchronizacja z serwerem następuje po odzyskaniu łączności.
- Idempotencja
- Właściwość operacji, której wielokrotne wykonanie daje ten sam wynik co jednokrotne. Chroni przed duplikatami przy ponawianiu wysyłki.
- Change Tracking
- Mechanizm SQL Server zapisujący, które wiersze tabeli zmieniły się od podanej wersji. Pozwala wysłać urządzeniu tylko zmiany od jego ostatniej synchronizacji.
- dp
- Piksel niezależny od gęstości ekranu w systemie Android. Jeden dp odpowiada jednemu pikselowi na ekranie o gęstości 160 dpi.
- Przydział ilości
- Ilość zasobu, którą urządzenie może wydać bez połączenia z serwerem. Suma przydziałów nie przekracza stanu, więc wydania offline nie prowadzą do stanu ujemnego.