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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/SensorStream.rb +319 -469
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d6699293fcd7d91151220cc95fc2c3f9b0ffd801
4
- data.tar.gz: 06d13baa1c9f613fb28e8e90b5f1edca12a5c5e0
3
+ metadata.gz: 70ba5d638690f23b23817b84f2937071762476b2
4
+ data.tar.gz: aba24b28112122738fa783611ce2fc865d7d7d05
5
5
  SHA512:
6
- metadata.gz: deeb66a8e324f490ec269779d0c67e4672c77a9675b12a1b6c6a26d1a74e5cc439746230b2709b9f534b8d5d15f6079fa462f5c603a238e13820b8d9abbe6d2e
7
- data.tar.gz: 91945130364b7a516eb353002a0b19497d7d385014734967a43282a9c71b4e27b1982fee09772627883dfd8c927435e02dd7a98f05a546d7ddd3b602b3471753
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
- @hostName = "dodeca.coas.oregonstate.edu";
12
- @portNumber = 80;
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
- # get/set hostname
15
- def self.hostName=(newHostName)
16
- @hostName = name;
17
- end
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
- def self.hostName
20
- return @hostName;
21
- end
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
- def self.portNumber
24
- return @portNumber;
25
- end
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
- def self.portNumber=(newPortNum)
28
- @portNumber = newPortNum;
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
- # create a new device on the server
32
- def self.createDevice(userName, deviceName, description)
33
- dict = {"UserName" => userName,
34
- "DeviceName" => deviceName,
35
- "Description" => description};
36
-
37
- uri = URI.parse("http://" + @hostName + "/device.ashx?create=");
38
- http = Net::HTTP.new(@hostName, @portNumber);
39
- http.read_timeout = 600; # 10 minute timeout
40
- resp = http.post(uri.request_uri,
41
- JSON.generate(dict),
42
- {"Content-Type" => "application/json"});
43
-
44
- if (resp.code != "200")
45
- STDERR.puts "Error creating SensorStream device! (" + resp.code + ")\n" + resp.body;
46
- return nil;
47
- else
48
- #Get the GUID from the response and make a device object
49
- respDict = JSON.parse(resp.body);
50
- return SensorStream::Device.new(deviceName, userName,
51
- description, respDict["guid"]);
52
- end
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
- def self.deleteDevice(deviceGUID)
56
- uri = URI.parse("http://" + @hostName + "/device.ashx?delete=device");
57
- http = Net::HTTP.new(@hostName, @portNumber);
58
- http.read_timeout = 600;
59
- resp = http.post(uri.request_uri, "",
60
- {"Content-Type" => "application/json", "key" => deviceGUID});
61
-
62
- if (resp.code != "200")
63
- STDERR.puts "Error deleting SensorStream device! (" + resp.code + ")\n" + resp.body;
64
- return false;
65
- else
66
- return true;
67
- end
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 self.getDevices()
71
- uri = URI.parse("http://" + @hostName + "/device.ashx?getdevices=");
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
- class Device
91
- @guid = "";
92
- @deviceName = "";
93
- @userName = "";
94
- @description = "";
95
-
96
- def initialize(newDN, newUN, newDSC, newGuid = "")
97
- @guid = newGuid;
98
- @deviceName = newDN;
99
- @userName = newUN;
100
- @description = newDSC;
101
- end
102
-
103
- def guid(newGUID = @guid)
104
- return @guid = newGUID;
105
- end
106
-
107
- def guid=(newGUID = @guid)
108
- self.guid(newGUID);
109
- end
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
- def deviceName(newDeviceName = @deviceName)
112
- return @deviceName = newDeviceName;
113
- end
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
- def deviceName=(newDeviceName)
116
- self.deviceName(newDeviceName);
117
- end
238
+ #puts dict
118
239
 
119
- def userName(newUserName = @userName)
120
- return @userName = newUserName;
121
- end
240
+ resp = SensorStream.make_http_post("/data.ashx?create=", dict, { "key" => @device.key })
122
241
 
123
- def userName=(newUserName)
124
- self.userName(newUserName);
125
- end
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
- def description(newDescription = @description)
128
- return @description = newDescription;
129
- end
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
- def description=(newDescription)
132
- self.description(newDescription);
133
- end
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
- def createComplexStream(name, description, elements)
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
- def getStreams()
205
- uri = URI.parse("http://" + SensorStream.hostName +
206
- "/stream.ashx?getstreams=" + @deviceName +
207
- "&user=" + @userName);
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
- if (resp.code != "200")
213
- return nil;
214
- else
215
- ret = JSON.parse(resp.body);
216
- streams = [];
217
- ret["Streams"].each do |streamDict|
218
- # Detect whether the stream we just got is complex
219
- if(streamDict["Streams"].nil?)
220
- tempStream = SimpleStream.new(@guid,
221
- streamDict["StreamID"],
222
- streamDict["Name"],
223
- streamDict["Type"],
224
- streamDict["Units"],
225
- streamDict["Description"]);
226
- streams << tempStream;
227
- else
228
- tempStream = ComplexStream.new(@guid,
229
- streamDict["StreamID"],
230
- streamDict["Streams"],
231
- streamDict["Name"],
232
- streamDict["Description"]);
233
- streams << tempStream;
234
- end
235
- end
236
-
237
- return streams;
238
- end
239
- end
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
- class SimpleStream
243
- @guid = "";
244
- @streamID = "";
245
- @name = "";
246
- @type = "";
247
- @units = "";
248
- @description = "";
249
-
250
- def initialize(newGuid = "",
251
- newStreamID = "",
252
- newName = "",
253
- newType = "",
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
- class ComplexStream
353
- @guid = "";
354
- @streamID = "";
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
- def initialize(newGuid = "", newStreamID = "",
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
- def publishEvent(values, time=nil)
433
- dict = {"StreamID" => @streamID, "Values" => values};
434
-
435
- # Need to convert from ruby time representation to ISO8601 format
436
- if(time != nil)
437
- dict["Time"] = time.strftime("%FT%T%:z");
438
- end
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
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.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Dillon