Integracja urządzeń z chmurą w IoT

Internet Rzeczy (IoT – Internet of Things) wnosi niespotykany dotąd poziom inteligencji do wbudowanych systemów sterowania. Urządzenia, które dawniej były od siebie odizolowane, dzięki IoT są ze sobą łączone, tworząc systemy systemów. To sprawia, że urządzenia mogą ze sobą współpracować i wchodzić w interakcje z innymi usługami, by zaoferować użytkownikom znacznie lepsze możliwości, lepsze reakcje i sprawniej działać przez dłuższy czas.

Użytkownicy mogą wykorzystać ogromną moc obliczeniową, dostępną w chmurze, by zaimplementować algorytmy uczenia maszynowego, wydobywania danych i inne technologie przetwarzające strumienie danych pochodzących z urządzeń IoT, które składają się na aplikację. Te urządzenia nie musza być nawet zaprojektowane specjalnie pod kątem konkretnej aplikacji. Systemy działające w chmurze mogą skorzystać z takich technologii przetwarzania danych, jak Spark czy Hadoop, by w obsługiwać informacje nadchodzące w czasie rzeczywistym i dane historyczne, pochodzące z różnych źródeł. To sprawia, że możliwe jest wyszukiwanie korelacji pomiędzy wieloma źródłami i na tej podstawie wyciąganie wartościowej wiedzy. Przy tak dużej mocy, złożoność wydaje się nieunikniona.

Kluczowym problemem podczas przygotowywania aplikacji IoT jest różnorodność komponentów, które składają się na każde rozwiązanie. Aplikacja IoT wymaga zbierania odczytów z różnych typów sensorów, takich jak czujniki temperatury, ruchu czy jakości powietrza. Nawet dla odczytów tego samego typu medium, dane mogą nadchodzić z urządzeń różnych producentów, lub bazujących na starszym sprzęcie, który nie był zaprojektowany pod kątem IoT.

Weźmy na przykład projekt IoT, w którym prowadzone jest monitorowanie temperatury wewnątrz każdego pokoju w hotelu. Każdy pokój mógłby być wyposażony w trzy czujniki temperatury. Jeden przy drzwiach, stanowiący część modułu alarmującego w przypadku pożaru. Drugi bliżej łóżka, powiązany ze sterownikiem klimatyzacji. Trzeci w łazience, zainstalowany oddzielnie, specjalnie pod kątem IoT.

Oprogramowanie, które pozyskuje dane z każdego z tych urządzeń musi uwzględniać sposób, w jaki każdy z sensorów jest skalibrowany i jak mierzy temperaturę. Niektóre urządzenia przesyłają dane w regularnych odstępach czasu, inne w momencie, gdy zajdzie zmiana, która wykroczy poza zadaną wartość graniczną, a jeszcze inne dokonują pomiaru na żądanie, wtedy gdy po dane zgłosi się aplikacja pracująca w chmurze. I każde z tych urządzeń może korzystać z innego interfejsu sieciowego – niektóre mogą pracować bezprzewodowo, a inne np. za pośrednictwem takiego interfejsu jak Bluetooth lub ZigBee. Aplikacja musi wziąć pod uwagę całą tę różnorodność. Ale to nie wszystko.

Pobór energii to podstawowy problem w wielu urządzeniach IoT. Najbardziej popularnym sposobem na uzyskanie długiego czasu pracy urządzenia na baterii jest minimalizacja czasu działania podsystemów pobierających najwięcej prądu, takich jak komunikacja bezprzewodowa i rdzeń głównego mikroprocesora. Dlatego utrzymuje się je w trybie uśpienia, przy bardzo niskim poborze mocy, przez większość czasu życia systemu. Budzi się je tylko na krótkie okresy, kiedy to wykonują zadania, by znów przejść w stan uśpienia. W rezultacie czas aktywnej pracy urządzenia jest niski. W praktyce może być tak, że nie więcej niż 1% czasu system spędza w trybie pełnego wybudzenia i dużego poboru mocy. Przez pozostałe 99% zasilane są jedynie podsystemy potrzebne do podtrzymania stanu urządzenia, takie jak zegary czasu rzeczywistego. Dzięki takiemu projektowi, węzeł IoT może przetrwać przez całe lata na tej samej baterii.

Wiele mikrokontrolerów (MCU) zawiera obecnie wbudowane, sprzętowe maszyny stanów, które pozwalają wzbudzać ważne czujniki co jakiś czas, w oparciu o dane z podsystemu zegara czasu rzeczywistego i umożliwiające dokonywanie odczytów bez budzenia głównego mikroprocesora. Niektóre z systemów mogą też wykonać z góry określony zestaw odczytów, zanim mikroprocesor zostanie obudzony celem przetworzenia zebranych danych. Inne mogą mieć zaprogramowane wartości graniczne, dzięki czemu skrajne wartości odczytów powodują natychmiastową reakcję układu.

Aplikacja sterująca, pracująca w chmurze, może wysyłać żądania danych, które chce pobrać z urządzenia lub przesyłać polecenia urządzeniom by te zmieniły swój stan. Ale urządzenie może nie odpowiadać przez jakiś czas, co często wynika z trybu pracy, narzucającego pozostawanie w uśpieniu przez długi okres, a więc i w momencie, gdy nadejdzie polecenie. Dlatego w aplikacji musi być zaimplementowana odpowiednia logika, by mieć pewność, że stan urządzenia jest poprawnie rozumiany i zgodny z rzeczywistością.

Na początku rozwoju IoT, integratorzy systemów odkryli, że muszą stworzyć własną infrastrukturę programową do połączenia ze sobą urządzeń w chmurze, przy wykorzystaniu własnych protokołów lub technik zdalnych wywołań procedur (RPC – Remote Procedure Call). Zazwyczaj korzystali z własnych centrów danych lub wynajmowali fizyczne, zdalne serwery, na których uruchamiali aplikacje. Programy te odbierały dane z podłączonych urządzeń wbudowanych, przesyłały informacje do centralnej bazy danych oraz to na nich pracowały aplikacje, które pozwalały prezentować dane użytkownikom na potrzeby analizy.

Integratorzy byli odpowiedzialni za zapewnienie niezawodności i ciągłości pracy systemu i musieli radzić sobie ze złożonością środowiska, w którym urządzenia nie są stale podłączone do sieci. Jednym ze sposobów osiągnięcia tego celu jest skorzystanie z tzw. cieni urządzeń (device shadows). Są to przechowywane w chmurze pliki, które zawierają informacje na temat stanu urządzenia, pochodzące z ostatniego odczytu i uwzględniające wszelkie zmiany, jakie powinny zajść od tego czasu.

O ile aplikacje mogą samodzielnie zarządzać cieniami urządzeń, zadaniem tym jest znacznie łatwiej zarządzać, jeśli przeniesie się je do warstwy serwerowej, która może oferować zestandaryzowany interfejs dla różnych typów urządzeń. Obecnie jest to jedna z funkcji realizowanych przez infrastrukturę chmurową w ramach takich usług jak Amazon Web Services, IBM Watson IoT i Google Cloud.

Inną usługą realizowaną przez platformy chmurowe jest mapowanie protokołów. Chmura wyewoluowała wokół popularności protokołu TCP/IP i usług na nim opartych. O ile jest to protokół bezstanowy, sam HTTP (HyperText Transport Protocol), wykorzystywany w wielu usługach sieciowych, pracuje na przygotowanej pod kątem pracy ze stanami warstwie TCP, co też wynika głównie z szerokiej dostępności TCP. Jednakże niewiele urządzeń IoT ma odpowiednie zasoby, by zaimplementować pełny stos protokołu TCP/IP, a więc by umożliwić bezpośrednią komunikację z aplikacją w chmurze. Organizacja IETF (Internet Engineering Task Force) zdefiniowała więc protokół CoAP (Constrained Application Protocol), który jest uproszczoną postacią HTTP, tak by mogła ona lepiej działać na urządzeniach o ograniczonych zasobach i by nie trzeba było korzystać z warstwy TCP.

CoAP korzysta z 4-bajtowego nagłówka i kodowania, które pozwalają lepiej pracować z pakietami danych o krótszej długości. Popularną alternatywą dla CoAP, która również dobrze sprawdza się w IoT jest MQTT (Message Queueing Telementry Transport) – protokół, który został opracowany przez firmę IBM. Może on być używany w różnych sieciach, czy to Bluetooth, czy ZigBee, czy też w TCP/IP. W odróżnieniu od tradycyjnego modelu komunikacji klient-serwer, jaki występuje w HTTP, MQTT korzysta z modelu publikacja-subskrypcja. Minimalizuje to liczbę indywidualnych żądań, wysyłanych do urządzeń IoT.

Bramka mapująca ruch MQTT i CoAP

Ilustracja 1: Bramka mapująca ruch MQTT i CoAP – źródło: Premier Farnell

Przykład działania modelu publikacja-subskrypcja w protokole MQTT

Ilustracja 2: Przykład działania modelu publikacja-subskrypcja w protokole MQTT – źródło: Premier Farnell

Aby zapewnić spójność danych transmitowanych pomiędzy różnymi platformami, w platformach chmurowych stosuje się format JSON (JavaScript Object Notation). By przesyłać dane do chmury, urządzenie musi najpierw zakodować je do postaci JSON, a następnie przesłać je jako treść wiadomości CoAP, HTTP lub MQTT. Osoby wykonujące implementację mają wybór: czy urządzenia końcowe powinny wykonywać tę operację samodzielnie, czy polegać na bramkach. W systemach, w których jest dużo starego sprzętu, bramka będzie często preferowanym wyborem. Bramka może zbierać dane za pomocą własnościowych lub starszych standardów, zgodnych z określonymi urządzeniami, a następnie konwertować informacje na format JSON, równocześnie pośrednicząc w przekazywaniu wszelkich komend z chmury. To na bramce będzie spoczywać zadanie zdecydowania, czy komendy te wymagają przekonwertowania i przekazania do urządzeń w zrozumiałej dla nich formie.

Urządzenia zaprojektowane pod kątem IoT mogą same mieć zaimplementowaną obsługę stosów programowych, odpowiadających za obsługę formatu JSON i interakcje z chmurą. Wsparcie dla JSONa i interfejsów sieciowych może być częścią rdzenia systemu czasu rzeczywistego (RTOS) i można z niego korzystać za pomocą języków programowania, takich jak C. Technika stosowana przez niektórych integratorów IoT i wspierana przez infrastrukturę dostawców usług chmurowych, polega na uruchomieniu maszyny wirtualnej na każdym urządzeniu, optymalnej pod kątem integracji z chmurą.

Przykład danych pochodzących z czujnika, przygotowanych w formacie JSON

Ilustracja 3: Przykład danych pochodzących z czujnika, przygotowanych w formacie JSON – źródło: Premier Farnell

Sterowniki urządzeń, zaimplementowane w każdej platformie IoT, służą do tłumaczenia komend z maszyny wirtualnej na postać, która będzie rozumiana przez uruchomione w sprzęcie firmware i RTOS. To firmware dba o optymalizację zużycia energii i niskopoziomowe regulowanie czasu pracy oraz zapewnia zestandaryzowany zestaw usług, do których odwoływać może się warstwa współpracująca z chmurą.

Praca w środowisku chmurowym wiąże się z dostępnością bogatszego zestawu narzędzi programistycznych, w porównaniu do pracy w tradycyjnym środowisku wbudowanym. Dziś języki używane do programowania w chmurze są projektowane tak, by działać w środowisku z kodem zarządzanym. Kod nie jest tak po prostu kompilowany, tylko interpretowany w trakcie działania lub – dla zapewnienia większej wydajności – kompilowany wtedy, gdy zaczyna być potrzebny. I o ile twórcy aplikacji wbudowanych zazwyczaj mają ograniczony wybór języków programowania, sprowadzający się głównie do C i C++, programiści aplikacji chmurowych mają dostęp do bogatego wyboru języków, z których wiele jest zoptymalizowanych pod kątem konkretnych potrzeb. I tak o ile Java i Python nadają się do wielu aplikacji, Hadoop rozszerza Javę by ułatwić przetwarzanie danych na wielu jednostkach obliczeniowych.

O ile zarówno programowanie systemów wbudowanych, jak i programowanie w chmurze, zakłada wykorzystanie różnych zasobów, twórcy piszący kod dla serwerów często mogą skorzystać z maszyn wirtualnych by móc stworzyć pomniejszoną wersję docelowego środowiska, zasymulowaną na własnych komputerach. Natomiast programiści systemów wbudowanych muszą tworzyć kod na komputerach, a następnie testować go na docelowych urządzeniach, ciągle przechodząc cykl: „edycja-kompilacja-wgranie”, co wydłuża czas tworzenia aplikacji. Środowiska pośrednie, które obsługują języki zarządzane, pozwalają przyspieszyć proces projektowania, umożliwiając prototypowanie kodu na lokalnej maszynie wirtualnej, a więc czyniąc pracę bardziej zbliżoną do tego, z czym mają do czynienia programiści aplikacji chmurowych.

Dzięki dostępności serwerów w chmurze, integratorzy mogą skorzystać z bogatego wyboru narzędzi, które czynią tworzenie kompletnych rozwiązań IoT znacznie łatwiejszym. Usługi chmurowe sięgają coraz głębiej w kierunku urządzeń, co sprawia że wdrażanie instalacji jest prostsze, a integratorzy mogą łatwiej wykorzystać moc IoT.

Integracja urządzeń z chmurą w IoT – Data publikacji: 4 września 2018 r. przez Farnell