aq.rb 0.2.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 ADDED
@@ -0,0 +1,18 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'chronic'
4
+ gem 'nokogiri'
5
+
6
+ group :development do
7
+ gem 'bundler', '>= 1.0.0'
8
+ gem 'fakeweb'
9
+ gem 'jeweler'
10
+ gem 'mocha'
11
+ gem 'guard'
12
+ gem 'guard-bundler'
13
+ gem 'guard-rspec'
14
+ gem 'rb-fsevent'
15
+ gem 'rspec'
16
+ gem 'timecop'
17
+ gem 'vcr'
18
+ end
@@ -0,0 +1,51 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ chronic (0.6.2)
5
+ diff-lcs (1.1.2)
6
+ fakeweb (1.3.0)
7
+ git (1.2.5)
8
+ guard (0.6.2)
9
+ thor (~> 0.14.6)
10
+ guard-bundler (0.1.3)
11
+ bundler (>= 1.0.0)
12
+ guard (>= 0.2.2)
13
+ guard-rspec (0.4.2)
14
+ guard (>= 0.4.0)
15
+ jeweler (1.6.4)
16
+ bundler (~> 1.0)
17
+ git (>= 1.2.5)
18
+ rake
19
+ mocha (0.9.12)
20
+ nokogiri (1.5.0)
21
+ rake (0.9.2)
22
+ rb-fsevent (0.4.3.1)
23
+ rspec (2.6.0)
24
+ rspec-core (~> 2.6.0)
25
+ rspec-expectations (~> 2.6.0)
26
+ rspec-mocks (~> 2.6.0)
27
+ rspec-core (2.6.4)
28
+ rspec-expectations (2.6.0)
29
+ diff-lcs (~> 1.1.2)
30
+ rspec-mocks (2.6.0)
31
+ thor (0.14.6)
32
+ timecop (0.3.5)
33
+ vcr (1.11.1)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ bundler (>= 1.0.0)
40
+ chronic
41
+ fakeweb
42
+ guard
43
+ guard-bundler
44
+ guard-rspec
45
+ jeweler
46
+ mocha
47
+ nokogiri
48
+ rb-fsevent
49
+ rspec
50
+ timecop
51
+ vcr
@@ -0,0 +1,18 @@
1
+ guard 'rspec', :all_on_start => false, :all_after_pass => false, :version => 2, :keep_failed => false, :cli => "--color --format nested --drb" do
2
+ watch(%r{^spec/.+_spec\.rb})
3
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+
6
+ # Rails example
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
9
+ watch('config/routes.rb') { ["spec/routing", "spec/requests"] }
10
+ watch(%r{^spec/.+_spec\.rb})
11
+ watch(%r{^app/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
12
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
13
+ watch(%r{^app/controllers/(.+)_(controller)\.rb}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
14
+ end
15
+
16
+ guard 'bundler' do
17
+ watch('Gemfile')
18
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2010 Chuck Collins
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.
File without changes
@@ -0,0 +1,18 @@
1
+ require "rake"
2
+
3
+ begin
4
+ require "jeweler"
5
+ Jeweler::Tasks.new do |gem|
6
+ gem.name = "aq.rb"
7
+ gem.summary = "Ruby library for interfacing with various aquarium controllers"
8
+ gem.email = "chuck.collins@gmail.com"
9
+ gem.homepage = "http://github.com/ccollins/aq.rb"
10
+ gem.authors = ["Chuck Collins"]
11
+ gem.files = Dir["*", "{lib}/**/*"]
12
+ gem.add_dependency("json")
13
+ end
14
+
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,93 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{aq.rb}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{Chuck Collins}]
12
+ s.date = %q{2011-08-21}
13
+ s.email = %q{chuck.collins@gmail.com}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ "Gemfile",
20
+ "Gemfile.lock",
21
+ "Guardfile",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "aq.rb.gemspec",
27
+ "init.rb",
28
+ "lib/aq.rb",
29
+ "lib/aq/controller.rb",
30
+ "lib/aq/controllers/apex.rb",
31
+ "lib/aq/controllers/aquacontroller.rb",
32
+ "lib/aq/controllers/aquatronica.rb",
33
+ "lib/aq/controllers/reefkeeper.rb",
34
+ "lib/aq/manufacturers/neptune.rb",
35
+ "lib/aq/response.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/ccollins/aq.rb}
38
+ s.require_paths = [%q{lib}]
39
+ s.rubygems_version = %q{1.8.6}
40
+ s.summary = %q{Ruby library for interfacing with various aquarium controllers}
41
+
42
+ if s.respond_to? :specification_version then
43
+ s.specification_version = 3
44
+
45
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
+ s.add_runtime_dependency(%q<chronic>, [">= 0"])
47
+ s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
48
+ s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
49
+ s.add_development_dependency(%q<fakeweb>, [">= 0"])
50
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
51
+ s.add_development_dependency(%q<mocha>, [">= 0"])
52
+ s.add_development_dependency(%q<guard>, [">= 0"])
53
+ s.add_development_dependency(%q<guard-bundler>, [">= 0"])
54
+ s.add_development_dependency(%q<guard-rspec>, [">= 0"])
55
+ s.add_development_dependency(%q<rb-fsevent>, [">= 0"])
56
+ s.add_development_dependency(%q<rspec>, [">= 0"])
57
+ s.add_development_dependency(%q<timecop>, [">= 0"])
58
+ s.add_development_dependency(%q<vcr>, [">= 0"])
59
+ s.add_runtime_dependency(%q<json>, [">= 0"])
60
+ else
61
+ s.add_dependency(%q<chronic>, [">= 0"])
62
+ s.add_dependency(%q<nokogiri>, [">= 0"])
63
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
64
+ s.add_dependency(%q<fakeweb>, [">= 0"])
65
+ s.add_dependency(%q<jeweler>, [">= 0"])
66
+ s.add_dependency(%q<mocha>, [">= 0"])
67
+ s.add_dependency(%q<guard>, [">= 0"])
68
+ s.add_dependency(%q<guard-bundler>, [">= 0"])
69
+ s.add_dependency(%q<guard-rspec>, [">= 0"])
70
+ s.add_dependency(%q<rb-fsevent>, [">= 0"])
71
+ s.add_dependency(%q<rspec>, [">= 0"])
72
+ s.add_dependency(%q<timecop>, [">= 0"])
73
+ s.add_dependency(%q<vcr>, [">= 0"])
74
+ s.add_dependency(%q<json>, [">= 0"])
75
+ end
76
+ else
77
+ s.add_dependency(%q<chronic>, [">= 0"])
78
+ s.add_dependency(%q<nokogiri>, [">= 0"])
79
+ s.add_dependency(%q<bundler>, [">= 1.0.0"])
80
+ s.add_dependency(%q<fakeweb>, [">= 0"])
81
+ s.add_dependency(%q<jeweler>, [">= 0"])
82
+ s.add_dependency(%q<mocha>, [">= 0"])
83
+ s.add_dependency(%q<guard>, [">= 0"])
84
+ s.add_dependency(%q<guard-bundler>, [">= 0"])
85
+ s.add_dependency(%q<guard-rspec>, [">= 0"])
86
+ s.add_dependency(%q<rb-fsevent>, [">= 0"])
87
+ s.add_dependency(%q<rspec>, [">= 0"])
88
+ s.add_dependency(%q<timecop>, [">= 0"])
89
+ s.add_dependency(%q<vcr>, [">= 0"])
90
+ s.add_dependency(%q<json>, [">= 0"])
91
+ end
92
+ end
93
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), "lib", "aq")
@@ -0,0 +1,8 @@
1
+ require 'aq/manufacturers/neptune'
2
+ require 'aq/controller'
3
+ require 'aq/controllers/aquacontroller'
4
+ require 'aq/controllers/apex'
5
+ require 'aq/controllers/aquatronica'
6
+ require 'aq/controllers/reefkeeper'
7
+ require 'aq/response'
8
+ require 'net/http'
@@ -0,0 +1,59 @@
1
+ module Aq
2
+ class Controller
3
+ attr_accessor :url, :status, :status_fetch_time
4
+
5
+ def initialize(host, user='', password='', port=80)
6
+ @url ||= build_url(user, password, host, port)
7
+ end
8
+
9
+ def fetch_status
10
+ @status_fetch_time = Time.now
11
+ status = parse_status(fetch_url(url, status_page))
12
+ end
13
+
14
+ def status
15
+ @status || fetch_status
16
+ end
17
+
18
+ def on? outlet
19
+ outlet.include?("ON")
20
+ end
21
+
22
+ def manual?
23
+ false
24
+ end
25
+
26
+ def number_or_string(value)
27
+ if value.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/)
28
+ value.to_s.match(/\./) ? Float(value) : Integer(value)
29
+ else
30
+ value
31
+ end
32
+ end
33
+
34
+ protected
35
+
36
+ def build_url(user, password, host, port)
37
+ if !user.nil? && !user.empty? && !password.nil? && !password.empty?
38
+ "http://#{user}:#{password}@#{host}:#{port.to_s}"
39
+ else
40
+ "http://#{host}:#{port.to_s}"
41
+ end
42
+ end
43
+
44
+ def fetch_url url, page
45
+ url = URI.parse(url)
46
+ Net::HTTP.start(url.host, url.port) do |http|
47
+ req = Net::HTTP::Get.new("/#{page}")
48
+ req.basic_auth url.user, url.password
49
+ response = http.request(req)
50
+
51
+ case response
52
+ when Net::HTTPSuccess then response.body
53
+ else
54
+ raise Exception.new(response.error!)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,7 @@
1
+ module Aq
2
+ module Controllers
3
+ class Apex < Aq::Controller
4
+ include Neptune
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Aq
2
+ module Controllers
3
+ class Aquacontroller < Aq::Controller
4
+ include Neptune
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,48 @@
1
+ module Aq
2
+ module Controllers
3
+ class Aquatronica < Aq::Controller
4
+ TIMER_BITMASK = 0x80
5
+ STATUS_BITMASK = 0x7F
6
+ MANUAL = 120
7
+
8
+ def status_page
9
+ 'rtMon.xml'
10
+ end
11
+
12
+ def parse_status(raw_status)
13
+ parsed_status = Nokogiri::XML raw_status
14
+ aq_status = {:general => read_general(parsed_status), :probes => read_probes(parsed_status),
15
+ :outlets => read_outlets(parsed_status), :power => {}}
16
+
17
+ return aq_status
18
+ end
19
+
20
+ def on? outlet
21
+ outlet.to_i & TIMER_BITMASK != 0
22
+ end
23
+
24
+ def manual? outlet
25
+ outlet.to_i & STATUS_BITMASK == MANUAL
26
+ end
27
+
28
+ protected
29
+
30
+ def read_general(xml)
31
+ {:date => status_fetch_time}
32
+ end
33
+
34
+ def read_probes(xml)
35
+ xml.xpath('//sensorList//sensor').map do |sensor|
36
+ value = sensor.at_xpath('value').text.scan(/[[:digit:]]|[[:punct:]]/).join.strip
37
+ {:name => sensor.at_xpath('name').text.strip, :value => number_or_string(value)}
38
+ end
39
+ end
40
+
41
+ def read_outlets(xml)
42
+ xml.xpath('//plugList//plug').map do |plug|
43
+ {:name => plug.at_xpath('name').text.strip, :state => number_or_string(plug.at_xpath('status').text.strip)}
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,45 @@
1
+ module Aq
2
+ module Controllers
3
+ class Reefkeeper < Aq::Controller
4
+ def status_page
5
+ 'rss/rss.xml'
6
+ end
7
+
8
+ def parse_status(raw_status)
9
+ parsed_status = Nokogiri::XML raw_status
10
+ aq_status = {:general => read_general(parsed_status), :power => {}}.merge(read_outlets_and_probes(parsed_status))
11
+
12
+ return aq_status
13
+ end
14
+
15
+ protected
16
+
17
+ def read_outlets_and_probes(xml)
18
+ o_and_ps = {:probes => [], :outlets => []}
19
+
20
+ xml.xpath('//item').each do |o_or_p|
21
+ if outlet? o_or_p
22
+ o_and_ps[:outlets].push({:name => o_or_p.at_xpath('title').text.strip, :state => clean_value(o_or_p.at_xpath('description').text)})
23
+ else
24
+ o_and_ps[:probes].push({:name => o_or_p.at_xpath('title').text.strip, :value => number_or_string(clean_value(o_or_p.at_xpath('description').text))})
25
+ end
26
+ end
27
+
28
+ o_and_ps
29
+ end
30
+
31
+ def outlet? node
32
+ node.at_xpath('description').text.include? ": ON"
33
+ end
34
+
35
+ def clean_value value
36
+ value.strip!.gsub!(/Current Value: /, '')
37
+ (value.match /ON|OFF/) ? value : value.scan(/[[:digit:]]|[[:punct:]]/).join.strip
38
+ end
39
+
40
+ def read_general(xml)
41
+ {:date => Time.strptime(xml.xpath('//pubDate').first.text.strip, "%a, %d %B %y %H:%M:%S")}
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ module Neptune
2
+ def status_page
3
+ 'cgi-bin/status.xml'
4
+ end
5
+
6
+ def parse_status(raw_status)
7
+ parsed_status = Nokogiri::XML raw_status
8
+ aq_status = {:general => read_general(parsed_status), :probes => read_probes(parsed_status),
9
+ :outlets => read_outlets(parsed_status), :power => read_power(parsed_status)}
10
+
11
+ return aq_status
12
+ end
13
+
14
+ protected
15
+
16
+ def read_probes(xml)
17
+ xml.xpath('//probes//probe').map do |probe|
18
+ {:name => probe.at_xpath('name').text, :value => number_or_string(probe.at_xpath('value').text.strip)}
19
+ end
20
+ end
21
+
22
+ def read_outlets(xml)
23
+ xml.xpath('//outlets//outlet').map do |outlet|
24
+ {:name => outlet.at_xpath('name').text, :state => outlet.at_xpath('state').text.strip}
25
+ end
26
+ end
27
+
28
+ def read_general(xml)
29
+ general = {}
30
+ general[:hostname] = xml.at_xpath('//hostname').text.strip
31
+ general[:serial] = xml.at_xpath('//serial').text.strip
32
+ general[:date] = Chronic.parse(xml.at_xpath('//date').text.strip)
33
+
34
+ general
35
+ end
36
+
37
+ def read_power(xml)
38
+ power = {}
39
+
40
+ power[:failed] = xml.at_xpath('//power//failed').text.strip
41
+ power[:restored] = xml.at_xpath('//power//restored').text.strip
42
+
43
+ power
44
+ end
45
+ end
@@ -0,0 +1,2 @@
1
+ class Aq::Response
2
+ end
metadata ADDED
@@ -0,0 +1,217 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aq.rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chuck Collins
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-21 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: chronic
16
+ requirement: &70321982448120 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70321982448120
25
+ - !ruby/object:Gem::Dependency
26
+ name: nokogiri
27
+ requirement: &70321982438980 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70321982438980
36
+ - !ruby/object:Gem::Dependency
37
+ name: bundler
38
+ requirement: &70321982437420 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 1.0.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70321982437420
47
+ - !ruby/object:Gem::Dependency
48
+ name: fakeweb
49
+ requirement: &70321982436160 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70321982436160
58
+ - !ruby/object:Gem::Dependency
59
+ name: jeweler
60
+ requirement: &70321982432920 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70321982432920
69
+ - !ruby/object:Gem::Dependency
70
+ name: mocha
71
+ requirement: &70321982431120 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70321982431120
80
+ - !ruby/object:Gem::Dependency
81
+ name: guard
82
+ requirement: &70321982429560 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70321982429560
91
+ - !ruby/object:Gem::Dependency
92
+ name: guard-bundler
93
+ requirement: &70321982428300 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70321982428300
102
+ - !ruby/object:Gem::Dependency
103
+ name: guard-rspec
104
+ requirement: &70321982425860 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70321982425860
113
+ - !ruby/object:Gem::Dependency
114
+ name: rb-fsevent
115
+ requirement: &70321982424760 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *70321982424760
124
+ - !ruby/object:Gem::Dependency
125
+ name: rspec
126
+ requirement: &70321982423680 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *70321982423680
135
+ - !ruby/object:Gem::Dependency
136
+ name: timecop
137
+ requirement: &70321982422040 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: *70321982422040
146
+ - !ruby/object:Gem::Dependency
147
+ name: vcr
148
+ requirement: &70321982420260 !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: *70321982420260
157
+ - !ruby/object:Gem::Dependency
158
+ name: json
159
+ requirement: &70321982418620 !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ type: :runtime
166
+ prerelease: false
167
+ version_requirements: *70321982418620
168
+ description:
169
+ email: chuck.collins@gmail.com
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files:
173
+ - LICENSE
174
+ - README.md
175
+ files:
176
+ - Gemfile
177
+ - Gemfile.lock
178
+ - Guardfile
179
+ - LICENSE
180
+ - README.md
181
+ - Rakefile
182
+ - VERSION
183
+ - aq.rb.gemspec
184
+ - init.rb
185
+ - lib/aq.rb
186
+ - lib/aq/controller.rb
187
+ - lib/aq/controllers/apex.rb
188
+ - lib/aq/controllers/aquacontroller.rb
189
+ - lib/aq/controllers/aquatronica.rb
190
+ - lib/aq/controllers/reefkeeper.rb
191
+ - lib/aq/manufacturers/neptune.rb
192
+ - lib/aq/response.rb
193
+ homepage: http://github.com/ccollins/aq.rb
194
+ licenses: []
195
+ post_install_message:
196
+ rdoc_options: []
197
+ require_paths:
198
+ - lib
199
+ required_ruby_version: !ruby/object:Gem::Requirement
200
+ none: false
201
+ requirements:
202
+ - - ! '>='
203
+ - !ruby/object:Gem::Version
204
+ version: '0'
205
+ required_rubygems_version: !ruby/object:Gem::Requirement
206
+ none: false
207
+ requirements:
208
+ - - ! '>='
209
+ - !ruby/object:Gem::Version
210
+ version: '0'
211
+ requirements: []
212
+ rubyforge_project:
213
+ rubygems_version: 1.8.6
214
+ signing_key:
215
+ specification_version: 3
216
+ summary: Ruby library for interfacing with various aquarium controllers
217
+ test_files: []