xively-rb-connector 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +142 -0
- data/Rakefile +1 -0
- data/lib/xively-rb-connector/connection.rb +39 -0
- data/lib/xively-rb-connector/datastream.rb +109 -0
- data/lib/xively-rb-connector/device.rb +130 -0
- data/lib/xively-rb-connector/logging.rb +25 -0
- data/lib/xively-rb-connector/version.rb +9 -0
- data/lib/xively-rb-connector.rb +31 -0
- data/xively-rb-connector.gemspec +39 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ea7c9c6444f3e234d46349afce7ce495e7b44b6d
|
4
|
+
data.tar.gz: 9bab33c8f37fa6b4783d77f100ffe665c9a26685
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 13b6b634f4e5d98ed315cabd8989c96ab2779ac798e6d3b96bcc42be27cd7e23d480448b8451cb7c17d1e7bd84b30d01d79aa023bddd4d68f2f3d0a80f3fe358
|
7
|
+
data.tar.gz: 73618b4fb24df88f295708236bc0507509e0bc7fb9c2d437979ee2e9cca37589c9718ffd397e016702dd35c78d80d18a04759a0ba5680aa6bcd384d774589525
|
data/.gitignore
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/test/tmp/
|
9
|
+
/test/version_tmp/
|
10
|
+
/tmp/
|
11
|
+
|
12
|
+
## Documentation cache and generated files:
|
13
|
+
/.yardoc/
|
14
|
+
/_yardoc/
|
15
|
+
/doc/
|
16
|
+
/rdoc/
|
17
|
+
|
18
|
+
## Environment normalisation:
|
19
|
+
/.bundle/
|
20
|
+
/lib/bundler/man/
|
21
|
+
|
22
|
+
# for a library or gem, you might want to ignore these files since the code is
|
23
|
+
# intended to run in multiple environments; otherwise, check them in:
|
24
|
+
Gemfile.lock
|
25
|
+
.ruby-version
|
26
|
+
.ruby-gemset
|
27
|
+
|
28
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
29
|
+
.rvmrc
|
30
|
+
|
31
|
+
## Specific to RubyMotion:
|
32
|
+
.dat*
|
33
|
+
.repl_history
|
34
|
+
build/
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Jordan Duggan
|
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 all
|
13
|
+
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 THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
xively-rb-connector
|
2
|
+
===================
|
3
|
+
|
4
|
+
xively-rb-connector is a ruby gem that provides an interface to [Xively](https://xively.com). It extends Sam Mulube's
|
5
|
+
excellent [xively-rb](https://github.com/xively/xively-rb) gem. This gem adds convenience functions such as find_by_id
|
6
|
+
lookup functions, datastream compression (only saves datapoints when value changes), a datapoint recording buffer, etc.
|
7
|
+
|
8
|
+
[Xively](https://xively.com/whats_xively/) is a public cloud specifically built for the "Internet of Things". With their
|
9
|
+
platform, developers can connect physical devices, that produce one or more datastreams, to a managed data store. The
|
10
|
+
device's details and datastreams are accessible via key-based access to any service or application that has access to the
|
11
|
+
web. Xively provides a fantastic development portal and prototyping accounts are free.
|
12
|
+
|
13
|
+
## Requirements
|
14
|
+
|
15
|
+
* Ruby 1.9.3 or higher
|
16
|
+
* A [Xively account](https://xively.com/signup)
|
17
|
+
|
18
|
+
## Contact, feedback and bugs
|
19
|
+
|
20
|
+
Please file bugs / issues and feature requests on the [issue tracker](https://github.com/jwtd/xively-rb-connector/issues)
|
21
|
+
|
22
|
+
## Install
|
23
|
+
|
24
|
+
```
|
25
|
+
gem install xively-rb-connector
|
26
|
+
```
|
27
|
+
|
28
|
+
## Examples
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
|
32
|
+
require 'xively-rb-connector'
|
33
|
+
|
34
|
+
# Xively provides a master api-key and device specific keys. To my knowledge, either can be used here.
|
35
|
+
my_api_key = 'XIVELY-ACCOUNT-OR-DEVICE-API-KEY-HERE'
|
36
|
+
|
37
|
+
# Each device on Xively gets thier own ID, which is exposed via thier REST API as a "feed"
|
38
|
+
feed_id = '123456789'
|
39
|
+
|
40
|
+
# Find your device on Xively by its feed_id
|
41
|
+
d = XivelyConnector.find_device_by_id(feed_id, my_api_key)
|
42
|
+
|
43
|
+
# Access details about the device
|
44
|
+
d.id # 123456789
|
45
|
+
d.feed # https://api.xively.com/v2/feeds/123456789.json
|
46
|
+
d.auto_feed_url # https://api.xively.com/v2/feeds/123456789.json
|
47
|
+
|
48
|
+
d.title # My Meter
|
49
|
+
d.device_serial # FOOBAR123456
|
50
|
+
d.description # The xively on xively.com
|
51
|
+
d.tags # ["Gas", "Power", "Propane", "Water"]
|
52
|
+
d.creator # https://xively.com/users/foo
|
53
|
+
d.email # your.email@gmail.com
|
54
|
+
d.website # http://www.your-website.com
|
55
|
+
d.icon
|
56
|
+
|
57
|
+
d.created # 2014-01-01 16:36:30 UTC
|
58
|
+
d.updated # 2014-03-31 05:02:25 UTC
|
59
|
+
d.private # true
|
60
|
+
d.is_private? # true
|
61
|
+
d.status # live
|
62
|
+
d.is_frozen? # false
|
63
|
+
|
64
|
+
# Access location data directly
|
65
|
+
d.has_location? # true
|
66
|
+
d.location_name # The location name on xively.com
|
67
|
+
d.location_domain # physical
|
68
|
+
d.location_lon # -78.12343456
|
69
|
+
d.location_lat # 35.12343454
|
70
|
+
d.location_ele # 354 feet
|
71
|
+
d.location_exposure
|
72
|
+
d.location_disposition
|
73
|
+
d.location_waypoints
|
74
|
+
|
75
|
+
# Or get a structure that has all the location details
|
76
|
+
l = d.location #<OpenStruct name="The location name on xively.com", latitude=35.12343454, longitude=-78.12343456, elevation="354 feet", exposure=nil, disposition=nil, waypoints=nil, domain="physical">
|
77
|
+
l.name # The location name on xively.com
|
78
|
+
l.domain # physical
|
79
|
+
l.longitude # -78.12343456
|
80
|
+
l.latitude # 35.12343454
|
81
|
+
l.elevation # 354 feet
|
82
|
+
l.exposure
|
83
|
+
l.disposition
|
84
|
+
l.waypoints
|
85
|
+
|
86
|
+
# Examine datastreams
|
87
|
+
d.datastream_ids # ["Amperage", "Propane", "Voltage", "Power", "Well"]
|
88
|
+
d.datastream_values # ["Amperage in Amps (A) = 0", "Propane in Cubic Feet (cft) = 0", "Voltage in Volts (V) = 9", "Power in Watts (W) = 0", "Well in Cubic Feet (cft) = 0"]
|
89
|
+
d.has_channel?('Voltage') # true
|
90
|
+
|
91
|
+
# Access datastreams by channel name using bracket syntax
|
92
|
+
d['Voltage'] # <XivelyConnector::Datastream:0x007ff62a137b80>
|
93
|
+
d['Voltage'].current_value # 9
|
94
|
+
|
95
|
+
ds = d['Volts']
|
96
|
+
ds.id # Voltage
|
97
|
+
ds.unit_label # Volts
|
98
|
+
ds.unit_symbol # V
|
99
|
+
ds.current_value # 9
|
100
|
+
ds.tags # Power
|
101
|
+
ds.min_value # 0.0
|
102
|
+
ds.max_value # 25.0
|
103
|
+
|
104
|
+
# Setup my datastream buffer
|
105
|
+
ds.only_save_changes = true # Will only queue a datapoint if its value is different from the previous datapoint's which is also the current_value
|
106
|
+
ds.datapoint_buffer_size = 60 # Will auto-save to feed when 60 points are queued
|
107
|
+
ds.only_save_changes # true
|
108
|
+
ds.only_saves_changes? # true
|
109
|
+
ds.datapoint_buffer_size # 60
|
110
|
+
|
111
|
+
# Queue new datapoints in a number of ways using the shift operator
|
112
|
+
# BigDecimal is used for value comparison so "10" == 10 == 10.0
|
113
|
+
|
114
|
+
ds.datapoints.size # 0
|
115
|
+
ds << Xively::Datapoint.new(:value => "10", :at => Time.now,())
|
116
|
+
ds << {:at=>':at => Time.now(), :value => "10"}
|
117
|
+
ds << "10"
|
118
|
+
ds << 10
|
119
|
+
ds << 10.0
|
120
|
+
ds << 11
|
121
|
+
|
122
|
+
# If ds.only_save_changes is true, the commands above only result in two datapoints being queued (because the only unique values recorded were 10 and 11)
|
123
|
+
ds.datapoints.size # 2
|
124
|
+
|
125
|
+
# Save datapoints to xively.com
|
126
|
+
ds.save_datapoints
|
127
|
+
ds.datapoints.size # 0
|
128
|
+
|
129
|
+
```
|
130
|
+
|
131
|
+
## Resources
|
132
|
+
|
133
|
+
* [Free Xively Developer Account](https://xively.com/signup)
|
134
|
+
* [xively-rb](https://github.com/xively/xively-rb)
|
135
|
+
* [xively-js](http://xively.github.io/xively-js) is a javascript lib for viewing and charting Xively data
|
136
|
+
|
137
|
+
## Special Thanks
|
138
|
+
|
139
|
+
* Xively - for an awesome data platform
|
140
|
+
* Sam Mulube - for xively-rb
|
141
|
+
* Ian Duggan - for introducing me to ruby
|
142
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'xively-rb'
|
2
|
+
|
3
|
+
module XivelyConnector
|
4
|
+
|
5
|
+
class Connection < Xively::Client
|
6
|
+
include XivelyConnector::Logging
|
7
|
+
|
8
|
+
format :json
|
9
|
+
|
10
|
+
# Mix in the ability to log
|
11
|
+
include XivelyConnector::Logging
|
12
|
+
|
13
|
+
def initialize(options)
|
14
|
+
@logger = options[:logger] || logger
|
15
|
+
@logger.debug "XivelyConnector::Connection initialize"
|
16
|
+
super(options[:api_key])
|
17
|
+
end
|
18
|
+
|
19
|
+
#Set HTTParty params that we need to set after initialize is called
|
20
|
+
#These params come from @options within initialize and include the following:
|
21
|
+
#:ssl_ca_file - SSL CA File for SSL connections
|
22
|
+
#:format - 'json', 'xml', 'html', etc. || Defaults to 'xml'
|
23
|
+
#:format_header - :format Header string || Defaults to 'application/xml'
|
24
|
+
#:pem_cert - /path/to/a/pem_formatted_certificate.pem for SSL connections
|
25
|
+
#:pem_cert_pass - plaintext password, not recommended!
|
26
|
+
def set_httparty_options(options={})
|
27
|
+
if options[:ssl_ca_file]
|
28
|
+
ssl_ca_file opts[:ssl_ca_file]
|
29
|
+
if options[:pem_cert_pass]
|
30
|
+
pem File.read(options[:pem_cert]), options[:pem_cert_pass]
|
31
|
+
else
|
32
|
+
pem File.read(options[:pem_cert])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'xively-rb'
|
2
|
+
require 'json'
|
3
|
+
require 'bigdecimal'
|
4
|
+
|
5
|
+
module XivelyConnector
|
6
|
+
|
7
|
+
# Extend https://github.com/xively-rb-connector/xively-rb
|
8
|
+
class Datastream < Xively::Datastream
|
9
|
+
|
10
|
+
attr_reader :device
|
11
|
+
attr :datapoint_buffer_size, :only_save_changes
|
12
|
+
|
13
|
+
# Mix in the ability to log
|
14
|
+
include XivelyConnector::Logging
|
15
|
+
|
16
|
+
def initialize(options)
|
17
|
+
@logger = options[:logger] || logger
|
18
|
+
@logger.debug "XivelyConnector::Datastream initialize"
|
19
|
+
|
20
|
+
raise "An instance of XivelyConnector::Device must be provided to create a datastream" unless options[:device]
|
21
|
+
raise "The data block for this datastream is missing" unless options[:data]
|
22
|
+
|
23
|
+
# Capture parent and initialize Xively::Datastream
|
24
|
+
@device = options[:device]
|
25
|
+
data = options[:data]
|
26
|
+
super(data)
|
27
|
+
|
28
|
+
# Set the default buffer size (1 reading per minute)
|
29
|
+
@datapoint_buffer_size = options[:datapoint_buffer_size] || 60
|
30
|
+
@only_save_changes = options[:only_save_changes] || true
|
31
|
+
|
32
|
+
# Initialize Xively::Datastream's datapoint array to allow shift style loading
|
33
|
+
@datapoints = []
|
34
|
+
|
35
|
+
# Fix the unit attribute assignments
|
36
|
+
@unit_symbol = data['unit']['symbol']
|
37
|
+
@unit_label = data['unit']['label']
|
38
|
+
|
39
|
+
# Cast the current value as a BigDecimal for casting strings and comparing to ints and floats
|
40
|
+
@current_value = 0 if current_value.nil?
|
41
|
+
|
42
|
+
@logger.info "Initialized Datastream #{@id} (#{@unit_symbol})"
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
# Add a question style accessor to only_save_changes attribute
|
47
|
+
def only_saves_changes?
|
48
|
+
only_save_changes
|
49
|
+
end
|
50
|
+
|
51
|
+
# Have shift operator load the datapoint into the datastream's datapoints array
|
52
|
+
def <<(measurement)
|
53
|
+
# Make sure the value provided is a datapoint
|
54
|
+
datapoint = cast_to_datapoint(measurement)
|
55
|
+
|
56
|
+
# If only_save_changes is true, ignore datapoints whose value is the same as the current value
|
57
|
+
if only_save_changes and BigDecimal.new(datapoint.value) == BigDecimal.new(current_value)
|
58
|
+
@logger.debug "Ignoring datapoint from #{datapoint.at} because value did not change from #{current_value}"
|
59
|
+
else
|
60
|
+
@current_value = datapoint.value
|
61
|
+
datapoints << datapoint
|
62
|
+
@logger.debug "Queuing datapoint from #{datapoint.at} with value #{current_value}"
|
63
|
+
end
|
64
|
+
|
65
|
+
# See if the buffer is full
|
66
|
+
check_datapoints_buffer
|
67
|
+
end
|
68
|
+
|
69
|
+
# Converts a measurement to a Datapoint
|
70
|
+
def cast_to_datapoint(measurement, at=Time.now())
|
71
|
+
@logger.debug "cast_to_datapoint(#{measurement.inspect})"
|
72
|
+
if measurement.is_a?(Xively::Datapoint)
|
73
|
+
return measurement
|
74
|
+
elsif measurement.is_a?(Hash)
|
75
|
+
raise "The datapoint hash does not contain :at" unless measurement[:at]
|
76
|
+
raise "The datapoint hash does not contain :value" unless measurement[:value]
|
77
|
+
return Xively::Datapoint.new(measurement)
|
78
|
+
else
|
79
|
+
return Xively::Datapoint.new(:at => at, :value => measurement.to_s)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Send the queued datapoints array to Xively
|
84
|
+
def save_datapoints
|
85
|
+
@logger.debug "Saving #{datapoints.size} datapoints to the #{id} datastream"
|
86
|
+
response = XivelyConnector.connection.post("/v2/feeds/#{device.id}/datastreams/#{id}/datapoints",
|
87
|
+
:body => {:datapoints => datapoints}.to_json)
|
88
|
+
# If the response succeeded, clear the datapoint buffer and return the response object
|
89
|
+
if response.success?
|
90
|
+
clear_datapoints_buffer
|
91
|
+
response
|
92
|
+
else
|
93
|
+
logger.error response.response
|
94
|
+
raise response.response
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# If the datapoints array has exceeded the datapoint_buffer_size, send them to Xively
|
99
|
+
def check_datapoints_buffer
|
100
|
+
save_datapoints if datapoints.size >= @datapoint_buffer_size
|
101
|
+
end
|
102
|
+
|
103
|
+
# Resets the datapoints
|
104
|
+
def clear_datapoints_buffer
|
105
|
+
@datapoints = []
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'xively-rb'
|
2
|
+
require 'json'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
|
6
|
+
module XivelyConnector
|
7
|
+
|
8
|
+
# Extend https://github.com/xively-rb-connector/xively-rb
|
9
|
+
class Device < Xively::Feed
|
10
|
+
|
11
|
+
# Mix in the ability to log
|
12
|
+
include XivelyConnector::Logging
|
13
|
+
|
14
|
+
# Connect to a device by ID
|
15
|
+
def self.find_by_id(id)
|
16
|
+
XivelyConnector.connection.logger.debug "Device.find_by_id(#{id})"
|
17
|
+
response = XivelyConnector.connection.get("/v2/feeds/#{id}.json")
|
18
|
+
if response.success?
|
19
|
+
self.new(:response => response)
|
20
|
+
else
|
21
|
+
logger.error response.response
|
22
|
+
response.response
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Converts the Xively dates to ruby DateTimnes and make the datastreams accessible via hash syntax
|
27
|
+
def initialize(options)
|
28
|
+
|
29
|
+
# Create logger
|
30
|
+
@logger = options[:logger] || logger
|
31
|
+
@logger.debug "XivelyConnector::Device initialize"
|
32
|
+
|
33
|
+
# initialize parent
|
34
|
+
data = options[:response]
|
35
|
+
super(options[:response])
|
36
|
+
|
37
|
+
# Convert date strings to ruby dates
|
38
|
+
@created = Time.iso8601(created) # 2014-03-28T16:36:30.651731Z
|
39
|
+
@updated = Time.iso8601(updated) # 2014-03-28T16:45:05.206472Z
|
40
|
+
|
41
|
+
# xively-rb doesn't set location attributes correctly, so do so here
|
42
|
+
if data['location']
|
43
|
+
loc = data['location']
|
44
|
+
@has_location = true
|
45
|
+
@location_name = loc['name'] if
|
46
|
+
@location_domain = loc['domain'] if loc['domain']
|
47
|
+
@location_lon = loc['lon'] if loc['lon']
|
48
|
+
@location_lat = loc['lat'] if loc['lat']
|
49
|
+
@location_ele = loc['ele'] if loc['ele']
|
50
|
+
@location_exposure = loc['exposure'] if loc['exposure']
|
51
|
+
@location_disposition = loc['disposition'] if loc['disposition']
|
52
|
+
@location_waypoints = loc['waypoints'] if loc['waypoints']
|
53
|
+
end
|
54
|
+
|
55
|
+
# Setup enhanced datastreams
|
56
|
+
@datastream_ref = {}
|
57
|
+
datastreams.each { |ds| @datastream_ref[ds.id] = ds }
|
58
|
+
|
59
|
+
@logger.info "Initialized Xively Device #{@id} with #{datastreams.size} datastreams"
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# Support bracket notation for retriving data streams
|
64
|
+
def [](channel_id)
|
65
|
+
@datastream_ref[channel_id]
|
66
|
+
end
|
67
|
+
|
68
|
+
# Override the datastreams function so that it creates XivelyConnector::Datastreams which extend the standard one
|
69
|
+
def datastreams=(array)
|
70
|
+
return unless array.is_a?(Array)
|
71
|
+
@datastreams = []
|
72
|
+
array.each do |datastream|
|
73
|
+
if datastream.is_a?(Datastream)
|
74
|
+
@datastreams << datastream
|
75
|
+
elsif datastream.is_a?(Hash)
|
76
|
+
#@datastreams << Datastream.new(datastream)
|
77
|
+
@datastreams << XivelyConnector::Datastream.new(:device => self, :data => datastream)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns an array of datastream ids which are present on this device
|
83
|
+
def datastream_ids
|
84
|
+
@datastream_ref.keys
|
85
|
+
end
|
86
|
+
|
87
|
+
def datastream_values
|
88
|
+
v = []
|
89
|
+
@datastream_ref.each do |id, ds|
|
90
|
+
v << "#{id} in #{ds.unit_label} (#{ds.unit_symbol}) = #{ds.current_value}"
|
91
|
+
end
|
92
|
+
v
|
93
|
+
end
|
94
|
+
|
95
|
+
def has_datastream?(channel)
|
96
|
+
@datastream_ref.has_key?(channel)
|
97
|
+
end
|
98
|
+
|
99
|
+
def has_channel?(channel)
|
100
|
+
has_datastream?(channel)
|
101
|
+
end
|
102
|
+
|
103
|
+
def is_private?
|
104
|
+
private == 'true'
|
105
|
+
end
|
106
|
+
|
107
|
+
def is_frozen?
|
108
|
+
status == 'frozen'
|
109
|
+
end
|
110
|
+
|
111
|
+
def has_location?
|
112
|
+
@has_location ||= false
|
113
|
+
end
|
114
|
+
|
115
|
+
def location
|
116
|
+
@location ||= OpenStruct.new(
|
117
|
+
:name => location_name,
|
118
|
+
:latitude => location_lat,
|
119
|
+
:longitude => location_lon,
|
120
|
+
:elevation => location_ele,
|
121
|
+
:exposure => location_exposure,
|
122
|
+
:disposition => location_disposition,
|
123
|
+
:waypoints => location_waypoints,
|
124
|
+
:domain => location_domain
|
125
|
+
)
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
include Log4r
|
3
|
+
module XivelyConnector
|
4
|
+
|
5
|
+
module Logging
|
6
|
+
|
7
|
+
def logger
|
8
|
+
@logger ||= XivelyConnector::Logging.logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.logger
|
12
|
+
@logger ||= self.configure_logger_for(self.class.name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.configure_logger_for(classname)
|
16
|
+
l = Logger.new(classname)
|
17
|
+
l.level = ERROR
|
18
|
+
l.trace = false
|
19
|
+
l.add Log4r::Outputter.stderr
|
20
|
+
l
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module XivelyConnector
|
2
|
+
|
3
|
+
@@connection = nil
|
4
|
+
|
5
|
+
# Lookup methods delegate to class methods
|
6
|
+
def self.connection
|
7
|
+
@@connection
|
8
|
+
end
|
9
|
+
|
10
|
+
# Lookup methods delegate to class methods
|
11
|
+
def self.connect(options)
|
12
|
+
raise "A connection can not be established without an :api_key" unless options[:api_key]
|
13
|
+
@@connection = Connection.new(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Lookup methods delegate to class methods
|
17
|
+
def self.find_device_by_id(id, api_key=nil)
|
18
|
+
self.connect(:api_key => api_key) unless api_key.nil?
|
19
|
+
Device.find_by_id(id)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Base XivelyConnector exception class
|
23
|
+
class XivelyConnectorError < ::Exception; end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
require "xively-rb-connector/version"
|
28
|
+
require "xively-rb-connector/logging"
|
29
|
+
require "xively-rb-connector/connection"
|
30
|
+
require "xively-rb-connector/device"
|
31
|
+
require "xively-rb-connector/datastream"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'xively-rb-connector/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "xively-rb-connector"
|
8
|
+
spec.version = XivelyConnector::VERSION::STRING
|
9
|
+
spec.authors = ["Jordan Duggan"]
|
10
|
+
spec.email = ["Jordan.Duggan@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Ruby gem that provides a high level interface to Xively}
|
13
|
+
spec.description = %q{xively-rb-connector is a ruby gem that provides an interface to Xively (https://xively.com). It extends Sam Mulube's
|
14
|
+
excellent xively-rb (https://github.com/xively/xively-rb) gem. The xively-rb-connector gem adds convenience functions such as find_by_id
|
15
|
+
lookup functions, datastream compression (only saves datapoints when value changes), a datapoint recording buffer, etc.
|
16
|
+
|
17
|
+
Xively (https://xively.com/whats_xively) is a public cloud specifically built for the "Internet of Things". With their
|
18
|
+
platform, developers can connect physical devices, that produce one or more datastreams, to a managed data store. The
|
19
|
+
device's details and datastreams are accessible via key-based access to any service or application that has access to the
|
20
|
+
web. Xively provides a fantastic development portal and prototyping accounts are free.}
|
21
|
+
|
22
|
+
spec.homepage = "https://github.com/jwtd/xively-rb-connector"
|
23
|
+
spec.license = "MIT"
|
24
|
+
|
25
|
+
spec.files = `git ls-files`.split($/)
|
26
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
27
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
# Development dependencies
|
31
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
32
|
+
spec.add_development_dependency "rake", "~> 10.2"
|
33
|
+
|
34
|
+
# Runtime dependencies
|
35
|
+
spec.add_runtime_dependency "log4r", "~> 1.1"
|
36
|
+
spec.add_runtime_dependency "xively-rb", "~> 0.2"
|
37
|
+
spec.add_runtime_dependency "bigdecimal", "~> 1.2"
|
38
|
+
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xively-rb-connector
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jordan Duggan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.2'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: log4r
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: xively-rb
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.2'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bigdecimal
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.2'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.2'
|
83
|
+
description: |-
|
84
|
+
xively-rb-connector is a ruby gem that provides an interface to Xively (https://xively.com). It extends Sam Mulube's
|
85
|
+
excellent xively-rb (https://github.com/xively/xively-rb) gem. The xively-rb-connector gem adds convenience functions such as find_by_id
|
86
|
+
lookup functions, datastream compression (only saves datapoints when value changes), a datapoint recording buffer, etc.
|
87
|
+
|
88
|
+
Xively (https://xively.com/whats_xively) is a public cloud specifically built for the "Internet of Things". With their
|
89
|
+
platform, developers can connect physical devices, that produce one or more datastreams, to a managed data store. The
|
90
|
+
device's details and datastreams are accessible via key-based access to any service or application that has access to the
|
91
|
+
web. Xively provides a fantastic development portal and prototyping accounts are free.
|
92
|
+
email:
|
93
|
+
- Jordan.Duggan@gmail.com
|
94
|
+
executables: []
|
95
|
+
extensions: []
|
96
|
+
extra_rdoc_files: []
|
97
|
+
files:
|
98
|
+
- .gitignore
|
99
|
+
- Gemfile
|
100
|
+
- LICENSE
|
101
|
+
- README.md
|
102
|
+
- Rakefile
|
103
|
+
- lib/xively-rb-connector.rb
|
104
|
+
- lib/xively-rb-connector/connection.rb
|
105
|
+
- lib/xively-rb-connector/datastream.rb
|
106
|
+
- lib/xively-rb-connector/device.rb
|
107
|
+
- lib/xively-rb-connector/logging.rb
|
108
|
+
- lib/xively-rb-connector/version.rb
|
109
|
+
- xively-rb-connector.gemspec
|
110
|
+
homepage: https://github.com/jwtd/xively-rb-connector
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 2.2.2
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: Ruby gem that provides a high level interface to Xively
|
134
|
+
test_files: []
|