device-cloud 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/.gitignore +20 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/Guardfile +19 -0
- data/LICENSE.txt +22 -0
- data/README.md +35 -0
- data/Rakefile +7 -0
- data/device-cloud.gemspec +38 -0
- data/lib/device_cloud/client.rb +52 -0
- data/lib/device_cloud/config.rb +19 -0
- data/lib/device_cloud/data_point.rb +21 -0
- data/lib/device_cloud/data_stream.rb +65 -0
- data/lib/device_cloud/device_core.rb +52 -0
- data/lib/device_cloud/monitor.rb +58 -0
- data/lib/device_cloud/result.rb +33 -0
- data/lib/device_cloud/version.rb +3 -0
- data/lib/device_cloud.rb +8 -0
- data/spec/device_cloud/client_spec.rb +20 -0
- data/spec/device_cloud/config_spec.rb +27 -0
- data/spec/device_cloud/data_point_spec.rb +79 -0
- data/spec/device_cloud/data_stream_spec.rb +155 -0
- data/spec/device_cloud/device_core_spec.rb +143 -0
- data/spec/device_cloud/monitor_spec.rb +43 -0
- data/spec/device_cloud/result_spec.rb +47 -0
- data/spec/spec_helper.rb +13 -0
- metadata +288 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec, cmd: 'rspec' do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/device_cloud/(.+)\.rb$}) { |m| "spec/device_cloud/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
guard :bundler do
|
15
|
+
watch('Gemfile')
|
16
|
+
watch(/^.+\.gemspec/)
|
17
|
+
end
|
18
|
+
|
19
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Eric Nelson
|
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
|
+
[](https://codeclimate.com/github/nelseric/device_cloud)
|
2
|
+
[](https://travis-ci.org/nelseric/device_cloud)
|
3
|
+
[](https://gemnasium.com/nelseric/device_cloud)
|
4
|
+
[](https://coveralls.io/r/nelseric/device_cloud)
|
5
|
+
# DeviceCloud
|
6
|
+
|
7
|
+
Provides API Access for the devicecloud platform to ruby
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'device_cloud'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install device_cloud
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
[Rubydoc](http://rubydoc.info/github/nelseric/device_cloud/frames)
|
26
|
+
|
27
|
+
TODO: Write usage instructions here
|
28
|
+
|
29
|
+
## Contributing
|
30
|
+
|
31
|
+
1. Fork it
|
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 new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'device_cloud/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "device-cloud"
|
8
|
+
spec.version = DeviceCloud::VERSION.dup
|
9
|
+
spec.authors = ["Eric Nelson"]
|
10
|
+
spec.email = ["eric@clean-logix.com"]
|
11
|
+
spec.description = %q{REST Wrapper for Etherios Devicecloud}
|
12
|
+
spec.summary = %q{REST Wrapper for Etherios Devicecloud}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "nokogiri"
|
22
|
+
spec.add_dependency "rest-client"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_development_dependency "webmock"
|
28
|
+
spec.add_development_dependency "pry"
|
29
|
+
spec.add_development_dependency "debugger"
|
30
|
+
spec.add_development_dependency "guard"
|
31
|
+
spec.add_development_dependency "guard-rspec"
|
32
|
+
spec.add_development_dependency "guard-bundler"
|
33
|
+
spec.add_development_dependency "libnotify"
|
34
|
+
spec.add_development_dependency "coveralls"
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "rest-client"
|
2
|
+
|
3
|
+
require "device_cloud/config"
|
4
|
+
|
5
|
+
module DeviceCloud
|
6
|
+
class Client
|
7
|
+
attr_accessor :config
|
8
|
+
|
9
|
+
def initialize(config)
|
10
|
+
@config = DeviceCloud::Config.new(config)
|
11
|
+
end
|
12
|
+
|
13
|
+
def devices(device, params = {})
|
14
|
+
DeviceCore.parse(get "/ws/DeviceCore/#{device}?#{ to_params params }")
|
15
|
+
end
|
16
|
+
|
17
|
+
def data_streams(stream_path, params = {})
|
18
|
+
DataStream.parse(get "#{DataStream::RESOURCE_PATH}/#{stream_path}?#{ to_params params }")
|
19
|
+
end
|
20
|
+
|
21
|
+
def data_points(stream_id, params = {})
|
22
|
+
DataPoint.parse(get "/ws/DataPoint/#{stream_id}?#{ to_params params }")
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(path, *args)
|
26
|
+
RestClient.get base_url + path, args
|
27
|
+
end
|
28
|
+
|
29
|
+
def put(path, *args)
|
30
|
+
RestClient.put base_url + path, args
|
31
|
+
end
|
32
|
+
|
33
|
+
def post(path, *args)
|
34
|
+
RestClient.post base_url + path, args
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(path, *args)
|
38
|
+
RestClient.delete base_url + path, args
|
39
|
+
end
|
40
|
+
|
41
|
+
def base_url
|
42
|
+
"#{config.protocol}://#{config.username}:#{config.password}@#{config.host}"
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def to_params(hash)
|
47
|
+
hash.each_pair.map do |key, value|
|
48
|
+
key + "=" + value
|
49
|
+
end.inject { |a, b| a + "&" + b }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DeviceCloud
|
2
|
+
class Config
|
3
|
+
DEFAULT_USERNAME = ""
|
4
|
+
DEFAULT_PASSWORD = ""
|
5
|
+
DEFAULT_HOST = "login.etherios.com"
|
6
|
+
DEFAULT_PROTOCOL = "https"
|
7
|
+
|
8
|
+
attr_accessor :username, :password, :host, :protocol
|
9
|
+
|
10
|
+
def initialize(args)
|
11
|
+
args = Hash[*args.map { |k, v| [k.to_sym, v] }.flatten]
|
12
|
+
@username = args[:username] || DEFAULT_USERNAME
|
13
|
+
@password = args[:password] || DEFAULT_PASSWORD
|
14
|
+
@host = args[:host] || DEFAULT_HOST
|
15
|
+
@protocol = args[:protocol] || DEFAULT_PROTOCOL
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "device_cloud/result"
|
2
|
+
|
3
|
+
module DeviceCloud
|
4
|
+
class DataPoint
|
5
|
+
def self.parse(xml)
|
6
|
+
result = Result.new(xml)
|
7
|
+
result.document.xpath("//result/DataPoint").map do |data_point|
|
8
|
+
DeviceCloud::DataPoint.new data_point
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :element, :id, :value, :timestamp, :stream_id
|
13
|
+
|
14
|
+
def initialize(element)
|
15
|
+
@id = element.xpath("id").text
|
16
|
+
@value = element.xpath("data").text
|
17
|
+
@timestamp = Time.at(element.xpath("timestamp").text.to_f / 1000)
|
18
|
+
@stream_id = element.xpath("streamId").text
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "device_cloud/result"
|
2
|
+
module DeviceCloud
|
3
|
+
class DataStream
|
4
|
+
RESOURCE_PATH = '/ws/DataStream'
|
5
|
+
|
6
|
+
def self.parse(xml)
|
7
|
+
result = Result.new(xml)
|
8
|
+
result.document.xpath("//result/DataStream").map do |stream|
|
9
|
+
DeviceCloud::DataStream.new stream
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :element
|
14
|
+
|
15
|
+
def initialize(element)
|
16
|
+
@element = element
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(client)
|
20
|
+
client.delete RESOURCE_PATH + "/" + stream_id
|
21
|
+
end
|
22
|
+
|
23
|
+
def value
|
24
|
+
current.value
|
25
|
+
end
|
26
|
+
|
27
|
+
def timestamp
|
28
|
+
current.timestamp
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_id
|
32
|
+
current.id
|
33
|
+
end
|
34
|
+
|
35
|
+
def stream_id
|
36
|
+
element.xpath("streamId").text
|
37
|
+
end
|
38
|
+
|
39
|
+
def device_id
|
40
|
+
stream_id_parse[1]
|
41
|
+
end
|
42
|
+
|
43
|
+
def mac
|
44
|
+
stream_id_parse[2].to_i(16)
|
45
|
+
end
|
46
|
+
|
47
|
+
def name
|
48
|
+
stream_id_parse[3]
|
49
|
+
end
|
50
|
+
|
51
|
+
def device_path
|
52
|
+
"dia/channel/#{device_id}/#{mac.to_s(16).rjust(16,"0")}/"
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def stream_id_parse
|
58
|
+
/dia\/channel\/((?:[0-9a-fA-F]{8}-?){4})\/([^\/]*)\/([a-z_]*)/.match stream_id
|
59
|
+
end
|
60
|
+
|
61
|
+
def current
|
62
|
+
DataPoint.new(element.xpath("currentValue"))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "device_cloud/result"
|
2
|
+
|
3
|
+
module DeviceCloud
|
4
|
+
class DeviceCore
|
5
|
+
|
6
|
+
def self.parse(xml)
|
7
|
+
result = Result.new(xml)
|
8
|
+
result.document.xpath("//result/DeviceCore").map do |device|
|
9
|
+
DeviceCloud::DeviceCore.new device
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :element
|
14
|
+
|
15
|
+
def initialize element
|
16
|
+
@element = element
|
17
|
+
end
|
18
|
+
|
19
|
+
def device_id
|
20
|
+
attribute "devConnectwareId"
|
21
|
+
end
|
22
|
+
|
23
|
+
def name
|
24
|
+
attribute "dpDescription"
|
25
|
+
end
|
26
|
+
|
27
|
+
def connection_state
|
28
|
+
attribute("dpConnectionStatus") == "1"
|
29
|
+
end
|
30
|
+
|
31
|
+
def last_connect_time
|
32
|
+
Time.parse attribute "dpLastConnectTime"
|
33
|
+
end
|
34
|
+
|
35
|
+
def last_disconnect_time
|
36
|
+
Time.parse attribute "dpLastDisconnectTime"
|
37
|
+
end
|
38
|
+
|
39
|
+
def global_ip
|
40
|
+
attribute "dpGlobalIp"
|
41
|
+
end
|
42
|
+
|
43
|
+
def local_ip
|
44
|
+
attribute "dpLastKnownIp"
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def attribute(xpath)
|
49
|
+
element.xpath(xpath).text
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
module DeviceCloud
|
3
|
+
class Monitor
|
4
|
+
|
5
|
+
RESOURCE_PATH = "/ws/Monitor"
|
6
|
+
|
7
|
+
attr_accessor :topic, :id, :element
|
8
|
+
|
9
|
+
def self.all(client)
|
10
|
+
xml_result = Nokogiri::XML.parse client.get RESOURCE_PATH
|
11
|
+
xml_result.xpath("//result/Monitor").map { |monitor| parse monitor }
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parse(xml)
|
15
|
+
topic = xml.xpath("monTopic").text
|
16
|
+
DeviceCloud::Monitor.new(topic, xml)
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(topic, element = nil)
|
20
|
+
@topic = topic
|
21
|
+
@element = element
|
22
|
+
end
|
23
|
+
|
24
|
+
def resource_path
|
25
|
+
RESOURCE_PATH
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def save(client)
|
30
|
+
response = client.post resource_path, build.to_xml
|
31
|
+
xml_res = Nokogiri::XML.parse response
|
32
|
+
@id = xml_res.xpath("//result/location").text
|
33
|
+
end
|
34
|
+
|
35
|
+
def delete(client)
|
36
|
+
raise NotImplementedError, "Incomplete"
|
37
|
+
puts client.delete resource_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def update
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def build
|
45
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
46
|
+
xml.Monitor {
|
47
|
+
xml.monTopic @topic
|
48
|
+
xml.monTransportType "http"
|
49
|
+
xml.monTransportUrl "https://staging.cleanintel.com/ivx/sync"
|
50
|
+
xml.monFormatType "json"
|
51
|
+
xml.monBatchSize 100
|
52
|
+
xml.monCompression "none"
|
53
|
+
xml.monBatchDuration 10
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
module DeviceCloud
|
3
|
+
class InvalidResultError < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class Result
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
attr_accessor :document
|
10
|
+
|
11
|
+
def initialize(xml)
|
12
|
+
@document = Nokogiri::XML.parse(xml)
|
13
|
+
raise InvalidResultError if @document.xpath("//result").empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def total
|
17
|
+
@document.xpath("//result/resultTotalRows").text.to_i
|
18
|
+
end
|
19
|
+
|
20
|
+
def offset
|
21
|
+
@document.xpath("//result/requestedStartRow").text.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def count
|
25
|
+
@document.xpath("//result/resultSize").text.to_i
|
26
|
+
end
|
27
|
+
|
28
|
+
def requested
|
29
|
+
@document.xpath("//result/requestedSize").text.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
data/lib/device_cloud.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'device_cloud/version'
|
2
|
+
require 'device_cloud/config'
|
3
|
+
require 'device_cloud/client'
|
4
|
+
require 'device_cloud/device_core'
|
5
|
+
require 'device_cloud/data_stream'
|
6
|
+
require 'device_cloud/data_point'
|
7
|
+
require 'device_cloud/result'
|
8
|
+
require 'device_cloud/monitor'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe DeviceCloud::Client do
|
4
|
+
subject do
|
5
|
+
DeviceCloud::Client.new(:username => username, :password => password, :host => host, :protocol => protocol)
|
6
|
+
end
|
7
|
+
let(:username) { "test" }
|
8
|
+
let(:password) { "test" }
|
9
|
+
let(:host) { "login.etherios.com" }
|
10
|
+
let(:protocol) { "https" }
|
11
|
+
|
12
|
+
|
13
|
+
it 'will generate a base_url using the configuration' do
|
14
|
+
subject.base_url.should == "#{protocol}://#{username}:#{password}@#{host}"
|
15
|
+
subject.config.protocol = "http"
|
16
|
+
subject.base_url.should == "http://#{username}:#{password}@#{host}"
|
17
|
+
subject.config.host = "google.com"
|
18
|
+
subject.base_url.should == "http://#{username}:#{password}@google.com"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe DeviceCloud::Config do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
DeviceCloud::Config.new(:username => username, :password => password, :host => host, :protocol => protocol)
|
7
|
+
end
|
8
|
+
let(:username) { "testl-user" }
|
9
|
+
let(:password) { "test-pass" }
|
10
|
+
let(:host) { "login.etherios.com" }
|
11
|
+
let(:protocol) { "https" }
|
12
|
+
|
13
|
+
it "sets provided values" do
|
14
|
+
subject.host.should == host
|
15
|
+
subject.protocol.should == protocol
|
16
|
+
subject.username.should == username
|
17
|
+
subject.password.should == password
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has default values" do
|
21
|
+
config = DeviceCloud::Config.new({})
|
22
|
+
config.host.should == "login.etherios.com"
|
23
|
+
config.protocol.should == "https"
|
24
|
+
config.username.should == ""
|
25
|
+
config.password.should == ""
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe DeviceCloud::DataPoint do
|
5
|
+
|
6
|
+
subject(:data_point) do
|
7
|
+
DeviceCloud::DataPoint.parse(xml).first
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:xml) do
|
11
|
+
<<-XML
|
12
|
+
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
13
|
+
<result>
|
14
|
+
<resultSize>2</resultSize>
|
15
|
+
<requestedSize>1000</requestedSize>
|
16
|
+
<pageCursor>51075196-53b4-11e3-8b51-bc764e113426</pageCursor>
|
17
|
+
<requestedStartTime>-1</requestedStartTime>
|
18
|
+
<requestedEndTime>-1</requestedEndTime>
|
19
|
+
<DataPoint>
|
20
|
+
<id>cfc57f41-520e-11e3-8b51-bc764e113426</id>
|
21
|
+
<cstId>5940</cstId>
|
22
|
+
<streamId>dia/channel/00000000-00000000-00409DFF-FF725771/0013a2004063d301/battery</streamId>
|
23
|
+
<timestamp>1384970932009</timestamp>
|
24
|
+
<serverTimestamp>1384970934108</serverTimestamp>
|
25
|
+
<data>5.5</data>
|
26
|
+
<description/>
|
27
|
+
<quality>0</quality>
|
28
|
+
</DataPoint>
|
29
|
+
<DataPoint>
|
30
|
+
<id>13b7174e-520f-11e3-8092-bc764e105279</id>
|
31
|
+
<cstId>5940</cstId>
|
32
|
+
<streamId>dia/channel/00000000-00000000-00409DFF-FF725771/0013a2004063d301/battery</streamId>
|
33
|
+
<timestamp>1384971046000</timestamp>
|
34
|
+
<serverTimestamp>1384971052748</serverTimestamp>
|
35
|
+
<data>4.45</data>
|
36
|
+
<description/>
|
37
|
+
<quality>0</quality>
|
38
|
+
</DataPoint>
|
39
|
+
</result>
|
40
|
+
XML
|
41
|
+
end
|
42
|
+
|
43
|
+
describe ".parse" do
|
44
|
+
it "will return a data point for each object" do
|
45
|
+
result = DeviceCloud::DataPoint.parse xml
|
46
|
+
expect(result.count).to eql 2
|
47
|
+
end
|
48
|
+
context "the xml to parse is empty" do
|
49
|
+
it "will raise an InvalidResultError" do
|
50
|
+
expect { DeviceCloud::DataPoint.parse "" }.to raise_error DeviceCloud::InvalidResultError
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#id" do
|
56
|
+
it "will return the data point id" do
|
57
|
+
expect(data_point.id).to eql "cfc57f41-520e-11e3-8b51-bc764e113426"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#value" do
|
62
|
+
it "will return the data points value" do
|
63
|
+
expect(data_point.value).to eql "5.5"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#timestamp" do
|
68
|
+
it "returns the timestamp of the data point" do
|
69
|
+
expect(Time.at(data_point.timestamp.to_i)).to eql Time.parse("2013-11-20T13:8:52-05:00")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#stream_id" do
|
74
|
+
it "returns the id for for the DataStream that represents these DataPoints" do
|
75
|
+
expect(data_point.stream_id).to eql "dia/channel/00000000-00000000-00409DFF-FF725771/0013a2004063d301/battery"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DeviceCloud::DataStream do
|
4
|
+
|
5
|
+
subject(:data_stream) do
|
6
|
+
DeviceCloud::DataStream.parse(xml).first
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:xml) do
|
10
|
+
<<-XML
|
11
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
12
|
+
<result>
|
13
|
+
<resultSize>4</resultSize>
|
14
|
+
<requestedSize>1000</requestedSize>
|
15
|
+
<pageCursor>76cab9ad-5-ebd5ccac</pageCursor>
|
16
|
+
<DataStream>
|
17
|
+
<cstId>5940</cstId>
|
18
|
+
<streamId>dia/channel/00000000-00000000-00409DFF-FF725771/0013a20040a52e1d/distance</streamId>
|
19
|
+
<dataType>DOUBLE</dataType>
|
20
|
+
<forwardTo/>
|
21
|
+
<currentValue>
|
22
|
+
<id>5101f920-53b4-11e3-8b51-bc764e113426</id>
|
23
|
+
<timestamp>1385151966954</timestamp>
|
24
|
+
<serverTimestamp>1385151968249</serverTimestamp>
|
25
|
+
<data>44.2</data>
|
26
|
+
<description/>
|
27
|
+
<quality>0</quality>
|
28
|
+
</currentValue>
|
29
|
+
<description/>
|
30
|
+
<units>in</units>
|
31
|
+
<dataTtl>2678400</dataTtl>
|
32
|
+
<rollupTtl>8035200</rollupTtl>
|
33
|
+
</DataStream>
|
34
|
+
<DataStream>
|
35
|
+
<cstId>5940</cstId>
|
36
|
+
<streamId>dia/channel/00000000-00000000-00409DFF-FF725771/0013a2004063d301/distance</streamId>
|
37
|
+
<dataType>DOUBLE</dataType>
|
38
|
+
<forwardTo/>
|
39
|
+
<currentValue>
|
40
|
+
<id>510c337d-53b4-11e3-8b51-bc764e113426</id>
|
41
|
+
<timestamp>1385151967021</timestamp>
|
42
|
+
<serverTimestamp>1385151968488</serverTimestamp>
|
43
|
+
<data>0.0</data>
|
44
|
+
<description/>
|
45
|
+
<quality>0</quality>
|
46
|
+
</currentValue>
|
47
|
+
<description/>
|
48
|
+
<units>in</units>
|
49
|
+
<dataTtl>2678400</dataTtl>
|
50
|
+
<rollupTtl>8035200</rollupTtl>
|
51
|
+
</DataStream>
|
52
|
+
<DataStream>
|
53
|
+
<cstId>5940</cstId>
|
54
|
+
<streamId>dia/channel/00000000-00000000-00409DFF-FF725771/0013a200408cb965/distance</streamId>
|
55
|
+
<dataType>DOUBLE</dataType>
|
56
|
+
<forwardTo/>
|
57
|
+
<currentValue>
|
58
|
+
<id>50e8a4e8-53b4-11e3-8b51-bc764e113426</id>
|
59
|
+
<timestamp>1385151966788</timestamp>
|
60
|
+
<serverTimestamp>1385151968064</serverTimestamp>
|
61
|
+
<data>0.0</data>
|
62
|
+
<description/>
|
63
|
+
<quality>0</quality>
|
64
|
+
</currentValue>
|
65
|
+
<description/>
|
66
|
+
<units>in</units>
|
67
|
+
<dataTtl>2678400</dataTtl>
|
68
|
+
<rollupTtl>8035200</rollupTtl>
|
69
|
+
</DataStream>
|
70
|
+
<DataStream>
|
71
|
+
<cstId>5940</cstId>
|
72
|
+
<streamId>dia/channel/00000000-00000000-00409DFF-FF725771/0013a20040a52b7a/distance</streamId>
|
73
|
+
<dataType>DOUBLE</dataType>
|
74
|
+
<forwardTo/>
|
75
|
+
<currentValue>
|
76
|
+
<id>50f1cc94-53b4-11e3-8b51-bc764e113426</id>
|
77
|
+
<timestamp>1385151966848</timestamp>
|
78
|
+
<serverTimestamp>1385151968068</serverTimestamp>
|
79
|
+
<data>0.0</data>
|
80
|
+
<description/>
|
81
|
+
<quality>0</quality>
|
82
|
+
</currentValue>
|
83
|
+
<description/>
|
84
|
+
<units>in</units>
|
85
|
+
<dataTtl>2678400</dataTtl>
|
86
|
+
<rollupTtl>8035200</rollupTtl>
|
87
|
+
</DataStream>
|
88
|
+
</result>
|
89
|
+
XML
|
90
|
+
end
|
91
|
+
|
92
|
+
describe ".parse" do
|
93
|
+
it "will return an array containing a data stream for each stream in the xml" do
|
94
|
+
expect(DeviceCloud::DataStream.parse(xml).count).to eql 4
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#delete" do
|
99
|
+
it "will use the client to delete the stream" do
|
100
|
+
client = double("DeviceCloud::Client", :delete => nil)
|
101
|
+
|
102
|
+
data_stream.delete(client)
|
103
|
+
|
104
|
+
expect(client).to have_received(:delete).with("/ws/DataStream/dia/channel/00000000-00000000-00409DFF-FF725771/0013a20040a52e1d/distance")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#value" do
|
109
|
+
it "returns the current value of the stream" do
|
110
|
+
expect(data_stream.value).to eql "44.2"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#timestamp" do
|
115
|
+
it "returns the timestamp of the current datapoint for the stream" do
|
116
|
+
expect(Time.at(data_stream.timestamp.to_i)).to eql Time.parse("2013-11-22T15:26:06-05:00")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#current_id" do
|
121
|
+
it "returns the id of the current datapoint for the stream" do
|
122
|
+
expect(data_stream.current_id).to eql "5101f920-53b4-11e3-8b51-bc764e113426"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#stream_id" do
|
127
|
+
it "returns the stream id" do
|
128
|
+
expect(data_stream.stream_id).to eql "dia/channel/00000000-00000000-00409DFF-FF725771/0013a20040a52e1d/distance"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#device_id" do
|
133
|
+
it "returns the device id out of the stream_id" do
|
134
|
+
expect(data_stream.device_id).to eql "00000000-00000000-00409DFF-FF725771"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#mac" do
|
139
|
+
it "returns the sensor mac from the device id and converts it to an integer" do
|
140
|
+
expect(data_stream.mac).to eql "0013a20040a52e1d".to_i(16)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "#name" do
|
145
|
+
it "returns the stream name" do
|
146
|
+
expect(data_stream.name).to eql "distance"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "#device_path" do
|
151
|
+
it "generates the path for the sensor from any stream belonging to the device" do
|
152
|
+
expect(data_stream.device_path).to eql "dia/channel/00000000-00000000-00409DFF-FF725771/0013a20040a52e1d/"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe DeviceCloud::DeviceCore do
|
4
|
+
subject(:device) { DeviceCloud::DeviceCore.parse(xml).first }
|
5
|
+
|
6
|
+
let(:xml) do
|
7
|
+
<<-XML
|
8
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
9
|
+
<result>
|
10
|
+
<resultTotalRows>2</resultTotalRows>
|
11
|
+
<requestedStartRow>0</requestedStartRow>
|
12
|
+
<resultSize>2</resultSize>
|
13
|
+
<requestedSize>1000</requestedSize>
|
14
|
+
<remainingSize>0</remainingSize>
|
15
|
+
<DeviceCore>
|
16
|
+
<id>
|
17
|
+
<devId>747711</devId>
|
18
|
+
<devVersion>4</devVersion>
|
19
|
+
</id>
|
20
|
+
<devRecordStartDate>2013-11-18T15:41:00.000Z</devRecordStartDate>
|
21
|
+
<devMac>00:40:9D:70:6F:FF</devMac>
|
22
|
+
<devConnectwareId>00000000-00000000-00409DFF-FF706FFF</devConnectwareId>
|
23
|
+
<cstId>5940</cstId>
|
24
|
+
<grpId>8892</grpId>
|
25
|
+
<devEffectiveStartDate>2013-11-18T13:53:00.000Z</devEffectiveStartDate>
|
26
|
+
<devTerminated>false</devTerminated>
|
27
|
+
<dvVendorId>4261412864</dvVendorId>
|
28
|
+
<dpDeviceType>ConnectPort X4</dpDeviceType>
|
29
|
+
<dpFirmwareLevel>34603011</dpFirmwareLevel>
|
30
|
+
<dpFirmwareLevelDesc>2.16.0.3</dpFirmwareLevelDesc>
|
31
|
+
<dpRestrictedStatus>0</dpRestrictedStatus>
|
32
|
+
<dpLastKnownIp>192.168.2.10</dpLastKnownIp>
|
33
|
+
<dpGlobalIp>99.91.75.14</dpGlobalIp>
|
34
|
+
<dpConnectionStatus>1</dpConnectionStatus>
|
35
|
+
<dpLastConnectTime>2013-11-22T18:05:45.590Z</dpLastConnectTime>
|
36
|
+
<dpContact/>
|
37
|
+
<dpDescription>IVX 400 Test Rig</dpDescription>
|
38
|
+
<dpLocation/>
|
39
|
+
<dpPanId>0x679d</dpPanId>
|
40
|
+
<xpExtAddr>00:13:A2:00:40:91:99:29</xpExtAddr>
|
41
|
+
<dpServerId>ClientID[15]</dpServerId>
|
42
|
+
<dpZigbeeCapabilities>383</dpZigbeeCapabilities>
|
43
|
+
<dpCapabilities>68154</dpCapabilities>
|
44
|
+
<grpPath>IVX</grpPath>
|
45
|
+
<dpLastDisconnectTime>2013-11-18T19:22:51.067Z</dpLastDisconnectTime>
|
46
|
+
</DeviceCore>
|
47
|
+
<DeviceCore>
|
48
|
+
<id>
|
49
|
+
<devId>873214</devId>
|
50
|
+
<devVersion>4</devVersion>
|
51
|
+
</id>
|
52
|
+
<devRecordStartDate>2013-11-18T15:41:00.000Z</devRecordStartDate>
|
53
|
+
<devMac>00:40:9d:72:57:71</devMac>
|
54
|
+
<devConnectwareId>00000000-00000000-00409DFF-FF725771</devConnectwareId>
|
55
|
+
<cstId>5940</cstId>
|
56
|
+
<grpId>8892</grpId>
|
57
|
+
<devEffectiveStartDate>2013-11-18T15:32:00.000Z</devEffectiveStartDate>
|
58
|
+
<devTerminated>false</devTerminated>
|
59
|
+
<dvVendorId>4261412864</dvVendorId>
|
60
|
+
<dpDeviceType>ConnectPort X4</dpDeviceType>
|
61
|
+
<dpFirmwareLevel>34603011</dpFirmwareLevel>
|
62
|
+
<dpFirmwareLevelDesc>2.16.0.3</dpFirmwareLevelDesc>
|
63
|
+
<dpRestrictedStatus>0</dpRestrictedStatus>
|
64
|
+
<dpLastKnownIp>192.168.2.58</dpLastKnownIp>
|
65
|
+
<dpGlobalIp>99.91.75.14</dpGlobalIp>
|
66
|
+
<dpConnectionStatus>0</dpConnectionStatus>
|
67
|
+
<dpLastConnectTime>2013-11-22T20:13:17.340Z</dpLastConnectTime>
|
68
|
+
<dpContact/>
|
69
|
+
<dpDescription>DeLaval IVX</dpDescription>
|
70
|
+
<dpLocation/>
|
71
|
+
<dpPanId>0x123d</dpPanId>
|
72
|
+
<xpExtAddr>00:13:A2:00:40:A4:C1:EC</xpExtAddr>
|
73
|
+
<dpServerId/>
|
74
|
+
<dpZigbeeCapabilities>383</dpZigbeeCapabilities>
|
75
|
+
<dpCapabilities>68154</dpCapabilities>
|
76
|
+
<grpPath>IVX</grpPath>
|
77
|
+
<dpLastDisconnectTime>2013-11-22T20:56:16.547Z</dpLastDisconnectTime>
|
78
|
+
</DeviceCore>
|
79
|
+
</result>
|
80
|
+
XML
|
81
|
+
end
|
82
|
+
|
83
|
+
describe ".parse" do
|
84
|
+
it "will return an array containing device core objects" do
|
85
|
+
expect(DeviceCloud::DeviceCore.parse(xml).count).to eql 2
|
86
|
+
end
|
87
|
+
context "the xml is empty" do
|
88
|
+
let(:xml) { "" }
|
89
|
+
it "will raise an error" do
|
90
|
+
expect { DeviceCloud::DeviceCore.parse(xml) }.to raise_error DeviceCloud::InvalidResultError
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#device_id" do
|
96
|
+
it "returns the connectware id" do
|
97
|
+
expect(device.device_id).to eql "00000000-00000000-00409DFF-FF706FFF"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#name" do
|
102
|
+
it "returns the device description" do
|
103
|
+
expect(device.name).to eql "IVX 400 Test Rig"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
describe "#connection_state" do
|
107
|
+
it "returns true if the device is connected" do
|
108
|
+
expect(device.connection_state).to eql true
|
109
|
+
end
|
110
|
+
context "the device is not connected" do
|
111
|
+
subject(:device) { DeviceCloud::DeviceCore.parse(xml).last }
|
112
|
+
|
113
|
+
it "returns false" do
|
114
|
+
expect(device.connection_state).to eql false
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "#last_connect_time" do
|
120
|
+
it "returns the time the device last connected" do
|
121
|
+
expect(device.last_connect_time).to eql Time.parse("2013-11-22T18:05:45.590Z")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#last_disconnect_time" do
|
126
|
+
it "returns the time the device last disconnected" do
|
127
|
+
expect(device.last_disconnect_time).to eql Time.parse("2013-11-18T19:22:51.067Z")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#global_ip" do
|
132
|
+
it "returns the global ip address of the device" do
|
133
|
+
expect(device.global_ip).to eql "99.91.75.14"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#local_ip" do
|
138
|
+
it "returns the local ip address of the device" do
|
139
|
+
expect(device.local_ip).to eql "192.168.2.10"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe DeviceCloud::Monitor do
|
4
|
+
subject(:monitor) do
|
5
|
+
DeviceCloud::Monitor.new(topic)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:client) { DeviceCloud::Client.new(:username => "test", :password => "test") }
|
9
|
+
|
10
|
+
let(:api_stub) { stub_request :any, /#{client.base_url}.*/ }
|
11
|
+
|
12
|
+
let(:topic) { "DiaChannelDataFull" }
|
13
|
+
|
14
|
+
describe "#build" do
|
15
|
+
let(:document) { monitor.build.doc }
|
16
|
+
it 'it will have the correct topic' do
|
17
|
+
document.xpath("//Monitor/monTopic").text.should == topic
|
18
|
+
monitor.topic = "DeviceCore,DataStream"
|
19
|
+
document.xpath("//Monitor/monTopic").text.should == topic
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
describe "#save" do
|
25
|
+
before do
|
26
|
+
api_stub
|
27
|
+
end
|
28
|
+
it "should POSTed to $base/ws/Monitor" do
|
29
|
+
monitor.save(client)
|
30
|
+
a_request(:post, client.base_url + "/ws/Monitor").should have_been_made
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "all" do
|
35
|
+
before do
|
36
|
+
api_stub
|
37
|
+
end
|
38
|
+
it "should get on the root of monitor" do
|
39
|
+
DeviceCloud::Monitor.all(client)
|
40
|
+
a_request(:get, client.base_url + "/ws/Monitor").should have_been_made
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe DeviceCloud::Result do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
DeviceCloud::Result.new xml
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:xml) do
|
10
|
+
<<-XML
|
11
|
+
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
12
|
+
<result>
|
13
|
+
<resultSize>2</resultSize>
|
14
|
+
<requestedSize>1000</requestedSize>
|
15
|
+
<pageCursor>51075196-53b4-11e3-8b51-bc764e113426</pageCursor>
|
16
|
+
<requestedStartTime>-1</requestedStartTime>
|
17
|
+
<requestedEndTime>-1</requestedEndTime>
|
18
|
+
<FooBar>
|
19
|
+
<Foo>Bar</Foo>
|
20
|
+
</FooBar>
|
21
|
+
<FooBar>
|
22
|
+
<Foo>Bar</Foo>
|
23
|
+
</FooBar>
|
24
|
+
</result>
|
25
|
+
XML
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
describe "#count" do
|
30
|
+
it "will return the total number of items in the result set" do
|
31
|
+
expect(subject.count).to eql 2
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#requested" do
|
36
|
+
it "will return the requested maximum size of the of the result dataset" do
|
37
|
+
expect(subject.requested).to eql 1000
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context("xml is empty or does not contrain a result root element") do
|
42
|
+
let(:xml) { "" }
|
43
|
+
it "will raise InvalidResultError" do
|
44
|
+
expect { subject }.to raise_error DeviceCloud::InvalidResultError
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'coveralls'
|
4
|
+
Coveralls.wear!
|
5
|
+
|
6
|
+
|
7
|
+
require "device_cloud"
|
8
|
+
|
9
|
+
require 'webmock/rspec'
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.include WebMock::API
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,288 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: device-cloud
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Eric Nelson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-01-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: nokogiri
|
16
|
+
requirement: !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: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rest-client
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.3'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: webmock
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: pry
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: debugger
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: guard
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: guard-rspec
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: guard-bundler
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: libnotify
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
- !ruby/object:Gem::Dependency
|
207
|
+
name: coveralls
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
209
|
+
none: false
|
210
|
+
requirements:
|
211
|
+
- - ! '>='
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: '0'
|
214
|
+
type: :development
|
215
|
+
prerelease: false
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ! '>='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
222
|
+
description: REST Wrapper for Etherios Devicecloud
|
223
|
+
email:
|
224
|
+
- eric@clean-logix.com
|
225
|
+
executables: []
|
226
|
+
extensions: []
|
227
|
+
extra_rdoc_files: []
|
228
|
+
files:
|
229
|
+
- .gitignore
|
230
|
+
- .travis.yml
|
231
|
+
- Gemfile
|
232
|
+
- Guardfile
|
233
|
+
- LICENSE.txt
|
234
|
+
- README.md
|
235
|
+
- Rakefile
|
236
|
+
- device-cloud.gemspec
|
237
|
+
- lib/device_cloud.rb
|
238
|
+
- lib/device_cloud/client.rb
|
239
|
+
- lib/device_cloud/config.rb
|
240
|
+
- lib/device_cloud/data_point.rb
|
241
|
+
- lib/device_cloud/data_stream.rb
|
242
|
+
- lib/device_cloud/device_core.rb
|
243
|
+
- lib/device_cloud/monitor.rb
|
244
|
+
- lib/device_cloud/result.rb
|
245
|
+
- lib/device_cloud/version.rb
|
246
|
+
- spec/device_cloud/client_spec.rb
|
247
|
+
- spec/device_cloud/config_spec.rb
|
248
|
+
- spec/device_cloud/data_point_spec.rb
|
249
|
+
- spec/device_cloud/data_stream_spec.rb
|
250
|
+
- spec/device_cloud/device_core_spec.rb
|
251
|
+
- spec/device_cloud/monitor_spec.rb
|
252
|
+
- spec/device_cloud/result_spec.rb
|
253
|
+
- spec/spec_helper.rb
|
254
|
+
homepage: ''
|
255
|
+
licenses:
|
256
|
+
- MIT
|
257
|
+
post_install_message:
|
258
|
+
rdoc_options: []
|
259
|
+
require_paths:
|
260
|
+
- lib
|
261
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
262
|
+
none: false
|
263
|
+
requirements:
|
264
|
+
- - ! '>='
|
265
|
+
- !ruby/object:Gem::Version
|
266
|
+
version: '0'
|
267
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
268
|
+
none: false
|
269
|
+
requirements:
|
270
|
+
- - ! '>='
|
271
|
+
- !ruby/object:Gem::Version
|
272
|
+
version: '0'
|
273
|
+
requirements: []
|
274
|
+
rubyforge_project:
|
275
|
+
rubygems_version: 1.8.23
|
276
|
+
signing_key:
|
277
|
+
specification_version: 3
|
278
|
+
summary: REST Wrapper for Etherios Devicecloud
|
279
|
+
test_files:
|
280
|
+
- spec/device_cloud/client_spec.rb
|
281
|
+
- spec/device_cloud/config_spec.rb
|
282
|
+
- spec/device_cloud/data_point_spec.rb
|
283
|
+
- spec/device_cloud/data_stream_spec.rb
|
284
|
+
- spec/device_cloud/device_core_spec.rb
|
285
|
+
- spec/device_cloud/monitor_spec.rb
|
286
|
+
- spec/device_cloud/result_spec.rb
|
287
|
+
- spec/spec_helper.rb
|
288
|
+
has_rdoc:
|