Skip to content

Instantly share code, notes, and snippets.

@rrudd
Last active April 11, 2016 08:07
Show Gist options
  • Save rrudd/0388e754bdc228b15a64ac84243a5019 to your computer and use it in GitHub Desktop.
Save rrudd/0388e754bdc228b15a64ac84243a5019 to your computer and use it in GitHub Desktop.
A Dashing widget for upcoming HSL departures.

Description

This is a Dashing widget that shows the upcoming departures of selected stops in the Helsinki region. It relies on the HSL HTTP GET Interface.

Usage

To use this widget, copy hsl.html, hsl.coffee, and hsl.scss into the /widgets/hsl directory. Put the hsl.rb file in your /jobs folder.

You will also need to set up your HSL API credentials as environment variables (HSL_USER and HSL_PASS), alternatively you can hard code them in the hsl.rb file. Get the credentials here.

Finally, replace the stop ID's in the stops array in hsl.rb with the stops you want to follow, and include the following tag in your dashboard (.erb) template:

<li data-row="1" data-col="1" data-sizex="1" data-sizey="2">
  <div data-id="hsl" data-view="Hsl"></div>
</li>

Note that this widget is intended to be used with the Lato Google Web Font, and styling may need fixing for use with other fonts.

Customization

Besides changing what stops you want to follow, you can also set a time limit for how long it takes to walk to the stops. Usually, you don't want to see buses and trams leaving right now, as you can't possibly catch them. The default is 2 minutes, but you can change this by modifying the time_limit_minutes variable in the beginning of the hsl.rb job.

class Dashing.Hsl extends Dashing.Widget
@accessor 'updatedAtMessage', ->
if updatedAt = @get('updatedAt')
timestamp = new Date(updatedAt * 1000)
hours = timestamp.getHours()
minutes = ("0" + timestamp.getMinutes()).slice(-2)
"#{hours}:#{minutes}"
ready: ->
# This is fired when the widget is done being rendered
onData: (data) ->
# Handle incoming data
# You can access the html node of this widget with `@node`
# Example: $(@node).fadeOut().fadeIn() will make the node flash each time data comes in.
<div class="widget-header">TRANSPORTATION<hr /></div>
<div class="updated-at" data-bind="updatedAtMessage"></div>
<div>
<table>
<thead>
<tr>
<th>Time</th>
<th>Destination</th>
<th>Line</th>
</tr>
</thead>
<tr data-foreach-dep="departures">
<td class="time" data-bind="dep.time_str"></td>
<td class="destination" data-bind="dep.destination"></td>
<td class="line" data-bind="dep.line"></td>
</tr>
</table>
</div>
require 'net/https'
require 'json'
host = "api.reittiopas.fi"
stops = ["1130139", "1130439", "1130109", "1130438", "1130110"]
time_limit_minutes = 2
user = ENV['HSL_USER']
pass = ENV['HSL_PASS']
def line_from_code(code)
line = code[1..4]
line.gsub!(/^0+/,'')
line = line.strip
return line
end
def time_string_from_int(time_int)
time_str = time_int.to_s.rjust(4, '0').insert(2, ":")
return time_str
end
def destination_from_code(code, destinations)
destination = destinations[destinations.index{|s| s.include?(code)}][8..-1]
return destination
end
SCHEDULER.every '1m', :first_in => 0 do |job|
all_departures = []
time_limit = Time.now + time_limit_minutes * 60
time_limit_str = time_limit.strftime("%H:%M")
stops.each do |stop|
response = Net::HTTP.get_response(host,"/hsl/prod/?request=stop&user=#{user}&pass=#{pass}&format=json&code=#{stop}")
stop = JSON.parse(response.body)
destinations = stop[0]["lines"]
departures = stop[0]["departures"]
departures.each do |departure|
departure["line"] = line_from_code(departure["code"])
departure["time_str"] = time_string_from_int(departure["time"])
departure["destination"] = destination_from_code(departure["code"], destinations)
if departure["time_str"] > time_limit_str
all_departures << departure
end
end
end
sorted_departures = all_departures.sort_by { |dep| dep["time"] }
send_event('hsl', { departures: sorted_departures[0..18] })
end
@import '../../assets/stylesheets/colors';
.widget-hsl {
background-color: #2196F3;
padding-bottom: 0 !important;
table {
margin-top: 25px;
}
td {
padding-top: 5px;
padding-bottom: 5px;
}
tr:nth-child(even) {
background-color: rgba(255, 255, 255, 0.2);
}
.time {
padding-left: 20px;
float:left;
}
.line {
padding-right: 20px;
float:right;
}
.destination {
font-size: small;
}
.updated-at {
color: rgba(255, 255, 255, 0.3);
top: 12px;
right: 10px;
left: auto;
}
.widget-header {
top: 10px;
left: 0px;
width: 100%;
position:absolute;
font-weight: 200;
color: rgba(255,255,255,0.7);
hr {
height: 1px;
border: 0;
border-top: 1px solid rgba(255,255,255,0.7);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment