Autor tego dokumentu nie jest w jakikolwiek sposób powiązany z ZTM, a informacje służące do jego napisania zostały pozyskane przez analizę kodu wykorzystywanego przez stronę http://www.peka.poznan.pl/vm oraz pakietów wymienianych między serwerem i klientem podczas korzystania z niej.
Zapytanie wykonywane jest przez HTTP do hosta www.peka.poznan.pl i zasobu /vm/method.vm
, z parametrem ts
przekazywanym przez GET
i zawierającym wynik javascriptowej new Date().getTime()
. Content-Type
zapytania musi być ustawione na application/x-www-form-urlencoded; charset=UTF-8
, w przeciwnym razie znaki spoza standardowego zakresu ASCII nie będą działały poprawnie.
Wszystkie znaki kodowane są jako UTF-8.
Dane POST
zapytania instruują serwer odnośnie funkcji, którą ma on wykonać. Nazwa funkcji mieści się w parametrze method
, natomiast jej parametry jako JSON w p0
. Implementacja przepuszcza jeszcze to, co idzie do p0
przez Object.toJSON
, ale serwer nie zdaje się zwracać na to uwagi.
Wygląda na to, że serwer zawsze zwraca 200 OK, nawet gdy wywoła się funkcję, której nie posiada : jako wynik zapytania jest wtedy zwracany pusty JSON.
Podanie niepoprawnych parametrów do funkcji kończy się zwróceniem obiektu JSON zawierającego komunikat błędu w atrybucie failure
, np. :
{
"failure":"error: java.lang.reflect.InvocationTargetException"
}
Poprawne wywołanie funkcji kończy się przesłaniem obiektu zawierającego w sobie obiekt success
, którego znaczenie jest uzależnione od wywołanej funkcji. Obiekt ten jest pomijany w tym dokumencie w opisie wyjścia danej funkcji.
W przykładach wykorzystywana jest funkcja peka_vm_get
, której definicja w Bashu wygląda następująco :
peka_vm_get()
{
curl -H 'Content-Type:application/x-www-form-urlencoded; charset=UTF-8' \
http://www.peka.poznan.pl/vm/method.vm?ts=$(($(date +'%s') * 1000)) \
-d "method=$1" \
-d "p0=$2"
}
Jeśli parametr wejściowy jakiejś funkcji jest "wzorcem", należy go rozumieć jak wyszukiwanie z glob-gwiazdkami po obu stronach wzorca. Wielkość liter jest ignorowana. Powinno być to widoczne w przykładach.
getStopPoints
Pobiera listę przystanków o nazwie pasującej do zadanego wzorca.
pattern
- wzorzec, według którego serwer ma szukać przystanku.Tablica zawierająca obiekty, w których mamy :
symbol
- identyfikator przystanku używany do późniejszych zapytańname
- pełna nazwa przystanku.peka_vm_get getStopPoints '{"pattern":"Pół"}'
{
"success":[
{
"symbol":"BOZSZ",
"name":"Bolechowo-Os./Zespół Szkół"
},
{
"symbol":"PRPLN",
"name":"Promnice/Północna"
},
{
"symbol":"POLW",
"name":"Półwiejska"
}
]
}
getBollards
Chyba nieużywana. Dla pustego obiektu przesłanego w zapytaniu pobiera wszystkie bollardy.
getBollardsByStopPoint
Zwraca listę bollardów dla danego przystanku i listę linii odjeżdżających z niego.
name
: nazwa przystanku, zwrócona w getStopPoints
Obiekt bollards
, będący tablicą obiektów bollard
(opisanym w getTimes
) i directions
, który sam jest tablicą obiektów zawierających :
returnVariant
: jakiś bool, z tego co widziałem prawie zawsze false.lineName
: nazwa linii odjeżdżającej z danego punktu,direction
: kierunek tejże linii.peka_vm_get getBollardsByStopPoint '{"name":"Termy Maltańskie"}'
{
"success":{
"bollards":[
{
"directions":[
{
"returnVariant":false,
"direction":"Rondo Rataje",
"lineName":"84"
},
{
"returnVariant":false,
"direction":"Termy Maltańskie",
"lineName":"84"
},
{
"returnVariant":false,
"direction":"Rondo Śródka",
"lineName":"84"
},
{
"returnVariant":false,
"direction":"Nowe ZOO",
"lineName":"84"
}
],
"bollard":{
"symbol":"TEMA22",
"tag":"TEMA01",
"name":"Termy Maltańskie",
"mainBollard":false
}
}
]
}
}
getBollardsByStreet
Zwraca listę bollardów znajdujących się przy zadanej ulicy.
name
: nazwa ulicyTo samo, co przy getBollardsByStopPoint
.
peka_vm_get getBollardsByStreet '{"name":"Lutycka"}'
{
"success":{
"bollards":[
{
"directions":[
{
"returnVariant":false,
"direction":"Szarych Szeregów",
"lineName":"83"
}
],
"bollard":{
"symbol":"LU I21",
"tag":"LU I01",
"name":"Lutycka I n/ż",
"mainBollard":false
}
},
{
"directions":[
{
"returnVariant":false,
"direction":"Szarych Szeregów",
"lineName":"83"
}
],
"bollard":{
"symbol":"LUII21",
"tag":"LUII01",
"name":"Lutycka II n/ż",
"mainBollard":false
}
},
{
"directions":[
{
"returnVariant":false,
"direction":"Rondo Śródka",
"lineName":"83"
}
],
"bollard":{
"symbol":"LUII22",
"tag":"LUII02",
"name":"Lutycka II n/ż",
"mainBollard":false
}
},
{
"directions":[
{
"returnVariant":false,
"direction":"Rondo Śródka",
"lineName":"83"
}
],
"bollard":{
"symbol":"LU I22",
"tag":"LU I02",
"name":"Lutycka I n/ż",
"mainBollard":false
}
},
{
"directions":[
{
"returnVariant":false,
"direction":"Poznań Główny",
"lineName":"236"
}
],
"bollard":{
"symbol":"ROOB22",
"tag":"ROOB02",
"name":"Rondo Obornicka",
"mainBollard":false
}
},
{
"directions":[
{
"returnVariant":false,
"direction":"Poznań Główny",
"lineName":"246"
}
],
"bollard":{
"symbol":"ROOB21",
"tag":"ROOB01",
"name":"Rondo Obornicka",
"mainBollard":false
}
}
]
}
}
getBollardsByLine
Zwraca bollardy, przy których zatrzymuje się dana linia, włącznie z jej wariacjami wynikającymi z wyjazdami/zjazdami z/do zajezdni.
name
: nazwa liniiObiekt directions
, będący tablicą obiektów zawierających w sobie obiekt direction
i bollards
. direction
zawiera :
returnVariant
- chyba true
dla "powracającego", chociaż trudno mi się domyślić, jakie to ma naprawdę znaczenie.direction
- kierunek jazdylineName
- nazwę linii.bollards
to natomiast tablica obiektów zawierających wszystkie bollardy, przy których zatrzymuje się dana wariacja linii. Każdy z tych obiektów zawiera to samo, co bollard
znajdujący się w wyniku getBollardsByStopPoint
, ale z dodanym orderNo
, czyli - chyba - kolejny numer przystanku dla linii. Atrybut ten pewnie być użyty do zrekonstruowania trasy danej linii i jej wariacji, ale nie udało mi się znaleźć na to jakiegoś algorytmu.
Pominięty ze względu na zbyt duży rozmiar.
getLines
Pobiera linie komunikacji pasujące do zadanego wzorca.
pattern
Tablica zawierająca obiekty, których name
zawiera pełną nazwę linii.
peka_vm_get getLines '{"pattern":"16"}'
{
"success":[
{
"name":"16"
},
{
"name":"616"
},
{
"name":"716"
}
]
}
getStreets
Pobiera listę ulic razem z ich identyfikatorami, pasującymi do zadanego wzorca.
pattern
: wzorzec.Tablica obiektów zawierających id
ulicy do użycia w późniejszych zapytaniach, oraz name
, czyli ich pełną nazwę.
peka_vm_get getStreets '{"pattern":"Gło"}'
{
"success":[
{
"id":3,
"name":"Głogowska"
},
{
"id":159,
"name":"Koziegłowy/Gdyńska"
},
{
"id":270,
"name":"Koziegłowy/Piaskowa"
},
{
"id":167,
"name":"Koziegłowy/Piłsudskiego"
},
{
"id":166,
"name":"Koziegłowy/Poznańska"
},
{
"id":165,
"name":"Koziegłowy/Taczaka"
},
{
"id":319,
"name":"Kórnik/pl. Niepodległości"
},
{
"id":277,
"name":"Luboń/Niepodległości"
},
{
"id":143,
"name":"al. Niepodległości"
},
{
"id":6,
"name":"zajezdnia Głogowska"
}
]
}
getTimes
Pobiera szacowane czasy przyjazdu kolejnych pojazdów na zadany bollard.
symbol
: tag
bollarda (niestety nie symbol
, jak mogłoby się wydawać) wyciągnięty przez którąś z wariacji funkcji getBollards
, dla którego pobrać listę przyjazdów.Dwa obiekty : bollard
opisujący bollarda i zawierający :
symbol
- identyfikator bollarda w systemie,tag
- alternatywny identyfikator?,name
- nazwę przystanku, do którego należy bollard,mainBollard
- na razie widziałem tutaj tylko false
, ale domyślam się, że może to być true
dla "jednobollardowych" przystanków.Oraz obiekt times
będący tablicą obiektów zawierających :
realTime
- czy przyjazd jest podany w oparciu o położenie pojazdu na podstawie odczytu jego lokalizacji,minutes
- ile minut zostało do przyjazdu,direction
- kierunek trasy,onStopPoint
- czy pojazd aktualnie znajduje się na bollardzie,departure
- szacowany czas odjazdu podany jako yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
. Nie jest to ISO 8601, ponieważ końcowe Z
sugerowałoby wtedy, że jest on podany w UTC. Tak się jednak nie dzieje : godzina podawana jest w czasie lokalnym , czyli CET albo CEST.line
- linia, którą obsługuje pojazd.peka_vm_get getTimes '{"symbol":"AWF03"}'
{
"success":{
"bollard":{
"symbol":"AWF03",
"tag":"AWF21",
"name":"AWF",
"mainBollard":false
},
"times":[
{
"realTime":true,
"minutes":0,
"direction":"Os. Orła Białego",
"onStopPoint":true,
"departure":"2016-11-25T21:48:00.000Z",
"line":"74"
},
{
"realTime":true,
"minutes":20,
"direction":"Os. Orła Białego",
"onStopPoint":false,
"departure":"2016-11-25T22:08:00.000Z",
"line":"74"
}
]
}
}
getTimesForAllBollards
Pobiera czasy przyjazdu na wszystkich bollardach przypisanych do danego przystanku. Swoiste połączenie getBollardsByStopPoint
i getTimes
.
name
: nazwa przystanku.Obiekt bollardsWithTimes
, będący tablicą struktur opisanych w getTimes
.
peka_vm_get getTimesForAllBollards '{"name":"Katowicka"}'
{
"success":{
"bollardsWithTimes":[
{
"bollard":{
"symbol":"KATO22",
"tag":"KATO02",
"name":"Katowicka",
"mainBollard":false
},
"times":[
{
"realTime":true,
"minutes":8,
"direction":"Rondo Śródka",
"onStopPoint":false,
"departure":"2016-11-25T22:48:00.000Z",
"line":"57"
},
{
"realTime":true,
"minutes":13,
"direction":"Termy Maltańskie",
"onStopPoint":false,
"departure":"2016-11-25T22:53:00.000Z",
"line":"84"
}
]
},
{
"bollard":{
"symbol":"KATO21",
"tag":"KATO01",
"name":"Katowicka",
"mainBollard":false
},
"times":[
{
"realTime":false,
"minutes":13,
"direction":"Rondo Rataje",
"onStopPoint":false,
"departure":"2016-11-25T22:53:00.000Z",
"line":"84"
},
{
"realTime":false,
"minutes":24,
"direction":"Mogileńska",
"onStopPoint":false,
"departure":"2016-11-25T23:04:00.000Z",
"line":"57"
}
]
}
]
}
}
getServerTime
Pobiera aktualny czas na serwerze jako coś, co wygląda na liczbę milisekund od 1. stycznia 1970. Na wejściu pusty obiekt.
peka_vm_get getServerTime '{}'
{"success":1480110116917}
findMessagesForBollard
Zwraca wiadomości zapisane przez administrację serwisu, skojarzone z danym bollardem. Z reguły wykorzystywane do zakomunikowania czasowych zmian w rozkładzie.
symbol
: identyfikator bollardaTablica obiektów zawierających następujące pola :
content
: wiadomość, która ma zostać wyświetlona, jako HTML,startHour
, stopsGroups
i endHour
: przeznaczenie nieznane, nie są używane w ogóle przez kod renderujący oficjalną stronę,startDate
: data oznaczająca początek okresu, kiedy komunikat ma zacząć zostać wyświetlany,endDate
: j.w., ale oznaczająca koniec tego okresu.Format daty jest taki sam jak ten używany przez pole departure
w getTimes
.
peka_vm_get findMessagesForBollard '{"symbol":"RJEZ04"}'
{
"success":[
{
"content":"INFO: Od 9 kwietnia, w związku z remontem torowiska na ul. 28 Czerwca 1956 r., zmianie ulegną trasy linii tramwajowych nr 2, 9, 10 i 11. Uruchomiona zostanie komunikacja zastępcza. Szczegóły na stronie <a href=\"http://tiny.pl/g5dss\">www.ztm.poznan.pl<\/a>.",
"startDate":"2017-04-06T01:00:00.000Z",
"stopsGroups":[
],
"startHour":60,
"endDate":"2017-04-11T23:00:00.000Z",
"endHour":1380
}
]
}