From f5e52662a5da59b56933fd50b297df41b6d29aa0 Mon Sep 17 00:00:00 2001 From: Konstantin Chukhlomin Date: Sat, 14 Dec 2019 21:06:37 -0500 Subject: [PATCH] Added MTA LIRR --- Makefile | 10 ++++ README.md | 2 +- go.mod | 7 ++- go.sum | 2 + lirr.go | 84 ++++++++++++++++++++++++++++++++++ lirr.md | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 lirr.go create mode 100644 lirr.md diff --git a/Makefile b/Makefile index 48ac2d2..6b3ed24 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,15 @@ +.PHONY: vet +## vet: runs go vet vet: @go vet ./... +.PHONY: test +## test: runs go vet and go test test: vet @go test ./... + +.PHONY: help +## help: prints this help message +help: + @echo "Usage: \n" + @sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /' diff --git a/README.md b/README.md index 33196d3..fe42107 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ resp, err := client.GetFeedMessage(mta.Line123456S) ### ProtoBuf -MTA uses realtime-GTFS with their own extension for subway feeds. +MTA uses realtime-GTFS with their own [extension for subway feeds](http://datamine.mta.info/sites/all/files/pdfs/nyct-subway.proto.txt). To re-regenerate generatated code run following command with [protoc](https://github.com/protocolbuffers/protobuf): ```bash diff --git a/go.mod b/go.mod index 5cbeb99..b490ea5 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,8 @@ module github.com/chuhlomin/mta -require github.com/golang/protobuf v1.3.2 +go 1.13 + +require ( + github.com/golang/protobuf v1.3.2 + github.com/pkg/errors v0.8.1 +) diff --git a/go.sum b/go.sum index 9a46bf9..24988a6 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/lirr.go b/lirr.go new file mode 100644 index 0000000..bb8ffdf --- /dev/null +++ b/lirr.go @@ -0,0 +1,84 @@ +package mta + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "time" + + "github.com/pkg/errors" +) + +const lirrDepartureURL = "https://traintime.lirr.org/api/Departure" + +type LIRRService interface { + Departures(locationCode string) (*DeparturesResponse, error) +} + +type LIRRClient struct { + client *http.Client +} + +type DeparturesResponse struct { + Location string `json:"LOC"` // The three-letter code for that station, e.g.: JAM + Time string `json:"TIME"` // The date and time the feed was returned at in mm/dd/yyyy hh:mm:ss format (24-hr time) + Tranis []DeparturesResponseTrain `json:"TRAINS"` // Countdown items for each arriving train +} + +// DeparturesResponseTrain - part of DeparturesResponse +type DeparturesResponseTrain struct { + ScheduledTime string `json:"SCHED"` // The scheduled date and time the train is supposed to arrive at the station in mm/dd/yyyy hh:mm:ss format (24-hr time) + TrainID string `json:"TRAIN_ID"` // The train number. These are typically 1-4 digit train numbers you can find in the timetables or as the train_id’s in the GTFS feeds, though since this feed shows inserts, they can be up to 8 alphanumeric characters long. + RunDate string `json:"RUN_DATE"` // E.g.: "2019-12-14", + Destination string `json:"DEST"` // The three-letter station code of the final stop on that train. + Stops []string `json:"STOPS"` // The three-letter station codes of all remaining stops that train is supposed to make. If the countdown is showing at the final destination, the field will be blank for “discharge only” trains. NOTE: Hillside stops are not shown in this field. + Track string `json:"TRACK"` // The track and platform the train is supposed to depart from. May be blank at terminals when the track is not yet posted. + Direction string `json:"DIR"` // The direction the train is travelling (E = eastbound, W = westbound) + HSF bool `json:"HSF"` // Indicates whether or not the train will stop at Hillisde (true = train stops, false = train does not stop) + JAM *bool `json:"JAM"` // Indicates whether or not the train will stop at Jamaica (ture = train stops, false = train will pass through Jamaica but not stop, null = train won’t pass through Jamaica). + ETA string `json:"ETA"` // The estimated arrival time of that train, updated to account for all reported schedule deviations. Returned in mm/dd/yyyy hh:mm:ss format (24-hr time). The difference between this time and the ScheduledTime is how late or early the train is. + Countdown int `json:"CD"` // The number of seconds between now and the time the train is supposed to arrive (a countdown field). +} + +// NewLIRRClient creates new LIRRClient +func NewLIRRClient(timeout time.Duration) *LIRRClient { + return &LIRRClient{ + client: &http.Client{ + Timeout: timeout, + }, + } +} + +// Departures gets train departures from specified station +// locationCore – three-letter code for the station, for example: +// "NYK" for NY-Penn Station +// "ATL" for Brklyn-Atlatnic Term +// "HVL" for Hicksville +// Full list of codes: https://github.com/chuhlomin/mta/blob/master/lirr.md +func (lc *LIRRClient) Departures(locationCode string) (*DeparturesResponse, error) { + v := url.Values{} + v.Add("loc", locationCode) + + url := fmt.Sprintf("%s?%s", lirrDepartureURL, v.Encode()) + + resp, err := lc.client.Get(url) + if err != nil { + return nil, errors.Wrap(err, "failed to send GetStopMonitoring request") + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, errors.Wrap(err, "failed to read GetStopMonitoring response") + } + + response := DeparturesResponse{} + err = json.Unmarshal(body, &response) + if err != nil { + return nil, errors.Wrapf(err, "failed to parse GetStopMonitoring response body: %s", body) + } + + return &response, nil +} diff --git a/lirr.md b/lirr.md new file mode 100644 index 0000000..95eb616 --- /dev/null +++ b/lirr.md @@ -0,0 +1,133 @@ +# LIRR - MTA Long Island Rail Road + +Stations: + +| Internal Stop ID | GTFS Stop ID | Code | Name | +|------------------|--------------|------|----------------------| +| 1 | 118 | LIC | Long Island City | +| 2 | 90 | HPA | Hunterspoint Avenue | +| 8 | 237 | NYK | Penn Station | +| 9 | 214 | WDD | Woodside | +| 10 | 55 | FHL | Forest Hills | +| 11 | 107 | KGN | Kew Gardens | +| 12 | 241 | ATL | Atlantic Terminal | +| 13 | 148 | NAV | Nostrand Avenue | +| 14 | 50 | ENY | East New York | +| 15 | 102 | JAM | Jamaica | +| 17 | 199 | SSM | Mets-Willets Point | +| 18 | 56 | FLS | Flushing-Main Street | +| 19 | 130 | MHL | Murray Hill | +| 20 | 11 | BDY | Broadway | +| 21 | 2 | ADL | Auburndale | +| 22 | 25 | BSD | Bayside | +| 23 | 42 | DGL | Douglaston | +| 24 | 120 | LNK | Little Neck | +| 25 | 72 | GNK | Great Neck | +| 26 | 131 | MHT | Manhasset | +| 27 | 162 | PDM | Plandome | +| 28 | 171 | PWS | Port Washington | +| 30 | 89 | HOL | Hollis | +| 31 | 175 | QVG | Queens Village | +| 32 | 24 | BRT | Belmont Park | +| 33 | 23 | BRS | Bellerose | +| 34 | 63 | FPK | Floral Park | +| 35 | 195 | SMR | Stewart Manor | +| 36 | 149 | NBD | Nassau Boulevard | +| 37 | 68 | GCY | Garden City | +| 38 | 36 | CLP | Country Life Press | +| 39 | 84 | HEM | Hempstead | +| 40 | 152 | NHP | New Hyde Park | +| 41 | 127 | MAV | Merillon Avenue | +| 42 | 132 | MIN | Mineola | +| 43 | 52 | EWN | East Williston | +| 44 | 1 | ABT | Albertson | +| 45 | 182 | RSN | Roslyn | +| 46 | 77 | GVL | Greenvale | +| 47 | 71 | GHD | Glen Head | +| 48 | 185 | SCF | Sea Cliff | +| 49 | 76 | GST | Glen Street | +| 50 | 67 | GCV | Glen Cove | +| 51 | 123 | LVL | Locust Valley | +| 53 | 154 | OBY | Oyster Bay | +| 54 | 39 | CPL | Carle Place | +| 55 | 213 | WBY | Westbury | +| 56 | 92 | HVL | Hicksville | +| 58 | 205 | SYT | Syosset | +| 59 | 40 | CSH | Cold Spring Harbor | +| 60 | 91 | HUN | Huntington | +| 61 | 78 | GWN | Greenlawn | +| 62 | 153 | NPT | Northport | +| 63 | 111 | KPK | Kings Park | +| 64 | 202 | STN | Smithtown | +| 65 | 193 | SJM | St. James | +| 66 | 14 | BK | Stony Brook | +| 67 | 164 | PJN | Port Jefferson | +| 68 | 20 | BPG | Bethpage | +| 69 | 59 | FMD | Farmingdale | +| 70 | 165 | PLN | Pinelawn | +| 71 | 220 | WYD | Wyandanch | +| 72 | 44 | DPK | Deer Park | +| 73 | 29 | BWD | Brentwood | +| 74 | 33 | CI | Central Islip | +| 75 | 179 | RON | Ronkonkoma | +| 77 | 129 | MFD | Medford | +| 78 | 223 | YPK | Yaphank | +| 79 | 176 | RHD | Riverhead | +| 80 | 126 | MAK | Mattituck | +| 81 | 190 | SHD | Southold | +| 82 | 73 | GPT | Greenport | +| 83 | 184 | SAB | St. Albans | +| 84 | 119 | LMR | Locust Manor | +| 85 | 122 | LTN | Laurelton | +| 86 | 180 | ROS | Rosedale | +| 87 | 211 | VSM | Valley Stream | +| 88 | 219 | WWD | Westwood | +| 89 | 142 | MVN | Malverne | +| 90 | 124 | LVW | Lakeview | +| 91 | 85 | HGN | Hempstead Gardens | +| 92 | 216 | WHD | West Hempstead | +| 93 | 66 | GBN | Gibson | +| 94 | 94 | HWT | Hewlett | +| 95 | 217 | WMR | Woodmere | +| 96 | 32 | CHT | Cedarhurst | +| 97 | 114 | LCE | Lawrence | +| 98 | 101 | IWD | Inwood | +| 99 | 65 | FRY | Far Rockaway | +| 100 | 125 | LYN | Lynbrook | +| 101 | 31 | CAV | Centre Avenue | +| 102 | 51 | ERY | East Rockaway | +| 103 | 155 | ODE | Oceanside | +| 104 | 99 | IPK | Island Park | +| 105 | 113 | LBH | Long Beach | +| 106 | 183 | RVC | Rockville Centre | +| 107 | 225 | BWN | Baldwin | +| 108 | 64 | FPT | Freeport | +| 109 | 226 | MRK | Merrick | +| 110 | 16 | BMR | Bellmore | +| 111 | 215 | WGH | Wantagh | +| 112 | 187 | SFD | Seaford | +| 113 | 136 | MQA | Massapequa | +| 114 | 135 | MPK | Massapequa Park | +| 115 | 8 | AVL | Amityville | +| 116 | 38 | CPG | Copiague | +| 117 | 117 | LHT | Lindenhurst | +| 118 | 27 | BTA | Babylon | +| 119 | 26 | BSR | Bay Shore | +| 120 | 100 | ISP | Islip | +| 121 | 74 | GRV | Great River | +| 122 | 157 | ODL | Oakdale | +| 123 | 204 | SVL | Sayville | +| 124 | 163 | PD | Patchogue | +| 126 | 21 | BPT | Bellport | +| 127 | 140 | MSY | Mastic-Shirley | +| 129 | 198 | SPK | Speonk | +| 130 | 233 | WHN | Westhampton | +| 132 | 83 | HBY | Hampton Bays | +| 134 | 191 | SHN | Southampton | +| 135 | 13 | BHN | Bridgehampton | +| 136 | 48 | EHN | East Hampton | +| 137 | 4 | AGT | Amagansett | +| 138 | 141 | MTK | Montauk | +| Landing | | BOL | Boland's | +| Interlocking | | HAR | HAROLD | +| Facility | | HIL | Hillside |