hue-cli 0.1.0 → 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.
data/README.md CHANGED
@@ -10,19 +10,21 @@ To begin using, install the ruby gem (this requires ruby 1.9 and rubygems)
10
10
  $ gem install hue-cli
11
11
  ```
12
12
 
13
+ This will install the "hue" command.
14
+
13
15
  # Usage
14
16
 
15
- This install the hue command. Simply type
17
+ To check the bridge state, simply type
16
18
 
17
19
  ```
18
20
  $ hue
19
21
  ```
20
22
 
21
- and the bridge state will be verified. Follow the instructions to register the application with your bridge.
23
+ If this is the first time the command is run, it will scan for bridges on the network and attempt to register the application. Follow the on-screen instructions to do so.
22
24
 
23
25
  ## Register
24
26
 
25
- You can explicity register the application with
27
+ You can also explicity register the application with
26
28
 
27
29
  ```
28
30
  $ hue register
@@ -30,13 +32,20 @@ $ hue register
30
32
 
31
33
  ## Bridge state
32
34
 
33
- Examine the current state of the bridge
35
+ Once registered, examine the current state of the bridge.
34
36
 
35
37
  ```
36
38
  $ hue
37
39
  Philips Hue
38
- IP: 196.168.0.1
39
40
  Button pressed: false
41
+ Timestamp: 2013-09-02T17:44:10
42
+ Network configuration:
43
+ IP: 196.168.0.1
44
+ Gateway: 196.168.0.255
45
+ Mask: 255.255.255.0
46
+ DHCP: true
47
+ MAC: 00:00:00:00:00:00
48
+ Proxy: none:0
40
49
  Applications:
41
50
  073f2ed95fcbbef2532c751dd404cc9d : hue-cli
42
51
  Lights:
@@ -45,26 +54,48 @@ Lights:
45
54
  3. Living Corner Lamp - OFF
46
55
  ```
47
56
 
57
+ ## Lights state
58
+
59
+ ### Examine or operate on all lights.
60
+
61
+ ```
62
+ $ hue lights
63
+ 1. Bedroom - Overhead: ON
64
+ Brightness: 254 (100%)
65
+ Color: XY=[0.6736, 0.3221], RGB\u2248[255, 60, 40]
66
+ 2. Living Room - Cabinet: OFF
67
+ Brightness: 142 (56%)
68
+ Color: XY=[0.674, 0.322], RGB\u2248[255, 60, 40]
69
+ 3. Living Room - Overhead: ON
70
+ Brightness: 254 (100%)
71
+ Color: Temperature=2710°K (369 mired), RGB\u2248[255, 166, 87]
72
+ ```
73
+
74
+ ### Find new lights.
75
+
76
+ ```
77
+ $ hue lights find
78
+ ```
48
79
  ## Light state
49
80
 
50
- Examine the state of one of the lights
81
+ Examine the state of a single light
51
82
 
52
83
  ```
53
- $ hue lights 1
84
+ $ hue light 1
54
85
  ```
55
86
 
56
87
  or just
57
88
 
58
89
  ```
59
90
  $ hue 1
60
- Living Overhead: ON
61
- Brightness: 254 (100%)
62
- Color: Temperature=2012°K (497 mired), RGB[255, 136, 13]
91
+ 1. Bedroom - Overhead: ON
92
+ Brightness: 254 (100%)
93
+ Color: XY=[0.6736, 0.3221], RGB\u2248[255, 60, 40]
63
94
  ```
64
95
 
65
- ## Change Light state
96
+ ### Change Light state
66
97
 
67
- Change a single lights state with the follow (rather self-explanatory) commands
98
+ Change a single light state with the follow (rather self-explanatory) commands
68
99
 
69
100
  ```
70
101
  $ hue 1 on
@@ -74,9 +105,10 @@ $ hue 1 blink
74
105
  $ hue 1 solid
75
106
  ```
76
107
 
77
- ### Light brightness
108
+ ### Brightness
109
+
110
+ Brightness can be set with a value (0-255) or percentage (0%-100%)
78
111
 
79
- The lights brightness command takes a value (0-255) or percentage (0%-100%)
80
112
  ```
81
113
  $ hue 1 brightness 200
82
114
  $ hue 1 brightness 50%
@@ -86,18 +118,22 @@ Brightness: 128 (50%)
86
118
  Color: Temperature=2012°K (497 mired), RGB≈[255, 136, 13]
87
119
  ```
88
120
 
89
- ### Light color
121
+ ### Color
122
+
123
+ The color command takes 1-3 arguments, each interpreted depending on range and value.
90
124
 
91
- The lights color command takes 1-3 arguments, each interpreted depending on range and value.
125
+ Set to 6500 Kelvin.
92
126
 
93
127
  ```
94
- $ hue 1 color 6500
128
+ $ hue 1 color 6500
95
129
  $ hue 1
96
130
  Living Overhead: ON
97
131
  Brightness: 128 (50%)
98
132
  Color: Temperature=6500°K (153 mired), RGB≈[255, 254, 250]
99
133
  ```
100
134
 
135
+ Set to 240 mired.
136
+
101
137
  ```
102
138
  $ hue 1 color 240
103
139
  $ hue 1
@@ -106,6 +142,8 @@ Brightness: 128 (50%)
106
142
  Color: Temperature=4167°K (240 mired), RGB≈[255, 208, 170]
107
143
  ```
108
144
 
145
+ Set the hue and saturation.
146
+
109
147
  ```
110
148
  $ hue 1 color 30000 255
111
149
  $ hue 1
@@ -114,4 +152,19 @@ Brightness: 128 (50%)
114
152
  Color: Hue=30000, Saturation=255, RGB≈[0, 255, 190]
115
153
  ```
116
154
 
117
- ## More coming...
155
+ Set the XY
156
+
157
+ ```
158
+ $ hue 1 color 0.25 0.25
159
+ $ hue 1
160
+ Living Overhead: ON
161
+ Brightness: 128 (50%)
162
+ Color: Hue=30000, Saturation=255, RGB≈[0, 255, 190]
163
+ ```
164
+ ## Set all lights.
165
+
166
+ All the single light state commands can be applied to all lights.
167
+
168
+ ```
169
+ $ hue lights brightness 50%
170
+ ```
data/Rakefile CHANGED
@@ -16,4 +16,30 @@ rescue LoadError
16
16
  end
17
17
  end
18
18
 
19
+ namespace :gem do
20
+ desc 'Build the gem'
21
+ task :build do
22
+ `mkdir -p pkg`
23
+ `gem build hue-cli.gemspec`
24
+ `mv *.gem pkg/`
25
+ end
26
+
27
+ desc 'Publish the gem'
28
+ task :publish => :build do
29
+ gem = `ls pkg | sort | tail -n 1`
30
+ exec("gem push pkg/#{gem}")
31
+ end
32
+
33
+ desc 'Install the gem locally'
34
+ task :install => :build do
35
+ gem = `ls pkg`.split.sort
36
+ `gem install pkg/#{gem.last}`
37
+ end
38
+ end
39
+
40
+ desc 'Remove generated files'
41
+ task :clean do
42
+ `rm -rf pkg`
43
+ end
44
+
19
45
  task :default => [:spec]
@@ -0,0 +1,9 @@
1
+ "relax": {"on":true,"bri":254,"ct":467,"alert":"none","effect":"none"}
2
+ "energize": {"on":true,"bri":203,"ct":156,"alert":"none","effect":"none"}
3
+ "reading": {"on":true,"bri":240,"ct":346,"alert":"none","effect":"none"}
4
+ "concentrate": {"on":true,"bri":219,"ct":231,"alert":"none","effect":"none"}
5
+ "red": {"on":true,"bri":254,"xy":[0.67,0.32],"alert":"none","effect":"none"}
6
+ "blue": {"on":true,"bri":254,"xy":[0.17,0.04],"alert":"none","effect":"none"}
7
+ "green": {"on":true,"bri":254,"xy":[0.41,0.52],"alert":"none","effect":"none"}
8
+ "white": {"on":true,"bri":254,"xy":[0.31,0.33],"alert":"none","effect":"none"}
9
+ "pink": {"on":true,"bri":254,"xy":[0.39,0.17],"alert":"none","effect":"none"}
data/hue-cli.gemspec CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "hue-cli"
6
- s.version = '0.1.0'
6
+ s.version = '0.1.1'
7
7
  s.authors = ["Birkir A. Barkarson", ""]
8
8
  s.email = ["birkirb@stoicviking.net"]
9
9
  s.homepage = "https://github.com/birkirb/hue-lib"
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.require_paths = ["lib"]
19
19
 
20
20
  s.add_runtime_dependency("json")
21
- s.add_runtime_dependency("hue-lib", '>= 0.7.0')
21
+ s.add_runtime_dependency("hue-lib", '>= 0.7.2')
22
22
  s.add_development_dependency("rspec", '>= 2.6.0')
23
23
  s.add_development_dependency("mocha", '>= 0.9.0')
24
24
  s.add_development_dependency("webmock", '>= 1.8.0')
@@ -27,10 +27,10 @@ module Hue
27
27
 
28
28
  def is_available!(method_name)
29
29
  is_available?(method_name) or
30
- raise Error.new("Action '#{method_name.to_s}' is not available for operation '#{name}'")
30
+ raise Error.new("Action '#{method_name.to_s}' is not available for operation '#{class_name}'")
31
31
  end
32
32
 
33
- def name
33
+ def class_name
34
34
  self.class.name.gsub(/.*\:\:/, '').downcase
35
35
  end
36
36
 
@@ -39,11 +39,10 @@ module Hue
39
39
  end
40
40
 
41
41
  def parse_methods
42
- @methods = self.class.instance_methods(false).inject(Hash.new(false)) do |hash, method_name|
42
+ @methods = (self.class.instance_methods - Command.instance_methods).inject(Hash.new(false)) do |hash, method_name|
43
43
  hash[method_name] = true
44
44
  hash
45
45
  end
46
- @methods[:execute] = false
47
46
  end
48
47
 
49
48
  def send_method(*args)
@@ -18,7 +18,13 @@ module Hue
18
18
  # bulb exists (is valid?)
19
19
 
20
20
  if args.size > 0
21
- super(*args)
21
+ if is_available?(args.first)
22
+ super(*args)
23
+ else
24
+ if _alias = Processors::LightStateAlias.new(args.join(' '))
25
+ bulb.state = _alias.state
26
+ end
27
+ end
22
28
  else
23
29
  bulb.print_state
24
30
  end
@@ -54,6 +60,39 @@ module Hue
54
60
  bulb.color = Colors.parse(*args)
55
61
  end
56
62
 
63
+ def name(*args)
64
+ name = args.join(' ')
65
+ bulb.name = name
66
+ end
67
+
68
+ def action(*args)
69
+ bulb.effect = args.join
70
+ end
71
+
72
+ def effect(*args)
73
+ bulb.effect = args.join
74
+ end
75
+
76
+ def colorloop(*args)
77
+ bulb.colorloop
78
+ end
79
+
80
+ def clear(*args)
81
+ case args.first
82
+ when 'effect'
83
+ bulb.clear_effect
84
+ when 'action'
85
+ bulb.solid
86
+ else
87
+ bulb.clear_effect
88
+ bulb.solid
89
+ end
90
+ end
91
+
92
+ def dump(*args)
93
+ puts bulb.state.to_json
94
+ end
95
+
57
96
  end
58
97
  end
59
98
  end
@@ -0,0 +1,29 @@
1
+ module Hue
2
+ module CLI
3
+ module Commands
4
+ class Lights < Hue::CLI::Command
5
+
6
+ def execute(*args)
7
+ if args.size > 0
8
+ if is_available?(args.first)
9
+ send_method(*args)
10
+ else
11
+ bridge.lights.each do |number, name|
12
+ Light.new.execute(number, *args)
13
+ end
14
+ end
15
+ else
16
+ bridge.print_bulbs
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ def find
23
+ bridge.add_lights
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ module Hue
2
+ module CLI
3
+ module Processors
4
+ class LightStateAlias
5
+
6
+ ALIAS_FILE_NAME = 'light_alias.yml'
7
+ ALIAS_FILE_PATHS = [
8
+ File.join(Hue::CLI::LOCATION, 'config'), # Default
9
+ '/etc/hue/', # System
10
+ '~/.hue-cli/', # User
11
+ ]
12
+
13
+ def self.read_alias_files
14
+ ALIAS_FILE_PATHS.each do |path|
15
+ file_path = File.join(path, ALIAS_FILE_NAME)
16
+ yaml = YAML.load_file(file_path) rescue []
17
+ yaml.each do |name, state|
18
+ @@alias_map[name.to_sym] = state
19
+ end
20
+ end
21
+ end
22
+
23
+ @@alias_map = Hash.new
24
+ read_alias_files
25
+
26
+ public
27
+
28
+ attr_reader :name,:state
29
+
30
+ def initialize(name)
31
+ @name = name
32
+ @state = @@alias_map[name.to_sym]
33
+ if @state.nil?
34
+ raise Error.new("Unknown light state: #{name}")
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
data/lib/hue/cli.rb CHANGED
@@ -1,14 +1,21 @@
1
1
  require 'hue'
2
2
  require 'find'
3
- require_relative 'cli/command'
4
- require_relative 'extensions/bulb'
5
- require_relative 'extensions/bridge'
6
- require_relative 'extensions/hue'
7
3
 
8
4
  module Hue
9
5
  module CLI
6
+
7
+ LOCATION = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
8
+
9
+ require_relative 'cli/command'
10
+ require_relative 'cli/processors/light_state_alias'
11
+ require_relative 'extensions/bulb'
12
+ require_relative 'extensions/bridge'
13
+ require_relative 'extensions/hue'
14
+
10
15
  class Error < StandardError; end;
11
16
 
17
+ ERROR_BRIDGE_CONNECTION_PROBLEM = /execution expired|No route to host/
18
+
12
19
  def self.bridge
13
20
  Hue.application
14
21
  end
@@ -20,14 +27,22 @@ module Hue
20
27
  first_arg = args.shift
21
28
  if command = commands[first_arg.to_sym]
22
29
  command.new.execute(*args)
23
- else
30
+ elsif first_arg.to_i > 0
24
31
  Commands::Light.new.execute(first_arg, *args)
32
+ else
33
+ raise Error.new("Unknown command: #{first_arg}")
25
34
  end
26
35
  else
27
36
  print_default
28
37
  end
29
38
  rescue Hue::Error => err
30
- puts err.message
39
+ if ERROR_BRIDGE_CONNECTION_PROBLEM.match(err.message)
40
+ Hue.logger.warn("Error contacting bridge, verifying IP and trying again.")
41
+ Hue.register_bridges
42
+ retry
43
+ else
44
+ puts err.message
45
+ end
31
46
  rescue Hue::CLI::Error => err
32
47
  puts err.message
33
48
  end
@@ -36,8 +51,8 @@ module Hue
36
51
 
37
52
  def self.print_default
38
53
  Command.new.execute
39
- rescue Hue::Error => err
40
- puts "Failed to initialize bridge."
54
+ rescue Hue::Config::NotFound => err
55
+ puts "Application not registered."
41
56
  if bridges = Hue.register_bridges
42
57
  puts "Found bridges:"
43
58
  bridges.each do |key, config|
@@ -1,12 +1,22 @@
1
1
  module Hue
2
2
  class Bridge
3
+ include Indentation
3
4
 
4
5
  def print_state
5
6
  state = self.status
6
7
  config = state['config']
7
8
  puts "#{config['name']}"
8
- puts "IP: #{config['ipaddress']}"
9
9
  puts "Button pressed: #{config['linkbutton']}"
10
+ puts "Timestamp: #{config['UTC']}"
11
+ puts "Network configuration:"
12
+ puts " IP: #{config['ipaddress']}"
13
+ puts " Gateway: #{config['gateway']}"
14
+ puts " Mask: #{config['netmask']}"
15
+ puts " DHCP: #{config['dhcp']}"
16
+ puts " MAC: #{config['mac']}"
17
+ if !config['proxyaddress'].strip.empty?
18
+ puts " Proxy: #{config['proxyaddress']}:#{config['proxyport']}"
19
+ end
10
20
  puts "Applications:"
11
21
  config['whitelist'].each do |key, values|
12
22
  puts " #{key} : #{values['name']}"
@@ -17,5 +27,11 @@ module Hue
17
27
  end
18
28
  end
19
29
 
30
+ def print_bulbs
31
+ self.bulbs.each do |bulb|
32
+ bulb.print_state
33
+ end
34
+ end
35
+
20
36
  end
21
37
  end
@@ -1,14 +1,21 @@
1
+ require_relative '../../utilities/indentation'
2
+
1
3
  module Hue
2
4
  class Bulb
5
+ include Indentation
3
6
 
4
7
  def print_state
5
- puts "#{self.name}: #{self.on? ? 'ON' : 'OFF'}"
6
- puts "Brightness: #{self.brightness} (#{(self.brightness_percent).to_i}%)"
7
- print "Color: "
8
- print self.color.to_s
9
- puts ", #{self.color.to_rgb.to_s}"
10
- if blinking?
11
- puts "Alert: Blinking!"
8
+ spaces = 4
9
+ puts "#{self.id}.".ljust(spaces) + "#{self.name}: #{self.on? ? 'ON' : 'OFF'}"
10
+ indent(spaces) do
11
+ puts "Brightness: #{self.brightness} (#{(self.brightness_percent).to_i}%)"
12
+ puts "Color: #{self.color}, #{self.color.to_rgb}"
13
+ transitory_state = [
14
+ (self.transition_time > 0 ? "Transition time: #{self.transition_time} sec" : nil),
15
+ (self.blinking? ? 'Alert: Blinking!' : nil),
16
+ (self.effect? ? "Effect: #{self.effect}" : nil),
17
+ ].compact
18
+ puts transitory_state.join(", ") unless transitory_state.empty?
12
19
  end
13
20
  end
14
21
 
@@ -0,0 +1,23 @@
1
+ module Indentation
2
+ DEFAULT_INDENTATION_SIZE = 2
3
+ @@indentation_size = 0
4
+ @@indentation_char = ' '
5
+ @@indentation_level = 0
6
+
7
+ def indent(size = DEFAULT_INDENTATION_SIZE, &block)
8
+ original_size = @@indentation_size
9
+ @@indentation_size = size
10
+ @@indentation_level += 1
11
+ yield
12
+ ensure
13
+ @@indentation_size = original_size
14
+ @@indentation_level -= 1
15
+ end
16
+
17
+ def puts(*message)
18
+ message.each do |line|
19
+ print(@@indentation_char * @@indentation_size * @@indentation_level)
20
+ super(line)
21
+ end
22
+ end
23
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hue-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-04 00:00:00.000000000 Z
13
+ date: 2013-09-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -35,7 +35,7 @@ dependencies:
35
35
  requirements:
36
36
  - - ! '>='
37
37
  - !ruby/object:Gem::Version
38
- version: 0.7.0
38
+ version: 0.7.2
39
39
  type: :runtime
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirements:
44
44
  - - ! '>='
45
45
  - !ruby/object:Gem::Version
46
- version: 0.7.0
46
+ version: 0.7.2
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -106,14 +106,18 @@ files:
106
106
  - README.md
107
107
  - Rakefile
108
108
  - bin/hue
109
+ - config/light_alias.yml
109
110
  - hue-cli.gemspec
110
111
  - lib/hue/cli.rb
111
112
  - lib/hue/cli/command.rb
112
113
  - lib/hue/cli/commands/light.rb
114
+ - lib/hue/cli/commands/lights.rb
113
115
  - lib/hue/cli/commands/register.rb
116
+ - lib/hue/cli/processors/light_state_alias.rb
114
117
  - lib/hue/extensions/bridge.rb
115
118
  - lib/hue/extensions/bulb.rb
116
119
  - lib/hue/extensions/hue.rb
120
+ - lib/utilities/indentation.rb
117
121
  homepage: https://github.com/birkirb/hue-lib
118
122
  licenses: []
119
123
  post_install_message:
@@ -139,4 +143,3 @@ signing_key:
139
143
  specification_version: 3
140
144
  summary: Command line interface for controlling Philips Hue system's lights and bridge.
141
145
  test_files: []
142
- has_rdoc: