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 polumethodw 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 protobufREST 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.72Wymaga 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
errorw 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)
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.
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 – gdy potrzebujesz integracji webowej, HTTPS i przejścia przez firewall. snap7 – gdy chcesz szybki natywny odczyt bloków danych w sieci lokalnej.
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/









