Skip to main content

Komunikacja Pythona z PLC wygląda prosto tylko do momentu, w którym musisz wybrać, jak Python ma odpytać sterownik. REST, JSON-RPC czy gRPC? Trzy style, ten sam efekt (odczyt jednej zmiennej ze sterownika), ale trzy zupełnie różne wywołania na kablu.

W tym wpisie rozkładamy je na części na żywym przykładzie: czytamy współczynnik OEE bieżącej zmiany ze sterownika Siemens S7-1200 G2 oraz Phoenix PLCnext. Po drodze odpowiadamy na pytanie, które wraca przy każdym szkoleniu: czy Web API w S7-1200 G2 to to samo co JSON API?

Ten sam odczyt, trzy sposoby

Załóżmy, że w programie sterownika mamy blok danych OEE_Data, a w nim zmienną LastShift.rOEE. Chcemy w Pythonie dostać jedną liczbę:

"OEE_Data".LastShift.rOEE    =    84.72 %

Ten sam odczyt możemy zrealizować na trzy sposoby. Różnią się filozofią, nie wynikiem:

  • REST – „daj mi ZASÓB”: cel siedzi w adresie URL, akcją jest czasownik HTTP (GET, PUT).
  • JSON-RPC – „WYKONAJ funkcję”: jeden adres, a akcję podajesz w treści (pole method).
  • gRPC – też „WYKONAJ funkcję”, ale binarnie i po HTTP/2.

Styl 1: REST, czyli zorientowany na zasób

W REST każda rzecz to zasób z własnym adresem (np. /api/variables), a to, co z nim robisz, określa czasownik HTTP: GET (czytaj), PUT (zapisz). Dane lecą w JSON, czytelne gołym okiem. Ten styl wykorzystuje Web API w Phoenix PLCnext – pokazujemy go szerzej w poradniku o programowaniu sterowników PLCnext.

# PLCnext _pxc_api (REST) - "daj mi ZASOB"
r = requests.get(".../api/variables",
                 params={"paths": "...rOEE"})
print(r.json()["variables"][0]["value"])
# -> 84.72

# na kablu:
GET /api/variables?paths=...rOEE   (akcja = czasownik HTTP + adres zasobu)

Styl 2: JSON-RPC, czyli Siemens S7-1200 G2 Web API

Siemens w S7-1200 G2 poszedł w JSON-RPC 2.0. Tu nie ma wielu adresów – zawsze robisz POST na jeden endpoint /api/jsonrpc, a akcję wybierasz polem method (np. PlcProgram.Read), argumenty wkładasz do params, a odpowiedź wraca w result albo error.

Najpierw musisz się zalogować metodą Api.Login – sterownik oddaje token, który dokładasz do każdego kolejnego żądania w nagłówku X-Auth-Token:

# 1) logowanie -> token
login = {"id": 1, "jsonrpc": "2.0", "method": "Api.Login",
         "params": {"user": "HMI_access", "password": "********"}}
token = requests.post(URL, json=login, verify=False).json()["result"]["token"]

Mając token, odczyt zmiennej to jeden POST:

# Siemens S7-1200 G2 Web API (JSON-RPC 2.0 po HTTPS)
msg = {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "PlcProgram.Read",                 # akcja = nazwa funkcji
    "params": {"var": '"OEE_Data".LastShift.rOEE',
               "mode": "simple"},
}
r = requests.post("https://192.168.0.3/api/jsonrpc",
                  json=msg,
                  headers={"X-Auth-Token": token},
                  verify=False)                   # PLC ma self-signed cert
print(r.json()["result"])   # -> 84.72

# na kablu:
POST /api/jsonrpc   (jeden adres, akcja w tresci)

Po stronie sterownika musisz w TIA Portal włączyć serwer WWW i Web API oraz nadać użytkownikowi prawa odczytu i zapisu zmiennych. Pełną listę metod znajdziesz w Siemens Industry Online Support.

S7-1200 G2 Web API – czy to to samo co JSON API?

Krótko: i tak, i nie. „JSON API” to potoczna nazwa każdego interfejsu, który przyjmuje i zwraca JSON po HTTP. W tym sensie Web API S7-1200 G2 jest JSON API – rozmawiasz z nim zwykłymi requestami HTTPS, a treść to JSON.

Ale technicznie to konkretny protokół: JSON-RPC 2.0, a nie REST-owe „JSON API”. Różnica jest praktyczna i łatwo się o nią potknąć:

  • REST (JSON API): różne adresy URL (rzeczowniki), akcja to czasownik HTTP. Czytasz zasób: GET /variables/....
  • Siemens Web API (JSON-RPC): jeden adres /api/jsonrpc, akcja siedzi w polu method w treści. Czytasz wywołując funkcję: PlcProgram.Read.
  • W JSON-RPC zawsze POST – nawet gdy tylko czytasz. GET-em niczego tu nie odczytasz.
  • Każda wiadomość ma sztywny szkielet: jsonrpc: 2.0, method, params, id.

Wniosek dla praktyka: jeśli szukasz w sieci „Siemens REST API”, będziesz rozczarowany. Szukaj „S7-1200 Web API JSON-RPC” i traktuj to jak wywoływanie funkcji (login, read, write, logout), a nie pobieranie adresów URL.

Styl 3: gRPC, czyli kontrakt i kod binarny

gRPC też „wykonuje funkcję”, ale inaczej niż JSON-RPC. Najpierw definiujesz kontrakt w pliku .proto (typy i usługi), generujesz z niego kod (stuby), a dane lecą w Protocol Buffers – format binarny po HTTP/2. Nieczytelne gołym okiem, za to szybkie i z gotowym kontraktem typów.

// kontrakt .proto (typy + uslugi)
service PlcData {
  rpc ReadTag(Req) returns (Reply);
}
message Reply { double value = 1; }

# Python (po wygenerowaniu stubow)
reply = stub.ReadTag(Req(var="...rOEE"))
print(reply.value)   # -> 84.72
# na kablu: HTTP/2 + binarny protobuf

REST vs JSON-RPC vs gRPC – różnice

Jeśli masz zapamiętać jedno zdanie: REST mówi „daj mi ZASÓB”, a RPC (JSON-RPC i gRPC) mówi „WYKONAJ FUNKCJĘ”. Różnica między JSON-RPC a gRPC to z kolei tekst po HTTP kontra format binarny po HTTP/2.

  • REST – wiele adresów, czasowniki HTTP, JSON tekstowy. Łatwy do podejrzenia i debugowania.
  • JSON-RPC – jeden adres, akcja w treści, JSON tekstowy. Tak działa Siemens Web API.
  • gRPC – kontrakt .proto, binarny protobuf, HTTP/2. Najszybszy, ale wymaga generowania kodu.

W naszym projekcie wygląda to tak: Siemens S7-1200 G2 to JSON-RPC, Phoenix PLCnext to REST. Kiedy co wybrać? REST i JSON-RPC do integracji IT, weba i chmury (przechodzą przez firewall na porcie 443). gRPC do szybkiej, binarnej wymiany między usługami. Podobne podejście do danych przemysłowych pokazujemy we wpisie o Industry 4.0 na PLCnext (OPC UA, MQTT, Node-RED, Python).

A jeśli nie chcę Web API? snap7 i natywny protokół S7

Web API to nie jedyna droga do Siemensa. Biblioteka python-snap7 gada ze sterownikiem natywnym protokołem S7 (port 102) – bez logowania tokenem, za to z surowymi bajtami, które sam dekodujesz po offsetach z bloku danych:

import snap7
from snap7.util import get_real

plc = snap7.client.Client()
plc.connect("192.168.0.3", 0, 1)   # IP, rack, slot
data = plc.db_read(1, 0, 4)        # DB1, offset 0, 4 bajty
print(get_real(data, 0))           # -> 84.72

Wymaga to włączonej komunikacji PUT/GET w CPU i bloku danych ze standardowym (nie zoptymalizowanym) dostępem – inaczej offsety bajtów nie będą się zgadzać. snap7 jest świetny do szybkich odczytów blokowych, a Web API do integracji webowych i przejścia przez firewall.

Najczęstsze problemy (i jak je rozwiązać)

  • SSLError / certyfikat – S7-1200 G2 ma self-signed cert. W teście użyj verify=False, a docelowo dodaj certyfikat do zaufanych.
  • HTTP 403 / brak uprawnień – użytkownik Web API nie ma praw „Read tags” / „Write tags”. Sprawdź konfigurację użytkownika w TIA Portal.
  • Token wygasł – po bezczynności sterownik unieważnia token. Zaloguj się ponownie metodą Api.Login.
  • Nazwa zmiennej – nazwa bloku danych w cudzysłowie, człony łączone kropką. Literówka kończy się polem error w odpowiedzi.
  • snap7: złe wartości – blok danych jest zoptymalizowany albo zły offset bajtu. Przełącz DB na dostęp standardowy i sprawdź offsety w TIA.

Najczęstsze pytania (FAQ)

Czy Web API w S7-1200 G2 to REST?

Nie. To JSON-RPC 2.0 – jeden endpoint /api/jsonrpc i akcja w polu method. JSON lecący po HTTP myli się z REST, ale to inny styl.

Czy potrzebuję loginu i hasła do odczytu?

Tak. Najpierw Api.Login zwraca token, który dokładasz w nagłówku X-Auth-Token do każdego żądania, a na koniec wołasz Api.Logout.

Web API czy snap7 do Siemensa?

Web API – gdy potrzebujesz integracji webowej, HTTPS i przejścia przez firewall. snap7 – gdy chcesz szybki natywny odczyt bloków danych w sieci lokalnej.

Który styl jest najszybszy?

gRPC (binarny protobuf po HTTP/2). REST i JSON-RPC są wolniejsze, ale prostsze do debugowania i bardziej uniwersalne.

Podsumowanie

Komunikacja Pythona z PLC sprowadza się do jednego wyboru: zasób czy funkcja. REST pobiera zasób, JSON-RPC i gRPC wywołują funkcję. Siemens S7-1200 G2 stawia na JSON-RPC (Web API), Phoenix PLCnext na REST, a gRPC zostaje do szybkiej, binarnej wymiany między usługami. Znając te trzy style, podłączysz Pythona do niemal każdego sterownika.

Chcesz przerobić to na żywym sterowniku i napisać własny raport OEE w Pythonie? Zajrzyj do naszych kursów PLC i automatyki: https://www.controlbyte.pl/python-od-podstaw/

O autorze

Kamil Biedulski

Author Kamil Biedulski

Automatyk i programista, CTO w ControlByte

Więcej postów tego autora Kamil Biedulski