Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@gaelrottier
Forked from freality/README.md
Last active December 21, 2015 01:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaelrottier/6230043 to your computer and use it in GitHub Desktop.
Save gaelrottier/6230043 to your computer and use it in GitHub Desktop.

Description

Dashing widget to display weather from forecast.io. This widget was forked from https://gist.github.com/freality/5629557 to manage case when minutely data is missing.

##Screenshot

##Usage

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

Get skycons.js from https://github.com/darkskyapp/skycons and put it in your assets/javascripts directory.

To include the widget in a dashboard, add the following to your dashboard layout file:

<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
  <div data-id="forecast" data-view="Forecast" data-widget_title="<img src='http://forecast.io/favicon.ico' />Weather Forecast"> ></div>
</li>

##Settings

  • Forecast API Key from developer.forecast.io
  • Latitude and Longitude for your desired location. Easily obtained from forward geocoding sites such as geocoder.ca
  • Configurable temperature units. (US, SI, UK)
  • Default schedule set to fetch weather every 5 minutes but can be changed from within forcast.rb.
class Dashing.Forecast extends Dashing.Widget
# Overrides Dashing.Widget method in dashing.coffee
@accessor 'updatedAtMessage', ->
if updatedAt = @get('updatedAt')
timestamp = new Date(updatedAt * 1000)
hours = timestamp.getHours()
minutes = ("0" + timestamp.getMinutes()).slice(-2)
"Updated at #{hours}:#{minutes}"
constructor: ->
super
@forecast_icons = new Skycons({"color": "white"})
@forecast_icons.play()
ready: ->
# This is fired when the widget is done being rendered
@setIcons()
onData: (data) ->
# Handle incoming data
# We want to make sure the first time they're set is after ready()
# has been called, or the Skycons code will complain.
if @forecast_icons.list.length
@setIcons()
setIcons: ->
@setIcon('current_icon')
@setIcon('next_icon')
@setIcon('later_icon')
setIcon: (name) ->
skycon = @toSkycon(name)
@forecast_icons.set(name, eval(skycon)) if skycon
toSkycon: (data) ->
if @get(data)
'Skycons.' + @get(data).replace(/-/g, "_").toUpperCase()
<div class="widget-title" data-bind="widget_title | raw"></div>
<div class="updated-at" data-bind="updatedAtMessage"></div>
<div>
<h1 class="title">RIGHT NOW</h1>
<canvas id="current_icon" class="forecast-icon" width="85px" height="85px"></canvas>
<div class="temp" data-bind="current_temp | raw"></div>
<div class="summary" data-bind="current_desc | raw"></div>
</div>
<div style="margin-top: 10px">
<h1 class="title">NEXT HOUR</h1>
<canvas id="next_icon" class="forecast-icon" width="25px" height="25px"></canvas>
<div class="summary" data-bind="next_desc | raw"></div>
</div>
<div style="margin-top: 10px">
<h1 class="title">LATER</h1>
<canvas id="later_icon" class="forecast-icon" width="25px" height="25px"></canvas>
<div class="summary" data-bind="later_desc | raw"></div>
</div>
require 'net/https'
require 'json'
# Forecast API Key from https://developer.forecast.io
forecast_api_key = ""
# Latitude, Longitude for location
forecast_location_lat = "45.429522"
forecast_location_long = "-75.689613"
# Unit Format
# "us" - U.S. Imperial
# "si" - International System of Units
# "uk" - SI w. windSpeed in mph
forecast_units = "si"
SCHEDULER.every '5m', :first_in => 0 do |job|
http = Net::HTTP.new("api.forecast.io", 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
response = http.request(Net::HTTP::Get.new(
"/forecast/#{forecast_api_key}/#{forecast_location_lat},#{forecast_location_long}?units=#{forecast_units}"
))
forecast = JSON.parse(response.body)
forecast_current_temp = forecast["currently"]["temperature"].round
forecast_current_icon = forecast["currently"]["icon"]
forecast_current_desc = forecast["currently"]["summary"]
if forecast["minutely"] # sometimes this is missing from the response. I don't know why
forecast_next_desc = forecast["minutely"]["summary"]
forecast_next_icon = forecast["minutely"]["icon"]
else
# When the minutely forecast is missing from the response,
# it's possible to get the weather by searching the 2nd occurrence in the hourly data
# by getting the 2nd entry of the "data" field to get the info about the next hour
# (the 1st entry is about the current hour)
puts "Did not get minutely forecast data again"
forecast_next_desc = forecast["hourly"]["data"][1]["summary"]
forecast_next_icon = forecast["hourly"]["data"][1]["icon"]
end
forecast_later_desc = forecast["hourly"]["summary"]
forecast_later_icon = forecast["hourly"]["icon"]
send_event('forecast', {
current_temp: "#{forecast_current_temp}&deg;",
current_icon: "#{forecast_current_icon}",
current_desc: "#{forecast_current_desc}",
next_icon: "#{forecast_next_icon}",
next_desc: "#{forecast_next_desc}",
later_icon: "#{forecast_later_icon}",
later_desc: "#{forecast_later_desc}"
})
end
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #3CAEEC;
$full-color: rgba(255, 255, 255, 1);
$light-color: rgba(255, 255, 255, 0.7);
// ----------------------------------------------------------------------------
// Widget-forecast styles
// ----------------------------------------------------------------------------
.widget-title {
color: $light-color;
font-size: 15px;
text-align: left;
text-transform: uppercase;
position: absolute;
top: 5px;
img {
vertical-align: baseline;
margin-right: 5px;
height: 16px;
}
}
.widget-forecast {
background-color: $background-color;
padding-top: 15px !important;
h1 {
margin-bottom: 0px;
}
.updated-at {
color: rgba(0, 0, 0, 0.3);
top: 5px;
right: 10px;
left: auto;
}
.title {
color: $light-color;
text-align: left;
font-size: 25px;
}
.temp {
color: $full-color;
text-align: left;
font-size: 45px;
}
.summary {
color: $full-color;
text-align: left;
vertical-align: middle;
font-size: 17px;
}
.forecast-icon {
float: left;
text-align: left;
margin-right: 20px;
}
.more-info {
color: $light-color;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment