Home Automation - Chapter 4

Internet Restore

In this chapter I’ll introduce a new library but let’s see the whole ‘modules/internet_restore.rb’ code first.

#!/usr/bin/env ruby

# Libraries

require 'pry'
require 'logger'
require 'watir'

# Credentials

ROUTER_U = ENV['router_user']
ROUTER_P = ENV['router_pass']

# Logger settings

logger = Logger.new(STDOUT)
logger.level = Logger::INFO
logger.datetime_format = '%Y-%m-%d %H:%M:%S'

logger.info("Internet Restore --> Engaged!")

# The next code is developed for TL-WR740N, not tested on other models.
# It will probably not work but the idea should be the same.

browser = Watir::Browser.new :chrome
browser.goto("http://192.168.0.1")

logger.info("Internet Restore --> Router #{browser.title} detected!")

browser.input(id: "userName").text_field(id: "userName").set "#{ROUTER_U}" # input username
browser.input(id: "pcPassword").text_field(id: "pcPassword").set "#{ROUTER_P}" # input username
browser.label(id: "loginBtn").click # click the login button

# Unfortunately this won't work:
# dyn_string = browser.url.match(/192.168.0.1\/(.*)\/userRpm\/Index.htm/)[1]  # match the URL dynamic string
# browser.goto("http://192.168.0.1/#{dyn_string}/userRpm/DateTimeCfgRpm.htm")
# browser.goto("http://192.168.0.1/#{dyn_string}/userRpm/SysRebootRpm.htm")
# I'll have to match and click or I'll get this nasty message: "You have no authority to access this router!"

browser.frameset.frame(name: "bottomLeftFrame").body.a(id: "a48").click # Click on "System Tools"
browser.frameset.frame(name: "bottomLeftFrame").body.a(id: "a54").click # Click on "System Tools -> Reboot"
browser.frameset.frame(name: "mainFrame").body.input(name: "Reboot").click # Click the Reboot button
browser.alert.ok # hit OK to reboot the router !

The new library I’ll be using is called Watir. You can find more information about it here. I love this project! It saved me so much time when I need to do something with a web page. It’s using the ‘selenium-webdriver’ gem under the hood. You can find this information by looking at Watir’s Gemfile which is available on Github.

Now back to the code of my Internet restore module. You’ll notice that I’m again using environment variables to pass credentials and I have my logger library in place and configured. I explained those in the earlier chapters so I won’t go over them again. Instead I’ll start with the Watir initialization method.

browser = Watir::Browser.new :chrome

I’m opening a new browser which you’ll see as soon as you fire this method. Try it in irb in this way:

$ irb
2.4.1 :001 > require 'watir'
 => true 
2.4.1 :002 > browser = Watir::Browser.new :chrome
 => #<Watir::Browser:0x..fe2290274647243a4 url="data:," title=""> 
2.4.1 :003 >

As soon as you do a Chrome browser will popup. If not you’ll be given specific instruction how to install the Chrome Drive that is required. The nice thing about it is that you can interact with it and inspect pages. If you need to run this code in batch mode you can switch to phantomjs which is a headless browser. You’ll need the phantomjs binary in your $PATH variable and then you can do this:

browser = Watir::Browser.new :phantomjs

Easy, isn’t it? That’s what I love about Watir - it can run in both interactive & batch modes with a simple switch.

Go over the rest of the code and read my notes after each line. You’ll see that I’m actually interacting with the webpage code and I’m triggering click (using the method .click) on certain pages. That could be very tricky because you’ll need to know the exact iframe the page is using, exact position of a button and stuff like that. That’s why I’m using the Chrome to find those and I’m also debugging in ‘pry’ by calling ‘binding.pry’ on interesting places where I want to work on.

You’ll probably wander about the commented code:

# Unfortunately this won't work:
# dyn_string = browser.url.match(/192.168.0.1\/(.*)\/userRpm\/Index.htm/)[1]  # match the URL dynamic string
# browser.goto("http://192.168.0.1/#{dyn_string}/userRpm/DateTimeCfgRpm.htm")
# browser.goto("http://192.168.0.1/#{dyn_string}/userRpm/SysRebootRpm.htm")
# I'll have to match and click or I'll get this nasty message: "You have no authority to access this router!"

That serves no other purpose but to illustrate what I initially had in mind when I noticed that my router is providing me with a hash string in the URI. I tried to leverage it because I knew where I want to go. The problem was that when I use the ‘.goto’ Watir method directly the router prints a security error. I have to run through all the javascript checks so I ended using Watir to click on the links just like I would normally do.

So that’s all. Thank you for reading and drop me an e-mail if you have questions or you find yourself in an interesting situation where you’re struggling with the same things I did.

The whole code of my Home Automation project is available on Github.

Home Automation - Chapter 1

Home Automation - Chapter 2

Home Automation - Chapter 3

Home Automation - Chapter 4

Categories:

Updated: