SensorStream 0.2.3 → 0.3.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 +4 -4
- data/lib/SensorStream.rb +112 -142
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5d46b32fc009e3df9406da27578c1c7dd9f3af9
|
4
|
+
data.tar.gz: f35a58d2343ab7ef44eae4cdf80fb331aaede55f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b54d4c6c333f5fdd86014aba0e1ef063976b63b45ad7ae030cf7714c0f6ad71c1b108c7723ce7184061eeb9ebe369fc265d9fa10d878e0dc26334f69619f5a25
|
7
|
+
data.tar.gz: 5fe47c0e29f9e57cc320dc6278cfe7a0a3d2800b6b9707b32ef84a0fd26eb761d73ff7bc9e5cf4e84174bb29b2541f477fa57419856dbf7336a1abc12ef2b804
|
data/lib/SensorStream.rb
CHANGED
@@ -28,8 +28,8 @@ module SensorStream
|
|
28
28
|
|
29
29
|
# Allows the SensorStream server to be overridden
|
30
30
|
def self.set_default_server
|
31
|
-
@host_name = "
|
32
|
-
@port_number =
|
31
|
+
@host_name = "dodeca.coas.oregonstate.edu"
|
32
|
+
@port_number = 443
|
33
33
|
end
|
34
34
|
|
35
35
|
# Internally used to wrap HTTP puts with the requires headers
|
@@ -40,7 +40,7 @@ module SensorStream
|
|
40
40
|
# Make sure that, at a minimum, the content type is set in the header
|
41
41
|
header_dict["Content-Type"] = "application/json";
|
42
42
|
|
43
|
-
uri = URI.
|
43
|
+
uri = URI::HTTPS.new('https', nil, @host_name, @port_number, nil, request, nil, nil, nil);
|
44
44
|
if (debug)
|
45
45
|
puts "POST to #{uri.to_s}"
|
46
46
|
puts "Header: #{header_dict}"
|
@@ -49,6 +49,7 @@ module SensorStream
|
|
49
49
|
|
50
50
|
http = Net::HTTP.new(@host_name, @port_number);
|
51
51
|
http.read_timeout = timeout; # 10 minute default timeout
|
52
|
+
http.use_ssl = true
|
52
53
|
retval = http.post(uri.request_uri, JSON.generate(body_dict), header_dict);
|
53
54
|
|
54
55
|
return retval
|
@@ -60,65 +61,20 @@ end
|
|
60
61
|
self.set_default_server unless !@host_name.nil?
|
61
62
|
|
62
63
|
|
63
|
-
uri = URI.
|
64
|
+
uri = URI::HTTPS.new('https', nil, @host_name, @port_number, nil, request, nil, nil, nil);
|
64
65
|
if (debug)
|
65
66
|
puts "GET from #{uri.to_s}"
|
66
67
|
puts "Header: #{header_dict.to_s}"
|
67
68
|
end
|
68
69
|
|
69
70
|
http = Net::HTTP.new(@host_name, @port_number);
|
70
|
-
http.read_timeout =
|
71
|
+
http.read_timeout = timeout; # 10 minute timeout
|
72
|
+
http.use_ssl = true
|
71
73
|
retval = http.get(uri.request_uri, header_dict);
|
72
74
|
|
73
75
|
return retval
|
74
76
|
end
|
75
|
-
|
76
|
-
# create a new device on the server
|
77
|
-
def self.create_device(user_name, device_name, description)
|
78
|
-
dict = {"username" => user_name,
|
79
|
-
"devicename" => device_name,
|
80
|
-
"description" => description}
|
81
|
-
|
82
|
-
resp = make_http_post("/device.ashx?create=", dict)
|
83
|
-
|
84
|
-
if (resp.code != "200")
|
85
|
-
STDERR.puts "Error creating SensorStream device! (#{resp.code})\n#{resp.body}"
|
86
|
-
else
|
87
|
-
SensorStream::Device.new(user_name, device_name, description, [], JSON.parse(resp.body)["guid"])
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Delete a device with a given key from the server
|
92
|
-
def self.delete_device_with_key(device_key)
|
93
|
-
puts "Deleting device #{device_key}"
|
94
|
-
resp = make_http_post("/device.ashx?delete=device", {}, { "key" => device_key })
|
95
|
-
|
96
|
-
if (resp.code != "200")
|
97
|
-
STDERR.puts "Error deleting SensorStream device! (#{resp.code})\n#{resp.body}"
|
98
|
-
return false;
|
99
|
-
else
|
100
|
-
return true;
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# Deletes a device from the server given a ruby object with a key
|
105
|
-
def self.delete_device(device)
|
106
|
-
delete_device_with_key(device.key)
|
107
|
-
end
|
108
|
-
|
109
|
-
# Delete a stream from a device given a streamID and device key
|
110
|
-
def self.delete_stream_with_key(streamID, device_key)
|
111
|
-
puts "Deleting Stream #{streamID}"
|
112
|
-
resp = make_http_post("/stream.ashx?delete=#{streamID}", {}, { "key" => device_key })
|
113
|
-
|
114
|
-
if (resp.code != "200")
|
115
|
-
STDERR.puts "Error deleting stream #{streamID} (#{resp.code})\n#{resp.body}"
|
116
|
-
false
|
117
|
-
else
|
118
|
-
true
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
77
|
+
|
122
78
|
# Reads a list of devices from the server
|
123
79
|
def self.get_devices()
|
124
80
|
resp = make_http_get("/device.ashx?getdevices=");
|
@@ -133,27 +89,58 @@ end
|
|
133
89
|
end
|
134
90
|
|
135
91
|
JSON.parse(resp.body).each { |device|
|
136
|
-
devices << SensorStream::Device.new(device["
|
137
|
-
device["
|
138
|
-
device["
|
92
|
+
devices << SensorStream::Device.new(device["DeviceID"],
|
93
|
+
device["UserName"],
|
94
|
+
device["DeviceName"],
|
95
|
+
device["Description"]) }
|
139
96
|
return devices;
|
140
97
|
end
|
141
98
|
end
|
142
99
|
|
143
100
|
# Retreives a device given a device name
|
144
|
-
def self.
|
145
|
-
|
146
|
-
|
101
|
+
def self.get_devices_by_name(name)
|
102
|
+
resp = make_http_get("/api/GetDevices?Dev=" + name, {})
|
103
|
+
|
104
|
+
if (resp.code != "200")
|
105
|
+
puts "Unable to get a response from SensorStream: " + resp.code
|
147
106
|
return nil
|
107
|
+
else
|
108
|
+
retDevices = []
|
109
|
+
JSON.parse(resp.body).each { |device|
|
110
|
+
retDevices << SensorStream::Device.new(device["DeviceID"],
|
111
|
+
device["UserName"],
|
112
|
+
device["DeviceName"],
|
113
|
+
device["Description"]) }
|
114
|
+
return retDevices
|
148
115
|
end
|
149
116
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
117
|
+
return nil
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.get_device_by_id(id, key = "")
|
121
|
+
if key.empty?
|
122
|
+
resp = make_http_get("/api/GetDevice/" + id, {})
|
123
|
+
else
|
124
|
+
resp = make_http_get("/api/GetDevice/" + id + "?key=" + key, {})
|
125
|
+
end
|
126
|
+
|
127
|
+
if (resp.code != "200")
|
128
|
+
puts "Unable to get a response from SensorStream: " + resp.code
|
129
|
+
return nil
|
130
|
+
else
|
131
|
+
json = JSON.parse(resp.body)
|
132
|
+
device = SensorStream::Device.new(id,
|
133
|
+
json["UserName"],
|
134
|
+
json["DeviceName"],
|
135
|
+
json["Description"])
|
136
|
+
if !key.empty?
|
137
|
+
device.key = key
|
154
138
|
end
|
155
|
-
|
156
|
-
|
139
|
+
|
140
|
+
device.get_streams
|
141
|
+
return device
|
142
|
+
end
|
143
|
+
|
157
144
|
return nil
|
158
145
|
end
|
159
146
|
|
@@ -161,12 +148,13 @@ end
|
|
161
148
|
class Device
|
162
149
|
# Each of the qualities of a device are immutable.
|
163
150
|
# The sensor stream API does not support changing device attributes.
|
164
|
-
attr_reader :user_name, :device_name, :description
|
151
|
+
attr_reader :id, :user_name, :device_name, :description
|
165
152
|
# It is possible to change the streams and assign a key later, however.
|
166
153
|
attr_accessor :streams, :key
|
167
154
|
|
168
155
|
# Initialize a new SensorStream device object
|
169
|
-
def initialize(newUserName, newDeviceName, newDescription, newStreams = [], newKey = "")
|
156
|
+
def initialize(newID, newUserName, newDeviceName, newDescription, newStreams = [], newKey = "")
|
157
|
+
@id = newID
|
170
158
|
@key = newKey
|
171
159
|
@device_name = newDeviceName
|
172
160
|
@user_name = newUserName
|
@@ -176,76 +164,27 @@ end
|
|
176
164
|
|
177
165
|
# Create a useful (to a human) representation of the device for printing
|
178
166
|
def to_s
|
179
|
-
"Name: #{@device_name} \n\tUser: #{@user_name} \n\tDescription: #{@description} \n\tKey: #{@key}"
|
167
|
+
string = "Name: #{@device_name} \n\tID: #{@id} \n\tUser: #{@user_name} \n\tDescription: #{@description} \n\tKey: #{@key}"
|
168
|
+
streams.each { |stream| string += stream.to_s }
|
169
|
+
return string
|
180
170
|
end
|
181
171
|
|
182
|
-
# Create a new stream on this device
|
183
|
-
def create_stream(name, description, elements)
|
184
|
-
|
185
|
-
# Enforce lower-case values on all given element keys
|
186
|
-
tempElements = []
|
187
|
-
elements.each { |element|
|
188
|
-
new_hash = element.each_with_object({}) do |(k, v), h|
|
189
|
-
h[k.downcase] = v
|
190
|
-
end
|
191
|
-
tempElements << new_hash
|
192
|
-
}
|
193
|
-
|
194
|
-
dict = {"name" => name,
|
195
|
-
"description" => description,
|
196
|
-
"streams" => tempElements};
|
197
|
-
|
198
|
-
resp = SensorStream.make_http_post("/stream.ashx?create=", dict, { "key" => @key })
|
199
|
-
|
200
|
-
if (resp.code != "200")
|
201
|
-
STDERR.puts "Error creating SensorStream device! (#{resp.code})\n#{resp.body}"
|
202
|
-
return nil
|
203
|
-
else
|
204
|
-
return Stream.new(self, JSON.parse(resp.body)["streamid"], name, description, tempElements)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
# Delete a stream from this device using a stream ID
|
209
|
-
def delete_stream_with_id(streamid)
|
210
|
-
puts "Deleting Stream #{streamid}"
|
211
|
-
resp = SensorStream.make_http_post("/stream.ashx?delete=#{streamid}", {}, { "key" => @key })
|
212
|
-
|
213
|
-
if (resp.code != "200")
|
214
|
-
STDERR.puts "Error deleting stream #{streamID} (#{resp.code})\n{resp.body}"
|
215
|
-
false
|
216
|
-
else
|
217
|
-
true
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
# Delete a stream from this device using a ruby object
|
222
|
-
def delete_stream(stream)
|
223
|
-
delete_stream_with_id(stream.streamid)
|
224
|
-
end
|
225
|
-
|
226
|
-
# Delete all the streams belonging to this device
|
227
|
-
def delete_streams
|
228
|
-
puts "Deleting all streams"
|
229
|
-
resp = SensorStream.make_http_post("/device.ashx?delete=streams", {}, { "key" => @key }, 600, true)
|
230
|
-
|
231
|
-
if (resp.code != "200")
|
232
|
-
STDERR.puts "Error deleting stream #{streamid} (#{resp.code})\n{resp.body}"
|
233
|
-
false
|
234
|
-
else
|
235
|
-
true
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
172
|
# Get a list of all the streams for this device
|
240
173
|
def get_streams
|
241
|
-
|
174
|
+
if key.empty?
|
175
|
+
resp = SensorStream.make_http_get("/api/GetStreams/#{@id}", {})
|
176
|
+
else
|
177
|
+
resp = SensorStream.make_http_get("/api/GetStreams/#{@id}?key=#{@key}", {})
|
178
|
+
end
|
242
179
|
|
243
180
|
if (resp.code == "200")
|
244
|
-
streams = []
|
245
|
-
JSON.parse(resp.body)
|
246
|
-
|
247
|
-
|
248
|
-
|
181
|
+
@streams = []
|
182
|
+
json = JSON.parse(resp.body)
|
183
|
+
puts json["Streams"].count.to_s + " streams found in device."
|
184
|
+
json["Streams"].each do |streamDict|
|
185
|
+
@streams << Stream.new(self, streamDict["StreamID"], streamDict["StreamName"], streamDict["Description"], streamDict["DataStreams"])
|
186
|
+
end
|
187
|
+
return @streams;
|
249
188
|
else
|
250
189
|
puts "Unable to get streams from server (#{resp.code})\n#{resp.body}"
|
251
190
|
return nil
|
@@ -264,6 +203,35 @@ end
|
|
264
203
|
|
265
204
|
return nil
|
266
205
|
end
|
206
|
+
|
207
|
+
def get_stream_by_id(id, key = "")
|
208
|
+
if key.empty?
|
209
|
+
resp = SensorStream.make_http_get("/api/GetStream/" + id, {})
|
210
|
+
else
|
211
|
+
resp = SensorStream.make_http_get("/api/GetStream/" + id + "?key=" + key, {})
|
212
|
+
end
|
213
|
+
|
214
|
+
if (resp.code != "200")
|
215
|
+
puts "Unable to get a response from SensorStream: " + resp.code
|
216
|
+
return nil
|
217
|
+
else
|
218
|
+
strms = []
|
219
|
+
json = JSON.parse(resp.body)
|
220
|
+
puts json["Streams"].count.to_s + " streams found in device."
|
221
|
+
json["Streams"].each do |streamDict|
|
222
|
+
strms << Stream.new(self, streamDict["StreamID"], streamDict["StreamName"], streamDict["Description"], streamDict["DataStreams"])
|
223
|
+
end
|
224
|
+
return strms[0];
|
225
|
+
if !key.empty?
|
226
|
+
device.key = key
|
227
|
+
end
|
228
|
+
|
229
|
+
device.get_streams
|
230
|
+
return device
|
231
|
+
end
|
232
|
+
|
233
|
+
return nil
|
234
|
+
end
|
267
235
|
end
|
268
236
|
|
269
237
|
# The simple stream class is the base class for complex streams
|
@@ -303,14 +271,14 @@ end
|
|
303
271
|
dict["time"] = time.strftime("%FT%T.%N%:z") unless time.nil?
|
304
272
|
attemptTime = Time.now
|
305
273
|
|
306
|
-
resp = SensorStream.make_http_post("/
|
307
|
-
|
274
|
+
resp = SensorStream.make_http_post("/api/AddData", [dict], { "key" => @device.key })
|
275
|
+
|
308
276
|
if (resp.code != "200")
|
309
277
|
STDERR.puts "Error publishing SensorStream event! (#{resp.code})\n#{resp.body} -- deferring message"
|
310
278
|
publish_event_deferred(values, attemptTime)
|
311
|
-
return
|
279
|
+
return false
|
312
280
|
else
|
313
|
-
|
281
|
+
return true
|
314
282
|
end
|
315
283
|
end
|
316
284
|
|
@@ -341,7 +309,7 @@ end
|
|
341
309
|
return 0
|
342
310
|
end
|
343
311
|
|
344
|
-
resp = SensorStream.make_http_post("/
|
312
|
+
resp = SensorStream.make_http_post("/api/AddData", @deferred_events, { "key" => @device.key })
|
345
313
|
|
346
314
|
# If the send failed, keep the messages
|
347
315
|
if resp.code != "200"
|
@@ -356,18 +324,18 @@ end
|
|
356
324
|
|
357
325
|
# Download a list of events from the server from this stream
|
358
326
|
def get_events(count = 1, start_time = nil, end_time = nil)
|
359
|
-
base = "/
|
327
|
+
base = "/api/GetData/#{@streamid}?"
|
328
|
+
base += "count=#{count}"
|
360
329
|
base += "&start=#{start_time.strftime("%FT%T.%N%:z")}" unless start_time.nil?
|
361
330
|
base += "&end=#{ end_time.strftime("%FT%T.%N%:z")}" unless end_time.nil?
|
362
|
-
base += "&count=#{count}"
|
363
331
|
|
364
|
-
resp = SensorStream.make_http_get(base, {"Accept-Encoding" => "gzip"}
|
332
|
+
resp = SensorStream.make_http_get(base, {"Accept-Encoding" => "gzip"})
|
365
333
|
|
366
334
|
if resp.code != "200"
|
367
335
|
STDERR.puts "Unable to load events from stream: #{resp.body}"
|
368
336
|
return nil
|
369
337
|
end
|
370
|
-
|
338
|
+
|
371
339
|
if (resp["Content-Encoding"] == "gzip")
|
372
340
|
puts "Content was zipped, inflating"
|
373
341
|
content = Zlib::Inflate.inflate(resp.body)
|
@@ -376,14 +344,16 @@ end
|
|
376
344
|
content = resp.body
|
377
345
|
end
|
378
346
|
|
347
|
+
#puts content
|
348
|
+
|
379
349
|
# We're only interested in the values and their timestamps
|
380
350
|
# but the server gives us the device information anyway
|
381
351
|
# Return only the Data array from the dictionary
|
382
|
-
streams = (JSON.parse(
|
352
|
+
streams = (JSON.parse(content)["Streams"])
|
383
353
|
data = nil;
|
384
354
|
streams.each { |stream|
|
385
|
-
if (stream["
|
386
|
-
data = stream["
|
355
|
+
if (stream["StreamID"] == @streamid)
|
356
|
+
data = stream["Data"]
|
387
357
|
end
|
388
358
|
}
|
389
359
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: SensorStream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Dillon
|
@@ -19,7 +19,7 @@ files:
|
|
19
19
|
- lib/SensorStream.rb
|
20
20
|
homepage: http://ramone.coas.oregonstate.edu
|
21
21
|
licenses:
|
22
|
-
-
|
22
|
+
- MIT
|
23
23
|
metadata: {}
|
24
24
|
post_install_message:
|
25
25
|
rdoc_options: []
|