Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

A Ruby API for the National Rail website

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 examples
Octocat-spinner-32 lib
Octocat-spinner-32 test
Octocat-spinner-32 .gitignore
Octocat-spinner-32 Gemfile
Octocat-spinner-32 LICENSE
Octocat-spinner-32 README.textile
Octocat-spinner-32 Rakefile
Octocat-spinner-32 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.