# TO DO # INSTALL PASSWORD PROMPT # ADD MENU ITEM FOR DEBUG? # PACKAGE INSTALLER require 'rubygems' require 'net/http' require 'net/scp' require 'uri' require 'socket' require 'timeout' require 'ipaddress' class Savant include GladeGUI #####Method to check to see if HA Bridge is running on host##### def up?(server, port) http = Net::HTTP.start(server, port, {open_timeout: 1, read_timeout: 1}) response = http.head("/") if response.code == "200" @builder["buttonHabridgeStatus"].label = "HA Bridge is Online\nClick to open in browser." @habridgeStatus = "Online" end rescue Timeout::Error, SocketError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED false @builder["buttonHabridgeStatus"].label = "HA Bridge is Offline\nClick for help." @habridgeStatus = "Offline" end #####Method to check to see if Racepoint and SCLI bridge ports are open on host##### def is_port_open?(ip, port) begin Timeout::timeout(1) do begin s = TCPSocket.new(ip, port) s.close return true rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH return false end end rescue Timeout::Error end return false end #####Set variables before windows load##### def before_show() @savantURL = "192.168.77.178" @haName = "" @habridgeStatus = "Offline" @installStatus = "" @savantRequestOn = '' @savantRequestOff = '' @savantRequestDim = '' @strRequestOn = '' @strRequestOff = '' @strRequestDim = '' @requestOnValue1 = "percent" @requestOnValue2 = "percent" @requestOnValue3 = "percent" @requestOnValue4 = "percent" @requestOnValue5 = "percent" @requestOnValue6 = "percent" @requestOnValue7 = "percent" @requestOnValue8 = "percent" @requestOnValue9 = "percent" @requestOffValue1 = "percent" @requestOffValue2 = "percent" @requestOffValue3 = "percent" @requestOffValue4 = "percent" @requestOffValue5 = "percent" @requestOffValue6 = "percent" @requestOffValue7 = "percent" @requestOffValue8 = "percent" @requestOffValue9 = "percent" @requestDimValue1 = "percent" @requestDimValue2 = "percent" @requestDimValue3 = "percent" @requestDimValue4 = "percent" @requestDimValue5 = "percent" @requestDimValue6 = "percent" @requestDimValue7 = "percent" @requestDimValue8 = "percent" @requestDimValue9 = "percent" up?(@savantURL,"8888") end #####Check HA bridge server status for feedback when textbox is edited##### def savantURL__focus_out_event(*argv) @savantURL = @builder["savantURL"].text up?(@savantURL,"8888") end def savantHelpURL__focus_out_event(*argv) @savantURL = @builder["savantHelpURL"].text up?(@savantURL,"8888") end #####Launch HA Bridge if online or help window if offline##### def buttonHabridgeStatus__clicked(*argv) if @habridgeStatus == "Offline" @builder["savantHelpURL"].text = @savantURL @builder["dialogHelp"].show elsif @habridgeStatus == "Online" system("open http://" + @savantURL + ":8888") end end ##### ##### ##### Help and installation window ##### ##### ##### ##### Try to launch HA bridge at specified IP ##### def buttonHelpHAbridge__clicked(*argv) if IPAddress.valid? @savantURL if is_port_open?(@savantURL,"8888") system("open " + @savantURLstr + ":8888") else alert "HA Bridge is not online at specified IP address.\nPlease change IP address or install HA bridge and set to port 8888." end else alert "Invalid IP Address." end end ##### Try to launch SCLI bridge at specified IP ##### def buttonHelpSCLIbridge__clicked(*argv) if IPAddress.valid? @savantURL if is_port_open?(@savantURL,"12000") system("open http://" + @savantURL + ":12000/userzones") else 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." end else alert "Invalid IP Address." end end ##### Install all components at specified IP ##### def buttonHelpInstall__clicked(*argv) #Check that specified host is a Savant Host running Racepoint if IPAddress.valid? @savantURL if is_port_open?(@savantURL,"11263") @builder["dialogInstall"].show login = 'RPM' @password = 'RPM' javaCount = 0 result = '' Net::SSH.start(@savantURL, login, :password => @password, :paranoid => false) do |ssh| #Copy files to host @builder["installStatus"].label = "Copying Files..." clear_events() ssh.exec!("mkdir -p /Users/RPM/habridge/") path = File.expand_path("..",__dir__) ssh.scp.upload!(path + "/habridge/", '/Users/RPM/', :recursive => true) ssh.exec!("mv /Users/RPM/habridge/com.habridge.plist /Users/RPM/Library/LaunchAgents/") ssh.exec!("mv /Users/RPM/habridge/com.SCLI_HTTP.plist /Users/RPM/Library/LaunchAgents/") @builder["installStatus"].label += "\nFiles copied!\n\nInstalling Homebrew on Host...this might take a minute.\n" clear_events() sleep 2 #Create terminal session with host ssh.open_channel do |ch, success| #debug alert "ch open" ch.request_pty do |ch, success| if success #debug alert "pty successfully obtained" else #debug alert "could not obtain pty" end end #Install homebrew on host ch.exec(%q{ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"}) do |ch, success| abort "could not execute command" unless success end ch.on_data do |ch, data| #debug alert "got data:" + data if data.to_s.include? "100%" print "." end if data.to_s.include? "Password:" ch.send_data @password ch.send_data "\n" end if data.to_s.include? "RETURN" ch.send_data "\n" end if data.to_s.include? "expected shallow list" @builder["installStatus"].label += "Homebrew already installed on Host.\n\n" clear_events() sleep 1 #debug #ch.send_data "brew cask install java" end if data.to_s.include? "Further documentation: https://git.io/brew-docs" @builder["installStatus"].label += "Homebrew installed on Host.\n\n" clear_events() sleep 1 #ch.send_data "brew cask install java" end end ch.on_extended_data do |ch, type, data| alert "got stderr: #{data.inspect}" end ch.wait end ssh.loop #Create terminal session on host ssh.open_channel do |ch, success| ch.request_pty do |ch, success| if success #debug alert "pty successfully obtained" else #debug alert "could not obtain pty" end end @builder["installStatus"].label += "Installing Java Dev Kit on Host...this might take a minute.\n" clear_events() sleep 1 #Install JDK on host ch.exec(%q{brew cask install java}) do |ch, success| abort "could not execute command" unless success end ch.on_data do |ch, data| #debug alert "got data:" + data if data.to_s.include? "0.0%" javaCount = javaCount + 1 if (javaCount%10).zero? @builder["installStatus"].label += "." clear_events() end end if data.to_s.include? "Password:" ch.send_data @password ch.send_data "\n" end if data.to_s.include? "RETURN" ch.send_data "\n" end if data.to_s.include? "A Cask for java is already installed." @builder["installStatus"].label += "Java already installed on Host.\n\n" clear_events() sleep 1 #ch.send_data "brew cask install java" end if data.to_s.include? "java was successfully installed!" @builder["installStatus"].label += "\nJava Installed on Host.\n\n" clear_events() sleep 1 #ch.send_data "brew cask install java" end end ch.on_extended_data do |ch, type, data| #debug alert "got stderr: #{data.inspect}" end ch.wait end ssh.loop #Update status window @builder["installStatus"].label += "Installing Launch Agents...\n" clear_events() result = ssh.exec!("launchctl load /Users/RPM/Library/LaunchAgents/com.SCLI_HTTP.plist") @builder["installStatus"].label += result clear_events() result = ssh.exec!("launchctl load /Users/RPM/Library/LaunchAgents/com.habridge.plist") @builder["installStatus"].label += result clear_events() @builder["installStatus"].label += "Launch Agents installed!\n\n" clear_events() sleep 1 @builder["installStatus"].label += "Installation complete.\n" clear_events() sleep 1 @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" clear_events() @builder["installStatus"].label += "\nWould you like to open these URLs in a browser now?" @builder["buttonInstallOK"].visible = true @builder["buttonInstallCancel"].visible = true clear_events() end else alert "Racepoint services not running at specified IP Address. Target for installation must be a Savant Pro Host." end else alert "Invalid IP Address." end end ##### Repeat install process in reverse for uninstall. BUG: Java uninstall can be flaky an might fail. ##### def buttonHelpUninstall__clicked(*argv) if IPAddress.valid? @savantURL if is_port_open?(@savantURL,"11263") @builder["dialogInstall"].show login = 'RPM' @password = 'RPM' result = '' result = '' Net::SSH.start(@savantURL, login, :password => @password, :paranoid => false) do |ssh| @builder["installStatus"].label += "\nUninstalling Launch Agents..." clear_events() result = ssh.exec!("launchctl unload /Users/RPM/Library/LaunchAgents/com.SCLI_HTTP.plist") result = ssh.exec!("launchctl unload /Users/RPM/Library/LaunchAgents/com.habridge.plist") @builder["installStatus"].label += result @builder["installStatus"].label += "Launch Agents uninstalled!\n\n" clear_events() sleep 3 ssh.open_channel do |ch, success| ch.request_pty do |ch, success| end @builder["installStatus"].label += "Uninstalling Java on Host...this might take a minute.\n" clear_events() ch.exec(%q{brew cask uninstall java}) do |ch, success| abort "could not execute command" unless success end ch.on_data do |ch, data| if data.to_s.include? "Password:" ch.send_data @password ch.send_data "\n" end if data.to_s.include? "RETURN" ch.send_data "\n" end if data.to_s.include? "java is not installed" @builder["installStatus"].label += "Java already uninstalled on Host.\n\n" clear_events() sleep 1 end if data.to_s.include? "Removing files: [" @builder["installStatus"].label += "Java uninstalled on Host.\n\n" clear_events() sleep 1 end end ch.on_extended_data do |ch, type, data| end ch.wait end ssh.loop ssh.open_channel do |ch, success| ch.request_pty do |ch, success| end @builder["installStatus"].label += "Uninstalling Homebrew on Host...this might take a minute.\n" clear_events() ch.exec(%q{ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"}) do |ch, success| abort "could not execute command" unless success end ch.on_data do |ch, data| if data.to_s.include? "Password:" ch.send_data @password ch.send_data "\n" end if data.to_s.include? "RETURN" ch.send_data "\n" end if data.to_s.include? "uninstall Homebrew? [y/N]" ch.send_data "y\n" end if data.to_s.include? "Failed to locate Homebrew!" @builder["installStatus"].label += "Homebrew already uninstalled on Host.\n\n" clear_events() sleep 3 end if data.to_s.include? "You may wish to remove them yourself." @builder["installStatus"].label += "Homebrew uninstalled on Host.\n\n" clear_events() sleep 3 end end ch.on_extended_data do |ch, type, data| @builder["installStatus"].label += "got stderr: #{data.inspect}" clear_events() end ch.wait end ssh.loop @builder["installStatus"].label += "\nRemoving Files..." clear_events() ssh.exec!("rm –Rf /Users/RPM/habridge/") ssh.exec!("rm -f /Users/RPM/habridge/com.habridge.plist /Users/RPM/Library/LaunchAgents/") ssh.exec!("rm -f /Users/RPM/habridge/com.SCLI_HTTP.plist /Users/RPM/Library/LaunchAgents/") @builder["installStatus"].label += "Files removed!\n\n" clear_events() @builder["installStatus"].label += "Uninstallation complete.\n\n" @builder["installStatus"].label += "To verify installation, test that the following URLs\nare no longer active.\n\nhttp://" + @savantURL + ":8888/\nhttp://" + @savantURL + ":12000/userzones\n" clear_events() @builder["installStatus"].label += "\nWould you like to open these URLs in a browser now?" @builder["buttonInstallOK"].visible = true @builder["buttonInstallCancel"].visible = true clear_events() end else alert "Racepoint services not running at specified IP Address. Target for installation must be a Savant Pro Host." end else alert "Invalid IP Address." end end ##### Close window ##### def buttonHelpCancel__clicked(*argv) @builder["dialogHelp"].hide end ##### Launch HABridge and SCLIbridge in browser and close installation status window ##### def buttonInstallOK__clicked(*argv) @builder["installStatus"].label = "" @builder["buttonInstallOK"].visible = false @builder["buttonInstallCancel"].visible = false @builder["dialogInstall"].hide system("open http://" + @savantURL + ":8888") system("open http://" + @savantURL + ":12000/userzones") end ##### Close installation status window ##### def buttonInstallCancel__clicked(*argv) @builder["buttonInstallOK"].visible = false @builder["buttonInstallCancel"].visible = false @builder["installStatus"].label = "" @builder["dialogInstall"].hide end ##### ##### ##### Zone request only toggle buttons ##### ##### ##### ##### Toggle On Request to/from Zone only ##### def buttonOnZoneOnly__clicked(*argv) if @builder["buttonOnZoneOnly"].active? @savantRequestOn = @builder["savantRequestOn"].text if !@savantRequestOn.empty? zoneOnlyOnArray = @savantRequestOn.split('-') zoneOnlyOnArray.fill('',1,4) @builder["savantRequestOn"].text = zoneOnlyOnArray.join('-') end else @builder["savantRequestOn"].text = @savantRequestOn end end ##### Toggle Off Request to/from Zone only ##### def buttonOffZoneOnly__clicked(*argv) if @builder["buttonOffZoneOnly"].active? @savantRequestOff = @builder["savantRequestOff"].text if !@savantRequestOff.empty? zoneOfflyOffArray = @savantRequestOff.split('-') zoneOfflyOffArray.fill('',1,4) @builder["savantRequestOff"].text = zoneOfflyOffArray.join('-') end else @builder["savantRequestOff"].text = @savantRequestOff end end ##### Toggle Dim Request to/from Zone only ##### def buttonDimZoneOnly__clicked(*argv) if @builder["buttonDimZoneOnly"].active? @savantRequestDim = @builder["savantRequestDim"].text if !@savantRequestDim.empty? zoneDimlyDimArray = @savantRequestDim.split('-') zoneDimlyDimArray.fill('',1,4) @builder["savantRequestDim"].text = zoneDimlyDimArray.join('-') end else @builder["savantRequestDim"].text = @savantRequestDim end end ##### ##### ##### Add command(s) to HA Bridge, first parsing for errors and needed parameters ##### ##### ##### def buttonAdd__clicked(*argv) get_glade_variables() #Error checking for empty fields and non-compliant workflows @error = nil errorCount = 0 #Check for valid Host IP and build bridge strings if @savantURL.to_s.empty? @error = "Missing Savant Host URL" elsif !(IPAddress.valid? @savantURL) @error = "Invalid URL" else @haURLstr = "http://" + @savantURL + ":8888/api/devices" @savantURLstr = "http://" + @savantURL + ":12000" end #Check for device name entry if @error.nil? && @haName.to_s.empty? @error = "Missing Device Name" end #Check for HA bridge online at specified IP if @habridgeStatus != "Online" @error = "HA Bridge Not Online" end #Proceed if no errors if @error.nil? #Check for empty On entry, create empty array if so, and count to make sure at least one entry is present if @savantRequestOn.to_s.empty? @requestOnArray = [] errorCount += 1 elsif @savantRequestOn.to_s.include?(":") || @savantRequestOn.to_s.include?("-") #Split off main service request from arguments if they exist @requestOnArray = @savantRequestOn.split(/:/) #Add escapes and formatting to pass through JSON to Ha Bridge @requestOnCmd = @requestOnArray.shift.gsub!(/[- ']/, '-' => '\\\'-\\\'', ' ' => '%20') @strRequestOn = %q{'onUrl' : '} + @savantURLstr + %q{/servicerequestcommand%20\'} + @requestOnCmd + %q{\'} else @error = "Not a valid On workflow." end #Repeat for off if @savantRequestOff.to_s.empty? @requestOffArray = [] errorCount += 1 elsif @savantRequestOff.to_s.include?(":") || @savantRequestOff.to_s.include?("-") @requestOffArray = @savantRequestOff.split(/:/) @requestOffCmd = @requestOffArray.shift.gsub!(/[- ']/, '-' => '\\\'-\\\'', ' ' => '%20') @strRequestOff = %q{'offUrl' : '} + @savantURLstr + %q{/servicerequestcommand%20\'} + @requestOffCmd + %q{\'} else @error = "Not a valid Off workflow." end #Repeat for dim if @savantRequestDim.to_s.empty? @requestDimArray = [] errorCount += 1 elsif @savantRequestDim.to_s.include?(":") || @savantRequestDim.to_s.include?("-") @requestDimArray = @savantRequestDim.split(/:/) @requestDimCmd = @requestDimArray.shift.gsub!(/[- ']/, '-' => '\\\'-\\\'', ' ' => '%20') @strRequestDim = %q{'dimUrl' : '} + @savantURLstr + %q{/servicerequestcommand%20\'} + @requestDimCmd + %q{\'} else @error = "Not a valid Dim workflow." end if errorCount == 3 @error = "You must enter at least one command to proceed." end end #Proceed as long as there is one valid command if @error.nil? #Checks to see how many action arguments are in the On 3rd party workflow, saves the Argument names to display on the UI #and hides ones that are not needed from appearing on the popup dialog. if @requestOnArray.length >= 1 @requestOnComplex = 1 requestOnArgs = @requestOnArray.shift.split(',') @requestOnArg1 = requestOnArgs.shift.chop if requestOnArgs.length > 0 @requestOnArg2 = requestOnArgs.shift.chop @builder["frameOnArg2"].visible = true else @builder["frameOnArg2"].visible = false @requestOnValue2 = nil end if requestOnArgs.length > 0 @requestOnArg3 = requestOnArgs.shift.chop @builder["frameOnArg3"].visible = true else @builder["frameOnArg3"].visible = false @requestOnValue3 = nil end if requestOnArgs.length > 0 @requestOnArg4 = requestOnArgs.shift.chop @builder["frameOnArg4"].visible = true else @builder["frameOnArg4"].visible = false @requestOnValue4 = nil end if requestOnArgs.length > 0 @requestOnArg5 = requestOnArgs.shift.chop @builder["frameOnArg5"].visible = true else @builder["frameOnArg5"].visible = false @requestOnValue5 = nil end if requestOnArgs.length > 0 @requestOnArg6 = requestOnArgs.shift.chop @builder["frameOnArg6"].visible = true else @builder["frameOnArg6"].visible = false @requestOnValue6 = nil end if requestOnArgs.length > 0 @requestOnArg7 = requestOnArgs.shift.chop @builder["frameOnArg7"].visible = true else @builder["frameOnArg7"].visible = false @requestOnValue7 = nil end if requestOnArgs.length > 0 @requestOnArg8 = requestOnArgs.shift.chop @builder["frameOnArg8"].visible = true else @builder["frameOnArg8"].visible = false @requestOnValue8 = nil end if requestOnArgs.length > 0 @requestOnArg9 = requestOnArgs.shift.chop @builder["frameOnArg9"].visible = true else @builder["frameOnArg9"].visible = false @requestOnValue9 = nil end else #Add JSON quote terminator is string is not empty if !@savantRequestOn.to_s.empty? @strRequestOn += %q{'} end @requestOnComplex = 0 end #Repeat for Off if @requestOffArray.length >= 1 @requestOffComplex = 1 requestOffArgs = @requestOffArray.shift.split(',') @requestOffArg1 = requestOffArgs.shift.chop if requestOffArgs.length > 0 @requestOffArg2 = requestOffArgs.shift.chop @builder["frameOffArg2"].visible = true else @builder["frameOffArg2"].visible = false @requestOffValue2 = nil end if requestOffArgs.length > 0 @requestOffArg3 = requestOffArgs.shift.chop @builder["frameOffArg3"].visible = true else @builder["frameOffArg3"].visible = false @requestOffValue3 = nil end if requestOffArgs.length > 0 @requestOffArg4 = requestOffArgs.shift.chop @builder["frameOffArg4"].visible = true else @builder["frameOffArg4"].visible = false @requestOffValue4 = nil end if requestOffArgs.length > 0 @requestOffArg5 = requestOffArgs.shift.chop @builder["frameOffArg5"].visible = true else @builder["frameOffArg5"].visible = false @requestOffValue5 = nil end if requestOffArgs.length > 0 @requestOffArg6 = requestOffArgs.shift.chop @builder["frameOffArg6"].visible = true else @builder["frameOffArg6"].visible = false @requestOffValue6 = nil end if requestOffArgs.length > 0 @requestOffArg7 = requestOffArgs.shift.chop @builder["frameOffArg7"].visible = true else @builder["frameOffArg7"].visible = false @requestOffValue7 = nil end if requestOffArgs.length > 0 @requestOffArg8 = requestOffArgs.shift.chop @builder["frameOffArg8"].visible = true else @builder["frameOffArg8"].visible = false @requestOffValue8 = nil end if requestOffArgs.length > 0 @requestOffArg9 = requestOffArgs.shift.chop @builder["frameOffArg9"].visible = true else @builder["frameOffArg9"].visible = false @requestOffValue9 = nil end else @requestOffComplex = 0 if !@savantRequestOff.to_s.empty? @strRequestOff += %q{'} end end #Repeat for Dim if @requestDimArray.length >= 1 @requestDimComplex = 1 requestDimArgs = @requestDimArray.shift.split(',') @requestDimArg1 = requestDimArgs.shift.chop if requestDimArgs.length > 0 @requestDimArg2 = requestDimArgs.shift.chop @builder["frameDimArg2"].visible = true else @builder["frameDimArg2"].visible = false @requestDimValue2 = nil end if requestDimArgs.length > 0 @requestDimArg3 = requestDimArgs.shift.chop @builder["frameDimArg3"].visible = true else @builder["frameDimArg3"].visible = false @requestDimValue3 = nil end if requestDimArgs.length > 0 @requestDimArg4 = requestDimArgs.shift.chop @builder["frameDimArg4"].visible = true else @builder["frameDimArg4"].visible = false @requestDimValue4 = nil end if requestDimArgs.length > 0 @requestDimArg5 = requestDimArgs.shift.chop @builder["frameDimArg5"].visible = true else @builder["frameDimArg5"].visible = false @requestDimValue5 = nil end if requestDimArgs.length > 0 @requestDimArg6 = requestDimArgs.shift.chop @builder["frameDimArg6"].visible = true else @builder["frameDimArg6"].visible = false @requestDimValue6 = nil end if requestDimArgs.length > 0 @requestDimArg7 = requestDimArgs.shift.chop @builder["frameDimArg7"].visible = true else @builder["frameDimArg7"].visible = false @requestDimValue7 = nil end if requestDimArgs.length > 0 @requestDimArg8 = requestDimArgs.shift.chop @builder["frameDimArg8"].visible = true else @builder["frameDimArg8"].visible = false @requestDimValue8 = nil end if requestDimArgs.length > 0 @requestDimArg9 = requestDimArgs.shift.chop @builder["frameDimArg9"].visible = true else @builder["frameDimArg9"].visible = false @requestDimValue9 = nil end else @requestDimComplex = 0 if !@savantRequestDim.to_s.empty? @strRequestDim += %q{'} end end #Set all variables to UI before showing next window set_glade_variables() #Shows popup dialog for action argument value entry if needed, else finishes building the string and sends it to the HA Bridge. if @requestOnComplex == 1 @builder["dialogOn"].show elsif @requestOffComplex == 1 @builder["dialogOff"].show elsif @requestDimComplex == 1 @builder["dialogDim"].show else sendHaRequest() end else #If any errors were found, alert user. alert @error end end ##### Exit main program ##### def buttonExit__clicked(*args) @builder["window1"].destroy end ##### ##### ##### Action argument windows ##### ##### ##### #For each On parameter field that is possible, check if user entered value, percent, or number, and push into arg/val array. def buttonAcceptOn__clicked(*argv) get_glade_variables() if @requestOnValue1 == 'percent' @requestOnValue1 = '${intensity.percent}' elsif @requestOnValue1 == 'number' @requestOnValue1 = '${intensity.byte}' end requestOnValues = [@requestOnArg1, @requestOnValue1] unless @requestOnArg2.nil? if @requestOnValue2 == 'percent' @requestOnValue2 = '${intensity.percent}' elsif @requestOnValue2 == 'number' @requestOnValue2 = '${intensity.byte}' end requestOnValues.push(@requestOnArg2) requestOnValues.push(@requestOnValue2) end unless @requestOnArg3.nil? if @requestOnValue3 == 'percent' @requestOnValue3 = '${intensity.percent}' elsif @requestOnValue3 == 'number' @requestOnValue3 = '${intensity.byte}' end requestOnValues.push(@requestOnArg3) requestOnValues.push(@requestOnValue3) end unless @requestOnArg4.nil? if @requestOnValue4 == 'percent' @requestOnValue4 = '${intensity.percent}' elsif @requestOnValue4 == 'number' @requestOnValue4 = '${intensity.byte}' end requestOnValues.push(@requestOnArg4) requestOnValues.push(@requestOnValue4) end unless @requestOnArg5.nil? if @requestOnValue5 == 'percent' @requestOnValue5 = '${intensity.percent}' elsif @requestOnValue5 == 'number' @requestOnValue5 = '${intensity.byte}' end requestOnValues.push(@requestOnArg5) requestOnValues.push(@requestOnValue5) end unless @requestOnArg6.nil? if @requestOnValue6 == 'percent' @requestOnValue6 = '${intensity.percent}' elsif @requestOnValue6 == 'number' @requestOnValue6 = '${intensity.byte}' end requestOnValues.push(@requestOnArg6) requestOnValues.push(@requestOnValue6) end unless @requestOnArg7.nil? if @requestOnValue7 == 'percent' @requestOnValue7 = '${intensity.percent}' elsif @requestOnValue7 == 'number' @requestOnValue7 = '${intensity.byte}' end requestOnValues.push(@requestOnArg7) requestOnValues.push(@requestOnValue7) end unless @requestOnArg8.nil? if @requestOnValue8 == 'percent' @requestOnValue8 = '${intensity.percent}' elsif @requestOnValue8 == 'number' @requestOnValue8 = '${intensity.byte}' end requestOnValues.push(@requestOnArg8) requestOnValues.push(@requestOnValue8) end unless @requestOnArg9.nil? if @requestOnValue9 == 'percent' @requestOnValue9 = '${intensity.percent}' elsif @requestOnValue9 == 'number' @requestOnValue9 = '${intensity.byte}' end requestOnValues.push(@requestOnArg9) requestOnValues.push(@requestOnValue9) end #Create On request string by joining each arg/val from array with proper JSON syntax @strRequestOn += '%20\\\'' + requestOnValues.join('\\\'%20\\\'') + '\\\'' @strRequestOn += %q{'} #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. @builder["dialogOn"].hide if @requestOffComplex == 0 && @requestDimComplex == 0 sendHaRequest() elsif @requestOffComplex == 1 @builder["dialogOff"].show elsif @requestDimComplex == 1 @builder["dialogDim"].show end end def buttonCancelOn__clicked(*args) @builder["dialogOn"].hide end ##### Repeat for off ##### def buttonAcceptOff__clicked(*argv) get_glade_variables() if @requestOffValue1 == 'percent' @requestOffValue1 = '${intensity.percent}' elsif @requestOffValue1 == 'number' @requestOffValue1 = '${intensity.byte}' end requestOffValues = [@requestOffArg1, @requestOffValue1] unless @requestOffArg2.nil? if @requestOffValue2 == 'percent' @requestOffValue2 = '${intensity.percent}' elsif @requestOffValue2 == 'number' @requestOffValue2 = '${intensity.byte}' end requestOffValues.push(@requestOffArg2) requestOffValues.push(@requestOffValue2) end unless @requestOffArg3.nil? if @requestOffValue3 == 'percent' @requestOffValue3 = '${intensity.percent}' elsif @requestOffValue3 == 'number' @requestOffValue3 = '${intensity.byte}' end requestOffValues.push(@requestOffArg3) requestOffValues.push(@requestOffValue3) end unless @requestOffArg4.nil? if @requestOffValue4 == 'percent' @requestOffValue4 = '${intensity.percent}' elsif @requestOffValue4 == 'number' @requestOffValue4 = '${intensity.byte}' end requestOffValues.push(@requestOffArg4) requestOffValues.push(@requestOffValue4) end unless @requestOffArg5.nil? if @requestOffValue5 == 'percent' @requestOffValue5 = '${intensity.percent}' elsif @requestOffValue5 == 'number' @requestOffValue5 = '${intensity.byte}' end requestOffValues.push(@requestOffArg5) requestOffValues.push(@requestOffValue5) end unless @requestOffArg6.nil? if @requestOffValue6 == 'percent' @requestOffValue6 = '${intensity.percent}' elsif @requestOffValue6 == 'number' @requestOffValue6 = '${intensity.byte}' end requestOffValues.push(@requestOffArg6) requestOffValues.push(@requestOffValue6) end unless @requestOffArg7.nil? if @requestOffValue7 == 'percent' @requestOffValue7 = '${intensity.percent}' elsif @requestOffValue7 == 'number' @requestOffValue7 = '${intensity.byte}' end requestOffValues.push(@requestOffArg7) requestOffValues.push(@requestOffValue7) end unless @requestOffArg8.nil? if @requestOffValue8 == 'percent' @requestOffValue8 = '${intensity.percent}' elsif @requestOffValue8 == 'number' @requestOffValue8 = '${intensity.byte}' end requestOffValues.push(@requestOffArg8) requestOffValues.push(@requestOffValue8) end unless @requestOffArg9.nil? if @requestOffValue9 == 'percent' @requestOffValue9 = '${intensity.percent}' elsif @requestOffValue9 == 'number' @requestOffValue9 = '${intensity.byte}' end requestOffValues.push(@requestOffArg9) requestOffValues.push(@requestOffValue9) end @strRequestOff += '%20\\\'' + requestOffValues.join('\\\'%20\\\'') + '\\\'' @strRequestOff += %q{'} @builder["dialogOff"].hide if @requestDimComplex == 1 @builder["dialogDim"].show else sendHaRequest() end end ##### Close window ##### def buttonCancelOff__clicked(*args) @builder["dialogOff"].hide end ##### Repeat for Dim ##### def buttonAcceptDim__clicked(*argv) get_glade_variables() if @requestDimValue1 == 'percent' @requestDimValue1 = '${intensity.percent}' elsif @requestDimValue1 == 'number' @requestDimValue1 = '${intensity.byte}' end requestDimValues = [@requestDimArg1, @requestDimValue1] unless @requestDimArg2.nil? if @requestDimValue2 == 'percent' @requestDimValue2 = '${intensity.percent}' elsif @requestDimValue2 == 'number' @requestDimValue2 = '${intensity.byte}' end requestDimValues.push(@requestDimArg2) requestDimValues.push(@requestDimValue2) end unless @requestDimArg3.nil? if @requestDimValue3 == 'percent' @requestDimValue3 = '${intensity.percent}' elsif @requestDimValue3 == 'number' @requestDimValue3 = '${intensity.byte}' end requestDimValues.push(@requestDimArg3) requestDimValues.push(@requestDimValue3) end unless @requestDimArg4.nil? if @requestDimValue4 == 'percent' @requestDimValue4 = '${intensity.percent}' elsif @requestDimValue4 == 'number' @requestDimValue4 = '${intensity.byte}' end requestDimValues.push(@requestDimArg4) requestDimValues.push(@requestDimValue4) end unless @requestDimArg5.nil? if @requestDimValue5 == 'percent' @requestDimValue5 = '${intensity.percent}' elsif @requestDimValue5 == 'number' @requestDimValue5 = '${intensity.byte}' end requestDimValues.push(@requestDimArg5) requestDimValues.push(@requestDimValue5) end unless @requestDimArg6.nil? if @requestDimValue6 == 'percent' @requestDimValue6 = '${intensity.percent}' elsif @requestDimValue6 == 'number' @requestDimValue6 = '${intensity.byte}' end requestDimValues.push(@requestDimArg6) requestDimValues.push(@requestDimValue6) end unless @requestDimArg7.nil? if @requestDimValue7 == 'percent' @requestDimValue7 = '${intensity.percent}' elsif @requestDimValue7 == 'number' @requestDimValue7 = '${intensity.byte}' end requestDimValues.push(@requestDimArg7) requestDimValues.push(@requestDimValue7) end unless @requestDimArg8.nil? if @requestDimValue8 == 'percent' @requestDimValue8 = '${intensity.percent}' elsif @requestDimValue8 == 'number' @requestDimValue8 = '${intensity.byte}' end requestDimValues.push(@requestDimArg8) requestDimValues.push(@requestDimValue8) end unless @requestDimArg9.nil? if @requestDimValue9 == 'percent' @requestDimValue9 = '${intensity.percent}' elsif @requestDimValue9 == 'number' @requestDimValue9 = '${intensity.byte}' end requestDimValues.push(@requestDimArg9) requestDimValues.push(@requestDimValue9) end @strRequestDim += '%20\\\'' + requestDimValues.join('\\\'%20\\\'') + '\\\'' @strRequestDim += %q{'} @builder["dialogDim"].hide sendHaRequest() end ##### Close window ##### def buttonCancelDim__clicked(*args) @builder["dialogDim"].hide end ##### ##### ##### Send commands to HA Bridge ##### ##### ##### def sendHaRequest #Build JSON string of On, Off, and Dim commands, if they exist. @haRequest = %q{\{'name' : '} + @haName + %q{','deviceType' : 'custom',} if !@strRequestOn.empty? @haRequest += @strRequestOn end if !@strRequestOff.empty? if !@strRequestOn.empty? @haRequest += ',' end @haRequest += @strRequestOff end if !@strRequestDim.empty? if (!@strRequestOn.empty? || !@strRequestOff.empty?) @haRequest += ',' end @haRequest += @strRequestDim end @haRequest += %q{\}} #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 #Send JSON string to specified host IP. Alert user of any errors or success. uri = URI.parse(@haURLstr) begin http = Net::HTTP.start(uri.host, uri.port, {open_timeout: 3, read_timeout: 3}) begin request = Net::HTTP::Post.new( uri.request_uri, 'Content-Type' => 'application/json' ) request.body = @haRequest response = http.request(request) if response.code == "201" alert 'Command successfully added to HA Bridge.' elsif response.code.include?("4" || "5") alert 'Command failed to be added to HA Bridge.' end rescue Timeout::Error, SocketError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED alert "Unable to reach host." end rescue Timeout::Error, SocketError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED alert "Unable to reach host." end #Reset variables for next command, preserving host IP @savantRequestOn = '' @savantRequestOff = '' @savantRequestDim = '' @strRequestOn = '' @strRequestOff = '' @strRequestDim = '' @requestOnValue1 = "percent" @requestOnValue2 = "percent" @requestOnValue3 = "percent" @requestOnValue4 = "percent" @requestOnValue5 = "percent" @requestOnValue6 = "percent" @requestOnValue7 = "percent" @requestOnValue8 = "percent" @requestOnValue9 = "percent" @requestOffValue1 = "percent" @requestOffValue2 = "percent" @requestOffValue3 = "percent" @requestOffValue4 = "percent" @requestOffValue5 = "percent" @requestOffValue6 = "percent" @requestOffValue7 = "percent" @requestOffValue8 = "percent" @requestOffValue9 = "percent" @requestDimValue1 = "percent" @requestDimValue2 = "percent" @requestDimValue3 = "percent" @requestDimValue4 = "percent" @requestDimValue5 = "percent" @requestDimValue6 = "percent" @requestDimValue7 = "percent" @requestDimValue8 = "percent" @requestDimValue9 = "percent" end end