savant-echo 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6a43146f3ad2e218989d36831bc1e78cd53a6bef
4
+ data.tar.gz: 825f1201278c73425cfa658768a3b3b85fe80a61
5
+ SHA512:
6
+ metadata.gz: 2a57c47c38240dd2108b6e16e874547e2804905b3d001d0628b7f7b0d1c6b16075d4d9b51e1b4bbe2e09257039eb054bb786a49287b2ce0ff52a689863e4e341
7
+ data.tar.gz: d361940b855dcfd1bb8c8659ecdb782bdba580e7e0143eb46eb6f332b1c19d18499dbe6cc14b0d7f938376f5dad02e8ca38f400411f2829ac9e21b9a94da62d6
data/bin/alexa ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'rubygems'
4
+ require "vrlib"
5
+ require 'net/http'
6
+ require 'uri'
7
+ require 'net/scp'
8
+ require 'socket'
9
+ require 'timeout'
10
+ require 'ipaddress'
11
+
12
+ # from require_all gem:
13
+ require_rel 'src/'
14
+
15
+
16
+ Savant.new.show_glade()
17
+
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env ruby
2
+ #Script should be run as daemon on host boot
3
+ require 'socket'
4
+ require 'uri'
5
+
6
+ $SCLI = "~/Applications/RacePointMedia/sclibridge "
7
+ a = RUBY_PLATFORM
8
+ if a.include? "linux"
9
+ $SCLI = "/usr/local/bin/sclibridge "
10
+ end
11
+ $savConn = true
12
+
13
+ def readFromRemote(rti)
14
+ rType = 'tcp'
15
+ data = rti.gets("\n")
16
+ if data.include? "HTTP"
17
+ rti.gets("\r\n\r\n")
18
+ /GET \/([^ ]+) HTTP/.match(data)
19
+ data = URI.unescape($1)
20
+ rType = 'http'
21
+ end
22
+ data.gsub!(/\0/, '')
23
+ #puts data
24
+ return data,rType
25
+ end
26
+
27
+ def writeToRequest(data)
28
+ d = data.gsub("servicerequestcommand ","")
29
+ d.gsub!("\n","")
30
+ puts d
31
+ begin
32
+ #puts data
33
+ $sav.write(d)
34
+ #puts "wrote it"
35
+ return $sav.gets("\r").gsub("\r","\n")
36
+ rescue
37
+ $savConn = false
38
+ #puts "savant not connected. fall back to scli"
39
+ th = Thread.new do
40
+ $sav = $savant.accept
41
+ $savConn = true
42
+ end
43
+ return writeToScli(data)
44
+ end
45
+ end
46
+
47
+ def writeToScli(data)
48
+ return `#{$SCLI + data}`
49
+ #puts data
50
+ end
51
+
52
+
53
+ def connThread(rti)
54
+ loop do
55
+ begin
56
+ data,rType = readFromRemote(rti)
57
+ rescue
58
+ break
59
+ end
60
+ #puts data.inspect
61
+ if /(readstate|writestate|servicerequestcommand|servicerequest|userzones|statenames|settrigger)/.match(data)
62
+ #puts $1.inspect
63
+ if $1 == "servicerequestcommand" && $savConn == true
64
+ r = writeToRequest(data)
65
+ else
66
+ #puts "writing to scli"
67
+ r = writeToScli(data)
68
+ #puts r.inspect
69
+ end
70
+ begin
71
+ if rType == 'http' && r
72
+ rti.write "HTTP/1.1 200 OK\r\n" +
73
+ "Content-Type: text/plain\r\n" +
74
+ "Content-Length: #{r.length}\r\n" +
75
+ "Connection: close\r\n\r\n"+ r
76
+ else
77
+ #puts "Replied with #{r.inspect} "
78
+ rti.write r
79
+ end
80
+ rescue
81
+ puts "connection closed, can't send reply"
82
+ end
83
+ break if rType == 'http'
84
+ else
85
+ puts "Format incorrect!: #{data.inspect}"
86
+ end
87
+ end
88
+ rti.close
89
+ end
90
+
91
+ #Thread.abort_on_exception = true
92
+ server = TCPServer.open(12000)
93
+ $savant = TCPServer.open(12001)
94
+
95
+ loop do
96
+ Thread.start(server.accept) { |rti| connThread(rti) }
97
+ end
data/bin/src/Savant.rb ADDED
@@ -0,0 +1,1178 @@
1
+ # TO DO
2
+
3
+ # INSTALL PASSWORD PROMPT
4
+ # ADD MENU ITEM FOR DEBUG?
5
+ # PACKAGE INSTALLER
6
+
7
+
8
+ require 'rubygems'
9
+ require 'net/http'
10
+ require 'net/scp'
11
+ require 'uri'
12
+ require 'socket'
13
+ require 'timeout'
14
+ require 'ipaddress'
15
+
16
+ class Savant
17
+ include GladeGUI
18
+
19
+ #####Method to check to see if HA Bridge is running on host#####
20
+ def up?(server, port)
21
+ http = Net::HTTP.start(server, port, {open_timeout: 1, read_timeout: 1})
22
+ response = http.head("/")
23
+ if response.code == "200"
24
+ @builder["buttonHabridgeStatus"].label = "HA Bridge is Online\nClick to open in browser."
25
+ @habridgeStatus = "Online"
26
+ end
27
+ rescue Timeout::Error, SocketError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED
28
+ false
29
+ @builder["buttonHabridgeStatus"].label = "HA Bridge is Offline\nClick for help."
30
+ @habridgeStatus = "Offline"
31
+ end
32
+
33
+ #####Method to check to see if Racepoint and SCLI bridge ports are open on host#####
34
+ def is_port_open?(ip, port)
35
+ begin
36
+ Timeout::timeout(1) do
37
+ begin
38
+ s = TCPSocket.new(ip, port)
39
+ s.close
40
+ return true
41
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
42
+ return false
43
+ end
44
+ end
45
+ rescue Timeout::Error
46
+ end
47
+
48
+ return false
49
+ end
50
+
51
+ #####Set variables before windows load#####
52
+ def before_show()
53
+ @savantURL = "192.168.77.178"
54
+ @haName = ""
55
+ @habridgeStatus = "Offline"
56
+ @installStatus = ""
57
+
58
+ @savantRequestOn = ''
59
+ @savantRequestOff = ''
60
+ @savantRequestDim = ''
61
+
62
+ @strRequestOn = ''
63
+ @strRequestOff = ''
64
+ @strRequestDim = ''
65
+
66
+ @requestOnValue1 = "percent"
67
+ @requestOnValue2 = "percent"
68
+ @requestOnValue3 = "percent"
69
+ @requestOnValue4 = "percent"
70
+ @requestOnValue5 = "percent"
71
+ @requestOnValue6 = "percent"
72
+ @requestOnValue7 = "percent"
73
+ @requestOnValue8 = "percent"
74
+ @requestOnValue9 = "percent"
75
+
76
+ @requestOffValue1 = "percent"
77
+ @requestOffValue2 = "percent"
78
+ @requestOffValue3 = "percent"
79
+ @requestOffValue4 = "percent"
80
+ @requestOffValue5 = "percent"
81
+ @requestOffValue6 = "percent"
82
+ @requestOffValue7 = "percent"
83
+ @requestOffValue8 = "percent"
84
+ @requestOffValue9 = "percent"
85
+
86
+ @requestDimValue1 = "percent"
87
+ @requestDimValue2 = "percent"
88
+ @requestDimValue3 = "percent"
89
+ @requestDimValue4 = "percent"
90
+ @requestDimValue5 = "percent"
91
+ @requestDimValue6 = "percent"
92
+ @requestDimValue7 = "percent"
93
+ @requestDimValue8 = "percent"
94
+ @requestDimValue9 = "percent"
95
+
96
+ up?(@savantURL,"8888")
97
+ end
98
+
99
+ #####Check HA bridge server status for feedback when textbox is edited#####
100
+ def savantURL__focus_out_event(*argv)
101
+ @savantURL = @builder["savantURL"].text
102
+ up?(@savantURL,"8888")
103
+ end
104
+
105
+ def savantHelpURL__focus_out_event(*argv)
106
+ @savantURL = @builder["savantHelpURL"].text
107
+ up?(@savantURL,"8888")
108
+ end
109
+
110
+ #####Launch HA Bridge if online or help window if offline#####
111
+ def buttonHabridgeStatus__clicked(*argv)
112
+ if @habridgeStatus == "Offline"
113
+ @builder["savantHelpURL"].text = @savantURL
114
+ @builder["dialogHelp"].show
115
+ elsif @habridgeStatus == "Online"
116
+ system("open http://" + @savantURL + ":8888")
117
+ end
118
+ end
119
+
120
+ ##### #####
121
+ ##### Help and installation window #####
122
+ ##### #####
123
+
124
+ ##### Try to launch HA bridge at specified IP #####
125
+ def buttonHelpHAbridge__clicked(*argv)
126
+ if IPAddress.valid? @savantURL
127
+ if is_port_open?(@savantURL,"8888")
128
+ system("open " + @savantURLstr + ":8888")
129
+ else
130
+ alert "HA Bridge is not online at specified IP address.\nPlease change IP address or install HA bridge and set to port 8888."
131
+ end
132
+ else
133
+ alert "Invalid IP Address."
134
+ end
135
+ end
136
+
137
+ ##### Try to launch SCLI bridge at specified IP #####
138
+ def buttonHelpSCLIbridge__clicked(*argv)
139
+ if IPAddress.valid? @savantURL
140
+ if is_port_open?(@savantURL,"12000")
141
+ system("open http://" + @savantURL + ":12000/userzones")
142
+ else
143
+ alert "SCLI_HTTP bridge is not online at specified IP address.\nPlease change IP address or install SCLI_HTTP bridge and set to port 120000."
144
+ end
145
+ else
146
+ alert "Invalid IP Address."
147
+ end
148
+ end
149
+
150
+ ##### Install all components at specified IP #####
151
+ def buttonHelpInstall__clicked(*argv)
152
+ #Check that specified host is a Savant Host running Racepoint
153
+ if IPAddress.valid? @savantURL
154
+ if is_port_open?(@savantURL,"11263")
155
+ @builder["dialogInstall"].show
156
+ login = 'RPM'
157
+ @password = 'RPM'
158
+ javaCount = 0
159
+ result = ''
160
+ Net::SSH.start(@savantURL, login, :password => @password, :paranoid => false) do |ssh|
161
+ #Copy files to host
162
+ @builder["installStatus"].label = "Copying Files..."
163
+ clear_events()
164
+ ssh.exec!("mkdir -p /Users/RPM/habridge/")
165
+ path = File.expand_path("..",__dir__)
166
+ ssh.scp.upload!(path + "/habridge/", '/Users/RPM/', :recursive => true)
167
+ ssh.exec!("mv /Users/RPM/habridge/com.habridge.plist /Users/RPM/Library/LaunchAgents/")
168
+ ssh.exec!("mv /Users/RPM/habridge/com.SCLI_HTTP.plist /Users/RPM/Library/LaunchAgents/")
169
+ @builder["installStatus"].label += "\nFiles copied!\n\nInstalling Homebrew on Host...this might take a minute.\n"
170
+ clear_events()
171
+ sleep 2
172
+ #Create terminal session with host
173
+ ssh.open_channel do |ch, success|
174
+ #debug alert "ch open"
175
+ ch.request_pty do |ch, success|
176
+ if success
177
+ #debug alert "pty successfully obtained"
178
+ else
179
+ #debug alert "could not obtain pty"
180
+ end
181
+ end
182
+ #Install homebrew on host
183
+ ch.exec(%q{ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"}) do |ch, success|
184
+ abort "could not execute command" unless success
185
+ end
186
+ ch.on_data do |ch, data|
187
+ #debug alert "got data:" + data
188
+ if data.to_s.include? "100%"
189
+ print "."
190
+ end
191
+ if data.to_s.include? "Password:"
192
+ ch.send_data @password
193
+ ch.send_data "\n"
194
+ end
195
+ if data.to_s.include? "RETURN"
196
+ ch.send_data "\n"
197
+ end
198
+ if data.to_s.include? "expected shallow list"
199
+ @builder["installStatus"].label += "Homebrew already installed on Host.\n\n"
200
+ clear_events()
201
+ sleep 1
202
+ #debug #ch.send_data "brew cask install java"
203
+ end
204
+ if data.to_s.include? "Further documentation: https://git.io/brew-docs"
205
+ @builder["installStatus"].label += "Homebrew installed on Host.\n\n"
206
+ clear_events()
207
+ sleep 1
208
+ #ch.send_data "brew cask install java"
209
+ end
210
+ end
211
+ ch.on_extended_data do |ch, type, data|
212
+ alert "got stderr: #{data.inspect}"
213
+ end
214
+
215
+ ch.wait
216
+
217
+ end
218
+ ssh.loop
219
+
220
+ #Create terminal session on host
221
+ ssh.open_channel do |ch, success|
222
+ ch.request_pty do |ch, success|
223
+ if success
224
+ #debug alert "pty successfully obtained"
225
+ else
226
+ #debug alert "could not obtain pty"
227
+ end
228
+ end
229
+ @builder["installStatus"].label += "Installing Java Dev Kit on Host...this might take a minute.\n"
230
+ clear_events()
231
+ sleep 1
232
+ #Install JDK on host
233
+ ch.exec(%q{brew cask install java}) do |ch, success|
234
+ abort "could not execute command" unless success
235
+ end
236
+ ch.on_data do |ch, data|
237
+ #debug alert "got data:" + data
238
+ if data.to_s.include? "0.0%"
239
+ javaCount = javaCount + 1
240
+ if (javaCount%10).zero?
241
+ @builder["installStatus"].label += "."
242
+ clear_events()
243
+ end
244
+ end
245
+ if data.to_s.include? "Password:"
246
+ ch.send_data @password
247
+ ch.send_data "\n"
248
+ end
249
+ if data.to_s.include? "RETURN"
250
+ ch.send_data "\n"
251
+ end
252
+
253
+ if data.to_s.include? "A Cask for java is already installed."
254
+ @builder["installStatus"].label += "Java already installed on Host.\n\n"
255
+ clear_events()
256
+ sleep 1
257
+ #ch.send_data "brew cask install java"
258
+ end
259
+ if data.to_s.include? "java was successfully installed!"
260
+ @builder["installStatus"].label += "\nJava Installed on Host.\n\n"
261
+ clear_events()
262
+ sleep 1
263
+ #ch.send_data "brew cask install java"
264
+ end
265
+ end
266
+ ch.on_extended_data do |ch, type, data|
267
+ #debug alert "got stderr: #{data.inspect}"
268
+ end
269
+ ch.wait
270
+ end
271
+ ssh.loop
272
+
273
+ #Update status window
274
+ @builder["installStatus"].label += "Installing Launch Agents...\n"
275
+ clear_events()
276
+ result = ssh.exec!("launchctl load /Users/RPM/Library/LaunchAgents/com.SCLI_HTTP.plist")
277
+ @builder["installStatus"].label += result
278
+ clear_events()
279
+ result = ssh.exec!("launchctl load /Users/RPM/Library/LaunchAgents/com.habridge.plist")
280
+ @builder["installStatus"].label += result
281
+ clear_events()
282
+ @builder["installStatus"].label += "Launch Agents installed!\n\n"
283
+ clear_events()
284
+ sleep 1
285
+ @builder["installStatus"].label += "Installation complete.\n"
286
+ clear_events()
287
+ sleep 1
288
+ @builder["installStatus"].label += "To verify installation, test the following URLs\nto make certain both the habridge and the scli_http bridge are active.\n\nhttp://" + @savantURL + ":8888/\nhttp://" + @savantURL + ":12000/userzones\n"
289
+ clear_events()
290
+ @builder["installStatus"].label += "\nWould you like to open these URLs in a browser now?"
291
+ @builder["buttonInstallOK"].visible = true
292
+ @builder["buttonInstallCancel"].visible = true
293
+ clear_events()
294
+ end
295
+ else
296
+ alert "Racepoint services not running at specified IP Address. Target for installation must be a Savant Pro Host."
297
+ end
298
+ else
299
+ alert "Invalid IP Address."
300
+ end
301
+ end
302
+
303
+ ##### Repeat install process in reverse for uninstall. BUG: Java uninstall can be flaky an might fail. #####
304
+ def buttonHelpUninstall__clicked(*argv)
305
+ if IPAddress.valid? @savantURL
306
+ if is_port_open?(@savantURL,"11263")
307
+ @builder["dialogInstall"].show
308
+ login = 'RPM'
309
+ @password = 'RPM'
310
+ result = ''
311
+ result = ''
312
+ Net::SSH.start(@savantURL, login, :password => @password, :paranoid => false) do |ssh|
313
+ @builder["installStatus"].label += "\nUninstalling Launch Agents..."
314
+ clear_events()
315
+ result = ssh.exec!("launchctl unload /Users/RPM/Library/LaunchAgents/com.SCLI_HTTP.plist")
316
+ result = ssh.exec!("launchctl unload /Users/RPM/Library/LaunchAgents/com.habridge.plist")
317
+ @builder["installStatus"].label += result
318
+ @builder["installStatus"].label += "Launch Agents uninstalled!\n\n"
319
+ clear_events()
320
+ sleep 3
321
+ ssh.open_channel do |ch, success|
322
+ ch.request_pty do |ch, success|
323
+ end
324
+ @builder["installStatus"].label += "Uninstalling Java on Host...this might take a minute.\n"
325
+ clear_events()
326
+ ch.exec(%q{brew cask uninstall java}) do |ch, success|
327
+ abort "could not execute command" unless success
328
+ end
329
+ ch.on_data do |ch, data|
330
+ if data.to_s.include? "Password:"
331
+ ch.send_data @password
332
+ ch.send_data "\n"
333
+ end
334
+ if data.to_s.include? "RETURN"
335
+ ch.send_data "\n"
336
+ end
337
+ if data.to_s.include? "java is not installed"
338
+ @builder["installStatus"].label += "Java already uninstalled on Host.\n\n"
339
+ clear_events()
340
+ sleep 1
341
+ end
342
+ if data.to_s.include? "Removing files: ["
343
+ @builder["installStatus"].label += "Java uninstalled on Host.\n\n"
344
+ clear_events()
345
+ sleep 1
346
+ end
347
+ end
348
+ ch.on_extended_data do |ch, type, data|
349
+ end
350
+ ch.wait
351
+ end
352
+ ssh.loop
353
+ ssh.open_channel do |ch, success|
354
+ ch.request_pty do |ch, success|
355
+ end
356
+ @builder["installStatus"].label += "Uninstalling Homebrew on Host...this might take a minute.\n"
357
+ clear_events()
358
+ ch.exec(%q{ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"}) do |ch, success|
359
+ abort "could not execute command" unless success
360
+ end
361
+ ch.on_data do |ch, data|
362
+ if data.to_s.include? "Password:"
363
+ ch.send_data @password
364
+ ch.send_data "\n"
365
+ end
366
+ if data.to_s.include? "RETURN"
367
+ ch.send_data "\n"
368
+ end
369
+ if data.to_s.include? "uninstall Homebrew? [y/N]"
370
+ ch.send_data "y\n"
371
+ end
372
+ if data.to_s.include? "Failed to locate Homebrew!"
373
+ @builder["installStatus"].label += "Homebrew already uninstalled on Host.\n\n"
374
+ clear_events()
375
+ sleep 3
376
+ end
377
+ if data.to_s.include? "You may wish to remove them yourself."
378
+ @builder["installStatus"].label += "Homebrew uninstalled on Host.\n\n"
379
+ clear_events()
380
+ sleep 3
381
+ end
382
+ end
383
+ ch.on_extended_data do |ch, type, data|
384
+ @builder["installStatus"].label += "got stderr: #{data.inspect}"
385
+ clear_events()
386
+ end
387
+ ch.wait
388
+ end
389
+ ssh.loop
390
+ @builder["installStatus"].label += "\nRemoving Files..."
391
+ clear_events()
392
+ ssh.exec!("rm –Rf /Users/RPM/habridge/")
393
+ ssh.exec!("rm -f /Users/RPM/habridge/com.habridge.plist /Users/RPM/Library/LaunchAgents/")
394
+ ssh.exec!("rm -f /Users/RPM/habridge/com.SCLI_HTTP.plist /Users/RPM/Library/LaunchAgents/")
395
+ @builder["installStatus"].label += "Files removed!\n\n"
396
+ clear_events()
397
+ @builder["installStatus"].label += "Uninstallation complete.\n\n"
398
+ @builder["installStatus"].label += "To verify installation, test that the following URLs\nare no longer active.\n\nhttp://" + @savantURL + ":8888/\nhttp://" + @savantURL + ":12000/userzones\n"
399
+ clear_events()
400
+ @builder["installStatus"].label += "\nWould you like to open these URLs in a browser now?"
401
+ @builder["buttonInstallOK"].visible = true
402
+ @builder["buttonInstallCancel"].visible = true
403
+ clear_events()
404
+ end
405
+ else
406
+ alert "Racepoint services not running at specified IP Address. Target for installation must be a Savant Pro Host."
407
+ end
408
+ else
409
+ alert "Invalid IP Address."
410
+ end
411
+ end
412
+
413
+ ##### Close window #####
414
+ def buttonHelpCancel__clicked(*argv)
415
+ @builder["dialogHelp"].hide
416
+ end
417
+
418
+ ##### Launch HABridge and SCLIbridge in browser and close installation status window #####
419
+ def buttonInstallOK__clicked(*argv)
420
+ @builder["installStatus"].label = ""
421
+ @builder["buttonInstallOK"].visible = false
422
+ @builder["buttonInstallCancel"].visible = false
423
+ @builder["dialogInstall"].hide
424
+ system("open http://" + @savantURL + ":8888")
425
+ system("open http://" + @savantURL + ":12000/userzones")
426
+ end
427
+
428
+ ##### Close installation status window #####
429
+ def buttonInstallCancel__clicked(*argv)
430
+ @builder["buttonInstallOK"].visible = false
431
+ @builder["buttonInstallCancel"].visible = false
432
+ @builder["installStatus"].label = ""
433
+ @builder["dialogInstall"].hide
434
+ end
435
+
436
+ ##### #####
437
+ ##### Zone request only toggle buttons #####
438
+ ##### #####
439
+
440
+ ##### Toggle On Request to/from Zone only #####
441
+ def buttonOnZoneOnly__clicked(*argv)
442
+ if @builder["buttonOnZoneOnly"].active?
443
+ @savantRequestOn = @builder["savantRequestOn"].text
444
+ if !@savantRequestOn.empty?
445
+ zoneOnlyOnArray = @savantRequestOn.split('-')
446
+ zoneOnlyOnArray.fill('',1,4)
447
+ @builder["savantRequestOn"].text = zoneOnlyOnArray.join('-')
448
+ end
449
+ else
450
+ @builder["savantRequestOn"].text = @savantRequestOn
451
+ end
452
+
453
+ end
454
+
455
+ ##### Toggle Off Request to/from Zone only #####
456
+ def buttonOffZoneOnly__clicked(*argv)
457
+ if @builder["buttonOffZoneOnly"].active?
458
+ @savantRequestOff = @builder["savantRequestOff"].text
459
+ if !@savantRequestOff.empty?
460
+ zoneOfflyOffArray = @savantRequestOff.split('-')
461
+ zoneOfflyOffArray.fill('',1,4)
462
+ @builder["savantRequestOff"].text = zoneOfflyOffArray.join('-')
463
+ end
464
+ else
465
+ @builder["savantRequestOff"].text = @savantRequestOff
466
+ end
467
+
468
+ end
469
+
470
+ ##### Toggle Dim Request to/from Zone only #####
471
+ def buttonDimZoneOnly__clicked(*argv)
472
+ if @builder["buttonDimZoneOnly"].active?
473
+ @savantRequestDim = @builder["savantRequestDim"].text
474
+ if !@savantRequestDim.empty?
475
+ zoneDimlyDimArray = @savantRequestDim.split('-')
476
+ zoneDimlyDimArray.fill('',1,4)
477
+ @builder["savantRequestDim"].text = zoneDimlyDimArray.join('-')
478
+ end
479
+ else
480
+ @builder["savantRequestDim"].text = @savantRequestDim
481
+ end
482
+
483
+ end
484
+
485
+ ##### #####
486
+ ##### Add command(s) to HA Bridge, first parsing for errors and needed parameters #####
487
+ ##### #####
488
+
489
+ def buttonAdd__clicked(*argv)
490
+ get_glade_variables()
491
+
492
+ #Error checking for empty fields and non-compliant workflows
493
+ @error = nil
494
+ errorCount = 0
495
+
496
+ #Check for valid Host IP and build bridge strings
497
+ if @savantURL.to_s.empty?
498
+ @error = "Missing Savant Host URL"
499
+ elsif !(IPAddress.valid? @savantURL)
500
+ @error = "Invalid URL"
501
+ else
502
+ @haURLstr = "http://" + @savantURL + ":8888/api/devices"
503
+ @savantURLstr = "http://" + @savantURL + ":12000"
504
+ end
505
+
506
+ #Check for device name entry
507
+ if @error.nil? && @haName.to_s.empty?
508
+ @error = "Missing Device Name"
509
+ end
510
+
511
+ #Check for HA bridge online at specified IP
512
+ if @habridgeStatus != "Online"
513
+ @error = "HA Bridge Not Online"
514
+ end
515
+
516
+ #Proceed if no errors
517
+ if @error.nil?
518
+ #Check for empty On entry, create empty array if so, and count to make sure at least one entry is present
519
+ if @savantRequestOn.to_s.empty?
520
+ @requestOnArray = []
521
+ errorCount += 1
522
+ elsif @savantRequestOn.to_s.include?(":") || @savantRequestOn.to_s.include?("-")
523
+ #Split off main service request from arguments if they exist
524
+ @requestOnArray = @savantRequestOn.split(/:/)
525
+ #Add escapes and formatting to pass through JSON to Ha Bridge
526
+ @requestOnCmd = @requestOnArray.shift.gsub!(/[- ']/, '-' => '\\\'-\\\'', ' ' => '%20')
527
+ @strRequestOn = %q{'onUrl' : '} + @savantURLstr + %q{/servicerequestcommand%20\'} + @requestOnCmd + %q{\'}
528
+ else
529
+ @error = "Not a valid On workflow."
530
+ end
531
+
532
+ #Repeat for off
533
+ if @savantRequestOff.to_s.empty?
534
+ @requestOffArray = []
535
+ errorCount += 1
536
+ elsif @savantRequestOff.to_s.include?(":") || @savantRequestOff.to_s.include?("-")
537
+ @requestOffArray = @savantRequestOff.split(/:/)
538
+ @requestOffCmd = @requestOffArray.shift.gsub!(/[- ']/, '-' => '\\\'-\\\'', ' ' => '%20')
539
+ @strRequestOff = %q{'offUrl' : '} + @savantURLstr + %q{/servicerequestcommand%20\'} + @requestOffCmd + %q{\'}
540
+ else
541
+ @error = "Not a valid Off workflow."
542
+ end
543
+
544
+ #Repeat for dim
545
+ if @savantRequestDim.to_s.empty?
546
+ @requestDimArray = []
547
+ errorCount += 1
548
+ elsif @savantRequestDim.to_s.include?(":") || @savantRequestDim.to_s.include?("-")
549
+ @requestDimArray = @savantRequestDim.split(/:/)
550
+ @requestDimCmd = @requestDimArray.shift.gsub!(/[- ']/, '-' => '\\\'-\\\'', ' ' => '%20')
551
+ @strRequestDim = %q{'dimUrl' : '} + @savantURLstr + %q{/servicerequestcommand%20\'} + @requestDimCmd + %q{\'}
552
+ else
553
+ @error = "Not a valid Dim workflow."
554
+ end
555
+ if errorCount == 3
556
+ @error = "You must enter at least one command to proceed."
557
+ end
558
+
559
+ end
560
+
561
+ #Proceed as long as there is one valid command
562
+ if @error.nil?
563
+ #Checks to see how many action arguments are in the On 3rd party workflow, saves the Argument names to display on the UI
564
+ #and hides ones that are not needed from appearing on the popup dialog.
565
+ if @requestOnArray.length >= 1
566
+ @requestOnComplex = 1
567
+ requestOnArgs = @requestOnArray.shift.split(',')
568
+ @requestOnArg1 = requestOnArgs.shift.chop
569
+ if requestOnArgs.length > 0
570
+ @requestOnArg2 = requestOnArgs.shift.chop
571
+
572
+ @builder["frameOnArg2"].visible = true
573
+ else
574
+ @builder["frameOnArg2"].visible = false
575
+ @requestOnValue2 = nil
576
+ end
577
+ if requestOnArgs.length > 0
578
+ @requestOnArg3 = requestOnArgs.shift.chop
579
+ @builder["frameOnArg3"].visible = true
580
+ else
581
+ @builder["frameOnArg3"].visible = false
582
+ @requestOnValue3 = nil
583
+ end
584
+ if requestOnArgs.length > 0
585
+ @requestOnArg4 = requestOnArgs.shift.chop
586
+ @builder["frameOnArg4"].visible = true
587
+ else
588
+ @builder["frameOnArg4"].visible = false
589
+ @requestOnValue4 = nil
590
+ end
591
+ if requestOnArgs.length > 0
592
+ @requestOnArg5 = requestOnArgs.shift.chop
593
+ @builder["frameOnArg5"].visible = true
594
+ else
595
+ @builder["frameOnArg5"].visible = false
596
+ @requestOnValue5 = nil
597
+ end
598
+ if requestOnArgs.length > 0
599
+ @requestOnArg6 = requestOnArgs.shift.chop
600
+ @builder["frameOnArg6"].visible = true
601
+ else
602
+ @builder["frameOnArg6"].visible = false
603
+ @requestOnValue6 = nil
604
+ end
605
+ if requestOnArgs.length > 0
606
+ @requestOnArg7 = requestOnArgs.shift.chop
607
+ @builder["frameOnArg7"].visible = true
608
+ else
609
+ @builder["frameOnArg7"].visible = false
610
+ @requestOnValue7 = nil
611
+ end
612
+ if requestOnArgs.length > 0
613
+ @requestOnArg8 = requestOnArgs.shift.chop
614
+ @builder["frameOnArg8"].visible = true
615
+ else
616
+ @builder["frameOnArg8"].visible = false
617
+ @requestOnValue8 = nil
618
+ end
619
+ if requestOnArgs.length > 0
620
+ @requestOnArg9 = requestOnArgs.shift.chop
621
+ @builder["frameOnArg9"].visible = true
622
+ else
623
+ @builder["frameOnArg9"].visible = false
624
+ @requestOnValue9 = nil
625
+ end
626
+ else
627
+ #Add JSON quote terminator is string is not empty
628
+ if !@savantRequestOn.to_s.empty?
629
+ @strRequestOn += %q{'}
630
+ end
631
+ @requestOnComplex = 0
632
+ end
633
+
634
+ #Repeat for Off
635
+ if @requestOffArray.length >= 1
636
+ @requestOffComplex = 1
637
+ requestOffArgs = @requestOffArray.shift.split(',')
638
+ @requestOffArg1 = requestOffArgs.shift.chop
639
+ if requestOffArgs.length > 0
640
+ @requestOffArg2 = requestOffArgs.shift.chop
641
+ @builder["frameOffArg2"].visible = true
642
+ else
643
+ @builder["frameOffArg2"].visible = false
644
+ @requestOffValue2 = nil
645
+ end
646
+ if requestOffArgs.length > 0
647
+ @requestOffArg3 = requestOffArgs.shift.chop
648
+ @builder["frameOffArg3"].visible = true
649
+ else
650
+ @builder["frameOffArg3"].visible = false
651
+ @requestOffValue3 = nil
652
+ end
653
+ if requestOffArgs.length > 0
654
+ @requestOffArg4 = requestOffArgs.shift.chop
655
+ @builder["frameOffArg4"].visible = true
656
+ else
657
+ @builder["frameOffArg4"].visible = false
658
+ @requestOffValue4 = nil
659
+ end
660
+ if requestOffArgs.length > 0
661
+ @requestOffArg5 = requestOffArgs.shift.chop
662
+ @builder["frameOffArg5"].visible = true
663
+ else
664
+ @builder["frameOffArg5"].visible = false
665
+ @requestOffValue5 = nil
666
+ end
667
+ if requestOffArgs.length > 0
668
+ @requestOffArg6 = requestOffArgs.shift.chop
669
+ @builder["frameOffArg6"].visible = true
670
+ else
671
+ @builder["frameOffArg6"].visible = false
672
+ @requestOffValue6 = nil
673
+ end
674
+ if requestOffArgs.length > 0
675
+ @requestOffArg7 = requestOffArgs.shift.chop
676
+ @builder["frameOffArg7"].visible = true
677
+ else
678
+ @builder["frameOffArg7"].visible = false
679
+ @requestOffValue7 = nil
680
+ end
681
+ if requestOffArgs.length > 0
682
+ @requestOffArg8 = requestOffArgs.shift.chop
683
+ @builder["frameOffArg8"].visible = true
684
+ else
685
+ @builder["frameOffArg8"].visible = false
686
+ @requestOffValue8 = nil
687
+ end
688
+ if requestOffArgs.length > 0
689
+ @requestOffArg9 = requestOffArgs.shift.chop
690
+ @builder["frameOffArg9"].visible = true
691
+ else
692
+ @builder["frameOffArg9"].visible = false
693
+ @requestOffValue9 = nil
694
+ end
695
+ else
696
+ @requestOffComplex = 0
697
+ if !@savantRequestOff.to_s.empty?
698
+ @strRequestOff += %q{'}
699
+ end
700
+ end
701
+
702
+ #Repeat for Dim
703
+ if @requestDimArray.length >= 1
704
+ @requestDimComplex = 1
705
+ requestDimArgs = @requestDimArray.shift.split(',')
706
+ @requestDimArg1 = requestDimArgs.shift.chop
707
+ if requestDimArgs.length > 0
708
+ @requestDimArg2 = requestDimArgs.shift.chop
709
+ @builder["frameDimArg2"].visible = true
710
+ else
711
+ @builder["frameDimArg2"].visible = false
712
+ @requestDimValue2 = nil
713
+ end
714
+ if requestDimArgs.length > 0
715
+ @requestDimArg3 = requestDimArgs.shift.chop
716
+ @builder["frameDimArg3"].visible = true
717
+ else
718
+ @builder["frameDimArg3"].visible = false
719
+ @requestDimValue3 = nil
720
+ end
721
+ if requestDimArgs.length > 0
722
+ @requestDimArg4 = requestDimArgs.shift.chop
723
+ @builder["frameDimArg4"].visible = true
724
+ else
725
+ @builder["frameDimArg4"].visible = false
726
+ @requestDimValue4 = nil
727
+ end
728
+ if requestDimArgs.length > 0
729
+ @requestDimArg5 = requestDimArgs.shift.chop
730
+ @builder["frameDimArg5"].visible = true
731
+ else
732
+ @builder["frameDimArg5"].visible = false
733
+ @requestDimValue5 = nil
734
+ end
735
+ if requestDimArgs.length > 0
736
+ @requestDimArg6 = requestDimArgs.shift.chop
737
+ @builder["frameDimArg6"].visible = true
738
+ else
739
+ @builder["frameDimArg6"].visible = false
740
+ @requestDimValue6 = nil
741
+ end
742
+ if requestDimArgs.length > 0
743
+ @requestDimArg7 = requestDimArgs.shift.chop
744
+ @builder["frameDimArg7"].visible = true
745
+ else
746
+ @builder["frameDimArg7"].visible = false
747
+ @requestDimValue7 = nil
748
+ end
749
+ if requestDimArgs.length > 0
750
+ @requestDimArg8 = requestDimArgs.shift.chop
751
+ @builder["frameDimArg8"].visible = true
752
+ else
753
+ @builder["frameDimArg8"].visible = false
754
+ @requestDimValue8 = nil
755
+ end
756
+ if requestDimArgs.length > 0
757
+ @requestDimArg9 = requestDimArgs.shift.chop
758
+ @builder["frameDimArg9"].visible = true
759
+ else
760
+ @builder["frameDimArg9"].visible = false
761
+ @requestDimValue9 = nil
762
+ end
763
+ else
764
+ @requestDimComplex = 0
765
+ if !@savantRequestDim.to_s.empty?
766
+ @strRequestDim += %q{'}
767
+ end
768
+ end
769
+
770
+ #Set all variables to UI before showing next window
771
+ set_glade_variables()
772
+
773
+ #Shows popup dialog for action argument value entry if needed, else finishes building the string and sends it to the HA Bridge.
774
+ if @requestOnComplex == 1
775
+ @builder["dialogOn"].show
776
+ elsif @requestOffComplex == 1
777
+ @builder["dialogOff"].show
778
+ elsif @requestDimComplex == 1
779
+ @builder["dialogDim"].show
780
+ else
781
+ sendHaRequest()
782
+ end
783
+
784
+ else
785
+ #If any errors were found, alert user.
786
+ alert @error
787
+ end
788
+ end
789
+
790
+ ##### Exit main program #####
791
+ def buttonExit__clicked(*args)
792
+ @builder["window1"].destroy
793
+ end
794
+
795
+ ##### #####
796
+ ##### Action argument windows #####
797
+ ##### #####
798
+
799
+ #For each On parameter field that is possible, check if user entered value, percent, or number, and push into arg/val array.
800
+ def buttonAcceptOn__clicked(*argv)
801
+ get_glade_variables()
802
+ if @requestOnValue1 == 'percent'
803
+ @requestOnValue1 = '${intensity.percent}'
804
+ elsif @requestOnValue1 == 'number'
805
+ @requestOnValue1 = '${intensity.byte}'
806
+ end
807
+ requestOnValues = [@requestOnArg1, @requestOnValue1]
808
+ unless @requestOnArg2.nil?
809
+ if @requestOnValue2 == 'percent'
810
+ @requestOnValue2 = '${intensity.percent}'
811
+ elsif @requestOnValue2 == 'number'
812
+ @requestOnValue2 = '${intensity.byte}'
813
+ end
814
+ requestOnValues.push(@requestOnArg2)
815
+ requestOnValues.push(@requestOnValue2)
816
+ end
817
+ unless @requestOnArg3.nil?
818
+ if @requestOnValue3 == 'percent'
819
+ @requestOnValue3 = '${intensity.percent}'
820
+ elsif @requestOnValue3 == 'number'
821
+ @requestOnValue3 = '${intensity.byte}'
822
+ end
823
+ requestOnValues.push(@requestOnArg3)
824
+ requestOnValues.push(@requestOnValue3)
825
+ end
826
+ unless @requestOnArg4.nil?
827
+ if @requestOnValue4 == 'percent'
828
+ @requestOnValue4 = '${intensity.percent}'
829
+ elsif @requestOnValue4 == 'number'
830
+ @requestOnValue4 = '${intensity.byte}'
831
+ end
832
+ requestOnValues.push(@requestOnArg4)
833
+ requestOnValues.push(@requestOnValue4)
834
+ end
835
+ unless @requestOnArg5.nil?
836
+ if @requestOnValue5 == 'percent'
837
+ @requestOnValue5 = '${intensity.percent}'
838
+ elsif @requestOnValue5 == 'number'
839
+ @requestOnValue5 = '${intensity.byte}'
840
+ end
841
+ requestOnValues.push(@requestOnArg5)
842
+ requestOnValues.push(@requestOnValue5)
843
+ end
844
+ unless @requestOnArg6.nil?
845
+ if @requestOnValue6 == 'percent'
846
+ @requestOnValue6 = '${intensity.percent}'
847
+ elsif @requestOnValue6 == 'number'
848
+ @requestOnValue6 = '${intensity.byte}'
849
+ end
850
+ requestOnValues.push(@requestOnArg6)
851
+ requestOnValues.push(@requestOnValue6)
852
+ end
853
+ unless @requestOnArg7.nil?
854
+ if @requestOnValue7 == 'percent'
855
+ @requestOnValue7 = '${intensity.percent}'
856
+ elsif @requestOnValue7 == 'number'
857
+ @requestOnValue7 = '${intensity.byte}'
858
+ end
859
+ requestOnValues.push(@requestOnArg7)
860
+ requestOnValues.push(@requestOnValue7)
861
+ end
862
+ unless @requestOnArg8.nil?
863
+ if @requestOnValue8 == 'percent'
864
+ @requestOnValue8 = '${intensity.percent}'
865
+ elsif @requestOnValue8 == 'number'
866
+ @requestOnValue8 = '${intensity.byte}'
867
+ end
868
+ requestOnValues.push(@requestOnArg8)
869
+ requestOnValues.push(@requestOnValue8)
870
+ end
871
+ unless @requestOnArg9.nil?
872
+ if @requestOnValue9 == 'percent'
873
+ @requestOnValue9 = '${intensity.percent}'
874
+ elsif @requestOnValue9 == 'number'
875
+ @requestOnValue9 = '${intensity.byte}'
876
+ end
877
+ requestOnValues.push(@requestOnArg9)
878
+ requestOnValues.push(@requestOnValue9)
879
+ end
880
+
881
+ #Create On request string by joining each arg/val from array with proper JSON syntax
882
+ @strRequestOn += '%20\\\'' + requestOnValues.join('\\\'%20\\\'') + '\\\''
883
+ @strRequestOn += %q{'}
884
+
885
+ #Hide On parameter window and check to see if Off or Dim commands had parameters, then show them. Else, send the string to the HA Bridge.
886
+ @builder["dialogOn"].hide
887
+ if @requestOffComplex == 0 && @requestDimComplex == 0
888
+ sendHaRequest()
889
+ elsif @requestOffComplex == 1
890
+ @builder["dialogOff"].show
891
+ elsif @requestDimComplex == 1
892
+ @builder["dialogDim"].show
893
+ end
894
+ end
895
+
896
+ def buttonCancelOn__clicked(*args)
897
+ @builder["dialogOn"].hide
898
+ end
899
+
900
+ ##### Repeat for off #####
901
+ def buttonAcceptOff__clicked(*argv)
902
+ get_glade_variables()
903
+ if @requestOffValue1 == 'percent'
904
+ @requestOffValue1 = '${intensity.percent}'
905
+ elsif @requestOffValue1 == 'number'
906
+ @requestOffValue1 = '${intensity.byte}'
907
+ end
908
+ requestOffValues = [@requestOffArg1, @requestOffValue1]
909
+ unless @requestOffArg2.nil?
910
+ if @requestOffValue2 == 'percent'
911
+ @requestOffValue2 = '${intensity.percent}'
912
+ elsif @requestOffValue2 == 'number'
913
+ @requestOffValue2 = '${intensity.byte}'
914
+ end
915
+ requestOffValues.push(@requestOffArg2)
916
+ requestOffValues.push(@requestOffValue2)
917
+ end
918
+ unless @requestOffArg3.nil?
919
+ if @requestOffValue3 == 'percent'
920
+ @requestOffValue3 = '${intensity.percent}'
921
+ elsif @requestOffValue3 == 'number'
922
+ @requestOffValue3 = '${intensity.byte}'
923
+ end
924
+ requestOffValues.push(@requestOffArg3)
925
+ requestOffValues.push(@requestOffValue3)
926
+ end
927
+ unless @requestOffArg4.nil?
928
+ if @requestOffValue4 == 'percent'
929
+ @requestOffValue4 = '${intensity.percent}'
930
+ elsif @requestOffValue4 == 'number'
931
+ @requestOffValue4 = '${intensity.byte}'
932
+ end
933
+ requestOffValues.push(@requestOffArg4)
934
+ requestOffValues.push(@requestOffValue4)
935
+ end
936
+ unless @requestOffArg5.nil?
937
+ if @requestOffValue5 == 'percent'
938
+ @requestOffValue5 = '${intensity.percent}'
939
+ elsif @requestOffValue5 == 'number'
940
+ @requestOffValue5 = '${intensity.byte}'
941
+ end
942
+ requestOffValues.push(@requestOffArg5)
943
+ requestOffValues.push(@requestOffValue5)
944
+ end
945
+ unless @requestOffArg6.nil?
946
+ if @requestOffValue6 == 'percent'
947
+ @requestOffValue6 = '${intensity.percent}'
948
+ elsif @requestOffValue6 == 'number'
949
+ @requestOffValue6 = '${intensity.byte}'
950
+ end
951
+ requestOffValues.push(@requestOffArg6)
952
+ requestOffValues.push(@requestOffValue6)
953
+ end
954
+ unless @requestOffArg7.nil?
955
+ if @requestOffValue7 == 'percent'
956
+ @requestOffValue7 = '${intensity.percent}'
957
+ elsif @requestOffValue7 == 'number'
958
+ @requestOffValue7 = '${intensity.byte}'
959
+ end
960
+ requestOffValues.push(@requestOffArg7)
961
+ requestOffValues.push(@requestOffValue7)
962
+ end
963
+ unless @requestOffArg8.nil?
964
+ if @requestOffValue8 == 'percent'
965
+ @requestOffValue8 = '${intensity.percent}'
966
+ elsif @requestOffValue8 == 'number'
967
+ @requestOffValue8 = '${intensity.byte}'
968
+ end
969
+ requestOffValues.push(@requestOffArg8)
970
+ requestOffValues.push(@requestOffValue8)
971
+ end
972
+ unless @requestOffArg9.nil?
973
+ if @requestOffValue9 == 'percent'
974
+ @requestOffValue9 = '${intensity.percent}'
975
+ elsif @requestOffValue9 == 'number'
976
+ @requestOffValue9 = '${intensity.byte}'
977
+ end
978
+ requestOffValues.push(@requestOffArg9)
979
+ requestOffValues.push(@requestOffValue9)
980
+ end
981
+ @strRequestOff += '%20\\\'' + requestOffValues.join('\\\'%20\\\'') + '\\\''
982
+ @strRequestOff += %q{'}
983
+ @builder["dialogOff"].hide
984
+ if @requestDimComplex == 1
985
+ @builder["dialogDim"].show
986
+ else
987
+ sendHaRequest()
988
+ end
989
+ end
990
+
991
+ ##### Close window #####
992
+ def buttonCancelOff__clicked(*args)
993
+ @builder["dialogOff"].hide
994
+ end
995
+
996
+ ##### Repeat for Dim #####
997
+ def buttonAcceptDim__clicked(*argv)
998
+ get_glade_variables()
999
+ if @requestDimValue1 == 'percent'
1000
+ @requestDimValue1 = '${intensity.percent}'
1001
+ elsif @requestDimValue1 == 'number'
1002
+ @requestDimValue1 = '${intensity.byte}'
1003
+ end
1004
+ requestDimValues = [@requestDimArg1, @requestDimValue1]
1005
+ unless @requestDimArg2.nil?
1006
+ if @requestDimValue2 == 'percent'
1007
+ @requestDimValue2 = '${intensity.percent}'
1008
+ elsif @requestDimValue2 == 'number'
1009
+ @requestDimValue2 = '${intensity.byte}'
1010
+ end
1011
+ requestDimValues.push(@requestDimArg2)
1012
+ requestDimValues.push(@requestDimValue2)
1013
+ end
1014
+ unless @requestDimArg3.nil?
1015
+ if @requestDimValue3 == 'percent'
1016
+ @requestDimValue3 = '${intensity.percent}'
1017
+ elsif @requestDimValue3 == 'number'
1018
+ @requestDimValue3 = '${intensity.byte}'
1019
+ end
1020
+ requestDimValues.push(@requestDimArg3)
1021
+ requestDimValues.push(@requestDimValue3)
1022
+ end
1023
+ unless @requestDimArg4.nil?
1024
+ if @requestDimValue4 == 'percent'
1025
+ @requestDimValue4 = '${intensity.percent}'
1026
+ elsif @requestDimValue4 == 'number'
1027
+ @requestDimValue4 = '${intensity.byte}'
1028
+ end
1029
+ requestDimValues.push(@requestDimArg4)
1030
+ requestDimValues.push(@requestDimValue4)
1031
+ end
1032
+ unless @requestDimArg5.nil?
1033
+ if @requestDimValue5 == 'percent'
1034
+ @requestDimValue5 = '${intensity.percent}'
1035
+ elsif @requestDimValue5 == 'number'
1036
+ @requestDimValue5 = '${intensity.byte}'
1037
+ end
1038
+ requestDimValues.push(@requestDimArg5)
1039
+ requestDimValues.push(@requestDimValue5)
1040
+ end
1041
+ unless @requestDimArg6.nil?
1042
+ if @requestDimValue6 == 'percent'
1043
+ @requestDimValue6 = '${intensity.percent}'
1044
+ elsif @requestDimValue6 == 'number'
1045
+ @requestDimValue6 = '${intensity.byte}'
1046
+ end
1047
+ requestDimValues.push(@requestDimArg6)
1048
+ requestDimValues.push(@requestDimValue6)
1049
+ end
1050
+ unless @requestDimArg7.nil?
1051
+ if @requestDimValue7 == 'percent'
1052
+ @requestDimValue7 = '${intensity.percent}'
1053
+ elsif @requestDimValue7 == 'number'
1054
+ @requestDimValue7 = '${intensity.byte}'
1055
+ end
1056
+ requestDimValues.push(@requestDimArg7)
1057
+ requestDimValues.push(@requestDimValue7)
1058
+ end
1059
+ unless @requestDimArg8.nil?
1060
+ if @requestDimValue8 == 'percent'
1061
+ @requestDimValue8 = '${intensity.percent}'
1062
+ elsif @requestDimValue8 == 'number'
1063
+ @requestDimValue8 = '${intensity.byte}'
1064
+ end
1065
+ requestDimValues.push(@requestDimArg8)
1066
+ requestDimValues.push(@requestDimValue8)
1067
+ end
1068
+ unless @requestDimArg9.nil?
1069
+ if @requestDimValue9 == 'percent'
1070
+ @requestDimValue9 = '${intensity.percent}'
1071
+ elsif @requestDimValue9 == 'number'
1072
+ @requestDimValue9 = '${intensity.byte}'
1073
+ end
1074
+ requestDimValues.push(@requestDimArg9)
1075
+ requestDimValues.push(@requestDimValue9)
1076
+ end
1077
+ @strRequestDim += '%20\\\'' + requestDimValues.join('\\\'%20\\\'') + '\\\''
1078
+ @strRequestDim += %q{'}
1079
+ @builder["dialogDim"].hide
1080
+ sendHaRequest()
1081
+ end
1082
+
1083
+ ##### Close window #####
1084
+ def buttonCancelDim__clicked(*args)
1085
+ @builder["dialogDim"].hide
1086
+ end
1087
+
1088
+ ##### #####
1089
+ ##### Send commands to HA Bridge #####
1090
+ ##### #####
1091
+
1092
+ def sendHaRequest
1093
+
1094
+ #Build JSON string of On, Off, and Dim commands, if they exist.
1095
+ @haRequest = %q{\{'name' : '} + @haName + %q{','deviceType' : 'custom',}
1096
+ if !@strRequestOn.empty?
1097
+ @haRequest += @strRequestOn
1098
+ end
1099
+ if !@strRequestOff.empty?
1100
+ if !@strRequestOn.empty?
1101
+ @haRequest += ','
1102
+ end
1103
+ @haRequest += @strRequestOff
1104
+ end
1105
+ if !@strRequestDim.empty?
1106
+ if (!@strRequestOn.empty? || !@strRequestOff.empty?)
1107
+ @haRequest += ','
1108
+ end
1109
+ @haRequest += @strRequestDim
1110
+ end
1111
+ @haRequest += %q{\}}
1112
+
1113
+ #Debug alert "Host address = " + @savantURLstr + "\n\nHA Bridge address = " + @haURLstr + "\n\nDevice name = " + @haName + "\n\nOnCommand = " + @strRequestOn + "\n\nOffCommand = " + @strRequestOff + "\n\nDimCommand = " + @strRequestDim + "\n\nRequest String = " + @haRequest
1114
+
1115
+
1116
+ #Send JSON string to specified host IP. Alert user of any errors or success.
1117
+ uri = URI.parse(@haURLstr)
1118
+ begin
1119
+ http = Net::HTTP.start(uri.host, uri.port, {open_timeout: 3, read_timeout: 3})
1120
+ begin
1121
+ request = Net::HTTP::Post.new(
1122
+ uri.request_uri,
1123
+ 'Content-Type' => 'application/json'
1124
+ )
1125
+ request.body = @haRequest
1126
+ response = http.request(request)
1127
+ if response.code == "201"
1128
+ alert 'Command successfully added to HA Bridge.'
1129
+ elsif response.code.include?("4" || "5")
1130
+ alert 'Command failed to be added to HA Bridge.'
1131
+ end
1132
+ rescue Timeout::Error, SocketError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED
1133
+ alert "Unable to reach host."
1134
+ end
1135
+ rescue Timeout::Error, SocketError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED
1136
+ alert "Unable to reach host."
1137
+ end
1138
+
1139
+ #Reset variables for next command, preserving host IP
1140
+ @savantRequestOn = ''
1141
+ @savantRequestOff = ''
1142
+ @savantRequestDim = ''
1143
+
1144
+ @strRequestOn = ''
1145
+ @strRequestOff = ''
1146
+ @strRequestDim = ''
1147
+
1148
+ @requestOnValue1 = "percent"
1149
+ @requestOnValue2 = "percent"
1150
+ @requestOnValue3 = "percent"
1151
+ @requestOnValue4 = "percent"
1152
+ @requestOnValue5 = "percent"
1153
+ @requestOnValue6 = "percent"
1154
+ @requestOnValue7 = "percent"
1155
+ @requestOnValue8 = "percent"
1156
+ @requestOnValue9 = "percent"
1157
+
1158
+ @requestOffValue1 = "percent"
1159
+ @requestOffValue2 = "percent"
1160
+ @requestOffValue3 = "percent"
1161
+ @requestOffValue4 = "percent"
1162
+ @requestOffValue5 = "percent"
1163
+ @requestOffValue6 = "percent"
1164
+ @requestOffValue7 = "percent"
1165
+ @requestOffValue8 = "percent"
1166
+ @requestOffValue9 = "percent"
1167
+
1168
+ @requestDimValue1 = "percent"
1169
+ @requestDimValue2 = "percent"
1170
+ @requestDimValue3 = "percent"
1171
+ @requestDimValue4 = "percent"
1172
+ @requestDimValue5 = "percent"
1173
+ @requestDimValue6 = "percent"
1174
+ @requestDimValue7 = "percent"
1175
+ @requestDimValue8 = "percent"
1176
+ @requestDimValue9 = "percent"
1177
+ end
1178
+ end