Zastosowanie takiego rozwiązania ma dodatkową zaletę. Drobne korekty w rozkazach obsługi kasy w tym dodanie nowych czy zmiana ilości i rodzaju parametrów nie wymagają wtedy zmian w bibliotece komunikacyjnej, a jedynie dostosowania aplikacji do tych zmian.
Po wykonaniu takiego obiektu rozkazowego przez kasę (por. Przepływ informacji) wyniki dostępne są w analogiczny sposób - przez zestaw funkcji pobierających je kolejno z obiektu rozkazowego.
Cztery niezależne kolejki rozkazowe (rozkazy oczekujące, rozkazy wykonane, zdarzenia asynchroniczne i pozycje paragonowe) umożliwiają jednocześnie dużą swobodę przy tworzeniu aplikacji klienckiej zostawiając znaczną swobodę wybory sposobu obsługi kasy jej twórcy.
Całość transmisji obsługiwana jest przez dwa niezależne wątki, jeden transmisyjny, drugi odbiorczy operujące na odpowiednich kolejkach rozkazów.
Do obsługi zdarzeń w tym trybie został przygotowany zestaw funkcji opisany w module Obsługa zdarzeń asynchronicznych. Przychodzące zdarzenia asynchroniczne gromadzone są w osobnej kolejce zdarzeń, w której oczekują na obsługę. Aplikacja główna może zostac powiadomiona o przyjściu nowego zdarzenia za pomocą:
Aplikacja może też cyklicznie sprawdzać, czy w kolejce znajdują się nowe zdarzenia asynchroniczne (polling).
W ten sposób wątek odbioru danych paragonowych może wysyłać zapytania o pozycje paragonowe w standadowy sposób (do głównej kolejki rozkazów). Główna kolejka rozkazów do wysłania może równolegle otrzymywać rozkazy przygotowywane przez różne wątki (jest w pełni wielowątkowa), serializować je i wysyłac w kolejności otrzymania do kasy.
Odpowiedzi są natomiast rozdzielane od siebie i trafiają do dwóch osobnych kolejek odbiorczych. W kolejce pozycji paragonowych umieszczane są wyłącznie wyniki wysyłanych rozkazów dotyczących pozycji paragonowych.
Mogą to być własciwe pozycje paragonowe lub informacje o błędach wykonania tych rozkazów.
Aby włączyć tryb modemowy należy ustawić parametr urządzenia RS232 POSNET_DEV_PARAM_MODEMMODE na wartość 1. Po wykonaniu tej czynności urządzenie nie będzie wykonywało zleconych poleceń do momentu nawiązania połączenia modemowego. Urządzenie jest także gotowe do przyjmowania połączeń przychodzących. W przypadku pojawienia się sygnału RING na modemie zostanie automatycznie odebrana rozmowa.
UWAGA: W trybie odbioru rozmowy nie ma możliwości ustawienia modemu ciągiem inicjującym bezpośrednio (tryb zaczyna się pasywnie) – można to jednak zrobić za pośrednictwem polecenia dzwonienia bez ustawiania numeru telefonu (polecenie to zakończy się błędem POSNET_STATUS_MODEM_BADDIAL) ale wyśle do modemu ciąg inicjujący.
Dla urządzenia modemowego można ustawić dwa ciągi:
Urządzenie modemowe NIGDY samo nie wybiera numeru i nie ponawia przerwanych połączeń – ta operacja pozostawiona jest w gestii aplikacji zarządzającej kasami.
Do obsługi trybu modemowego służą następujące funkcje
Przykład użycia – patrz demo demo_modem.exe.
// Deklaracje zmiennych POSNET_HANDLE hDevice; POSNET_HANDLE hGlobalDevice; POSNET_HANDLE hRequest; // Wyniki unsigned char kontrast; unsigned char podswietlenie; unsigned char tryb; // Utworzenie obiektu urządzenia hGlobalDevice = POS_CreateDeviceHandle(POSNET_INTERFACE_RS232); // Ustawienie parametrów urządzenia POS_SetDeviceParam(hGlobalDevice, POSNET_DEV_PARAM_COMSETTINGS,"COM1,19200,8,N,1,H"); // Otwarcie urządzenia hDevice = POS_OpenDevice(hGlobalDevice); // Przygotowanie polecenia // Numer polecenia DSPPARAMGET = 101 hRequest = POS_CreateRequest(hDevice,POSNET_CMDID_DSPPARAMGET); // Przygotowanie parametrów polecenia // Pobierz dane dla wyświetlacza operatora // Wymagany 1 paramter typu 'B' o wartości 0 POS_PushRequestParamByte(hRequest,0); // Wyślij rozkaz do kasy w trybie interaktywnym POS_PostRequest(hRequest,POSNET_REQMODE_IMMEDIATE); // Oczekuj na wykonanie POS_WaitForRequestCompleted(hRequest,INFINITE); // Sprawdź czy zakończyło się sukcesem if (POS_GetRequestStatus(hRequest) == POSNET_STATUS_OK) { // Pobranie wyników, polecenie zwraca 3 wartości typu byte unsigned char kontrast,podswietlenie,tryb; POS_PopResponseValueByte(hRequest,&kontrast); POS_PopResponseValueByte(hRequest,&podswietlenie); POS_PopResponseValueByte(hRequest,&tryb); } // Usuń stworzone zapytanie POS_DestroyRequest(hRequest); // Zamknij urządzenie POS_CloseDevice(hDevice);
Poniżej przedstawiono przykładowy kod dla VBA.
Private Declare Function POS_PopSalesQueue Lib "posnet.dll" (ByVal H As Long, ByVal P As Long) As Long
Podobny kod dla Delphi 7
function POS_PopSalesQueue (hDevice : THandle; k: longint) : THandle; stdcall; external 'posnet.dll'
libposnet.so.1.0
libhlapi.so.1.0
oraz
libptypes.so.2.0.2 (http://www.melikyan.com/ptypes/)
Biblioteki te są zależne także od dostępnych na licencji LGPL bibliotek obsługujących podsystem USB:
libusb - w wersji 0.1.11+ dostępnej standardowo w większości dystrybucji (http://libusb.sourceforge.net/)
oraz
libftdi w wersji 0.7+ (http://www.intra2net.com/de/produkte/opensource/ftdi/index.php) do obsługi konwertera FTDI zastosowanego w urządzeniu.
UWAGA!!! W przypadku korzystania z trybu natywnego USB (POSNET_INTERFACE_USB) do poprawnego działania kasy niezbędne jest zablokowanie automatycznego ładowania i usunięcie jesli jest załadowany modułu jądra ftdi_sio. W przeciwnym razie połączenie z kasą nie będzie możliwe (w pliku logu zgłaszany będzie błąd o kodzie -5), gdyż moduł ten przejmuje kontrolę nad konwerterem FTDI tworząc wirtualny port szeregowy (/dev/ttyUSBx).
W przypadku korzystania w trybie wirtualnego portu szeregowego, sterownik ftdi_sio jest potrzebny.