hue_ble 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 35bbe17153882b5eef86728879b72cc48a954b2d540d42960555305804412a95
4
+ data.tar.gz: b964a25de0c0f4ced9af51495cc12a13a8b1131a6b7b8eee8b63e5eccc28df1d
5
+ SHA512:
6
+ metadata.gz: 584f0ca1ddf9280a8039299c4a92636e8213bc229c660555558a3959f21a1b9d75407f76553e8b2ee72eefeb7e7fffd731d049a4cbacbc11453faeb08c385006
7
+ data.tar.gz: 99dd3ecb36ad5ad010497a957b4c814340b9ce48cdfe7d50fbe91f4c7fdf614c3825a77f4892b3473fdca4f1677c253b8c0d9ddc43ab678016a0c877c220371b
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in hue_ble.gemspec
4
+ gemspec
5
+
6
+ # ruby_ble-1.0.0 is not compatible with recent bluez DBus interface, so use patched version...
7
+ gem 'ble', git: 'https://gitlab.com/NeoCat/ruby-ble.git'
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 NeoCat
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.
@@ -0,0 +1,91 @@
1
+ # HueBLE
2
+
3
+ This gem enables to control Hue light bulbs which support Bluetooth LE using Ruby.
4
+
5
+ ## Warning
6
+
7
+ This gem is very experimental and unstable.
8
+
9
+ - You need to factory reset Hue bulbs using smartphone apps before pairing.
10
+ - Once the pairing is lost by some reasons, you need to reset the bulbs again before reconnecting to them.
11
+ - The Hue's Bluetooth LE control interface may be subject to change in the future.
12
+ - bluez seems not to support connecting to more than 5 BLE devices at the same time. You need to disconnect and reconnect to others if you want to control more than 5 blubs.
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'hue_ble'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle install
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install hue_ble
29
+
30
+ ## Usage
31
+
32
+ At first, reset the Hue bulbs using Hue Bluetooth app on your smartphone.
33
+ Then, you need to scan bulbs and pair with them:
34
+
35
+ ```ruby
36
+ require 'hue_ble'
37
+ HueBLE.scan_cli
38
+ ```
39
+
40
+ When unpaired bulbs are found, this confirms if you want to pair with them.
41
+ The BLE address is randomized on factory reset.
42
+ Your PC's BLE adapger and bulbs need to be very close (<90cm) on pairing, and the bulbs are scanned right after powered on.
43
+
44
+ This scan will also add the already paired bulbs to the HueBLE class. (So you need to scan it every time your script is launched.)
45
+
46
+ Once bulbs are added, you can control them as followings:
47
+
48
+ ```ruby
49
+ def all_on
50
+ HueBLE.hues.each_value { |hue| hue.on }
51
+ end
52
+
53
+ def all_off
54
+ HueBLE.hues.each_value { |hue| hue.off }
55
+ end
56
+
57
+ def all_set(brightness: nil, color_temperature: nil, color: nil)
58
+ HueBLE.hues.each_value do |hue|
59
+ hue.brightness = brightness if brightness
60
+ hue.color_temperature = color_temperature if color_temperature
61
+ hue.color = color if color
62
+ rescue BLE::Characteristic::NotFound
63
+ end
64
+ end
65
+
66
+ def party!
67
+ 30.times do
68
+ HueBLE.hues.each_value do |hue|
69
+ hue.brightness = rand(253) + 1
70
+ hue.color_temperature = rand(510) + 1
71
+ 10.times do
72
+ hue.color = [rand(65533) + 1, rand(65533) + 1]
73
+ break
74
+ rescue BLE::Characteristic::NotFound
75
+ break
76
+ rescue
77
+ next
78
+ end
79
+ end
80
+ sleep 1
81
+ end
82
+ end
83
+ ```
84
+
85
+ ## Contributing
86
+
87
+ Bug reports and pull requests are welcome on GitHub at https://github.com/NeoaCat/ruby_hue_ble.
88
+
89
+ ## License
90
+
91
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "hue_ble"
3
+ spec.version = "0.1.0"
4
+ spec.authors = ["NeoCat"]
5
+ spec.email = ["neocat@neocat.jp"]
6
+
7
+ spec.summary = %q{Control Hue light bulbs with Bluetooth LE support.}
8
+ spec.description = %q{Control color temperature, brightness, and color of Hue light bulbs which supports Bluetooth LE.}
9
+ spec.homepage = "https://github.com/NeoCat/ruby_hue_ble"
10
+ spec.license = "MIT"
11
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
12
+
13
+ spec.metadata["homepage_uri"] = spec.homepage
14
+ spec.metadata["source_code_uri"] = spec.homepage
15
+
16
+ # Specify which files should be added to the gem when it is released.
17
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ end
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_dependency 'ble'
26
+ end
@@ -0,0 +1,157 @@
1
+ require 'ble'
2
+
3
+ class HueBLE
4
+ VERSION = "0.1.0"
5
+
6
+ extend Forwardable
7
+
8
+ HUE_BLE_SERVICE_UUID = '932c32bd-0000-47a2-835a-a8d455b859dd'
9
+
10
+ BLE::Service.add HUE_BLE_SERVICE_UUID,
11
+ name: 'Hue Lamp Control',
12
+ nick: :hue_lamp_control
13
+
14
+ BLE::Characteristic.add '932c32bd-0002-47a2-835a-a8d455b859dd',
15
+ name: 'ON',
16
+ nick: :on,
17
+ vrfy: ->(x) { x == true || x == false },
18
+ in: ->(s) { s[0] == "\x01" },
19
+ out: ->(v) { v ? "\x01" : "\x00" }
20
+
21
+ BLE::Characteristic.add '932c32bd-0003-47a2-835a-a8d455b859dd',
22
+ name: 'Brightness',
23
+ nick: :brightness,
24
+ vrfy: ->(x) { x >= 1 && x <= 254 },
25
+ in: ->(s) { s[0].ord },
26
+ out: ->(v) { v.chr }
27
+
28
+ BLE::Characteristic.add '932c32bd-0004-47a2-835a-a8d455b859dd',
29
+ name: 'Color Temperature',
30
+ nick: :color_temperature,
31
+ vrfy: ->(x) { x >= 1 && x <= 511 },
32
+ in: ->(s) { s.unpack('v')[0] },
33
+ out: ->(v) { [v].pack('v') }
34
+
35
+ BLE::Characteristic.add '932c32bd-0005-47a2-835a-a8d455b859dd',
36
+ name: 'Color a,b',
37
+ nick: :color,
38
+ vrfy: ->(x) { x.is_a?(Array) && x.size == 2 && x.all?{ |v| v >= 1 && v <= 65534 } },
39
+ in: ->(s) { s.unpack('v*') },
40
+ out: ->(v) { v.pack('v*') }
41
+
42
+ def self.hues
43
+ @hues ||= {}
44
+ end
45
+
46
+ def self.scan(adapter_name: BLE::Adapter.list.first, wait: 5)
47
+ adapter = BLE::Adapter.new(adapter_name)
48
+ adapter.start_discovery
49
+ sleep(wait)
50
+ adapter.stop_discovery
51
+
52
+ unpaired_devices = []
53
+ adapter.devices.each do |address|
54
+ device = adapter[address]
55
+ name = device.name rescue nil
56
+ if name == 'Hue Lamp' && !device.is_paired?
57
+ unpaired_devices << device
58
+ elsif device.services.include?(HUE_BLE_SERVICE_UUID)
59
+ hues[device.address] = new(device)
60
+ end
61
+ end
62
+
63
+ { hues: hues, unpaired_devices: unpaired_devices }
64
+ end
65
+
66
+ def self.add(address, adapter_name: BLE::Adapter.list.first)
67
+ adapter = BLE::Adapter.new(adapter_name)
68
+ device = adapter[address]
69
+ device.trusted = true
70
+ unless device.is_paired?
71
+ begin
72
+ device.pair
73
+ sleep(3)
74
+ device = adapter[address] # reload
75
+ rescue BLE::NotAuthorized => e
76
+ puts "Failed to pair: #{e}. Please try scanning after power off/on the bulb, getting closer, or resetting it using the smart phone app."
77
+ end
78
+ end
79
+ fail "device does not have Hue Lamp Control service" unless device.services.include?(HUE_BLE_SERVICE_UUID)
80
+ hues[address] = new(device)
81
+ end
82
+
83
+ def self.scan_cli(reset = false)
84
+ puts "Scanning devices ..."
85
+ scan_results = scan(wait: 1)
86
+ puts "Found #{scan_results[:hues].count} Hue devices:"
87
+ scan_results[:hues].each { |address, device| puts " #{address} #{device.name}" }
88
+
89
+ if @reset
90
+ scan_results[:hues].each { |address, device| device.remove }
91
+ scan_results[:unpaired_devices].each { |device| device.remove }
92
+ return
93
+ end
94
+
95
+ scan_results[:unpaired_devices].each do |device|
96
+ print "Found a new #{device.name} #{device.address} : Do you want to pair? (Y/n)> "
97
+ STDOUT.flush
98
+ add(device.address) if ["Y", "y", "\n"].include? gets[0]
99
+ end
100
+ end
101
+
102
+
103
+ def_delegators :@device, :address, :name, :alias, :alias=, :is_connected?, :connect, :disconnect, :pair, :is_paired?
104
+
105
+ def initialize(device)
106
+ @device = device
107
+ end
108
+
109
+ def inspect
110
+ "#<HueBLE:#{@device.address}>"
111
+ end
112
+
113
+ def on?
114
+ connect
115
+ @device[:hue_lamp_control, :on]
116
+ end
117
+
118
+ def on
119
+ connect
120
+ @device[:hue_lamp_control, :on] = true
121
+ end
122
+
123
+ def off
124
+ connect
125
+ @device[:hue_lamp_control, :on] = false
126
+ end
127
+
128
+ def brightness
129
+ connect
130
+ @device[:hue_lamp_control, :brightness]
131
+ end
132
+
133
+ def brightness=(value)
134
+ connect
135
+ @device[:hue_lamp_control, :brightness] = value
136
+ end
137
+
138
+ def color_temperature
139
+ connect
140
+ @device[:hue_lamp_control, :color_temperature]
141
+ end
142
+
143
+ def color_temperature=(value)
144
+ connect
145
+ @device[:hue_lamp_control, :color_temperature] = value
146
+ end
147
+
148
+ def color
149
+ connect
150
+ @device[:hue_lamp_control, :color]
151
+ end
152
+
153
+ def color=(value)
154
+ connect
155
+ @device[:hue_lamp_control, :color] = value
156
+ end
157
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hue_ble
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - NeoCat
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-08-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ble
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Control color temperature, brightness, and color of Hue light bulbs which
28
+ supports Bluetooth LE.
29
+ email:
30
+ - neocat@neocat.jp
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - Gemfile
37
+ - LICENSE.txt
38
+ - README.md
39
+ - hue_ble.gemspec
40
+ - lib/hue_ble.rb
41
+ homepage: https://github.com/NeoCat/ruby_hue_ble
42
+ licenses:
43
+ - MIT
44
+ metadata:
45
+ homepage_uri: https://github.com/NeoCat/ruby_hue_ble
46
+ source_code_uri: https://github.com/NeoCat/ruby_hue_ble
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 2.3.0
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.7.6.2
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Control Hue light bulbs with Bluetooth LE support.
67
+ test_files: []