savant-echo 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/alexa +17 -0
- data/bin/habridge/SCLI_HTTP.rb +97 -0
- data/bin/src/Savant.rb +1178 -0
- data/bin/src/glade/Savant.glade +1830 -0
- metadata +88 -0
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
|