tuya_cloud 0.1.1

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
+ SHA256:
3
+ metadata.gz: 52aa7c71fcdb20ebf5709f83880770f6b2de248a39e638dd26335da0c2ca2a3d
4
+ data.tar.gz: f130d01929e1b19ce3fef563346e5fa0fa87727c9f2e0fda8b0713615e13f85e
5
+ SHA512:
6
+ metadata.gz: 46438f9489eeff54e50468a436c27685e124e39b22c3caab3ed24ce6c8c10873c6a9a10d7e9e62147ade073ae752aad18e02e8543fece547440a0c7521792dac
7
+ data.tar.gz: 055de85de19a35f59d2b50e66a580ba7504c72ea3f707c905899303ae184c0ceb91e1d24e143fbfc50c366b04686e0941afa42bf6984b53d624e14cb897b4ec3
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.6.2
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.2
7
+ before_install: gem install bundler -v 2.0.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in tuya_cloud.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,47 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tuya_cloud (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ addressable (2.7.0)
10
+ public_suffix (>= 2.0.2, < 5.0)
11
+ crack (0.4.3)
12
+ safe_yaml (~> 1.0.0)
13
+ diff-lcs (1.3)
14
+ hashdiff (1.0.0)
15
+ public_suffix (4.0.1)
16
+ rake (10.5.0)
17
+ rspec (3.8.0)
18
+ rspec-core (~> 3.8.0)
19
+ rspec-expectations (~> 3.8.0)
20
+ rspec-mocks (~> 3.8.0)
21
+ rspec-core (3.8.2)
22
+ rspec-support (~> 3.8.0)
23
+ rspec-expectations (3.8.4)
24
+ diff-lcs (>= 1.2.0, < 2.0)
25
+ rspec-support (~> 3.8.0)
26
+ rspec-mocks (3.8.1)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.8.0)
29
+ rspec-support (3.8.2)
30
+ safe_yaml (1.0.5)
31
+ webmock (3.7.5)
32
+ addressable (>= 2.3.6)
33
+ crack (>= 0.3.2)
34
+ hashdiff (>= 0.4.0, < 2.0.0)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ bundler (~> 2.0)
41
+ rake (~> 10.0)
42
+ rspec (~> 3.0)
43
+ tuya_cloud!
44
+ webmock
45
+
46
+ BUNDLED WITH
47
+ 2.0.1
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Jeremy Mercer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # TuyaCloud
2
+
3
+ TuyaCloud is a small Ruby gem to allow control of smart devices connected to the [Tuya Cloud](https://en.tuya.com/), without the need to flash custom firmware or discover device keys.
4
+
5
+ These devices are sold under many different brands internationally, and usually all have their own mobile apps (i.e. [Smart Life](https://play.google.com/store/apps/details?id=com.tuya.smartlife), [Tuya Smart](https://play.google.com/store/apps/details?id=com.tuya.smart) or [Genio](https://play.google.com/store/apps/details?id=com.mirabella.genio))
6
+
7
+ If you're app looks something like the images [here](https://iotrant.com/2019/06/07/smart-home-apps-volume-11-tuya-smart/), chances are this library will work for you.
8
+
9
+ This Ruby implementation was based on work by [PaulAnnekov](https://github.com/PaulAnnekov/tuyaha), using an endpoint specifically designed for [Home Assistant](https://www.home-assistant.io/).
10
+
11
+ The online devices which are supported at this stage are LED globes (white and colour) and mains switches, along with support for activating scenes you've created within the Tuya app.
12
+
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'tuya_cloud'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install tuya_cloud
29
+
30
+ ## Usage
31
+
32
+ **Log into the Tuya Cloud:**
33
+ ```ruby
34
+ api = TuyaCloud::API.new(username, password, country_code, brand)
35
+ ```
36
+ `country_code` is the international dialing code for your country (i.e. 61 for Australia).<br>
37
+ `brand` is an underscored brand name of the app you're using (i.e. `smart_life` or `tuya`) - you may have to guess.
38
+
39
+ **Discover your devices:**
40
+ ```ruby
41
+ api.find_device_by_name(name) # The name you've given your device in the Tuya app
42
+
43
+ api.find_device_by_id(id) # The ID of the device available within the Tuya app
44
+
45
+ api.discover_devices # Gets all of your devices
46
+ api.devices # An array of all of your devices
47
+
48
+ api.refresh_devices # Refresh the states of all devices
49
+ ```
50
+
51
+ **Device status:**
52
+ ```ruby
53
+ light = api.find_device_by_name(name)
54
+
55
+ light.controls.state # true / false for on or off
56
+ light.controls.online # true / false
57
+
58
+ light.controls.brightness # Current brightness setting (lights only)
59
+
60
+ light.controls.color_mode # Current colour mode (RGB lights only)
61
+ light.controls.color # Current colour setting (RGB lights only)
62
+ ```
63
+
64
+ **Controlling lights and mains switches:**
65
+ ```ruby
66
+ switch = api.find_device_by_name(name)
67
+
68
+ switch.controls.toggle # Toggles on / off
69
+ switch.controls.turn_off # Turns device off
70
+ switch.controls.turn_on # Turns the device on
71
+ ```
72
+
73
+ **Controlling light brightness:**
74
+ ```ruby
75
+ light = api.find_device_by_name(name)
76
+
77
+ light.controls.set_brightness(25) # Sets brightness to 25 - max value is 255
78
+ ```
79
+
80
+ **Controlling colour lights:**
81
+ ```ruby
82
+ rgb_light = api.find_device_by_name(name)
83
+
84
+ rgb_light.controls.set_white # Sets the light to normal white mode
85
+ rgb_light.controls.set_color(r, g, b) # Set the colour of the globe using RGB values
86
+ ```
87
+
88
+ **Activating scenes:**
89
+ ```ruby
90
+ scene = api.find_device_by_name(name)
91
+
92
+ scene.controls.activate
93
+ ```
94
+
95
+ ## Development
96
+
97
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
98
+
99
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
100
+
101
+ ## Contributing
102
+
103
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dzheremi/tuya_cloud.
104
+
105
+ ## License
106
+
107
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "tuya_cloud"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'json'
6
+ require 'time'
7
+
8
+ module TuyaCloud
9
+ class API
10
+ CLOUD_URL = 'https://px1.tuya%.com'
11
+ DEFAULT_REGION = 'us'
12
+ attr_accessor :auth,
13
+ :devices
14
+
15
+ def initialize(username, password, country_code, brand, region = DEFAULT_REGION)
16
+ self.auth = Auth.new(username, password, country_code, brand, region)
17
+ auth.login
18
+ self.devices = []
19
+ end
20
+
21
+ def discover_devices
22
+ request = auth.process_request('Discovery', 'discovery')
23
+ return nil unless request &&
24
+ request['devices'] &&
25
+ request['devices'].is_a?(Array)
26
+
27
+ self.devices = []
28
+ request['devices'].each do |device|
29
+ devices << Device.new(device, auth)
30
+ end
31
+ devices
32
+ end
33
+
34
+ def refresh_devices
35
+ discover_devices
36
+ end
37
+
38
+ def find_device_by_id(id)
39
+ discover_devices if devices.size.zero?
40
+ devices.each { |device| return device if device.id == id }
41
+ nil
42
+ end
43
+
44
+ def find_device_by_name(name)
45
+ discover_devices if devices.size.zero?
46
+ devices.each { |device| return device if device.name == name }
47
+ nil
48
+ end
49
+
50
+ class Auth
51
+ attr_accessor :username,
52
+ :password,
53
+ :country_code,
54
+ :brand,
55
+ :access_token,
56
+ :refresh_token,
57
+ :expire_time,
58
+ :region
59
+
60
+ def initialize(username, password, country_code, brand, region)
61
+ raise ArgumentError unless username.is_a?(String) &&
62
+ password.is_a?(String) &&
63
+ country_code.is_a?(String) &&
64
+ brand.is_a?(String) &&
65
+ region.is_a?(String)
66
+
67
+ self.username = username
68
+ self.password = password
69
+ self.country_code = country_code
70
+ self.brand = brand
71
+ self.region = region
72
+ end
73
+
74
+ def cloud_url
75
+ CLOUD_URL.gsub('%', region)
76
+ end
77
+
78
+ def login
79
+ uri = URI.parse("#{cloud_url}/homeassistant/auth.do")
80
+ response = Net::HTTP.post_form(uri,
81
+ userName: username,
82
+ password: password,
83
+ countryCode: country_code,
84
+ bizType: brand,
85
+ from: 'tuya')
86
+ unless response.is_a?(Net::HTTPOK)
87
+ raise Error,
88
+ 'invalid HTTP response from Tuya Cloud whilst trying to '\
89
+ 'get access token'
90
+ end
91
+
92
+ json = JSON.parse(response.body)
93
+ process_auth_response(json)
94
+ end
95
+
96
+ def refresh_access_token
97
+ uri = URI.parse("#{cloud_url}/homeassistant/access.do?grant_type=refresh_token&"\
98
+ "refresh_token=#{refresh_token}")
99
+ response = Net::HTTP.get uri
100
+ unless response.is_a?(String) && !response.empty?
101
+ raise Error, 'failed to refresh access token'
102
+ end
103
+
104
+ json = JSON.parse(response)
105
+ process_auth_response(json)
106
+ end
107
+
108
+ def token_expired?
109
+ Time.now > expire_time
110
+ end
111
+
112
+ def process_auth_response(json)
113
+ unless json['access_token'] &&
114
+ json['refresh_token'] &&
115
+ json['expires_in']
116
+ raise Error,
117
+ 'invalid JSON response from Tuya Cloud whilst trying to '\
118
+ 'get access token'
119
+ end
120
+
121
+ self.access_token = json['access_token']
122
+ self.refresh_token = json['refresh_token']
123
+ self.expire_time = Time.now + json['expires_in'].to_i
124
+ true
125
+ end
126
+
127
+ def process_request(name, namespace, device_id: nil, payload: {})
128
+ raise ArgumentError unless name.is_a?(String) &&
129
+ namespace.is_a?(String)
130
+
131
+ header = {
132
+ name: name,
133
+ namespace: namespace,
134
+ payloadVersion: 1
135
+ }
136
+ payload[:accessToken] = access_token
137
+ payload[:devId] = device_id unless namespace == 'discovery'
138
+ data = {
139
+ header: header,
140
+ payload: payload
141
+ }
142
+ uri = URI.parse("#{cloud_url}/homeassistant/skill")
143
+ http = Net::HTTP.new(uri.host, uri.port)
144
+ http.use_ssl = true
145
+ request = Net::HTTP::Post.new(uri.request_uri,
146
+ 'Content-Type' => 'application/json')
147
+ request.body = data.to_json
148
+ response = http.request(request)
149
+ unless response.is_a?(Net::HTTPOK)
150
+ raise Error,
151
+ 'request was not processed by Tuya Cloud'
152
+ end
153
+
154
+ json = JSON.parse(response.body)
155
+ unless json['header']['code'] == 'SUCCESS'
156
+ raise Error,
157
+ 'request was not processed by Tuya Cloud'
158
+ end
159
+
160
+ json['payload']
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,180 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TuyaCloud
4
+ class Device
5
+ attr_accessor :id,
6
+ :name,
7
+ :type,
8
+ :controls
9
+
10
+ def initialize(json, auth_context)
11
+ self.id = json['id']
12
+ self.name = json['name']
13
+ self.type = json['dev_type']
14
+ case type
15
+ when 'light'
16
+ self.controls = if json['data'] && json['data']['color_mode']
17
+ ColorLight.new(json, auth_context)
18
+ else
19
+ Light.new(json, auth_context)
20
+ end
21
+ when 'switch'
22
+ self.controls = Switch.new(json, auth_context)
23
+ when 'scene'
24
+ self.controls = Scene.new(json, auth_context)
25
+ else
26
+ raise ArgumentError, 'unknown device type'
27
+
28
+ end
29
+ end
30
+
31
+ class Control
32
+ attr_accessor :id,
33
+ :auth_context
34
+
35
+ def initialize(json, auth_context)
36
+ self.id = json['id']
37
+ self.auth_context = auth_context
38
+ end
39
+
40
+ def process_request(name, payload: {})
41
+ auth_context.process_request(name, 'control',
42
+ device_id: id,
43
+ payload: payload)
44
+ end
45
+ end
46
+
47
+ class Switchable < Control
48
+ attr_accessor :online,
49
+ :state
50
+
51
+ def initialize(json, auth_context)
52
+ super(json, auth_context)
53
+ self.online = json['data']['online'].to_s == 'true'
54
+ self.state = json['data']['state'].to_s == 'true'
55
+ end
56
+
57
+ def toggle
58
+ process_request('turnOnOff', payload: { value: state ? 0 : 1 })
59
+ self.state = !state
60
+ end
61
+
62
+ def turn_off
63
+ process_request('turnOnOff', payload: { value: 0 })
64
+ self.state = false
65
+ end
66
+
67
+ def turn_on
68
+ process_request('turnOnOff', payload: { value: 1 })
69
+ self.state = true
70
+ end
71
+ end
72
+
73
+ class Light < Switchable
74
+ attr_accessor :brightness
75
+
76
+ def initialize(json, auth_context)
77
+ super(json, auth_context)
78
+ self.brightness = json['data']['brightness'].to_i
79
+ end
80
+
81
+ def set_brightness(value)
82
+ raise ArgumentError unless value.is_a?(Integer)
83
+ raise ArgumentError if value.negative? || value > 255
84
+
85
+ process_request('brightnessSet', payload: { value: value })
86
+ self.brightness = value
87
+ end
88
+ end
89
+
90
+ class ColorLight < Light
91
+ attr_accessor :color_mode,
92
+ :color
93
+
94
+ def initialize(json, auth_context)
95
+ super(json, auth_context)
96
+ self.color_mode = json['data']['color_mode']
97
+ self.color = ColorSetting.new(json['data']['color'])
98
+ end
99
+
100
+ def set_white
101
+ self.color_mode = 'white'
102
+ color.hue = 0
103
+ color.saturation = 0
104
+ color.brightness = 100
105
+ process_request('colorSet', payload: { color: color.to_h })
106
+ color.to_h
107
+ end
108
+
109
+ def set_color(red, green, blue)
110
+ raise ArgumentError unless red.is_a?(Integer) &&
111
+ green.is_a?(Integer) &&
112
+ blue.is_a?(Integer)
113
+ raise ArgumentError if (red.negative? || red > 255) ||
114
+ (green.negative? || green > 255) ||
115
+ (blue.negative? || blue > 255)
116
+
117
+ self.color_mode = 'colour'
118
+ color.from_rgb(red, green, blue)
119
+ process_request('colorSet', payload: { color: color.to_h })
120
+ color.to_h
121
+ end
122
+
123
+ class ColorSetting
124
+ attr_accessor :saturation,
125
+ :brightness,
126
+ :hue
127
+
128
+ def initialize(json)
129
+ self.saturation = json['saturation']
130
+ self.brightness = json['brightness']
131
+ self.hue = json['hue']
132
+ end
133
+
134
+ def from_rgb(r, g, b)
135
+ r /= 255.0
136
+ g /= 255.0
137
+ b /= 255.0
138
+ max = [r, g, b].max
139
+ min = [r, g, b].min
140
+ delta = max - min
141
+ v = max * 255
142
+ s = 0.0
143
+ s = delta / max * 255 if max != 0.0
144
+ if s == 0.0
145
+ h = 0.0
146
+ else
147
+ if r == max
148
+ h = (g - b) / delta
149
+ elsif g == max
150
+ h = 2 + (b - r) / delta
151
+ elsif b == max
152
+ h = 4 + (r - g) / delta
153
+ end
154
+ h *= 60.0
155
+ h += 360.0 if h.negative?
156
+ end
157
+ self.hue = h.round
158
+ self.saturation = s.round
159
+ self.brightness = v.round
160
+ end
161
+
162
+ def to_h
163
+ { hue: hue,
164
+ saturation: saturation,
165
+ brightness: brightness }
166
+ end
167
+ end
168
+ end
169
+
170
+ class Switch < Switchable
171
+ end
172
+
173
+ class Scene < Control
174
+ def activate
175
+ process_request('turnOnOff', payload: { value: 1 })
176
+ true
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TuyaCloud
4
+ class Error < RuntimeError; end
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TuyaCloud
4
+ VERSION = '0.1.1'
5
+ end
data/lib/tuya_cloud.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tuya_cloud/version'
4
+ require 'tuya_cloud/api'
5
+ require 'tuya_cloud/device'
6
+ require 'tuya_cloud/error'
7
+
8
+ module TuyaCloud
9
+ end
@@ -0,0 +1,39 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "tuya_cloud/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tuya_cloud"
8
+ spec.version = TuyaCloud::VERSION
9
+ spec.authors = ["Jeremy Mercer"]
10
+ spec.email = ["dzheremi@outlook.com"]
11
+ spec.homepage = "https://github.com/dzheremi/tuya_cloud"
12
+ spec.summary = "TuyaCloud is a small Ruby gem to allow control of smart devices connected to the Tuya Cloud,"\
13
+ " without the need to flash customer firmware or discover device keys."
14
+ spec.description = <<-DESCEND
15
+ TuyaCloud is a small Ruby gem to allow control of smart devices connected to the
16
+ Tuya Cloud, without the need to flash custom firmware or discover device keys.
17
+ These devices are sold under many different brands internationally, and usually all have their own mobile
18
+ apps (i.e. Smart Life, Tuya Smart or Genio).
19
+ This Ruby implementation was based on work by PaulAnnekov (https://github.com/PaulAnnekov/tuyaha), using an
20
+ endpoint specifically designed for Home Assistant.
21
+ The online devices which are supported at this stage are LED globes (white and colour) and mains switches,
22
+ along with support for activating scenes you've created within the Tuya app.
23
+ DESCEND
24
+ spec.license = "MIT"
25
+
26
+ # Specify which files should be added to the gem when it is released.
27
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
29
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
30
+ end
31
+ spec.bindir = "exe"
32
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
+ spec.require_paths = ["lib"]
34
+
35
+ spec.add_development_dependency "bundler", "~> 2.0"
36
+ spec.add_development_dependency "rake", "~> 10.0"
37
+ spec.add_development_dependency "rspec", "~> 3.0"
38
+ spec.add_development_dependency "webmock"
39
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tuya_cloud
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Mercer
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-09-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
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: " TuyaCloud is a small Ruby gem to allow control of smart devices
70
+ connected to the \n Tuya Cloud, without the need to flash custom firmware or
71
+ discover device keys.\n These devices are sold under many different brands internationally,
72
+ and usually all have their own mobile\n apps (i.e. Smart Life, Tuya Smart or
73
+ Genio).\n This Ruby implementation was based on work by PaulAnnekov (https://github.com/PaulAnnekov/tuyaha),
74
+ using an\n endpoint specifically designed for Home Assistant.\n The online
75
+ devices which are supported at this stage are LED globes (white and colour) and
76
+ mains switches,\n along with support for activating scenes you've created within
77
+ the Tuya app.\n"
78
+ email:
79
+ - dzheremi@outlook.com
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files: []
83
+ files:
84
+ - ".gitignore"
85
+ - ".rspec"
86
+ - ".ruby-version"
87
+ - ".travis.yml"
88
+ - Gemfile
89
+ - Gemfile.lock
90
+ - LICENSE.txt
91
+ - README.md
92
+ - Rakefile
93
+ - bin/console
94
+ - bin/setup
95
+ - lib/tuya_cloud.rb
96
+ - lib/tuya_cloud/api.rb
97
+ - lib/tuya_cloud/device.rb
98
+ - lib/tuya_cloud/error.rb
99
+ - lib/tuya_cloud/version.rb
100
+ - tuya_cloud.gemspec
101
+ homepage: https://github.com/dzheremi/tuya_cloud
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubygems_version: 3.0.3
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: TuyaCloud is a small Ruby gem to allow control of smart devices connected
124
+ to the Tuya Cloud, without the need to flash customer firmware or discover device
125
+ keys.
126
+ test_files: []