Created
August 20, 2014 14:52
-
-
Save kenkeiter/1827a1da743494be29b4 to your computer and use it in GitHub Desktop.
Display RescueTime productivity on the Quirky Nimbus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rest_client' | |
require 'json' | |
require 'pp' | |
class RescueTimeProfile | |
API_BASE_URL = 'https://www.rescuetime.com/anapi' | |
TIME_SCORE_SCALE = { | |
2 => 1, | |
1 => 0.75, | |
0 => 0.50, | |
-1 => 0, | |
-2 => 0 | |
} | |
def initialize(api_key) | |
@api_key = api_key | |
end | |
def productivity | |
query_params = { | |
key: @api_key, | |
format: 'json', | |
op: 'select', | |
vn: 0, | |
pv: 'interval', | |
rs: 'day', | |
rb: Time.now.strftime('%Y-%m-%d'), | |
re: (Time.now + (60 * 60 * 24)).strftime('%Y-%m-%d'), | |
rk: 'productivity' | |
} | |
resp = RestClient.get(API_BASE_URL + "/data", params: query_params) | |
data = JSON.parse(resp) | |
# go through and parse the data | |
total_seconds = 0 | |
productive_seconds = 0 | |
data['rows'].each do |row| | |
seconds = row[1].to_i | |
score = row[3].to_i | |
total_seconds += seconds | |
productive_seconds += seconds * TIME_SCORE_SCALE.fetch(score) | |
end | |
return (100 * productive_seconds / total_seconds).round | |
end | |
end | |
class NimbusDial | |
def initialize(nimbus, state = {}) | |
@nimbus = nimbus | |
@dial_id = state['dial_id'] | |
@state = { | |
'name' => state['name'], | |
'value' => state['value'], | |
'position' => state['position'].to_f, | |
'label' => state['label'], | |
'labels' => state['labels'], | |
'brightness' => state['brightness'].to_i, | |
'channel_configuration' => {'channel_id' => 10}, | |
'dial_index' => state['dial_index'].to_i | |
} | |
end | |
def update(opts = {}) | |
@state.merge!(opts.inject({}){ |memo,(k,v)| memo[k.to_s] = v; memo }) | |
@nimbus.request(:put, "/dials/#{@dial_id}", @state) | |
end | |
end | |
class Nimbus | |
attr_reader :dials | |
API_BASE_URL = "https://winkapi.quirky.com" | |
def initialize(opts) | |
@opts = opts | |
@dials = [] | |
self.initialize_dials | |
end | |
def reauthorize! | |
creds = { | |
'client_id' => @opts.fetch(:client_id), | |
'client_secret' => @opts.fetch(:client_secret), | |
'username' => @opts.fetch(:username), | |
'password' => @opts.fetch(:password), | |
'grant_type' => 'password' | |
} | |
headers = {:content_type => 'application/json'} | |
response = RestClient.post( | |
Nimbus::API_BASE_URL + '/oauth2/token', | |
creds.to_json, | |
headers) | |
response_data = JSON.parse(response) | |
@access_token = response_data['access_token'] | |
@refresh_token = response_data['refresh_token'] | |
end | |
def request(_type, endpoint, data = nil, _headers = {}, &block) | |
attempts = 0 | |
type = _type.downcase.to_sym | |
begin | |
headers = { | |
authorization: "Bearer #{@access_token}", | |
content_type: 'application/json' | |
}.merge!(_headers) | |
case type | |
when :get | |
resp = RestClient.get(API_BASE_URL + endpoint, {params: data}.merge!(headers)) | |
return JSON.parse(resp) | |
when :post | |
resp = RestClient.post(API_BASE_URL + endpoint, data.to_json, headers) | |
return JSON.parse(resp) | |
when :put | |
resp = RestClient.put(API_BASE_URL + endpoint, data.to_json, headers) | |
return JSON.parse(resp) | |
when :delete | |
resp = RestClient.delete(API_BASE_URL + endpoint, headers) | |
return JSON.parse(resp) | |
end | |
attempts += 1 | |
rescue RestClient::Exception => e | |
if e.http_code == 401 | |
self.reauthorize! | |
retry if attempts < 2 | |
else | |
raise e | |
end | |
end | |
end | |
def initialize_dials | |
# fetch all Wink devices | |
devices = self.request(:get, '/users/me/wink_devices') | |
clock = devices["data"].select{|d| d['name'] == "Nimbus" }.first | |
# get the first clock, and add each of its dials | |
@dials = [] | |
clock['dials'].each do |dial| | |
@dials[dial['dial_index'].to_i] = NimbusDial.new(self, dial) | |
end | |
return @dials | |
end | |
end | |
##### | |
# APP | |
##### | |
rescue_time = RescueTimeProfile.new('your_api_key') | |
clock = Nimbus.new( | |
client_id: 'your_client_id', | |
client_secret: 'your_client_secret', | |
username: 'you@example.com', | |
password: 'your_password' | |
) | |
loop do | |
current_productivity = rescue_time.productivity | |
clock.dials[1].update( | |
value: current_productivity, | |
position: 360 * (current_productivity * 0.01), | |
label: "PROD. SCORE", | |
labels: ["#{current_productivity}%", "PRODUCTIVE"] | |
) | |
puts "#{Time.now} - Updated productivity: #{current_productivity}%" | |
sleep(60 * 15) # sleep 15 minutes, and refresh | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment