huey 0.2.0 → 1.0.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.
data/Gemfile CHANGED
@@ -2,4 +2,9 @@ source "http://rubygems.org"
2
2
  gemspec
3
3
 
4
4
  gem 'rake'
5
- gem 'color-tools'
5
+ gem 'color-tools'
6
+ gem 'chronic'
7
+
8
+ group :development, :test do
9
+ gem 'timecop'
10
+ end
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- huey (0.1.0)
4
+ huey (1.0.0)
5
+ chronic (>= 0.9.0)
5
6
  eventmachine (>= 1.0.0)
6
7
  httparty (>= 0.9.0)
7
8
 
@@ -9,18 +10,20 @@ GEM
9
10
  remote: http://rubygems.org/
10
11
  specs:
11
12
  addressable (2.3.2)
13
+ chronic (0.9.0)
12
14
  color-tools (1.3.0)
13
15
  crack (0.3.1)
14
16
  eventmachine (1.0.0)
15
- httparty (0.9.0)
17
+ httparty (0.10.2)
16
18
  multi_json (~> 1.0)
17
- multi_xml
19
+ multi_xml (>= 0.5.2)
18
20
  metaclass (0.0.1)
19
21
  mocha (0.13.1)
20
22
  metaclass (~> 0.0.1)
21
- multi_json (1.5.0)
22
- multi_xml (0.5.1)
23
+ multi_json (1.6.1)
24
+ multi_xml (0.5.3)
23
25
  rake (0.9.5)
26
+ timecop (0.5.9.2)
24
27
  webmock (1.9.0)
25
28
  addressable (>= 2.2.7)
26
29
  crack (>= 0.1.7)
@@ -31,9 +34,11 @@ PLATFORMS
31
34
 
32
35
  DEPENDENCIES
33
36
  bundler
37
+ chronic
34
38
  color-tools
35
39
  huey!
36
40
  mocha (>= 0.13.1)
37
41
  rake
42
+ timecop
38
43
  webmock (>= 1.9.0)
39
44
  yard (>= 0.8.3)
data/README.markdown CHANGED
@@ -7,11 +7,9 @@ Easy control of your Phillips Hue lights, in an attractive Gem format!
7
7
  Installing Huey is pretty simple. First include the Gem in your Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'huey', git: 'git://github.com/Veraticus/huey.git'
10
+ gem 'huey'
11
11
  ```
12
12
 
13
- (It's not in RubyGems yet because I'm not totally sure it's actually stable enough for release.)
14
-
15
13
  You shouldn't need to initialize anything to make Huey work correctly, but if you want to specify some configuration options go nuts:
16
14
 
17
15
  ```ruby
@@ -106,6 +104,49 @@ group.save # All changes you've made are committed to all the bulbs in a group
106
104
  group.update(bri: 200, ct: 500) # Set and save in one step
107
105
  ```
108
106
 
107
+ ### Events
108
+
109
+ You probably want to always do the same actions over and over again to a group of bulbs. To help encapsulate that idea, we have events.
110
+
111
+ ```ruby
112
+ all = Huey::Group.new(bulbs: Huey::Bulb.all)
113
+ event = Huey::Event.new(name: 'All Lights Off', group: all, actions: {on: false})
114
+
115
+ event.execute # All lights turn off
116
+ ```
117
+
118
+ If you like, you can schedule an event to execute only at a particular time if you have a really gimpy scheduling system.
119
+
120
+ ```ruby
121
+ event = Huey::Event.new(name: 'All Lights Off', group: all, actions: {on: false}, at: '9PM')
122
+
123
+ event.execute # nothing happens unless it's 9PM
124
+ Huey::Event.execute # run all events that should be run this second
125
+ ```
126
+
127
+ It's probably easier for you to just directly invoke events from your scheduling system (cron or the like). To aid with that you can load events from a YAML file:
128
+
129
+ ```ruby
130
+ Huey::Group.import('groups.yml') # So that we can find groups
131
+ Huey::Event.import('events.yml')
132
+ # The file should look like this:
133
+ # Wakeup Call:
134
+ # group: Bedroom
135
+ # at: 9AM
136
+ # actions:
137
+ # bri: 100
138
+ # "on": true # Note the quotes, `on` is a reserved word for Yaml parsers
139
+ #
140
+ # Goodnight Time:
141
+ # group: Living Room
142
+ # at: 12AM
143
+ # actions:
144
+ # bri: 10
145
+ # "on": false # Note the quotes, `on` is a reserved word for Yaml parsers
146
+
147
+ Huey::Event.find('Wakeup Call').execute
148
+ ```
149
+
109
150
  ## Attribution
110
151
 
111
152
  The structure of the configuration files and the modules are taken from [Mongoid](https://github.com/mongoid/mongoid), which had some really great ideas.
data/huey.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
20
20
 
21
21
  s.add_dependency('eventmachine', '>=1.0.0')
22
22
  s.add_dependency('httparty', '>=0.9.0')
23
+ s.add_dependency('chronic', '>=0.9.0')
23
24
 
24
25
  s.add_development_dependency('bundler', '>=0')
25
26
  s.add_development_dependency('yard', '>=0.8.3')
data/lib/huey/event.rb ADDED
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ module Huey
4
+
5
+ # An event encapsulates logic to send to a group, either at a certain time or arbitrarily
6
+ class Event
7
+ attr_accessor :group, :at, :actions, :name
8
+
9
+ def self.import(file)
10
+ hash = YAML.load_file(file)
11
+
12
+ hash.each do |key, value|
13
+ options = {name: key}
14
+ value.each do |k, v|
15
+ options[k.to_sym] = v
16
+ end
17
+
18
+ Huey::Event.new(options)
19
+ end
20
+ Huey::Event.all
21
+ end
22
+
23
+ def self.all
24
+ @all ||= []
25
+ end
26
+
27
+ def self.find(name)
28
+ Huey::Event.all.find {|s| s.name == name}
29
+ end
30
+
31
+ def self.execute(force = false)
32
+ Huey::Event.all.collect {|s| s.execute(force)}
33
+ end
34
+
35
+ def initialize(options)
36
+ [:group, :actions].each do |key|
37
+ raise ArgumentError, "You must supply #{key} to create an event" unless options.keys.include?(key)
38
+
39
+ self.instance_variable_set("@#{key}".to_sym, options[key])
40
+ end
41
+
42
+ self.at = options[:at]
43
+ self.name = options[:name]
44
+ self.group = Huey::Group.find(self.group) unless self.group.is_a?(Huey::Group)
45
+
46
+ Huey::Event.all << self
47
+ end
48
+
49
+ def should_run?
50
+ ((Chronic.parse(self.at) - 0.5)..(Chronic.parse(self.at) + 0.5)).cover?(Time.now)
51
+ end
52
+
53
+ def execute(force = false)
54
+ self.group.send(:update, actions) if force || at.nil? || should_run?
55
+ end
56
+
57
+ end
58
+
59
+ end
data/lib/huey/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Huey
2
- VERSION = "0.2.0"
3
- end
2
+ VERSION = "1.0.0"
3
+ end
data/lib/huey.rb CHANGED
@@ -5,6 +5,7 @@ require 'logger'
5
5
  require 'httparty'
6
6
  require 'color'
7
7
  require 'yaml'
8
+ require 'chronic'
8
9
 
9
10
  require 'huey/version'
10
11
 
@@ -14,6 +15,7 @@ require 'huey/ssdp'
14
15
  require 'huey/request'
15
16
  require 'huey/bulb'
16
17
  require 'huey/group'
18
+ require 'huey/event'
17
19
 
18
20
  module Huey
19
21
  extend self
@@ -0,0 +1,13 @@
1
+ Wakeup Call:
2
+ group: Bedroom
3
+ at: 9AM
4
+ actions:
5
+ bri: 100
6
+ "on": true
7
+
8
+ Goodnight Time:
9
+ group: Living Room
10
+ at: 12AM
11
+ actions:
12
+ bri: 10
13
+ "on": false
@@ -0,0 +1,3 @@
1
+ Living Room: [TV, Living Room - Fireplace]
2
+ Foyer: [Foyer]
3
+ Bedroom: [Bedroom]
data/test/test_helper.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  require 'test/unit'
2
2
  require 'webmock/test_unit'
3
3
  require "mocha/setup"
4
+ require 'timecop'
4
5
  require 'huey'
5
6
 
6
-
7
7
  class Test::Unit::TestCase
8
8
  def setup
9
9
  super
@@ -0,0 +1,99 @@
1
+ require 'test_helper'
2
+
3
+ class EventTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ super
7
+ Huey::Event.stubs(:all).returns([])
8
+
9
+ @bulb1 = init_bulb('1', 'Living Room - TV')
10
+ @bulb2 = init_bulb('2', 'Living Room - Fireplace')
11
+ @bulb3 = init_bulb('3', 'Foyer')
12
+ @bulb4 = init_bulb('4', 'Bedroom')
13
+ Huey::Bulb.stubs(:all).returns([@bulb1, @bulb2, @bulb3, @bulb4])
14
+
15
+ @group1 = Huey::Group.new(@bulb1, @bulb2)
16
+ @group1.name = 'Living Room'
17
+ @group2 = Huey::Group.new(@bulb1, @bulb2, @bulb3)
18
+ @group3 = Huey::Group.new(@bulb3)
19
+ @group4 = Huey::Group.new(@bulb4)
20
+ Huey::Group.stubs(:all).returns([@group1, @group2, @group3, @group4])
21
+ end
22
+
23
+ def test_initializes_event
24
+ @event = Huey::Event.new(group: @group1, at: '8PM', actions: {bri: 100, on: true})
25
+
26
+ assert_equal @group1, @event.group
27
+ assert_equal '8PM', @event.at
28
+ assert_equal @event.actions, {bri: 100, on: true}
29
+ end
30
+
31
+ def test_initializes_event_with_name
32
+ @event = Huey::Event.new(group: 'Living Room', at: '8PM', actions: {bri: 100, on: true})
33
+
34
+ assert_equal @group1, @event.group
35
+ end
36
+
37
+ def test_executes_event
38
+ @event = Huey::Event.new(group: @group1, at: '8PM', actions: {bri: 100, on: true})
39
+
40
+ @group1.expects(:update).once.returns(true)
41
+
42
+ Timecop.freeze(Chronic.parse('8PM')) do
43
+ assert @event.should_run?
44
+ Huey::Event.execute
45
+ end
46
+
47
+ Timecop.freeze(Chronic.parse('10PM')) do
48
+ assert !@event.should_run?
49
+ Huey::Event.execute
50
+ end
51
+ end
52
+
53
+ def test_executes_event_with_some_leeway
54
+ @event = Huey::Event.new(group: @group1, at: '8PM', actions: {bri: 100, on: true})
55
+
56
+ @group1.expects(:update).once.returns(true)
57
+
58
+ Timecop.freeze(Chronic.parse('8PM') - 0.3) do
59
+ assert @event.should_run?
60
+ Huey::Event.execute
61
+ end
62
+
63
+ Timecop.freeze(Chronic.parse('8PM') + 0.8) do
64
+ assert !@event.should_run?
65
+ Huey::Event.execute
66
+ end
67
+ end
68
+
69
+ def test_force_execution
70
+ @event = Huey::Event.new(group: @group1, at: '8PM', actions: {bri: 100, on: true})
71
+
72
+ @group1.expects(:update).twice.returns(true)
73
+
74
+ Timecop.freeze(Chronic.parse('10PM')) do
75
+ assert !@event.should_run?
76
+ @event.execute(true)
77
+ Huey::Event.execute(true)
78
+ end
79
+ end
80
+
81
+ def test_execute_event_without_schedule
82
+ @event = Huey::Event.new(group: @group1, actions: {bri: 100, on: true})
83
+
84
+ @group1.expects(:update).once.returns(true)
85
+
86
+ @event.execute
87
+ end
88
+
89
+ def test_import_schedule_from_yaml
90
+ Huey::Event.import('test/fixtures/events.yml')
91
+
92
+ assert_equal 2, Huey::Event.all.count
93
+ assert_equal 'Wakeup Call', Huey::Event.all[0].name
94
+ assert_equal Huey::Group.find('Bedroom'), Huey::Event.all[0].group
95
+ assert_equal '9AM', Huey::Event.all[0].at
96
+ assert_equal Huey::Event.all[0].actions, {'bri' => 100, 'on' => true}
97
+ end
98
+
99
+ end
@@ -4,6 +4,8 @@ class GroupTest < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
6
  super
7
+ Huey::Group.stubs(:all).returns([])
8
+
7
9
  @bulb1 = init_bulb('1', 'Living Room - TV')
8
10
  @bulb2 = init_bulb('2', 'Living Room - Fireplace')
9
11
  @bulb3 = init_bulb('3', 'Foyer')
@@ -31,9 +33,7 @@ class GroupTest < Test::Unit::TestCase
31
33
  end
32
34
 
33
35
  def test_initializes_groups_from_yml
34
- Huey::Group.instance_variable_set(:@all, [])
35
-
36
- Huey::Group.import('test/fixtures/group.yml')
36
+ Huey::Group.import('test/fixtures/groups.yml')
37
37
 
38
38
  assert_equal 3, Huey::Group.all.count
39
39
  assert_equal [@bulb1, @bulb2], Huey::Group.all[0].bulbs
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: huey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-20 00:00:00.000000000 Z
12
+ date: 2013-02-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -43,6 +43,22 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: 0.9.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: chronic
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.9.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.0
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: bundler
48
64
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +144,17 @@ files:
128
144
  - lib/huey/config.rb
129
145
  - lib/huey/config/options.rb
130
146
  - lib/huey/errors.rb
147
+ - lib/huey/event.rb
131
148
  - lib/huey/group.rb
132
149
  - lib/huey/request.rb
133
150
  - lib/huey/ssdp.rb
134
151
  - lib/huey/ssdp/searcher.rb
135
152
  - lib/huey/version.rb
136
- - test/fixtures/group.yml
153
+ - test/fixtures/events.yml
154
+ - test/fixtures/groups.yml
137
155
  - test/test_helper.rb
138
156
  - test/unit/bulb_test.rb
157
+ - test/unit/event_test.rb
139
158
  - test/unit/group_test.rb
140
159
  - test/unit/request_test.rb
141
160
  - test/unit/ssdp_test.rb
@@ -1,3 +0,0 @@
1
- living_room: [TV, Living Room - Fireplace]
2
- foyer: [Foyer]
3
- bedroom: [Bedroom]