nest_away 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dd208c0d0466f5eea1e1d966f0ba112b77fbc7ea
4
+ data.tar.gz: b8da11671f524194931fa537646d6f43aec22ff6
5
+ SHA512:
6
+ metadata.gz: 1df548910c82d7f8811862c380fe0e7ec057970c1d36ba81f2488a17a642f22761e7b70eddf0893d074b071e91d7145a7c546ba9b1ea2acbe99f21b438ad5e39
7
+ data.tar.gz: 7bc7982aae185cfd68e0a8c6d11f92068338571af615fcf9c985194e100041f3463383f6f68eb13f6ff65fefa307a581f4b08f091e7b5c4550681a7bbe4a8b57
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ .env
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Eric Boehs
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Nest Away
2
+
3
+ This does one thing. It sets your status to away or home.
4
+
5
+ ## Usage
6
+
7
+ Create the client:
8
+ ```ruby
9
+ require 'nest_away'
10
+ nest = NestAway::Client.new(email: 'joe@example.com', password: 'hunter2')
11
+ ```
12
+
13
+ Change the away status:
14
+ ```ruby
15
+ nest.away? # => false
16
+ nest.home? # => true
17
+
18
+ nest.away! # => {status: 'away'}
19
+ nest.home! # => {status: 'home'}
20
+ ```
21
+
22
+ ## Why?
23
+
24
+ As Nest expands its product line, and since they all tie into the idea of people being away/home, I thought it would be useful to have a small, effective API wrapper that did one thing well.
25
+
26
+ A possible use-case is to use IFTTT to make a recipe with the Alexa and Maker channels that will send this gem a request on Amazon's Lambda service.
27
+
28
+ Saying "Alexa, trigger Home" would send an HTTP request to Lambda using Maker which will trigger Lambda to run some code that instantiates a client that runs the `Client#home!` method.
data/lib/nest_away.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "nest_away/version"
2
+ require "nest_away/nest"
@@ -0,0 +1,103 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+ require 'json'
4
+ require 'uri'
5
+
6
+ module NestAway
7
+ class Client
8
+ attr_accessor :login_url, :user_agent, :auth, :login, :token, :user_id,
9
+ :transport_url, :transport_host, :headers
10
+
11
+ def initialize(email:,
12
+ password:,
13
+ login_url: 'https://home.nest.com/user/login',
14
+ user_agent: 'Nest/1.1.0.10 CFNetwork/548.0.4')
15
+
16
+ @login_url = login_url
17
+ @user_agent = user_agent
18
+
19
+ # populates @auth variable
20
+ login(email: email, password: password)
21
+
22
+ @token = auth["access_token"]
23
+ @user_id = auth["userid"]
24
+ @transport_url = auth["urls"]["transport_url"]
25
+ @transport_host = URI.parse(transport_url).host
26
+ @headers = {
27
+ 'Host' => transport_host,
28
+ 'User-Agent' => user_agent,
29
+ 'Authorization' => 'Basic ' + token,
30
+ 'X-nl-user-id' => user_id,
31
+ 'X-nl-protocol-version' => '1',
32
+ 'Accept-Language' => 'en-us',
33
+ 'Connection' => 'keep-alive',
34
+ 'Accept' => '*/*'
35
+ }
36
+ end
37
+
38
+ def status
39
+ request = get(url: "#{transport_url}/v2/mobile/user.#{user_id}", headers: headers)
40
+ JSON.parse(request.body) if request
41
+ end
42
+
43
+ def away?
44
+ status["structure"][structure_id]["away"]
45
+ end
46
+
47
+ def home?
48
+ !away?
49
+ end
50
+
51
+ def home!
52
+ self.away = false
53
+ { status: 'home', timestamp: Time.now }
54
+ end
55
+
56
+ def away!
57
+ self.away = true
58
+ { status: 'away', timestamp: Time.now }
59
+ end
60
+
61
+ def structure_id
62
+ @structure_id ||= status['user'][user_id]['structures'][0].split('.')[1]
63
+ end
64
+
65
+ private
66
+
67
+ def away=(state)
68
+ post(
69
+ url: "#{transport_url}/v2/put/structure.#{structure_id}",
70
+ body: %Q({"away_timestamp":#{Time.now.to_i},"away":#{!!state},"away_setter":0}),
71
+ headers: headers
72
+ )
73
+ end
74
+
75
+ def login(email:, password:)
76
+ request = post(
77
+ url: login_url,
78
+ body: { username: email, password: password },
79
+ headers: { 'User-Agent' => user_agent }
80
+ )
81
+ @auth = JSON.parse(request.body)
82
+ raise 'Invalid login credentials' if auth.key?('error') && @auth['error'] == "access_denied"
83
+ end
84
+
85
+ def post(url:, body:, headers:)
86
+ begin
87
+ HTTParty.post(url, body: body, headers: headers)
88
+ rescue => e
89
+ puts "ERROR: Method #{__METHOD__}, #{e.message}"
90
+ raise e
91
+ end
92
+ end
93
+
94
+ def get(url:, headers:)
95
+ begin
96
+ HTTParty.get(url, headers: headers)
97
+ rescue => e
98
+ puts "ERROR: Method #{__METHOD__}, #{e.message}"
99
+ raise e
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,3 @@
1
+ module NestAway
2
+ VERSION = "0.1.0"
3
+ end
data/nest_away.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/nest_away/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Alex Flores"]
6
+ gem.email = ["virtualsnyper@gmail.com"]
7
+ gem.description = %q{Control your nest away status}
8
+ gem.summary = %q{Set away status for your Nest account}
9
+ gem.homepage = "http://github.com/audibleblink/nest_away"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "nest_away"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = NestAway::VERSION
17
+ gem.add_dependency "httparty", "~> 0.8.3"
18
+
19
+ gem.add_development_dependency "rspec", "~> 3.1"
20
+ gem.add_development_dependency "dotenv"
21
+ gem.add_development_dependency "pry"
22
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ module NestAway
4
+ describe Client do
5
+ let(:nest) { Client.new(email: ENV['NEST_EMAIL'], password: ENV['NEST_PASS']) }
6
+
7
+ it "logs in to home.nest.com" do
8
+ expect(nest.transport_url).to match(/transport\.(home\.)?nest\.com/)
9
+ end
10
+
11
+ it "detects invalid logins" do
12
+ expect {
13
+ Client.new(email: 'invalid@example.com', password: 'asdf')
14
+ }.to raise_error
15
+ end
16
+
17
+ it "detects empty logins" do
18
+ expect { Client.new() }.to raise_error
19
+ end
20
+
21
+ it "gets the status" do
22
+ expect(nest.status).to be_truthy
23
+ end
24
+
25
+ it "gets away status" do
26
+ expect(nest.away?).to_not be_nil
27
+ end
28
+
29
+ it "sets statuses" do
30
+ if nest.home?
31
+ expect { nest.away! }.to change { nest.away? }.from(false).to(true)
32
+ else
33
+ expect { nest.home! }.to change { nest.home? }.from(false).to(true)
34
+ end
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,10 @@
1
+ require 'nest_away'
2
+ require 'dotenv'
3
+ require 'pry'
4
+
5
+ Dotenv.load
6
+
7
+ RSpec.configure do |c|
8
+ c.filter_run focus: true
9
+ c.run_all_when_everything_filtered = true
10
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nest_away
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alex Flores
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.8.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.8.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dotenv
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Control your nest away status
70
+ email:
71
+ - virtualsnyper@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - Gemfile
79
+ - LICENSE
80
+ - README.md
81
+ - lib/nest_away.rb
82
+ - lib/nest_away/nest.rb
83
+ - lib/nest_away/version.rb
84
+ - nest_away.gemspec
85
+ - spec/nest_away_spec.rb
86
+ - spec/spec_helper.rb
87
+ homepage: http://github.com/audibleblink/nest_away
88
+ licenses: []
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.4.5.1
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Set away status for your Nest account
110
+ test_files:
111
+ - spec/nest_away_spec.rb
112
+ - spec/spec_helper.rb
113
+ has_rdoc: