#!/bin/ruby # Script to log information from my Qwest Century-Link # Actiontek PK5000 modem. # Every 10 seconds this gets data via the web interface. # # Tom Trebisky 5-29-2013 # # The Web interface shows two status fields that directly # mimic the lights on the modem. So if you are too lazy # (I mean, it is too inconvenient) to physically look at # the modem if you have them on the phone, here is how it # goes: # # Look at "Connection Status" section at the top of the # Connection Status or WAN Status page. # When all is well there are two green fields that say "CONNECTED". # # The top field (Qwest Broadband) corresponds to the "DSL" light. # The second field (Internet Service Provider (ISP)) # corresponds to the "Internet" light. # # When either field is red "NOT CONNECTED" that is the same as the light off. # When either field is yellow "CONNECTING" that is the same as the light blinking. # When either field is green "CONNECTED" that is the same as the light on steady. # # The normal sequence is that we start with both lights off. # Then the top light blinks, and eventually goes on solid. # Then the second light blinks, and eventually goes on solid. # -------------------------------- # Here are some variables you may need to tailor to your # specific setup $log_file = "/home/tom/bin/modem.log" $modem_host = "192.168.0.1" $debug = false $noisy = false # You should not need to fiddle below here. ----- # ----------------------------------------------- $wan_file = "wan_status.html" # This file actually in turn fetches two others #$stat_file0 = "status.html" #$stat_file1 = "status_hide.html" #$stat_file2 = "modemstatus_real.html" $stat_file = "modemstatus_real.html" def log ( msg ) ts = `date`.chomp lmsg = "#{ts} #{msg}\n" print lmsg if $noisy return if $debug File.open($log_file,"a") { |f| f.print lmsg } end def getmodem ( file ) url = "http://#{$modem_host}/cgi-bin/webcm?getpage=../html/#{file}" cmd = "curl -s --connect-timeout 8 -m 16 -o #{file} #{url}" system cmd end def proc_line ( l ) rv = l.chomp rv.gsub! /.*\("/, '' rv.gsub! /"\).*/, '' #rv.gsub! /&#..;/, '' rv.gsub! /</, '<' rv.gsub! />/, '>' rv.gsub! /<[^>]+>/, '' rv end def proc_inner ( l ) rv = l.chomp rv.gsub! /.*= "/, '' rv.gsub! /";.*/, '' rv.gsub! /<[^>]+>/, '' rv end def proc_rate ( l ) rv = l.chomp rv.gsub! /<[^>]+>/, '' rv.gsub! /.*Rate:\s*/, '' rv.gsub! /\s*Kbps.*/, '' rv end def process ( wfile, sfile ) con = "----" isp = "----" uptime = "?" ipaddr = nil up = "0" down = "0" File.new(wfile).each_line { |l| if l =~ /var con_state/ con = proc_line l end if l =~ /var isp_status/ isp = proc_line l end if l =~ /getElementById.*sts2_pppuptime/ uptime = proc_inner l end } File.new(sfile).each_line { |l| if l =~ /getElementById.*WAN_IPaddress/ unless ipaddr v = proc_inner l ipaddr = v if v != "" end end if l =~ /Downstream/ down = proc_rate l end if l =~ /Upstream/ up = proc_rate l end } ipaddr = "0.0.0.0" unless ipaddr log "#{con} #{isp} #{uptime} (#{ipaddr}) #{down}/#{up} Kbps" end def probe_once unless system "ping -q -c 1 -W 2 #{$modem_host} > /dev/null" log "Cannot reach modem" return end unless getmodem $wan_file log "Failed to get WAN status" return end unless getmodem $stat_file log "Failed to get MODEM status" return end process $wan_file, $stat_file end if $debug probe_once exit end loop { probe_once sleep 10.0 } # THE END