-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdoc.go
196 lines (142 loc) · 4.94 KB
/
doc.go
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
Package ecobee provides a Go client for the ecobee API.
For more information about the ecobee API, see the documentation:
https://www.ecobee.com/home/developer/api/introduction/index.shtml
# Authentication
By design, the ecobee Client accepts any http.Client so OAuth2 requests can be
made by using the appropriate authenticated client.
Use the https://github.com/golang/oauth2 package to obtain an http.Client which
transparently authorizes requests.
# Usage
You use the library by creating a Client and invoking its methods. The client
can be created manually with NewClient.
The below example illustrates how to:
- Fetch a persisted OAuth2 token from a file in JSON format if one exists.
- Authorize an app and create the OAuth2 token using the ecobee PIN authorization method if no persisted OAuth2 token is found.
- Create an http.Client using the OAuth2 token. The Client will auto-refresh the token as necessary.
- Create an ecobee.Client.
- Retrieve a selection of thermostat data for one or more thermostats.
- Retrieve the OAuth2 token from the ecobee.Client (In case it was auto-refreshed).
- Persist the OAuth2 token to a file in JSON format
package main
import (
"bufio"
"context"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"time"
"golang.org/x/oauth2"
"github.com/sherif-fanous/go-ecobee"
"github.com/sherif-fanous/go-ecobee/objects"
)
var applicationKey string
var filename string
var oauth2Endpoint = oauth2.Endpoint{
AuthURL: "https://api.ecobee.com/authorize",
TokenURL: "https://api.ecobee.com/token",
}
func persistToken(oauth2Token *oauth2.Token) error {
b, err := json.MarshalIndent(oauth2Token, "", " ")
if err != nil {
return err
}
if err := ioutil.WriteFile(filename, b, 0644); err != nil {
return err
}
return nil
}
func fetchToken() (*oauth2.Token, error) {
b, err := ioutil.ReadFile(filename)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, err
}
oauth2Token := oauth2.Token{}
if err := json.Unmarshal(b, &oauth2Token); err != nil {
return nil, err
}
return &oauth2Token, nil
}
func main() {
flag.StringVar(&applicationKey, "key", "", "ecobee Application Key")
flag.StringVar(&filename, "file", "", "token persistent store path")
flag.Parse()
oauth2Token, err := fetchToken()
if err != nil {
fmt.Println(err)
return
}
if oauth2Token == nil {
client := ecobee.NewClient()
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
fmt.Println("PINAuthorization...Step #1")
fmt.Println()
authorizeResponse, err := client.PINAuthorization(ctx, applicationKey, ecobee.ScopeSmartWrite)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("AuthorizeResponse %s\n", authorizeResponse)
fmt.Println()
fmt.Printf("Please goto ecobee.com, login to the web portal and click on the settings tab. "+
"Ensure the My Apps widget is enabled. If it is not click on the My Apps option in the menu on the left. "+
"In the My Apps widget paste '%s' in the textbox labelled 'Enter your 4 digit pin to install your third party app' "+
"and then click 'Install App'. The next screen will display any permissions the app requires and will ask you to click "+
"'Authorize' to add the application.\n\nAfter completing this step please hit 'Enter' to continue", authorizeResponse.PIN())
input := bufio.NewScanner(os.Stdin)
input.Scan()
fmt.Println()
fmt.Println("PINAuthorization...Step #2")
fmt.Println()
nowUTC := time.Now().UTC()
ctx = context.Background()
ctx, cancel = context.WithTimeout(ctx, 5*time.Second)
defer cancel()
tokensResponse, err := client.RequestTokens(ctx, applicationKey, authorizeResponse.AuthorizationToken())
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("TokensResponse %s\n", tokensResponse)
oauth2Token = &oauth2.Token{
TokenType: tokensResponse.TokenType(),
AccessToken: tokensResponse.AccessToken(),
Expiry: nowUTC.Add(time.Second * time.Duration(tokensResponse.ExpiresIn())),
RefreshToken: tokensResponse.RefreshToken(),
}
}
oauth2Config := &oauth2.Config{
ClientID: applicationKey,
Endpoint: oauth2Endpoint,
}
client := ecobee.NewClient(ecobee.WithHTTPClient(oauth2Config.Client(context.Background(), oauth2Token)))
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
selection := objects.Selection{
SelectionType: ecobee.String("registered"),
SelectionMatch: ecobee.String(""),
IncludeSettings: ecobee.Bool(true),
}
thermostatResponse, err := client.Thermostat(ctx, &selection, nil)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("ThermostatResponse %s\n", thermostatResponse)
// Get the updated token
oauth2Token = client.OAuth2Token()
if err := persistToken(oauth2Token); err != nil {
fmt.Println(err)
return
}
}
*/
package ecobee