peka-vm-api.md 16 KB

Ostrzeżenie

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

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.

Słowniczek

  • bollard - coś, co najwygodniej chyba wytłumaczyć jako "słupek". Jest to fizyczne miejsce, w którym zatrzymują się pojazdy. Na jeden przystanek może przypadać więcej niż jeden bollard : jeden dla pojazdów jadących w jednym kierunku, a drugi - w drugim. Dochodzą do tego jeszcze osobne punkty przystankowe dla linii nocnych. Przystanek AWF ma na przykład aż siedem takich punktów : dwa tramwajowe na Królowej Jadwigi, jeden tramwajowy na Garbarach, i autobusowe rozrzucone w różnych miejscach.

Funkcje

getStopPoints

Pobiera listę przystanków o nazwie pasującej do zadanego wzorca.

Wejście

  • pattern - wzorzec, według którego serwer ma szukać przystanku.

Wyjście

Tablica zawierająca obiekty, w których mamy :

  • symbol - identyfikator przystanku używany do późniejszych zapytań
  • name - pełna nazwa przystanku.

Przykład

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.

Wejście

  • name : nazwa przystanku, zwrócona w getStopPoints

Wyjście

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.

Przykład

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.

Wejście

  • name : nazwa ulicy

Wyjście

To samo, co przy getBollardsByStopPoint.

Przykład

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.

Wejście

  • name : nazwa linii

Wyjście

Obiekt 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 jazdy
  • lineName - 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.

Przykład

Pominięty ze względu na zbyt duży rozmiar.

getLines

Pobiera linie komunikacji pasujące do zadanego wzorca.

Wejście

  • pattern

Wyjście

Tablica zawierająca obiekty, których name zawiera pełną nazwę linii.

Przykład

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.

Wejście

  • pattern : wzorzec.

Wyjście

Tablica obiektów zawierających id ulicy do użycia w późniejszych zapytaniach, oraz name, czyli ich pełną nazwę.

Przykład

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.

Wejście

  • 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.

Wyjście

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.

Przykład

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.

Wejście

  • name : nazwa przystanku.

Wyjście

Obiekt bollardsWithTimes, będący tablicą struktur opisanych w getTimes.

Przykład

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.

Przykład

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.

Wejście

  • symbol : identyfikator bollarda

Wyjście

Tablica 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.

Przykład

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
      }
   ]
}