Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
A Ruby API for the National Rail website
Ruby

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
examples
lib
test
.gitignore
Gemfile
Gemfile.lock
LICENSE
README.textile
Rakefile
national-rail.gemspec

README.textile

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

Something went wrong with that request. Please try again.