I've recently had to make a number of changes to my Internet connection (local cable company). More specifically, I've had to trade in the old reliable hulk of a modem I originally signed up with for a sleek new Motorola SURFboard due to service upgrades. The new modem is far less tolerant of the poor cable connection that brings the world to my door, and it's been the source of many help desk calls and now quite a few installer visits to locate problems in the cable.
It was during one of these frustrating moments that I googled the modem and discovered it has a built in web interface complete with status page of signal strength conditions. As I was explaining to the help desk person (again) about my loss of Internet, he explained that the modem's signal condition was logged at the office and indeed the modem had reset several thousand times during the last few days (you'd think they would be calling me!). That's when it hit me. Rather than waiting for my Internet service to die without explanation, I could actively monitor the modem for signs of life and get someone looking into the problem before it got so bad that I would have to spend hours (or days) waiting for the 'cable guy' to show up and fix it.
Thus was born modem.pl.
Now when my modem starts getting twitchy, I get an email which is my cue to call the help desk and get somebody working on it, usually before it gets so bad as to cause an Internet outage. I've also got a log file I can refer to which tells me exactly when things started going bad. The only thing sweeter would be to have the cable company do their own monitoring so the cable guy could be waiting at the door before I have to call. But that's beyond Perl's abilities, or is it? ;)
Update: tweaked expression matching for the SB5100E model. Cleaned up commments a little.
Update: Didn't quite get the SB5100E model right first time around :(.
It was during one of these frustrating moments that I googled the modem and discovered it has a built in web interface complete with status page of signal strength conditions. As I was explaining to the help desk person (again) about my loss of Internet, he explained that the modem's signal condition was logged at the office and indeed the modem had reset several thousand times during the last few days (you'd think they would be calling me!). That's when it hit me. Rather than waiting for my Internet service to die without explanation, I could actively monitor the modem for signs of life and get someone looking into the problem before it got so bad that I would have to spend hours (or days) waiting for the 'cable guy' to show up and fix it.
Thus was born modem.pl.
Now when my modem starts getting twitchy, I get an email which is my cue to call the help desk and get somebody working on it, usually before it gets so bad as to cause an Internet outage. I've also got a log file I can refer to which tells me exactly when things started going bad. The only thing sweeter would be to have the cable company do their own monitoring so the cable guy could be waiting at the door before I have to call. But that's beyond Perl's abilities, or is it? ;)
Update: tweaked expression matching for the SB5100E model. Cleaned up commments a little.
Update: Didn't quite get the SB5100E model right first time around :(.
This script is dog simple. It scrapes the modem's status page for the various signal strength values then outputs one line with the 3 most useful values. I have a cron job setup to run it every 5 minutes piping the output to the end of a log file. If there's a problem getting the values, or the values are outside reasonable operating conditions, the output is also sent to STDERR (warning or die) causing the cronjob to email root (or whoever gets notice of cron messages) with the error. I expect most modern cable modems have similar web interfaces and the code could probably be adapted to other brands/models as well.
I'd really appreciate any and all comments regarding this code. Errors, style, faster, smaller, it's all up for criticism.
I'd really appreciate any and all comments regarding this code. Errors, style, faster, smaller, it's all up for criticism.
#!/usr/bin/perl # # modem.pl - Report the status a Motorola 'SURFboard' cable modem # (models: SB5101, SB5100E) # # copyright(C) 2007 Scott Mazur <scott.AT.littlefish.ca> # GNU General Public License # -------------------------------------------------------------------- # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, # Boston, MA 02111-1307 USA # requires: # Time::Local; # LWP::Simple; my $ver = '0.11'; # Version 0.11 # - now handles SB5100E model as well # The Motorola 'SURFboard' cable modem includes a built in web # interface that contains useful information like signal to noise # ratios and power levels. # # This script uses LWP:Simple to scrape the status page from the # modem and report the most useful information in a single line: # Down power, Signal to Noise, Up power # # If the script is not running interactively (like say from a cron # job) the output line is prefixed with a standard log time stamp # and Errors/warnings are duplicated to STDOUT and STDERR. This # is so that cron jobs can report errors while still sending # output to a log file use strict; use warnings; use Time::Local; use LWP::Simple; use constant SB5101_URL => 'http://192.168.100.1/RgSignal.asp'; use constant SB5100E_URL => 'http://192.168.100.1/signaldata.html'; # are we running from a shell or maybe crond? use constant I_am_interactive => (-t STDIN and -t STDOUT); # format current time into standard system log file format my $tm_str = localtime; $tm_str = sprintf("$1 % 2d $3", $2) if $tm_str =~ m/^\S+\s+(\S+)\s+(\S+)\s+(\S+)/; # print message in addition to die unless interactive # This lets you pipe STDOUT to a file yet still get # a message on the console (or from cron) sub My_Die { my $msg = shift; print "$tm_str $msg\n" unless I_am_interactive; die "$msg\n"; } # main script ############# # get the modem status page my $content = get(SB5101_URL) || get(SB5100E_URL) || My_Die("Couldn't get modem signal page!"); # clean up the html a bit for parsing $content =~ s/\n//g; # drop new lines $content =~ s!</?t[dr]>! !ig; # strip table tags $content =~ s/\s\s+/ /g; # reduce double spaces # check that the page has what we expect $content =~ m{ Frequency \s (\d+\s Hz) \s (Locked\s)? Signal \s To \s Noise \s Ratio \s ([\d.]+\s dB) \s Power \s Level \s ([\d.-]+\s dBmV) }xi or My_Die('content failed!'); # build a hash of signal strength values my %results = ( DownStream => {freq => $1, sn => $3, power => $4}, UpStream => {channel => '?', freq => '? Hz', power => '0 dBmV'} ); # get the upstream values $results{UpStream} = {channel => $1, freq => $2, power => $5} if $content =~ m/ID (\d+) Frequency (\d+ Hz)( Ranged)? Power( Leve +l)? ([\d.-]+ dBmV)/i; # create the result message my $msg = "Down Power: $results{DownStream}->{power}" . " S/N: $results{DownStream}->{sn}" . " Up Power: $results{UpStream}->{power}"; # check up power for reasonable range my $power = $results{UpStream}->{power}; # strip down to raw number my ($stripped) = $power =~ m/^([\d.-]+)/; my $status = ''; $status = 'Up Power high!' if $stripped > 54; $status = 'Up Power low!' if $stripped < 36; # better call the cable guy! if ($status) { warn "$status $power\n"; $msg .= " warning: $status"; } # check down power for reasonable range $power = $results{DownStream}->{power}; # strip down to raw number ($stripped) = $power =~ m/^([\d.-]+)/; $status = ''; $status = 'Down Power high!' if $stripped > 10; $status = 'Down Power low!' if $stripped < -10; # not good either! if ($status) { warn "$status $power\n"; $msg .= " warning: $status"; } $msg = "$tm_str $msg" unless I_am_interactive; print "$msg\n"; # debug dump all values # foreach (qw(DownStream UpStream)) { # print "$_ - "; # my $hash = $results{$_}; # foreach (sort keys %$hash) { # print " $_: $hash->{$_}"; # } # print "\n"; # } exit;
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Cable modem status
by rkrieger (Friar) on Feb 17, 2007 at 02:40 UTC | |
by ruzam (Curate) on Feb 17, 2007 at 03:11 UTC | |
Re: Cable modem status
by GrandFather (Saint) on Feb 17, 2007 at 02:52 UTC | |
by ruzam (Curate) on Feb 17, 2007 at 03:19 UTC | |
by GrandFather (Saint) on Feb 17, 2007 at 03:27 UTC | |
by ruzam (Curate) on Feb 17, 2007 at 03:46 UTC | |
Re: Cable modem status
by qbxk (Friar) on Feb 17, 2007 at 16:13 UTC |
Back to
Cool Uses for Perl