
Na rynku istnieje dosyć dużo komercyjnych rozwiązań do monitoringu GPS. Korzystanie z takich systemów nie jest darmowe, często trzeba kupić dedykowane do danego systemu urządzenie za kilkaset złotych, do tego dochodzi abonament miesięczny w kwocie conajmniej kilkudziesięciu złotych. Drugą drogą jest kupienie gotowego urządzenia do trackingu na polskim (np. Allegro) lub chińskim (np.AliExpress) portalu aukcyjnym. Do większości urządzeń jest dodawane darmowe konto ważne przez kilka lat. Wadą tego rozwiązania jest ograniczenie do urządzeń danego producenta, przechowywanie danych na chińskich serwerach, mało intuicyjne interfejsy graficzne aplikacji do zarządzania. Poszedłem więc własną drogą i stworzyłem własny system monitoringu od zera.
Moje założenia budowy systemu opierały się na technologiach:
- Frontend oparty na Angularze i Bootstrap
- Backend opartyna SpringBoot z bazą danych (miałabyć Cassandra, ale ze względów na ograniczenia pamięci taniego VPS musiałem ograniczyć się do Postgresa)
- Autoryzacja oparta na tokenach wykorzystująca coraz popularniejszy opensourcowy system zarządzania tożsamością i dostępem – Keycloak
- Lokalizatory GPS: programowe i sprzętowe

Frontend
Część frontendową stworzyłem w Angularze, dodatkowo użyłem bibliotek:
- keycloak-angular – jest to biblioteka do autentykacji opartej o serwer Keycloak i komunikacji z autoryzacją bazującą m.in. na JSON Web Token.
- ngx-leaflet biblioteka pozwalająca osadzić na stronie większość popularnych map: Google, OpenStreetMap, MapTiler i wiele innych. Biblioteka posiada także rozbudowane API pozwalające zaznaczać punkty, obszary, definiować menu.
- Bootstrap – bibliotek do łatwego komponowania widoków HTML/CSS

Backend
Do stworzenia części backendowej użyłem Spring Boot z kilkoma bibliotekami:
- Keycloak-admin-client i keycloak-authz-client-biblioteki pozwalające zdekodować otrzymywany w nagłówku komunikatu REST token JWT, zdekodować, zweryfikować podpis i zintegrować otrzymane uprawnienia ze Spring Security
- Integracja z bazą danych-baza potrzebna do przechowywania informacji o zarejestrowanych urządzeniachi ich pozycjach. Początkowo system oparłem o nierelacyjną bazę Apache Cassandra. Niestety docelowy system uruchomiłem na tanim serwerze VPS z 4GB pamięci RAM i ponad połowę pamięci musiałem przeznaczyć na Cassandrę. Zmusiło mnie to do implementacji opartej na Postgresie.
- REST API + Swagger – do komunikacji między frontem, a backendem użyłem najpopularniejszego rozwiązania, czyli REST API i do prezentacji api Swagger-a. Komunikację opartą o RESTAPI wykorzystałem też w aplikacji trakera napisanej na Android oraz w dedykowanym lokalizatorze sprzętowym opartym na Arduino.
- Aby obsłużyć lokalizatory dostępne na rynku zgodne z TK-102 i TK-103 musiałem wystawić dodatkowy port obsługujący komunikację opartą na TCP/IP.
- Serwer autoryzacji
- Postanowiłem w projekcie użyć gotowego serwera autoryzacji. Wybór padł na bardzo szybko rozwijający się Keycloak. Można pobrać kompletną wersję zintegrowaną z serwerem aplikacyjnym Wildfly. Twórcy serwera dostarczyli szereg bibliotek i przykładów pozwalających na szybką integrację z większością frameworków, w tym ze SpringBoot i Angular. Użycie autoryzacji we frameworkach SpringBoot i Angular sprowadza się do importu odpowiednich bibliotek i dodaniu kilku parametrów konfiguracyjnych.
Lokalizatory
Założyłem wsparcie dla urządzeń:
- własna prosta aplikacja na Androida
- obsługa najpopularniejszych tanich lokalizatorów
- zbudowanie własnego lokalizatora
Lokalizator – aplikacja na Androida
Aplikacja w założeniu jest dosyć prosta, po uruchomieniu subskrybuje się podsystemowe powiadomienia o zmianie pozycji GPS. Po otrzymaniu nowej pozycji przygotowywany jest odpowiedni JSON, który jest wysyłany przez REST API na serwer. Połączenie jest szyfrowane protokołem HTTPS. Jako identyfikator urządzenia wykorzystywany jest numer IMEI. Aby ułatwić parowanie aplikacji trakera z kontem użytkownika dodałem do aplikacji na Androidzie ekran logowania przy pierwszym uruchomieniu. Użytkownik podając prawidłowy login i hasło autoryzuje się w oparciu o Keycloak, następnie dyskopując tokenem JWT przekazuje numer IMEI do serwera, gdzie następuje powiązanie numeru IMEI posiadanego urządzenia z kontem zalogowanego użytkownika.
Lokalizatory TK-102 i TK-103
W wielu sytuacjach chcielibyśmy użyć gotowych małych i możliwie tanich urządzeń np. do śledzenia pozycji własnego samochodu. Na rynku są dostępne tanie lokalizatory TK-102 i TK-103 oraz ich klony. Wszystkie obsługują sprawdzanie pozycji przez wymianę informacji przez SMS-y, niestety nie wszystkie klony działają w trybie GPRS i nie wszystkie obsługują wysyłanie informacji o położeniu na konfigurowalny adres IP, a o tym sam się przekonałem podczas moich eksperymentów. Istotne z naszego punktu widzenia komunikaty wymagają odpowiedzi na odebrane dane przez TCP/IP. Z tego też powodu zwykły nasłuch przychodzących danych nie jest wystarczający do napisania logiki odbierającej dane GPS. Z pomocą przyszła mi dokumentacja krążąca po Internecie, jej jakość jest na tyle niska, że trudno nawet określić czy są to oficjalne dokumenty czy stworzone przez hobbystów. Posiłkowałem się też fragmentami innych aplikacji.
Lokalizator zbudowany według własnego projektu
Układ zbudowałem z kilku modułów:
- ArduinoNano – pełni rolę głównego kontrolera, pośredniczy w komunikacji między modułami GPS i GSM. Oprogramowanie piszemy w języku bazującym na C++ używając darmowego środowiska Arduino IDE.
- NEO-7M GPS – układ odbiornika sygnałów GPS, procesor dekodujący, układ udostępnia dane protokołem NMEA
- GSM SIM800L-układ pozwalający łączyć się z siecią GSM, posiada gniazdo na kartę SIM. Możliwa jest również komunikacja GPRS i wysłanie requestów HTTP i HTTPS. Dokomunikacji z układem również wykorzystujemy port szeregowy, przez który komunikujemy się używając komend SIM800 AT.
Zasada działania układu jest następująca. Arduino nasłuchujek omunikatów NMEA zawierających pozycje GPS, tj. dokładnie oczekuje komunikatu GGA. Po jego otrzymaniu następuje rozkodowanie długości, szerokości geograficznej i kilku dodatkowych informacji. Następnie na bazie tych informacji tworzony jest odpowiedni JSON, który jest wysyłany przez łącze szeregowe komendami AT do modułu GSM. Który przez sieć komórkową przekazuje request do mojego serwera. Oczywiście taka aplikacja może dopiero służyć za bazę bardziej złożonych rozwiązań.

Źródła:
- https://start.spring.io/
- https://angular.io/
- https://www.keycloak.org/
- https://store.arduino.cc/arduino-nano
- https://www.arduino.cc/en/software
- https://www.999gps.org/Manual_en.html
- https://en.wikipedia.org/wiki/NMEA_0183
- https://www.elecrow.com/wiki/images/2/20/SIM800_Series_AT_Command_Manual_V1.09.pdf