SensorStream 0.0.1 → 0.0.2
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 +319 -469
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70ba5d638690f23b23817b84f2937071762476b2
|
4
|
+
data.tar.gz: aba24b28112122738fa783611ce2fc865d7d7d05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b3333ece83b1fb079785e9954460ea7129ff97bf4e58fec4d69744263951f00e442ff41ce136acbfa08276b8b524ff534934b0a2303885d5bd662559ad21127
|
7
|
+
data.tar.gz: e376404d031a6d4a6f12d53a9114d35010d606ab148219ee9213b6f20c1672c641be901898c0e93391d70c129fd6aa870b4da82f2e67b45ad79dcab8aa166e3c
|
data/lib/SensorStream.rb
CHANGED
@@ -6,502 +6,352 @@ require 'json'
|
|
6
6
|
require 'pp'
|
7
7
|
require 'base64'
|
8
8
|
require 'open3'
|
9
|
+
require 'date'
|
9
10
|
|
10
11
|
module SensorStream
|
11
|
-
|
12
|
-
|
12
|
+
attr_accessor :host_name, :port_number
|
13
|
+
|
14
|
+
def self.set_default_server
|
15
|
+
@host_name = "dodeca.coas.oregonstate.edu"
|
16
|
+
@port_number = 80
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.make_http_post(request = "", body_dict = {}, header_dict = {}, timeout = 600, debug = false)
|
20
|
+
# Ensure that the hostname and port are set
|
21
|
+
self.set_default_server unless !@host_name.nil?
|
22
|
+
|
23
|
+
# Make sure that, at a minimum, the content type is set in the header
|
24
|
+
header_dict["Content-Type"] = "application/json";
|
13
25
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
26
|
+
puts header_dict unless !debug
|
27
|
+
|
28
|
+
uri = URI.parse("http://" + @host_name + request);
|
29
|
+
puts "POST to #{uri.to_s}" unless !debug
|
18
30
|
|
19
|
-
|
20
|
-
|
21
|
-
|
31
|
+
http = Net::HTTP.new(@host_name, @port_number);
|
32
|
+
http.read_timeout = timeout; # 10 minute default timeout
|
33
|
+
http.post(uri.request_uri, JSON.generate(body_dict), header_dict);
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.make_http_get(request = "", header_dict = {}, timeout = 600, debug = false)
|
37
|
+
# Ensure that the hostname and port are set
|
38
|
+
self.set_default_server unless !@host_name.nil?
|
22
39
|
|
23
|
-
|
24
|
-
|
25
|
-
|
40
|
+
puts header_dict unless !debug
|
41
|
+
|
42
|
+
uri = URI.parse("http://" + @host_name + request);
|
43
|
+
puts "GET from #{uri.to_s}" unless !debug
|
26
44
|
|
27
|
-
|
28
|
-
|
45
|
+
http = Net::HTTP.new(@host_name, @port_number);
|
46
|
+
http.read_timeout = 600; # 10 minute timeout
|
47
|
+
http.get(uri.request_uri, header_dict);
|
48
|
+
end
|
49
|
+
|
50
|
+
# create a new device on the server
|
51
|
+
def self.create_device(user_name, device_name, description)
|
52
|
+
dict = {"UserName" => user_name,
|
53
|
+
"DeviceName" => device_name,
|
54
|
+
"Description" => description}
|
55
|
+
|
56
|
+
resp = make_http_post("/device.ashx?create=", dict)
|
57
|
+
|
58
|
+
if (resp.code != "200")
|
59
|
+
STDERR.puts "Error creating SensorStream device! (#{resp.code})\n#{resp.body}"
|
60
|
+
else
|
61
|
+
SensorStream::Device.new(user_name, device_name, description, [], JSON.parse(resp.body)["guid"])
|
29
62
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.delete_device_with_key(device_key)
|
66
|
+
puts "Deleting device #{device_key}"
|
67
|
+
resp = make_http_post("/device.ashx?delete=device", {}, { "key" => device_key })
|
68
|
+
|
69
|
+
if (resp.code != "200")
|
70
|
+
STDERR.puts "Error deleting SensorStream device! (#{resp.code})\n#{resp.body}"
|
71
|
+
return false;
|
72
|
+
else
|
73
|
+
return true;
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.delete_device(device)
|
78
|
+
delete_device_with_key(device.key)
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.delete_stream_with_key(streamID, device_key)
|
82
|
+
puts "Deleting Stream #{streamID}"
|
83
|
+
resp = make_http_post("/stream.ashx?delete=#{streamID}", {}, { "key" => device_key })
|
84
|
+
|
85
|
+
if (resp.code != "200")
|
86
|
+
STDERR.puts "Error deleting stream #{streamID} (#{resp.code})\n#{resp.body}"
|
87
|
+
false
|
88
|
+
else
|
89
|
+
true
|
53
90
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.get_devices()
|
94
|
+
resp = make_http_get("/device.ashx?getdevices=");
|
95
|
+
|
96
|
+
if (resp.code != "200")
|
97
|
+
return nil;
|
98
|
+
else
|
99
|
+
devices = [];
|
100
|
+
JSON.parse(resp.body)["Devices"].each { |device|
|
101
|
+
devices << SensorStream::Device.new(device["UserName"],
|
102
|
+
device["DeviceName"],
|
103
|
+
device["Description"])
|
104
|
+
devices.last.get_streams
|
105
|
+
}
|
106
|
+
return devices;
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Device
|
111
|
+
# Each of the qualities of a device are immutable.
|
112
|
+
# The sensor stream API does not support changing device attributes.
|
113
|
+
attr_reader :user_name, :device_name, :key, :description
|
114
|
+
attr_accessor :streams
|
115
|
+
|
116
|
+
def initialize(newUserName, newDeviceName, newDescription, newStreams = [], newKey = "")
|
117
|
+
@key = newKey
|
118
|
+
@device_name = newDeviceName
|
119
|
+
@user_name = newUserName
|
120
|
+
@description = newDescription
|
121
|
+
@streams = newStreams
|
68
122
|
end
|
69
123
|
|
70
|
-
def
|
71
|
-
|
72
|
-
http = Net::HTTP.new(@hostName, @portNumber);
|
73
|
-
http.read_timeout = 600; # 10 minute timeout
|
74
|
-
resp = http.get(uri.request_uri);
|
75
|
-
|
76
|
-
if (resp.code != "200")
|
77
|
-
return nil;
|
78
|
-
else
|
79
|
-
deviceDict = JSON.parse(resp.body);
|
80
|
-
devices = [];
|
81
|
-
deviceDict["Devices"].each do |device|
|
82
|
-
devices << SensorStream::Device.new(device["DeviceName"],
|
83
|
-
device["UserName"],
|
84
|
-
device["Description"]);
|
85
|
-
end
|
86
|
-
return devices;
|
87
|
-
end
|
124
|
+
def to_s
|
125
|
+
"Name: #{@device_name} \n\tUser: #{@user_name} \n\tDescription: #{@description} \n\tKey: #{@key}"
|
88
126
|
end
|
89
127
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
128
|
+
def create_complex_stream(name, description, elements)
|
129
|
+
dict = {"Name" => name,
|
130
|
+
"Description" => description,
|
131
|
+
"Streams" => elements};
|
132
|
+
|
133
|
+
resp = SensorStream.make_http_post("/stream.ashx?create=", dict, { "key" => @key })
|
134
|
+
|
135
|
+
if (resp.code != "200")
|
136
|
+
STDERR.puts "Error creating SensorStream device! (#{resp.code})\n#{resp.body}"
|
137
|
+
return nil
|
138
|
+
else
|
139
|
+
return ComplexStream.new(self, JSON.parse(resp.body)["StreamID"], name, description, elements)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def create_stream(name, type, units, description)
|
144
|
+
dict = {"Name" => name,
|
145
|
+
"Type" => type,
|
146
|
+
"Units" => units,
|
147
|
+
"Description" => description}
|
148
|
+
|
149
|
+
resp = SensorStream.make_http_post("/stream.ashx?create=", dict, { "key" => @key })
|
150
|
+
|
151
|
+
if (resp.code != "200")
|
152
|
+
STDERR.puts "Error creating SensorStream stream! (#{resp.code})\n#{resp.body}"
|
153
|
+
else
|
154
|
+
Stream.new(self, JSON.parse(resp.body)["StreamID"], name, type, units, description)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def delete_stream_with_id(streamID)
|
159
|
+
puts "Deleting Stream #{streamID}"
|
160
|
+
resp = SensorStream.make_http_post("/stream.ashx?delete=#{streamID}", {}, { "key" => @key })
|
161
|
+
|
162
|
+
if (resp.code != "200")
|
163
|
+
STDERR.puts "Error deleting stream #{streamID} (#{resp.code})\n{resp.body}"
|
164
|
+
false
|
165
|
+
else
|
166
|
+
true
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def delete_stream(stream)
|
171
|
+
delete_stream_with_id(stream.streamID)
|
172
|
+
end
|
173
|
+
|
174
|
+
def delete_streams
|
175
|
+
puts "Deleting all streams"
|
176
|
+
resp = SensorStream.make_http_post("/device.ashx?delete=streams", {}, { "key" => @key }, 600, true)
|
177
|
+
|
178
|
+
if (resp.code != "200")
|
179
|
+
STDERR.puts "Error deleting stream #{streamID} (#{resp.code})\n{resp.body}"
|
180
|
+
false
|
181
|
+
else
|
182
|
+
true
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def get_streams
|
187
|
+
resp = SensorStream.make_http_get("/stream.ashx?getstreams=#{URI::encode(@device_name)}&user=#{URI::encode(@user_name)}")
|
188
|
+
|
189
|
+
if (resp.code == "200")
|
190
|
+
streams = []
|
191
|
+
JSON.parse(resp.body)["Streams"].each do |streamDict|
|
192
|
+
# Detect whether the stream we just got is complex
|
193
|
+
if(streamDict["Streams"].nil?)
|
194
|
+
streams << Stream.new(self,
|
195
|
+
streamDict["StreamID"], streamDict["Name"],
|
196
|
+
streamDict["Type"], streamDict["Units"],
|
197
|
+
streamDict["Description"])
|
198
|
+
else
|
199
|
+
streams << ComplexStream.new(self,
|
200
|
+
streamDict["StreamID"], streamDict["Streams"],
|
201
|
+
streamDict["Name"], streamDict["Description"])
|
202
|
+
end
|
203
|
+
end
|
204
|
+
return streams;
|
205
|
+
else
|
206
|
+
puts "Unable to get streams from server (#{resp.code})\n#{resp.body}"
|
207
|
+
return nil
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# The simple stream class is the base class for complex streams
|
213
|
+
class Stream
|
214
|
+
# Each of the qualities of the stream are immutable.
|
215
|
+
# The sensor stream API does not support changing stream attributes.
|
216
|
+
attr_reader :device, :streamID, :name, :type, :units, :description
|
217
|
+
|
218
|
+
def initialize(newDevice, newStreamID, newName, newType, newUnits, newDescription)
|
219
|
+
@device = newDevice
|
220
|
+
@streamID = newStreamID
|
221
|
+
@name = newName
|
222
|
+
@type = newType
|
223
|
+
@units = newUnits
|
224
|
+
@description = newDescription
|
225
|
+
@deferedEvents = [];
|
226
|
+
end
|
227
|
+
|
228
|
+
def to_s
|
229
|
+
"Name: #{@name} \n\tStreamID: #{@streamID} \n\tType: #{@type} " +
|
230
|
+
"\n\tUnits: #{@units} \n\tDescription: #{@description}" +
|
231
|
+
"\n\tDevice: #{device.device_name}"
|
232
|
+
end
|
110
233
|
|
111
|
-
|
112
|
-
|
113
|
-
|
234
|
+
def publish_event(value, time = nil)
|
235
|
+
dict = { "StreamID" => @streamID, "value" => value.to_s }
|
236
|
+
dict["Time"] = time.strftime("%FT%T.%N%:z") unless time.nil?
|
114
237
|
|
115
|
-
|
116
|
-
self.deviceName(newDeviceName);
|
117
|
-
end
|
238
|
+
#puts dict
|
118
239
|
|
119
|
-
|
120
|
-
return @userName = newUserName;
|
121
|
-
end
|
240
|
+
resp = SensorStream.make_http_post("/data.ashx?create=", dict, { "key" => @device.key })
|
122
241
|
|
123
|
-
|
124
|
-
|
125
|
-
|
242
|
+
if (resp.code != "200")
|
243
|
+
STDERR.puts "Error publishing SensorStream event! (#{resp.code})\n#{resp.body}"
|
244
|
+
return nil;
|
245
|
+
else
|
246
|
+
DateTime.strptime(JSON.parse(resp.body)["Time"],"%FT%T.%N%:z")
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def publish_event_defered(value, time = nil)
|
251
|
+
time ||= Time.now
|
252
|
+
@defered_events << { "StreamID" => @streamID,
|
253
|
+
"value" => value.to_s,
|
254
|
+
"Time" => time.strftime("%FT%T.%N%:z") }
|
255
|
+
end
|
256
|
+
|
257
|
+
def publish_defered_events
|
258
|
+
# Ensure that there are defered messages to send
|
259
|
+
if(@deferedEvents.nil? || @deferedEvents.empty?)
|
260
|
+
@deferedEvents = [] unless !@deferedEvents.nil?
|
261
|
+
return
|
262
|
+
end
|
126
263
|
|
127
|
-
|
128
|
-
|
129
|
-
|
264
|
+
resp = SensorStream.make_http_post("/data.ashx?create=", @defered_events, { "key" => @device.key })
|
265
|
+
|
266
|
+
# If the send failed, keep the messages
|
267
|
+
if resp.code != "200"
|
268
|
+
puts "Unable to publish defered events, keeping events."
|
269
|
+
else
|
270
|
+
count = @deferedEvents.count
|
271
|
+
@deferedEvents = []
|
272
|
+
return count
|
273
|
+
end
|
274
|
+
end
|
130
275
|
|
131
|
-
|
132
|
-
|
133
|
-
|
276
|
+
def get_events(count = 1, start_time = nil, end_time = nil)
|
277
|
+
base = "/data.ashx?getdata=#{@streamID}"
|
278
|
+
base += "&start=#{start_time.strftime("%FT%T.%N%:z")}" unless start_time.nil?
|
279
|
+
base += "&end=#{ end_time.strftime("%FT%T.%N%:z")}" unless end_time.nil?
|
280
|
+
base += "&count=#{count}"
|
134
281
|
|
135
|
-
|
136
|
-
dict = {"Name" => name,
|
137
|
-
"Description" => description,
|
138
|
-
"Streams" => elements};
|
139
|
-
|
140
|
-
uri = URI.parse("http://" + SensorStream.hostName + "/stream.ashx?create=");
|
141
|
-
http = Net::HTTP.new(SensorStream.hostName, SensorStream.portNumber);
|
142
|
-
http.read_timeout = 600; # 10 minute timeout
|
143
|
-
resp = http.post(uri.request_uri,
|
144
|
-
JSON.generate(dict),
|
145
|
-
{"Content-Type" => "application/json",
|
146
|
-
"key" => @guid});
|
147
|
-
|
148
|
-
if (resp.code != "200")
|
149
|
-
STDERR.puts "Error creating SensorStream device! (" + resp.code + ")\n" + resp.body;
|
150
|
-
return "";
|
151
|
-
else
|
152
|
-
#Get the GUID from the response
|
153
|
-
respDict = JSON.parse(resp.body);
|
154
|
-
tempStream = ComplexStream.new(@guid, respDict["StreamID"],
|
155
|
-
elements, name, description);
|
156
|
-
return tempStream;
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def createSimpleStream(name, type, units, description)
|
161
|
-
dict = {"Name" => name,
|
162
|
-
"Description" => description,
|
163
|
-
"Type" => type,
|
164
|
-
"Units" => units};
|
165
|
-
|
166
|
-
uri = URI.parse("http://" + SensorStream.hostName + "/stream.ashx?create=");
|
167
|
-
http = Net::HTTP.new(SensorStream.hostName, SensorStream.portNumber);
|
168
|
-
http.read_timeout = 600; # 10 minute timeout
|
169
|
-
resp = http.post(uri.request_uri,
|
170
|
-
JSON.generate(dict),
|
171
|
-
{"Content-Type" => "application/json",
|
172
|
-
"key" => @guid});
|
173
|
-
|
174
|
-
if (resp.code != "200")
|
175
|
-
STDERR.puts "Error creating SensorStream stream! (" + resp.code + ")\n" + resp.body;
|
176
|
-
#puts "Request URI: ";
|
177
|
-
#puts uri;
|
178
|
-
#puts "Request JSON: " + JSON.generate(dict);
|
179
|
-
return nil;
|
180
|
-
else
|
181
|
-
#Get the GUID from the response, return an object for the stream
|
182
|
-
respDict = JSON.parse(resp.body);
|
183
|
-
tempStream = SimpleStream.new(@guid, respDict["StreamID"],
|
184
|
-
name, type, units, description);
|
185
|
-
return tempStream;
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
def deleteStream(streamID)
|
190
|
-
uri = URI.parse("http://" + SensorStream.hostName + "/stream.ashx?delete=" + streamID);
|
191
|
-
http = Net::HTTP.new(SensorStream.hostName, SensorStream.portNumber);
|
192
|
-
http.read_timeout = 600; # 10 minute timeout
|
193
|
-
resp = http.post(uri.request_uri, "",
|
194
|
-
{"Content-Type" => "application/json", "key" => @guid});
|
195
|
-
|
196
|
-
if (resp.code != "200")
|
197
|
-
STDERR.puts "Error deleting stream " + streamID + " (" + resp.code + ")\n" + resp.body;
|
198
|
-
return false;
|
199
|
-
else
|
200
|
-
return true;
|
201
|
-
end
|
202
|
-
end
|
282
|
+
resp = SensorStream.make_http_get(base)
|
203
283
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
http = Net::HTTP.new(SensorStream.hostName, SensorStream.portNumber);
|
209
|
-
http.read_timeout = 600; # 10 minute timeout
|
210
|
-
resp = http.get(uri.request_uri);
|
284
|
+
if resp.code != "200"
|
285
|
+
puts "Unable to load events from stream"
|
286
|
+
return nil
|
287
|
+
end
|
211
288
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
289
|
+
# We're only interested in the values and their timestamps
|
290
|
+
# but the server gives us the device information anyway
|
291
|
+
# Return only the Data array from the dictionary
|
292
|
+
#puts resp.body
|
293
|
+
data = JSON.parse(resp.body)["Stream"]["Data"]
|
294
|
+
if data.class == Array
|
295
|
+
data.each { |event_dict|
|
296
|
+
#puts event_dict
|
297
|
+
# Replace the time string with Ruby time objects
|
298
|
+
event_dict["Time"] = DateTime.strptime(event_dict["Time"],"%FT%T.%N%:z")
|
299
|
+
#puts event_dict
|
300
|
+
}
|
301
|
+
return data
|
302
|
+
else
|
303
|
+
return [event_dict["Time"] = DateTime.strptime(event_dict["Time"],"%FT%T.%N%:z")];
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
class ComplexStream < Stream
|
309
|
+
#attr_protected :type, :units
|
310
|
+
attr_reader :elements
|
311
|
+
def initialize(newDevice, newStreamID, newName, newDescription, newElements)
|
312
|
+
@device = newDevice
|
313
|
+
@streamID = newStreamID
|
314
|
+
@name = newName
|
315
|
+
@elements = newElements
|
316
|
+
@description = newDescription
|
317
|
+
@deferedEvents = []
|
240
318
|
end
|
241
319
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
newUnits = "",
|
255
|
-
newDescription = "")
|
256
|
-
@guid = newGuid;
|
257
|
-
@streamID = newStreamID;
|
258
|
-
@name = newName;
|
259
|
-
@type = newType;
|
260
|
-
@units = newUnits;
|
261
|
-
@description = newDescription;
|
262
|
-
end
|
263
|
-
|
264
|
-
def guid(newGUID = @guid)
|
265
|
-
return @guid = newGUID;
|
266
|
-
end
|
267
|
-
|
268
|
-
def guid=(newGUID = @guid)
|
269
|
-
self.guid(newGUID);
|
270
|
-
end
|
271
|
-
|
272
|
-
def streamID(newStreamID = @streamID)
|
273
|
-
return @streamID = newStreamID;
|
274
|
-
end
|
275
|
-
|
276
|
-
def streamID=(newStreamID)
|
277
|
-
self.streamID(newStreamID);
|
278
|
-
end
|
279
|
-
|
280
|
-
def name(newName = @name)
|
281
|
-
return @name = newName;
|
282
|
-
end
|
283
|
-
|
284
|
-
def name=(newName)
|
285
|
-
self.name(newName);
|
286
|
-
end
|
287
|
-
|
288
|
-
def type(newType = @type)
|
289
|
-
return @type = newType;
|
290
|
-
end
|
291
|
-
|
292
|
-
def type=(newType)
|
293
|
-
self.type(newType);
|
294
|
-
end
|
295
|
-
|
296
|
-
def units(newUnits = @units)
|
297
|
-
return @units = newUnits;
|
298
|
-
end
|
299
|
-
|
300
|
-
def units=(newUnits)
|
301
|
-
self.units(newUnits);
|
302
|
-
end
|
303
|
-
|
304
|
-
def description(newDescription = @description)
|
305
|
-
return @description = newDescription;
|
306
|
-
end
|
307
|
-
|
308
|
-
def description=(newDescription)
|
309
|
-
self.description(newDescription);
|
310
|
-
end
|
311
|
-
|
312
|
-
def to_s
|
313
|
-
return "Name: " + @name +
|
314
|
-
"\n\tStreamID: " + @streamID +
|
315
|
-
"\n\tType: " + @type +
|
316
|
-
"\n\tUnits: " + @units +
|
317
|
-
"\n\tDescription: " + @description;
|
318
|
-
end
|
319
|
-
|
320
|
-
|
321
|
-
def publishEvent(value, time=nil)
|
322
|
-
dict = {"StreamID" => @streamID, "Value" => value.to_s};
|
323
|
-
|
324
|
-
# This is unlikely to work yet.
|
325
|
-
# Need to convert from ruby time representation to ISO8601 format
|
326
|
-
if(time != nil)
|
327
|
-
dict["Time"] = time.strftime("%FT%T%:z");
|
328
|
-
end
|
329
|
-
|
330
|
-
uri = URI.parse("http://" + SensorStream.hostName + "/data.ashx?create=");
|
331
|
-
http = Net::HTTP.new(SensorStream.hostName, SensorStream.portNumber);
|
332
|
-
http.read_timeout = 600; # 10 minute timeout
|
333
|
-
resp = http.post(uri.request_uri,
|
334
|
-
JSON.generate(dict),
|
335
|
-
{"Content-Type" => "application/json", "key" => @guid});
|
336
|
-
|
337
|
-
if (resp.code != "200")
|
338
|
-
STDERR.puts "Error publishing SensorStream event! (" + resp.code + ")\n" + resp.body;
|
339
|
-
return "";
|
340
|
-
else
|
341
|
-
#Get the GUID from the response
|
342
|
-
respDict = JSON.parse(resp.body);
|
343
|
-
return respDict["Time"];
|
344
|
-
end
|
345
|
-
end
|
346
|
-
|
347
|
-
def streamID
|
348
|
-
return @streamID;
|
349
|
-
end
|
320
|
+
def to_s
|
321
|
+
elementsString = "";
|
322
|
+
@elements.each do |element|
|
323
|
+
elementsString += "\n\t\t#{element["Name"]}" +
|
324
|
+
"\n\t\t\tTypes: #{element["Type"]}" +
|
325
|
+
"\n\t\t\tUnits: #{element["Units"]}"
|
326
|
+
end
|
327
|
+
|
328
|
+
"Name: #{@name} \n\tStreamID: #{@streamID} " +
|
329
|
+
"\n\tElements: #{elementsString} " +
|
330
|
+
"\n\tDescription: #{@description}" +
|
331
|
+
"\n\tDevice: #{device.device_name}"
|
350
332
|
end
|
351
333
|
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
@elements = [];
|
356
|
-
@name = "";
|
357
|
-
@description = "";
|
358
|
-
@deferedMsgs = [];
|
334
|
+
def publish_event(values, time=nil)
|
335
|
+
dict = {"StreamID" => @streamID, "Values" => values};
|
336
|
+
dict["Time"] = time.strftime("%FT%T.%N%:z") unless time.nil?
|
359
337
|
|
360
|
-
|
361
|
-
newElements = [], newName = "",
|
362
|
-
newDescription = "")
|
363
|
-
@guid = newGuid;
|
364
|
-
@streamID = newStreamID;
|
365
|
-
@elements = newElements;
|
366
|
-
@name = newName;
|
367
|
-
@description = newDescription;
|
368
|
-
end
|
369
|
-
|
370
|
-
def guid(newGUID = @guid)
|
371
|
-
return @guid = newGUID;
|
372
|
-
end
|
373
|
-
|
374
|
-
def guid=(newGUID = @guid)
|
375
|
-
self.guid(newGUID);
|
376
|
-
end
|
377
|
-
|
378
|
-
def streamID(newStreamID = @streamID)
|
379
|
-
return @streamID = newStreamID;
|
380
|
-
end
|
381
|
-
|
382
|
-
def streamID=(newStreamID)
|
383
|
-
self.streamID(newStreamID);
|
384
|
-
end
|
385
|
-
|
386
|
-
def name(newName = @name)
|
387
|
-
return @name = newName;
|
388
|
-
end
|
389
|
-
|
390
|
-
def name=(newName)
|
391
|
-
self.name(newName);
|
392
|
-
end
|
393
|
-
|
394
|
-
def type(newType = @type)
|
395
|
-
return @type = newType;
|
396
|
-
end
|
397
|
-
|
398
|
-
def type=(newType)
|
399
|
-
self.type(newType);
|
400
|
-
end
|
401
|
-
|
402
|
-
def units(newUnits = @units)
|
403
|
-
return @units = newUnits;
|
404
|
-
end
|
405
|
-
|
406
|
-
def units=(newUnits)
|
407
|
-
self.units(newUnits);
|
408
|
-
end
|
409
|
-
|
410
|
-
def description(newDescription = @description)
|
411
|
-
return @description = newDescription;
|
412
|
-
end
|
413
|
-
|
414
|
-
def description=(newDescription)
|
415
|
-
self.description(newDescription);
|
416
|
-
end
|
417
|
-
|
418
|
-
def to_s
|
419
|
-
elementsString = "";
|
420
|
-
@elements.each {|element|
|
421
|
-
elementsString += "\n\t\t" + element["Name"] +
|
422
|
-
"\n\t\t\tUnits: " + element["Type"] +
|
423
|
-
"\n\t\t\tUnits: " + element["Units"];
|
424
|
-
};
|
425
|
-
|
426
|
-
return "Name: " + @name +
|
427
|
-
"\n\tStreamID: " + @streamID +
|
428
|
-
"\n\tElements: " + elementsString +
|
429
|
-
"\n\tDescription: " + @description;
|
430
|
-
end
|
338
|
+
#puts dict
|
431
339
|
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
uri = URI.parse("http://" + SensorStream.hostName + "/data.ashx?create=");
|
441
|
-
http = Net::HTTP.new(SensorStream.hostName, SensorStream.portNumber);
|
442
|
-
http.read_timeout = 600; # 10 minute timeout
|
443
|
-
resp = http.post(uri.request_uri, JSON.generate(dict),
|
444
|
-
{"Content-Type" => "application/json", "key" => @guid});
|
445
|
-
|
446
|
-
if (resp.code != "200")
|
447
|
-
STDERR.puts "Error publishing SensorStream event! (" + resp.code + ")\n" + resp.body;
|
448
|
-
puts JSON.generate(dict);
|
449
|
-
return "";
|
450
|
-
else
|
451
|
-
#Get the time from the response
|
452
|
-
respDict = JSON.parse(resp.body);
|
453
|
-
return respDict["Time"];
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
def publishEventDefered(values, time=nil)
|
458
|
-
dict = {"StreamID" => @streamID, "Values" => values};
|
459
|
-
|
460
|
-
# Need to convert from ruby time representation to ISO8601 format
|
461
|
-
if(time != nil)
|
462
|
-
dict["Time"] = time.strftime("%FT%T%:z");
|
463
|
-
end
|
464
|
-
|
465
|
-
if(@deferedMsgs.nil?)
|
466
|
-
#puts "Defered messages array was nil, not supposed to happen.";
|
467
|
-
@deferedMsgs = [];
|
468
|
-
end
|
469
|
-
@deferedMsgs << dict;
|
470
|
-
end
|
471
|
-
|
472
|
-
def flushDeferedMsgs()
|
473
|
-
if @deferedMsgs.nil?
|
474
|
-
return 0;
|
475
|
-
end
|
476
|
-
|
477
|
-
if (@deferedMsgs.count == 0)
|
478
|
-
return 0;
|
479
|
-
end
|
480
|
-
|
481
|
-
jsonString = JSON.generate(@deferedMsgs)
|
482
|
-
#puts "Created JSON string";
|
483
|
-
|
484
|
-
uri = URI.parse("http://" + SensorStream.hostName + "/data.ashx?create=");
|
485
|
-
http = Net::HTTP.new(SensorStream.hostName, SensorStream.portNumber);
|
486
|
-
http.read_timeout = 600; # 10 minute timeout
|
487
|
-
|
488
|
-
#puts "Created http object";
|
489
|
-
resp = http.post(uri.request_uri, jsonString,
|
490
|
-
{"Content-Type" => "application/json", "key" => @guid});
|
491
|
-
|
492
|
-
if (resp.code != "200")
|
493
|
-
STDERR.puts "Error publishing SensorStream event! (" + resp.code + ")\n" + resp.body;
|
494
|
-
#puts JSON.generate(@deferedMsgs);
|
495
|
-
return -1;
|
496
|
-
else
|
497
|
-
#Get the GUID from the response
|
498
|
-
respDict = JSON.parse(resp.body);
|
499
|
-
count = @deferedMsgs.count;
|
500
|
-
@deferedMsgs = [];
|
501
|
-
return count;
|
502
|
-
end
|
503
|
-
|
504
|
-
end
|
340
|
+
resp = SensorStream.make_http_post("/data.ashx?create=", dict, { "key" => @device.key })
|
341
|
+
|
342
|
+
if (resp.code != "200")
|
343
|
+
STDERR.puts "Error publishing SensorStream event! (#{resp.code})\n#{resp.body}"
|
344
|
+
return nil;
|
345
|
+
else
|
346
|
+
DateTime.strptime(JSON.parse(resp.body)["Time"],"%FT%T.%N%:z")
|
347
|
+
end
|
505
348
|
end
|
506
349
|
|
350
|
+
def publish_event_defered(values, time=nil)
|
351
|
+
time ||= Time.now
|
352
|
+
@defered_events << { "StreamID" => @streamID,
|
353
|
+
"Values" => values,
|
354
|
+
"Time" => time.strftime("%FT%T.%N%:z") }
|
355
|
+
end
|
356
|
+
end
|
507
357
|
end
|