neptune_apex 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +35 -0
- data/Rakefile +8 -0
- data/bin/apex +5 -0
- data/lib/neptune_apex/cli/main.rb +44 -0
- data/lib/neptune_apex/cli/profile.rb +19 -0
- data/lib/neptune_apex/controller.rb +70 -0
- data/lib/neptune_apex/datalog.rb +30 -0
- data/lib/neptune_apex/profiles/base.rb +8 -0
- data/lib/neptune_apex/profiles/vega.rb +18 -0
- data/lib/neptune_apex/status.rb +60 -0
- data/lib/neptune_apex/version.rb +3 -0
- data/lib/neptune_apex.rb +14 -0
- data/neptune_apex.gemspec +29 -0
- data/spec/lib/controller_spec.rb +9 -0
- data/spec/lib/datalog_spec.rb +11 -0
- data/spec/lib/neptune_apex_spec.rb +2 -0
- data/spec/lib/status_spec.rb +14 -0
- data/spec/spec_helper.rb +1 -0
- data/test-data/datalog.xml +1149 -0
- data/test-data/profiles.json +32 -0
- data/test-data/status.xml +158 -0
- metadata +172 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dc8ffa43bd65e6f68071b9c4c88d08b5733ff076
|
4
|
+
data.tar.gz: d36aa42af0b4e5f7d3f638d1a913d065a5eef6e2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 43318cb0eb0bd69592bf38459427cc5bf4772e9d287f7e6b67909e0c957cd7a341c6c792f46da957ad2c7a1165602e17c0c934e235ea999e548e202c05ad8680
|
7
|
+
data.tar.gz: ae125a0da2674874e2c0accb60bbedcf4e3b9ae6f2424aa3d86a6c18700ec0a6e356320ee7113076fc12066d676bc8de4e07caaac3b2f83128c213e6fa61c6df
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Scott Peshak
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# NeptuneApex
|
2
|
+
|
3
|
+
A Ruby Gem for interacting with a Neptune Apex aquarium controller.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'neptune_apex'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install neptune_apex
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Legal
|
26
|
+
|
27
|
+
This module is in no way affiliated with Neptune Systems, the maker of the Apex controller.
|
28
|
+
|
29
|
+
## Contributing
|
30
|
+
|
31
|
+
1. Fork it ( https://github.com/speshak/apex/fork )
|
32
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
33
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
34
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
35
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/apex
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'neptune_apex'
|
2
|
+
require 'thor'
|
3
|
+
require 'terminal-table'
|
4
|
+
|
5
|
+
require_relative 'profile'
|
6
|
+
|
7
|
+
module NeptuneApex
|
8
|
+
module Cli
|
9
|
+
class Main < Thor
|
10
|
+
desc "status", "Get current status of controller outlets & probes"
|
11
|
+
def status
|
12
|
+
cont = NeptuneApex::Controller.new()
|
13
|
+
status = cont.status
|
14
|
+
|
15
|
+
puts "Apex status as of #{status.date.strftime('%F %R')}"
|
16
|
+
|
17
|
+
puts Terminal::Table.new :headings => ['Probe', 'Value'] {|t|
|
18
|
+
status.probes.each{|name, probe|
|
19
|
+
t << [name, probe[:value].to_s('F')]
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
puts "\n"
|
24
|
+
|
25
|
+
puts Terminal::Table.new :headings => ['Outlet', 'State'] {|t|
|
26
|
+
status.outlets.each{|name, outlet|
|
27
|
+
t << [name, outlet[:state]]
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
desc "datalog", "Get datalog values"
|
36
|
+
def datalog
|
37
|
+
puts "Not yet implemented"
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "profile SUBCOMMAND", "manage profiles"
|
41
|
+
subcommand "profile", ProfileCli
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module NeptuneApex
|
4
|
+
module Cli
|
5
|
+
class ProfileCli < Thor
|
6
|
+
desc "export <name>", "Exports profile named <name>"
|
7
|
+
def export(name)
|
8
|
+
puts "Not yet implemented"
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
desc "import <name>", "Imports a profile named <name>. Overwrites existing profile of the same name."
|
13
|
+
def import(name)
|
14
|
+
puts "Not yet implemented"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'yaml'
|
3
|
+
require 'httpclient'
|
4
|
+
|
5
|
+
module NeptuneApex
|
6
|
+
class Controller
|
7
|
+
# Controller URL
|
8
|
+
attr_accessor :url
|
9
|
+
|
10
|
+
# Controller username
|
11
|
+
attr_accessor :user
|
12
|
+
|
13
|
+
# Controller password
|
14
|
+
attr_accessor :password
|
15
|
+
|
16
|
+
|
17
|
+
def initialize(url=nil)
|
18
|
+
load_conf
|
19
|
+
|
20
|
+
if url
|
21
|
+
@url = url
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Look for a config file & load
|
27
|
+
def load_conf
|
28
|
+
conf_file = File.expand_path('~/.apexcli')
|
29
|
+
|
30
|
+
if ENV['APEXCONF']
|
31
|
+
conf_file = ENV['APEXCONF']
|
32
|
+
end
|
33
|
+
|
34
|
+
if File.exist?(conf_file)
|
35
|
+
conf = YAML.load_file(conf_file)
|
36
|
+
@url = conf['url']
|
37
|
+
@user = conf['user']
|
38
|
+
@password = conf['password']
|
39
|
+
else
|
40
|
+
raise Exception.new('Config file not found!')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
##
|
46
|
+
# Get the current status of the controller
|
47
|
+
def status
|
48
|
+
Status.from_xml(open("#{@url}/cgi-bin/status.xml"))
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
##
|
53
|
+
# Get the datalog from the controller
|
54
|
+
def datalog
|
55
|
+
Datalog.from_xml(open("#{@url}/cgi-bin/datalog.xml"))
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# Get a prepared UserAgent
|
60
|
+
def user_agent
|
61
|
+
unless @user_agent
|
62
|
+
@user_agent = HTTPClient.new
|
63
|
+
@user_agent.set_auth(@url, @user, @password)
|
64
|
+
end
|
65
|
+
|
66
|
+
@user_agent
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
|
3
|
+
module NeptuneApex
|
4
|
+
class Datalog
|
5
|
+
attr_accessor :records
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@records = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def read_xml(xml)
|
13
|
+
doc = Nokogiri::XML(xml)
|
14
|
+
|
15
|
+
doc.xpath('//datalog/record').each{|record|
|
16
|
+
stat = Status.new
|
17
|
+
|
18
|
+
record.xpath('./probe').each{|probe|
|
19
|
+
stat.add_probe(
|
20
|
+
probe.at_xpath('./name').text,
|
21
|
+
probe.at_xpath('./value').text,
|
22
|
+
probe.at_xpath('./type').text
|
23
|
+
)
|
24
|
+
}
|
25
|
+
|
26
|
+
@records[record.at_xpath('./date').text] = stat
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Apex
|
2
|
+
module Profile
|
3
|
+
# An AI Vega/Hydra LED light profile
|
4
|
+
class Vega < Base
|
5
|
+
# Colors
|
6
|
+
attr_accessor :cWhite, :wWhite, :nWhite, :green, :violet, :red, :dBlue, :rBlue, :UV, :blue
|
7
|
+
|
8
|
+
# Parameters
|
9
|
+
attr_accessor :min, :max, :rampTime
|
10
|
+
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@type = 'vega'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require "nokogiri"
|
3
|
+
|
4
|
+
module NeptuneApex
|
5
|
+
class Status
|
6
|
+
attr_accessor :date, :power, :probes, :outlets
|
7
|
+
|
8
|
+
def self.from_xml(data)
|
9
|
+
status = Status.new
|
10
|
+
status.read_xml(data)
|
11
|
+
return status
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@probes = {}
|
17
|
+
@outlets = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def read_xml(xml)
|
22
|
+
doc = Nokogiri::XML(xml)
|
23
|
+
|
24
|
+
@date = Date.strptime(doc.at_xpath('//status/date').text, '%m/%d/%Y %H:%M:%s')
|
25
|
+
|
26
|
+
doc.xpath('//status/probes/probe').each{|probe|
|
27
|
+
add_probe(
|
28
|
+
probe.at_xpath('./name').text,
|
29
|
+
probe.at_xpath('./value').text,
|
30
|
+
probe.at_xpath('./type').text
|
31
|
+
)
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
doc.xpath('//status/outlets/outlet').each{|outlet|
|
36
|
+
add_outlet(
|
37
|
+
outlet.at_xpath('./name').text,
|
38
|
+
outlet.at_xpath('./outputID').text,
|
39
|
+
outlet.at_xpath('./state').text,
|
40
|
+
outlet.at_xpath('./deviceID').text
|
41
|
+
)
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def add_probe(name, value, type)
|
47
|
+
@probes[name] = { :value => BigDecimal.new(value), :type => type }
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def add_outlet(name, id, state, device_id)
|
52
|
+
@outlets[name] = {
|
53
|
+
:id => id,
|
54
|
+
:state => state,
|
55
|
+
:device_id => device_id,
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/lib/neptune_apex.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Class for interacting with a Neptune Systems Apex aquarium controller.
|
2
|
+
#
|
3
|
+
# Author:: Scott Peshak (mailto:scott@peshak.net)
|
4
|
+
# Copyright:: Copyright (c) 2014 Scott Peshak
|
5
|
+
|
6
|
+
require "neptune_apex/version"
|
7
|
+
require "neptune_apex/controller"
|
8
|
+
require "neptune_apex/status"
|
9
|
+
require "neptune_apex/datalog"
|
10
|
+
|
11
|
+
|
12
|
+
module NeptuneApex
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'neptune_apex/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "neptune_apex"
|
8
|
+
spec.version = NeptuneApex::VERSION
|
9
|
+
spec.authors = ["Scott Peshak"]
|
10
|
+
spec.email = ["scott@peshak.net"]
|
11
|
+
spec.summary = %q{Gem for interacting with a Neptune Apex aquarium controller.}
|
12
|
+
spec.homepage = "https://github.com/speshak/apex"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
spec.executables << "apex"
|
20
|
+
|
21
|
+
spec.add_dependency "nokogiri", "~> 1.6"
|
22
|
+
spec.add_dependency "thor", "~> 0.19"
|
23
|
+
spec.add_dependency "terminal-table", "~> 1.5"
|
24
|
+
spec.add_dependency "httpclient", "~> 2.7"
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.4"
|
29
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NeptuneApex::Datalog, "#read_xml" do
|
4
|
+
it "reads xml data into structures" do
|
5
|
+
datalog = NeptuneApex::Datalog.new
|
6
|
+
datalog.read_xml(File.open(File.expand_path('../../../test-data/datalog.xml', __FILE__)))
|
7
|
+
|
8
|
+
expect(datalog.records['11/02/2014 00:10:00'].probes['Temp'][:value]).to eq(BigDecimal.new('75.5'))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bigdecimal'
|
3
|
+
|
4
|
+
describe NeptuneApex::Status, '#read_xml' do
|
5
|
+
it "reads xml data into structures" do
|
6
|
+
status = NeptuneApex::Status.new
|
7
|
+
status.read_xml(File.open(File.expand_path('../../../test-data/status.xml', __FILE__)))
|
8
|
+
|
9
|
+
expect(status.date).to eq(Date.strptime('12/29/2013 19:14:58', '%m/%d/%Y %H:%M:%s'))
|
10
|
+
|
11
|
+
expect(status.probes['Temp'][:value]).to eq(BigDecimal.new('77.6'))
|
12
|
+
expect(status.outlets['VarSpd3_I3'][:state]).to eq('OFF')
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'neptune_apex'
|