NationalRail
A Ruby API for the National Rail website.
Components
- Journey Planner
- Live Departure Boards
- Station List
Notes
- Not all website functionality is available yet.
- There are no tests – so use at your own risk.
- Journey Planner doesn’t handle details for journeys with changes.
- Likely to be brittle if National Rail website changes.
- All working as of 04 Nov 2010.
- Thanks to Michael Pritchard for station location data.
Journey Planner
require "national-rail"
require "active_support"
Time.zone = "London"
planner = NationalRail::JourneyPlanner.new
summary_rows = planner.plan(
:from => "London Kings Cross",
:to => "Edinburgh",
:time => Time.zone.parse("2010-05-30 10:30")
)
summary_rows.each do |row|
p row.departure_time
p row.number_of_changes
p row.details
end
Train departing at: 2010-05-30 10:30:00 +0100 with 0 changes...
{:initial_stop=>
{:departs_at=>Sun, 30 May 2010 10:30:00 BST +01:00, :station_code=>"KGX"},
:origins=>["London Kings Cross"],
:final_stop=>
{:station_code=>"EDB", :arrives_at=>Sun, 30 May 2010 15:02:00 BST +01:00},
:destinations=>["Glasgow Central"],
:stops=>
[{:departs_at=>Sun, 30 May 2010 10:49:00 BST +01:00,
:station_code=>"SVG",
:arrives_at=>Sun, 30 May 2010 10:49:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 11:19:00 BST +01:00,
:station_code=>"PBO",
:arrives_at=>Sun, 30 May 2010 11:18:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 12:10:00 BST +01:00,
:station_code=>"DON",
:arrives_at=>Sun, 30 May 2010 12:09:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 12:35:00 BST +01:00,
:station_code=>"YRK",
:arrives_at=>Sun, 30 May 2010 12:33:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 13:03:00 BST +01:00,
:station_code=>"DAR",
:arrives_at=>Sun, 30 May 2010 13:02:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 13:34:00 BST +01:00,
:station_code=>"NCL",
:arrives_at=>Sun, 30 May 2010 13:32:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 14:17:00 BST +01:00,
:station_code=>"BWK",
:arrives_at=>Sun, 30 May 2010 14:17:00 BST +01:00}]}
...
Train departing at: 2010-05-30 13:00:00 +0100 with 0 changes...
{:initial_stop=>
{:departs_at=>Sun, 30 May 2010 13:00:00 BST +01:00, :station_code=>"KGX"},
:origins=>["London Kings Cross"],
:final_stop=>
{:station_code=>"EDB", :arrives_at=>Sun, 30 May 2010 17:37:00 BST +01:00},
:destinations=>["Glasgow Central"],
:stops=>
[{:departs_at=>Sun, 30 May 2010 13:19:00 BST +01:00,
:station_code=>"SVG",
:arrives_at=>Sun, 30 May 2010 13:19:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 13:51:00 BST +01:00,
:station_code=>"PBO",
:arrives_at=>Sun, 30 May 2010 13:50:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 14:42:00 BST +01:00,
:station_code=>"DON",
:arrives_at=>Sun, 30 May 2010 14:41:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 15:07:00 BST +01:00,
:station_code=>"YRK",
:arrives_at=>Sun, 30 May 2010 15:05:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 15:35:00 BST +01:00,
:station_code=>"DAR",
:arrives_at=>Sun, 30 May 2010 15:34:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 15:54:00 BST +01:00,
:station_code=>"DHM",
:arrives_at=>Sun, 30 May 2010 15:54:00 BST +01:00},
{:departs_at=>Sun, 30 May 2010 16:11:00 BST +01:00,
:station_code=>"NCL",
:arrives_at=>Sun, 30 May 2010 16:10:00 BST +01:00}]}
Live Departure Boards
Departures
require "national-rail"
boards = NationalRail::LiveDepartureBoards.new
summary_rows = boards.summary(:type => :arrivals, :from => "York", :to => "London Kings Cross")
summary_rows.each do |row|
puts
p row.attributes
stops = row.details
stops.each do |stop|
p stop
end
end
{:status=>["17:40", "12 mins late"], :origin=>"Newcastle", :platform=>"", :due=>"17:28", :service_id=>"nWwWcnOh4QGgGZ7mKtdcXQ=="}
{:station=>"Newcastle", :status=>["Departed", "On time"], :platform=>"", :departs=>"14:05"}
{:station=>"Durham", :status=>["Departed", "3 mins late"], :platform=>"", :departs=>"14:17"}
{:station=>"Darlington", :status=>["Departed", "4 mins late"], :platform=>"", :departs=>"14:35"}
{:station=>"Northallerton", :status=>["Departed", "6 mins late"], :platform=>"", :departs=>"14:46"}
{:station=>"York", :status=>["Departed", "4 mins late"], :platform=>"", :departs=>"15:11"}
{:station=>"Doncaster", :status=>["Departed", "6 mins late"], :platform=>"", :departs=>"15:36"}
{:station=>"Retford", :status=>["Departed", "10 mins late"], :platform=>"", :departs=>"15:51"}
{:station=>"Newark North Gate", :status=>["Departed", "12 mins late"], :platform=>"", :departs=>"16:06"}
{:station=>"Grantham", :status=>["Departed", "12 mins late"], :platform=>"", :departs=>"16:19"}
{:station=>"London Kings Cross", :status=>["17:40", "12 mins late"], :platform=>"", :departs=>"17:28"}
{:status=>["17:48", "7 mins late"], :origin=>"Glasgow Central", :platform=>"", :due=>"17:41", :service_id=>"O0kuecMXx+V4XAXTnIKGbA=="}
{:station=>"Glasgow Central", :status=>["Departed", "On time"], :platform=>"", :departs=>"11:50"}
{:station=>"Motherwell", :status=>["Departed", "On time"], :platform=>"", :departs=>"12:06"}
{:station=>"Haymarket", :status=>["Departed", "On time"], :platform=>"", :departs=>"12:49"}
{:station=>"Edinburgh", :status=>["Departed", "On time"], :platform=>"", :departs=>"13:00"}
{:station=>"Berwick-upon-Tweed", :status=>["Departed", "8 mins late"], :platform=>"", :departs=>"13:39"}
{:station=>"Newcastle", :status=>["Departed", "On time"], :platform=>"", :departs=>"14:34"}
{:station=>"Darlington", :status=>["Departed", "3 mins late"], :platform=>"", :departs=>"15:02"}
{:station=>"York", :status=>["Departed", "On time"], :platform=>"", :departs=>"15:35"}
{:station=>"Doncaster", :status=>["Departed", "On time"], :platform=>"", :departs=>"16:00"}
{:station=>"Peterborough", :status=>["Departed", "11 mins late"], :platform=>"", :departs=>"16:48"}
{:station=>"London Kings Cross", :status=>["17:48", "7 mins late"], :platform=>"", :departs=>"17:41"}
{:status=>["18:18", "14 mins late"], :origin=>"Newcastle", :platform=>"", :due=>"18:04", :service_id=>"wlmXSLpJUnlxkKVOjjReDw=="}
{:station=>"Newcastle", :status=>["Departed", "On time"], :platform=>"", :departs=>"14:55"}
{:station=>"Durham", :status=>["Departed", "4 mins late"], :platform=>"", :departs=>"15:07"}
{:station=>"Darlington", :status=>["Departed", "8 mins late"], :platform=>"", :departs=>"15:25"}
{:station=>"York", :status=>["Departed", "7 mins late"], :platform=>"", :departs=>"15:54"}
{:station=>"Grantham", :status=>["Departed", "20 mins late"], :platform=>"", :departs=>"16:44"}
{:station=>"Peterborough", :status=>["17:24", "20 mins late"], :platform=>"", :departs=>"17:04"}
{:station=>"Stevenage", :status=>["17:51", "17 mins late"], :platform=>"", :departs=>"17:34"}
{:station=>"London Kings Cross", :status=>["18:18", "14 mins late"], :platform=>"", :departs=>"18:04"}
{:status=>["On time"], :origin=>"Edinburgh", :platform=>"", :due=>"18:28", :service_id=>"Sejy3zPbNyIK5QMDwZ7ZdA=="}
{:station=>"Edinburgh", :status=>["Departed", "On time"], :platform=>"", :departs=>"14:00"}
{:station=>"Berwick-upon-Tweed", :status=>["Departed", "10 mins late"], :platform=>"", :departs=>"14:39"}
{:station=>"Newcastle", :status=>["Departed", "13 mins late"], :platform=>"", :departs=>"15:30"}
{:station=>"Darlington", :status=>["Departed", "10 mins late"], :platform=>"", :departs=>"16:02"}
{:station=>"York", :status=>["Departed", "9 mins late"], :platform=>"", :departs=>"16:32"}
{:station=>"London Kings Cross", :status=>["On time", ""], :platform=>"", :departs=>"18:28"}
Arrivals
require "national-rail"
boards = NationalRail::LiveDepartureBoards.new
summary_rows = boards.summary(:type => :departures, :from => "York", :to => "London Kings Cross")
summary_rows.each do |row|
puts
p row.attributes
stops = row.details
stops.each do |stop|
p stop
end
end
{:destination=>"London Kings Cross", :status=>["17:25", "4 mins late"], :platform=>"3", :due=>"17:21", :service_id=>"TeAdv6Eygk3YYKcj#1dLKQ=="}
{:station=>"Glasgow Central", :status=>["Departed", "On time"], :platform=>"", :departs=>"13:50"}
{:station=>"Motherwell", :status=>["Departed", "4 mins late"], :platform=>"", :departs=>"14:05"}
{:station=>"Haymarket", :status=>["Departed", "4 mins late"], :platform=>"", :departs=>"14:49"}
{:station=>"Edinburgh", :status=>["Departed", "On time"], :platform=>"", :departs=>"15:00"}
{:station=>"Newcastle", :status=>["Departed", "4 mins late"], :platform=>"", :departs=>"16:28"}
{:station=>"York", :status=>["17:25", "4 mins late"], :platform=>"3", :departs=>"17:21"}
{:station=>"Peterborough", :status=>["On time", ""], :platform=>"", :departs=>"18:26"}
{:station=>"London Kings Cross", :status=>["On time", ""], :platform=>"", :departs=>"19:19"}
{:destination=>"London Kings Cross", :status=>["On time"], :platform=>"3", :due=>"17:55", :service_id=>"KbVdMlKOX0Y80aSv3f+Ztg=="}
{:station=>"Newcastle", :status=>["Departed", "On time"], :platform=>"", :departs=>"16:55"}
{:station=>"Durham", :status=>["On time", ""], :platform=>"", :departs=>"17:07"}
{:station=>"Darlington", :status=>["On time", ""], :platform=>"", :departs=>"17:25"}
{:station=>"York", :status=>["On time", ""], :platform=>"3", :departs=>"17:55"}
{:station=>"Doncaster", :status=>["On time", ""], :platform=>"", :departs=>"18:20"}
{:station=>"Retford", :status=>["On time", ""], :platform=>"", :departs=>"18:36"}
{:station=>"Newark North Gate", :status=>["On time", ""], :platform=>"", :departs=>"18:51"}
{:station=>"Peterborough", :status=>["On time", ""], :platform=>"", :departs=>"19:19"}
{:station=>"Stevenage", :status=>["On time", ""], :platform=>"", :departs=>"19:50"}
{:station=>"London Kings Cross", :status=>["On time", ""], :platform=>"", :departs=>"20:19"}
{:destination=>"London Kings Cross", :status=>["On time"], :platform=>"", :due=>"18:31", :service_id=>"mqyP34FV2xdcNRn#17pbTA=="}
{:station=>"Edinburgh", :status=>["Departed", "On time"], :platform=>"", :departs=>"16:00"}
{:station=>"Dunbar", :status=>["Departed", "2 mins late"], :platform=>"", :departs=>"16:20"}
{:station=>"Berwick-upon-Tweed", :status=>["Departed", "5 mins late"], :platform=>"", :departs=>"16:43"}
{:station=>"Newcastle", :status=>["On time", ""], :platform=>"", :departs=>"17:32"}
{:station=>"Darlington", :status=>["On time", ""], :platform=>"", :departs=>"17:59"}
{:station=>"York", :status=>["On time", ""], :platform=>"", :departs=>"18:31"}
{:station=>"Doncaster", :status=>["On time", ""], :platform=>"", :departs=>"18:53"}
{:station=>"Newark North Gate", :status=>["On time", ""], :platform=>"", :departs=>"19:17"}
{:station=>"Peterborough", :status=>["On time", ""], :platform=>"", :departs=>"19:46"}
{:station=>"Stevenage", :status=>["On time", ""], :platform=>"", :departs=>"20:16"}
{:station=>"London Kings Cross", :status=>["On time", ""], :platform=>"", :departs=>"20:44"}
Virgin Trains Live Departure Boards
require "national-rail"
boards = NationalRail::VirginLiveDepartureBoards.new
boards.summary("DHM").each do |row|
puts
puts "Summary :-"
p row.attributes
puts "Will call at :-"
row.details[:will_call_at].each { |stop| p stop }
puts "Previous calling points :-"
row.details[:previous_calling_points].each { |stop| p stop }
end
Summary :-
{:platform=>"", :expected_arrival=>"1041", :to=>"Newcastle", :timetabled_departure=>"1035", :expected_departure=>"1041", :from=>"Birmingham New Street", :timetabled_arrival=>"1034", :details_url=>"http://realtime.nationalrail.co.uk/virgintrains/train.aspx?T=DRHM++++&J=157410&R=0"}
Will call at :-
{:expected_arrival=>"On time", :station=>"Newcastle", :timetabled_arrival=>"1052"}
Previous calling points :-
{:timetabled_departure=>"0730", :expected_departure=>"", :station=>"Birmingham New Street", :actual_departure=>"0732"}
{:timetabled_departure=>"0811", :expected_departure=>"", :station=>"Derby", :actual_departure=>"On time"}
{:timetabled_departure=>"0832", :expected_departure=>"", :station=>"Chesterfield", :actual_departure=>"On time"}
{:timetabled_departure=>"0854", :expected_departure=>"", :station=>"Sheffield", :actual_departure=>"On time"}
{:timetabled_departure=>"0922", :expected_departure=>"", :station=>"Doncaster", :actual_departure=>"0924"}
{:timetabled_departure=>"0951", :expected_departure=>"", :station=>"York", :actual_departure=>"0957"}
{:timetabled_departure=>"1019", :expected_departure=>"", :station=>"Darlington", :actual_departure=>"1026"}
...
Summary :-
{:platform=>"2", :expected_arrival=>"1046", :to=>"Edinburgh", :timetabled_departure=>"1040", :expected_departure=>"1046", :from=>"London Kings Cross", :timetabled_arrival=>"1040", :details_url=>"http://realtime.nationalrail.co.uk/virgintrains/train.aspx?T=DRHM++++&J=155938&R=0"}
Will call at :-
{:expected_arrival=>"1100", :station=>"Newcastle", :timetabled_arrival=>"1057"}
{:expected_arrival=>"On time", :station=>"Berwick-upon-Tweed", :timetabled_arrival=>"1142"}
{:expected_arrival=>"On time", :station=>"Edinburgh", :timetabled_arrival=>"1231"}
Previous calling points :-
{:timetabled_departure=>"0800", :expected_departure=>"", :station=>"London Kings Cross", :actual_departure=>"On time"}
{:timetabled_departure=>"0846", :expected_departure=>"", :station=>"Peterborough", :actual_departure=>"0852"}
{:timetabled_departure=>"0955", :expected_departure=>"", :station=>"York", :actual_departure=>"1001"}
{:timetabled_departure=>"1023", :expected_departure=>"", :station=>"Darlington", :actual_departure=>"1030"}
...
Summary :-
{:platform=>"2", :expected_arrival=>"1055", :to=>"Newcastle", :timetabled_departure=>"1051", :expected_departure=>"1055", :from=>"Manchester Airport", :timetabled_arrival=>"1050", :details_url=>"http://realtime.nationalrail.co.uk/virgintrains/train.aspx?T=DRHM++++&J=144193&R=0"}
Will call at :-
{:expected_arrival=>"1100", :station=>"Chester-le-Street", :timetabled_arrival=>"1056"}
{:expected_arrival=>"1110", :station=>"Newcastle", :timetabled_arrival=>"1108"}
Previous calling points :-
{:timetabled_departure=>"0805", :expected_departure=>"", :station=>"Manchester Airport", :actual_departure=>"On time"}
{:timetabled_departure=>"0826", :expected_departure=>"", :station=>"Manchester Piccadilly", :actual_departure=>"On time"}
{:timetabled_departure=>"0857", :expected_departure=>"", :station=>"Huddersfield", :actual_departure=>"On time"}
{:timetabled_departure=>"0907", :expected_departure=>"", :station=>"Dewsbury", :actual_departure=>"On time"}
{:timetabled_departure=>"0927", :expected_departure=>"", :station=>"Leeds", :actual_departure=>"On time"}
{:timetabled_departure=>"1000", :expected_departure=>"", :station=>"York", :actual_departure=>"1003"}
{:timetabled_departure=>"1021", :expected_departure=>"", :station=>"Northallerton", :actual_departure=>"1026"}
{:timetabled_departure=>"1033", :expected_departure=>"", :station=>"Darlington", :actual_departure=>"1038"}
...
Summary :-
{:platform=>"", :expected_arrival=>"No report", :to=>"Reading", :timetabled_departure=>"1235", :expected_departure=>"No report", :from=>"Newcastle", :timetabled_arrival=>"1234", :details_url=>"http://realtime.nationalrail.co.uk/virgintrains/train.aspx?T=DRHM++++&J=142167&R=0"}
Will call at :-
{:expected_arrival=>"No report", :station=>"Darlington", :timetabled_arrival=>"1251"}
{:expected_arrival=>"No report", :station=>"York", :timetabled_arrival=>"1324"}
{:expected_arrival=>"No report", :station=>"Doncaster", :timetabled_arrival=>"1353"}
{:expected_arrival=>"No report", :station=>"Sheffield", :timetabled_arrival=>"1420"}
{:expected_arrival=>"No report", :station=>"Derby", :timetabled_arrival=>"1451"}
{:expected_arrival=>"On time", :station=>"Birmingham New Street", :timetabled_arrival=>"1527"}
{:expected_arrival=>"On time", :station=>"Leamington Spa", :timetabled_arrival=>"1558"}
{:expected_arrival=>"On time", :station=>"Banbury", :timetabled_arrival=>"1617"}
{:expected_arrival=>"On time", :station=>"Oxford", :timetabled_arrival=>"1640"}
{:expected_arrival=>"On time", :station=>"Reading", :timetabled_arrival=>"1708"}
Previous calling points :-
{:timetabled_departure=>"1219", :expected_departure=>"No report", :station=>"Newcastle", :actual_departure=>""}
{:timetabled_departure=>"1228", :expected_departure=>"No report", :station=>"Chester-le-Street", :actual_departure=>""}
Station List
require "national-rail"
stations = NationalRail::StationList.new
stations.each do |name, code, latitude, longitude|
puts "#{name} (#{code}) @ #{latitude},#{longitude}"
end
Abbey Wood (ABW) @ 51.490957,0.120287 Aber (ABE) @ 51.575382,-3.230133 Abercynon (ACY) @ 51.643007,-3.329765 Aberdare (ABA) @ 51.714723,-3.441704 Aberdeen (ABD) @ 57.143591,-2.098804 Aberdour (AUR) @ 56.054604,-3.300914 Aberdovey (AVY) @ 52.544322,-4.055988 Abererch (ABH) @ 52.898292,-4.37505 Abergavenny (AGV) @ 51.81767,-3.008827 Abergele & Pensarn (AGL) @ 53.294721,-3.582118 Aberystwyth (AYW) @ 52.41396,-4.081767 Accrington (ACR) @ 53.752973,-2.369535 ... Yatton (YAT) @ 51.390771,-2.827513 Yeoford (YEO) @ 50.77603,-3.726381 Yeovil Junction (YVJ) @ 50.923943,-2.612948 Yeovil Pen Mill (YVP) @ 50.944343,-2.612981 Yetminster (YET) @ 50.895286,-2.573571 Ynyswen (YNW) @ 51.664737,-3.521422 Yoker (YOK) @ 55.892785,-4.387607 York (YRK) @ 53.958243,-1.092918 Yorton (YRT) @ 52.808903,-2.7365 Ystrad Mynach (YSM) @ 51.641017,-3.241498 Ystrad Rhondda (YSR) @ 51.643441,-3.466631
License
This code is free to use under the terms of the MIT licence.
© James Mead 2010