-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnibe_uplink.rb
152 lines (121 loc) · 4.13 KB
/
nibe_uplink.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# nibe_uplink.rb
# frozen_string_literal: true
require 'json'
require 'net/http'
require 'simpleoauth'
class NibeUplinkError < StandardError
end
class ServerError < NibeUplinkError
end
class AuthorizationError < NibeUplinkError
end
class RateLimitError < NibeUplinkError
end
# Class for interfacing with Nibe Uplink
class NibeUplink
BASE_URL = 'https://api.nibeuplink.com'
TOKEN_ENDPOINT = '/oauth/token'
API_ENDPOINT = '/api/v1/systems'
attr_accessor :system_id
def initialize(client_id, client_secret, system_id = nil)
@system_id = system_id
@oauth = SimpleOAuth::Client.new(BASE_URL,
TOKEN_ENDPOINT,
client_id,
client_secret)
@oauth.load_token('/var/lib/misc/')
end
# Send authorization code to get a token for the first time
def authorize(auth_code, callback_url, scope = 'READSYSTEM+WRITESYSTEM')
@oauth.authorize(auth_code, callback_url, scope)
end
# Get info on the current system
def system
return false unless @system_id
uri = "#{API_ENDPOINT}/#{@system_id}"
request(:get, uri).body
end
# List all systems connected to the account
def systems
request(:get, API_ENDPOINT).body
end
# Get system status. Returns which subsystems are currently active
def status
return false unless @system_id
uri = "#{API_ENDPOINT}/#{@system_id}/status/system"
request(:get, uri).body
end
# Get info on installed software and software updates
def software
return false unless @system_id
uri = "#{API_ENDPOINT}/#{@system_id}/software"
request(:get, uri).body
end
# Get info and current values of the requested parameters,
# or set parameters if a hash is provided as argument
def parameters(parameters)
return false unless @system_id
uri = "#{API_ENDPOINT}/#{@system_id}/parameters"
if parameters.is_a?(Hash)
body = { settings: parameters }
request(:put, uri, nil, body.to_json).body
else
request(:get, uri, 'parameterIds' => parameters).body
end
end
# Get notifications/alarms registered on the system
def notifications
return false unless @system_id
uri = "#{API_ENDPOINT}/#{@system_id}/notifications"
request(:get, uri).body
end
# Get info on the system. If arg is set to true it returns parameters for all systems,
# if set to a valid category, returns info on only that category
def serviceinfo(arg = false)
return false unless @system_id
uri = "#{API_ENDPOINT}/#{@system_id}/serviceinfo/categories"
uri += "/#{arg}" if arg.is_a? String
query = { 'parameters' => true } if arg && !arg.is_a?(String)
request(:get, uri, query).body
end
# Get or set the smarthome mode
def mode(mode = nil)
return false unless @system_id
uri = "#{API_ENDPOINT}/#{@system_id}/smarthome/mode"
if mode
body = { mode: mode }
request(:put, uri, nil, body.to_json).body
else
request(:get, uri).body
end
end
# Get all registered smart home thermostats if no arguments are passed,
# or create/update a smart home thermostat with the provided values
def thermostats(values = {})
return false unless @system_id
uri = "#{API_ENDPOINT}/#{@system_id}/smarthome/thermostats"
if values.empty?
request(:get, uri).body
else
raise ArgumentError, '`values` must contain externalId and name' if values['externalId'].nil? || values['name'].nil?
request(:post, uri, nil, values.to_json).message
end
end
private
def request(verb, uri, query = nil, body = nil)
extheader = { 'accept' => 'application/json' }
res = case verb
when :get
@oauth.get(uri, query, extheader)
when :post, :put
extheader['content-type'] = 'application/json'
@oauth.send(verb, uri, body, extheader)
end
raise AuthorizationError, res.body if res.is_a? Net::HTTPUnauthorized
raise RateLimitError if res.is_a? Net::HTTPTooManyRequests
raise ServerError, "#{res.code} #{res.msg}" if res.is_a? Net::HTTPServerError
res
rescue Net::ReadTimeout => e
raise ServerError, e.message
end
end