O API! Cz. 1
Oprogramowanie IIoT bez wchodzenia w świat OT – wyspy I/O
W poniższym wpisie chciałbym spojrzeć szerzej na kwestie IIoT oraz tym samym rozpocząć serię przeznaczoną zarówno dla twórców, jak i użytkowników oprogramowania w systemach IIoT. Tematyka może być szczególnie interesująca dla software house’ów z ambicją wejścia na rynek IIoT, ale także dla firm powiązanych z przemysłem, które uważają, że dedykowane rozwiązania są kluczem do sukcesu.
Niezależnie od tego, po której stronie stoisz, zapraszam do lektury niniejszego wpisu!
Jakiś czas temu trafiłem na ciekawy artykuł nt. outsourcingu w branży IT [1]. Oczywiście samo zjawisko od dawna nikogo już nie zaskakuje; coroczny wzrost w wyborze zewnętrznych dostawców oprogramowania tylko to potwierdza. Co ciekawe, w badaniu przeprowadzonym przez Deloitte w 2020 roku, w 70% takich przypadków kluczowym aspektem jest zmniejszenie kosztów wytworzenia oprogramowania. Następnie zostały wymienione takie kwestie, jak elastyczność czy szybkość wdrożenia rozwiązania.
Badania przeprowadzone przez Deloitte w 2020 roku pokazują zalety woboru outsourcing'u.[1]
Jednak nie każda organizacja chce i może pozwolić sobie na taki ruch. Widoczne jest to szczególnie w przemyśle, gdzie obsługiwane procesy bywają krytyczne z punktu widzenia produkcji czy świadczonych usług. W takich miejscach spotkamy też restrykcyjne wymogi dotyczące prywatności i bezpieczeństwa systemu. Ponadto reakcja w przypadku awarii musi być szybka i pewna.
Dlatego pojawia się pytanie: czy oddelegować tworzenie całego systemu firmie zewnętrznej czy może próbować to zrobić na własną rękę?
A może zastosować jakiś kompromis?
Wpis ten skierowany jest głównie do osób, którym automatyka, porty szeregowe czy konwersja protokołów nie mówi zbyt wiele, natomiast JavaScript, Python, Coud Services czy REST API… czyli główny temat wpisu, owszem. Zacznijmy jednak, z myślą osobach, które może nie miały okazji zaznajomić się jeszcze z tą technologią i króciutko omówmy podstawowe definicje.
Czym jest REST API?
Jeśli znasz już to pojęcie, możesz spokojnie przeskrolować do następnego rozdziału, jednak jeśli jest dla Ciebie nowe lub chciałbyś odświeżyć tę wiedzę, zacznijmy od wyjaśnienia.
API (z ang. Application Programming Interface), czyli Interfejs Programistyczny Aplikacji jest niczym innym jak zestawem reguł definiujących sposób, w jaki aplikacje czy urządzenia mogą się ze sobą komunikować.
REST (z ang. REpresentational State Transfer) jest stylem architektonicznym, który zakłada:
- komunikację klient <-> serwer (pytanie <-> odpowiedź)
- bezstanowość – serwer nie musi przechowywać żądnych parametrów w pamięci, aby odpowiedzieć na otrzymanie zapytanie od klienta. Wszystkie potrzebne parametry powinny być zamieszczone w pytaniu od klienta.
- identyfikacja zasobów przez URL – interfejs udostępniający zasoby powinny być identyfikowane poprzez adresy URL (konkretny punkt dostępowy do zasobu to tzw. Endpoint).
Połączenie obu haseł, daje tzw. RESTful API, co narzuca pewien standard w dostępie do naszej aplikacji i definiuje to, jak możemy z niej skorzystać. Informacje przesyłane pomiędzy klientem a serwerem zazwyczaj przyjmują format JSON lub XML. Często też RESTful API wiąże się z protokołem HTTP.
Protokół HTTP udostępnia szereg metod, takich jak:
- GET – pobieranie zasobu
- POST – tworzenie nowego zasobu
- PUT – aktualizowanie istniejącego zasobu
- DELETE – usuwanie zasobu
- PATCH – częściowe aktualizowanie zasobu
To tylko podstawowe metody, najczęściej spotykane. Ale na tym poziomie się zatrzymajmy. W sieci jest mnóstwo wpisów i video na temat REST API oraz HTTP, dlatego zainteresowanych odsyłam do wujka Google ;)
Do czego przydaje się RESTFUL API w projektach IIoT?
Komunikacja, a w zasadzie jej brak, spędzała sen z powiek podczas wielu wdrożeń systemu i testowała cierpliwość niejednego inżyniera. W sieciach OT (ang. Operational Technology), czyli wszelkich „sieciach automatyki”, często możemy spotkać podziały, od różnych mediów transmisyjnych (np. świtało, miedź) po różne protokoły i standardy komunikacyjne. Branża przemysłowa pracowała i dalej pracuje nad wspólnym standardem, który uprościłby komunikację, ale póki co wygląda to jak wygląda…
Dziś głównym standardem jest Ethernet, który przy nowotworzonych projektach z reguły bywa pierwszym wyborem. W starszych systemach niejednokrotnie można spotkać standardy RS-232/485, ze względu na urządzenia, które komunikowały się głównie w ten sposób, ale czasem taki wybór bywa kwestią bezpieczeństwa. Okazuje się, że nieco trudniej o cyberatak w komunikacji szeregowej, dlatego w przypadku przesyłania lekkich, ale istotnych danych, jak np. klucze dostępowe, czasami wybierane są jeszcze standardy szeregowe. Ale jest to stosunkowo rzadki wybór i możemy to raczej uznać za ciekawostkę.
Najważniejszym celem w komunikacji jest po prostu wymiana danych pomiędzy urządzeniami. Jak i z pomocą jakich protokołów jest ona realizowana, jest już kwestią wyboru. Natomiast tworząc aplikację pod system IIoT zależy nam na tym, aby przejść już na standardy bliższe IT. A tutaj RESTful API nie trzeba już nikomu przedstawiać...
Wyzwania rzucane przez sieci OT
Wykonując projekt od A do Z nie unikniemy zejścia do samego źródła, z którego pobieramy parametry lub je zadajemy (np. gdy chcemy coś wysterować). Często spotkamy się tam z sygnałami cyfrowymi/analogowymi, czujnikami temperatury, urządzeniami komunikującymi się po portach RS (np. w protokole Modbus RTU), jak również po standardach Ethernet (np. w protokole Modbus TCP).
Stosowanie danych protokołów jest zależne również od branży.
W energetyce standardem są protokoły DNP3, IEC 61850, IEC 60870-5-101, IEC 60870-5-104, które określają, jak można komunikować się w obrębie stacji energetycznych. W systemach biurowych, czyli popularnych BMS’ach, króluje BACnet. Na liniach produkcyjnych często spotykamy PROFIBUS/PROFINET, czyli standardy narzucone głównie przez sterowniki Siemensa.
Aby ujednolicić między sobą różne standardy, stosuje się konwertery protokołów, np. takie jak rodzina MGate od Moxa — odsyłam do małej ściągi.
Jak wygląda dostęp do wysp I/O przez API?
Skoro omówiliśmy to, czym jest REST API, dlaczego może nam się przydać w IIoT (i z czym przychodzi się mierzyć po stronie OT) przejdźmy do clou.
Czego możemy użyć, aby otrzymać dostęp do OT za pomocą REST API?
Skupię się na rozwiązaniach Moxa, która ma swoje propozycje w tym zakresie.
Gdy przyjdzie nam obsłużyć sygnały wejść/wyjść cyfrowych/analogowych, możemy skorzystać z wysp I/O z rodziny ioLogik lub bardziej zaawansowanej serii o nazwie ioThinx.
Wyspa ioLogik (po lewej) oraz ioThinx (po prawej).
Wyspa pozwala na odczyt konfiguracji oraz rejestrów wejść/wyjść. Spójrzmy, jak to wygląda w praktyce.
W pierwszym kroku należy upewnić się, czy mamy włączoną obsługę RESTful API na urządzeniu. Konfigurację przeprowadzimy przez Web Server, dostępny po wpisaniu adresu IP do przeglądarki.
Web serwer wyspy ioLogik
Do wysyłania zapytań http wykorzystamy popularnego Postmana i z jego poziomu potestujemy API. Od razu warto umieścić tu link do dokumentacji ioLogik, gdzie znajdziemy tabelkę z możliwościami API.
Uwaga: Przy tworzeniu zapytań http musimy pamiętać o dodaniu dwóch nagłówków (headers):
Accept: vdn.dac.v1
Content-Type: application/json
IoLogik zwraca odpowiedzi w formacie JSON, co jest łatwe w odczycie i wygodne z punktu widzenia dalszej analizy danych.
Rzućmy jeszcze okiem na dokumentację API i zauważmy, że część atrybutów jest tylko do odczytu, a część z nich możemy również nadpisać.
Fragment dokumentacji API wyspy ioLogik
Teraz sprawdźmy, jak wygląda odczyt np. wyjść cyfrowych (DigitalOutput) poprzez API. Ja korzystam aktualnie z modelu ioLogik E1242, który ma 4 wyjścia cyfrowe. Dlatego odpowiedź pokazuje stan czterech wyjść cyfrowych (pierwsze wyjście ma status 1, co oznacza, że jest „załączone”).
No dobrze, a jak nadpisać stan wyjścia przez API?
Powinniśmy wysłać zapytanie typu PUT, aby edytować aktualny stan.
Tylko co wpisać w polu „Body”?
Tutaj najprostszym sposobem jest wysłanie najpierw zapytanie GET, aby otrzymać odpowiedź, a następnie przekopiować całego JSON’a do Body dla zapytania PUT. Zmieńmy tylko wartości w odpowiednich polach, na takie jakie chcemy ustawić i możemy wysłać zapytanie, czekając na otrzymanie statusu 200 ;) (po więcej informacji o kodach odpowiedzi http odsyłam na tutaj). W dokumentacji REST API ioLogika znajdziemy też listę błędów, którą możemy się posiłkować, jeśli coś pójdzie nie tak.
Zapytanie typu GET na endpoint /api/slot/0/io/do
Zapytanie typu PUT na endpoint /api/slot/0/io/do
Kończąc już wątek ioLogik, załączam notkę producenta Moxa w temacie RESTful API, w którym możemy znaleźć przykładowe implementacje funkcji w JavaScript oraz krótkie porównanie komunikacji po RESTful API a MQTT. W tym wpisie nie będziemy poruszać tego tematu, dlatego zainteresowanych odsyłam do materiału źródłowego.
Przejdziemy teraz do bardziej rozbudowanej wyspy I/O z oferty Moxa, czyli ioThinx – modelu ioThinx 4510. Od strony użytkowej można do niego dołożyć do 32 modułów wejść/wyjść, co daje nam całkiem potężny zestaw. Przejrzysta web konsola, również robi dobre wrażenie i pomaga w pracy. Po więcej informacji technicznych odsyłam na stronę modelu.
My tymczasem wróćmy do API.
Tak jak w poprzednim przypadku dokumentację API znajdziemy w manual’u urządzenia. I tutaj również musimy uruchomić obsługę REST API przez web konsolę na urządzeniu.
Fragment dokumentacji API wyspy ioThinx
Samo wykorzystanie API nie różni się zbyt wiele od tego z ioLogik. Z racji większych możliwości urządzenia mamy po prostu więcej endpoint’ów.
Uwaga: Przy tworzeniu zapytań http (szczególnie PUT) na ioThinx musimy pamiętać o dodaniu dodatkowego nagłówka Content-Length:
Accept: vdn.dac.v2
Content-Type: application/json
Content-Length: <calculated when request is sent>
Tym, co zasługuje na uwagę, jest parametr {ioName}, który występuje w większości endpoint’ów. Składa się on z „NazwyModułu + @ + NazwaKanału”. A więc: gdy przykładowy moduł nazywa się “45MR-1600-0” i konkretne wejście ma nazwę “DI-00” to {ioName} = 45MR-1600-0@DI-00.
Kilka słów o cyberbezpieczeństwie…
Na koniec chciałbym odnieść się do bardzo ważnej kwestii, jaką jest bezpieczeństwo naszego systemu. Jak być może zauważyłeś, korzystanie z API nie wymaga wcześniejszego uwierzytelnienia użytkownika. Oznacza to, że każdy, kto ma lub będzie miał dostęp sieciowy do urządzenia, może mieć wpływ na stan wejść/wyjść. Konsekwencje takiego stanu rzeczy mogą być groźne…
Dlatego włączając RESTful API na urządzeniu musimy mieć pewność, że nikt niepowołany nie otrzyma dostępu do sieci. Zalecałbym w tym wypadku wyposażyć sieć w firewall’a, tunel VPN, system IPS/IDS lub inne mechanizmy, które zapewnią, że wyspa I/O nie wpadnie w niepowołane ręce.
Wykorzystać też można gateway z rodziny UC z API ThingsPro Edge, który po połączeniu pozwali na odczyt danych z ioLogik i ioThinx, ale tylko po przejściu uwierzytelnienia. ThingsPro Edge ma o wiele więcej mechanizmów bezpieczeństwa, które zasługują na uwagę, lecz temu poświęcę kolejny wpis.
Niemniej wszystkich zainteresowanych odsyłam do wpisów (podpiętych poniżej), w których poruszyłem temat wykorzystania komputerów UC w architekturze Edge Computing, oraz dokumentacji samego ThingsPro Edge.
Źródła:
[1] https://intersog.com/blog/software-development-outsourcing-statistics/
Skontaktuj się ze specjalistą Elmark
Masz pytania? Potrzebujesz porady? Zadzwoń lub napisz do nas!