Is it possible to create a do-it-yourself substitute for Aereo?

 

Disclosure
Disclosure: There are a few links to Amazon in this article. Those are affiliate links, and we might make a few bucks if you click on them and buy anything.

 

Important
Note: This article should be considered somewhat dynamic, because we may update it from time to time as we discover additional information on this topic.

By now you’ve probably heard of a new service called Aereo, which is described by Wikipedia as follows:

Aereo is a technology company based in New York City that allows subscribers to view live as well as time-shiftedstreams of over-the-air television on Internet-connected devices.[1]

…..

Aereo provides this service by leasing to each user an individual remote antenna. [4][9][10] This distinguishes Aereo from purely internet-based streaming services.[11]

You can find a full review of Aereo here. Unfortunately, there are several problems with Aereo. The issue is that they only serve certain specific areas of the country, and due to conflicting court rulings, it may be a very long time before they are able to enter certain markets, particularly on the west coast of the United States.

But also, you are for the most part limited to receiving only the channels you would be able to receive if you had a very good outdoor antenna system mounted on your home (in fact, you might get more channels than Aereo provides with such an antenna, depending on your location). Hate your local broadcasters? Too bad, because Aereo won’t let you subscribe to out-of-area signals. In fact, the Aereo Terms of Use includes this section (under “MEMBERSHIP, USE AND BILLING”):

1. You may only register for an Aereo Membership if you live within a market in which Aereo is available (the “Aereo Market”) and you must register for the Aereo Membership using your residential address. A Member may only use the Site and the Equipment to receive television signals that are available in your Home Market. A Member may not use or attempt to use the Site and/or Equipment to access signals that are not available in your Home Market or register for a Membership if you reside outside of the Aereo Market, including, without limitation, by providing a false home address, using a business address, by using another person’s login and password or by any other method that misrepresents or conceals your residential address. Aereo reserves the right to verify your residential home address using your Internet Protocol address, your billing information, geo-location and any other information that you, your ISP, or computer system provide to Aereo, as well as any publicly available information. To the extent offered by Aereo, temporary promotional access will only be available to users physically located within one of the markets in which Aereo is available, and we reserve the right to verify your location through geo-location and exclude you from using Aereo if the geo-location check fails.

So if you were thinking of trying to use a VPN, and/or some other method to conceal your actual location from Aereo, be aware that as far as Aereo is concerned you are persona non grata. We are not so naive as to think that no one will figure out a way to do it anyway. But since Aereo charges a monthly fee for their service, we wondered if there isn’t a better way to go.

How well do you get along with your family and friends?

We are going to discuss an alternative that, quite frankly, won’t work for everyone. Actually, there are two methods. One is for if you are in reception range of your local TV signals, and those are the signals you want to receive. The other is for everyone else, but it builds on the first one. However, the second method only works if you have a close family member or good friend living in a strong reception area, and both they and you have high speed broadband and generous (or no) bandwidth caps. It might also work if you own or rent space that you control in such an area. So, if you are a business owner and one of your business locations is in a strong reception area, you will be able to use the second method.

How do you know what’s a strong reception area? Go to the site TVfool.com and where it says “If you’d like to check your location, then…
>> Click HERE <<“, click on that link. Fill in the requested information for your location and it will give you a graphic that contains information about the TV signals available in your area. Let’s say, for example, that you live in Niagara Falls, New York. You might get a chart that looks something like this:

Sample TVFool chart for unspecified location in Niagara Falls, New York
Sample TVFool chart for unspecified location in Niagara Falls, New York

When you look at this chart, the channel list is color coded, with the strongest signals at the top. Now, TVFool tends to be a bit optimistic about reception conditions. Assuming that you will only tolerate a perfect signal, with no or only very rare breakups and glitches, you should probably interpret the chart this way:

Green: An indoor “set-top” antenna might be sufficient to pick up these channels, but you would be better off with an attic or outdoor antenna unless you can actually see the transmitter towers from your home.
Yellow: If you want a reliable signal on these, don’t even think of trying to get by with anything less than a good outdoor antenna, or at the very least, an attic antenna that is preferably located in a window facing the transmitters.
Red: Fuggeddaboutit! Despite what the site may say, it’s very unlikely that even a good outdoor antenna will get you those stations reliably. Of course, if your tolerance for breakups and interruptions, and total blackouts during bad weather is high, and you want to spend a LOT of money on a tall tower and excellent antenna, you might get a few of these.
Grey: The transmitter may as well be in Antarctica as far as you are concerned. On RARE occasions you might receive these channels, but don’t ever count on it.

If all of the channels you really want to receive are in the green, then you may want to try method , which you will need to read about in any case because it also forms the basis of method .

Method : Your own antenna at your home.

Why pay Aereo if you can pick up all the signals (and maybe more) at your own home location? We chose Niagara Falls as an example for a couple of reasons: Most people have some general idea where it is, and Aereo doesn’t yet offer service there, and even if they did it’s unlikely they would offer the Canadian channels as part of their package (we will see when they come to Detroit, supposedly later this year, which is also in a market with a Canadian channel or two.  EDIT March 2014: Aereo does not carry any Canadian stations in Detroit).

 

Important
EDIT March 2014: In the text below, there are several references to the “HDHomeRun Dual”, but this device is being superseded by two newer devices:  The HDHomeRun DUAL – Generation 4 (Amazon Link), which is said to have a better tuner and other improvements over the previous model, and the HDHomeRun PLUS (Amazon Link), which in addition to the other improvements also “Converts video to H.264 AVC for more efficient streaming and better playback support on portable devices.” This latter feature, available on the HDHomeRun PLUS model only, could be important if you are sending the video to another location over the Internet, as will be discussed in the next section.
The basis of an alternative to Aereo involves a hardware device, and a software package. The hardware device is the HDHomeRun Dual (Amazon link). It is basically a network-connected tuner that can tune up to two signals at a time from an antenna. You can use more than one on the same network, so if you wanted the ability to tune up to four channels simultaneously, you could buy two HDHomeRun Duals. Note that each HDHomeRun Dual can connect to a separate antenna, or to the same antenna through a splitter. So if, as often happens, you have a clusters of stations in two (or more) different directions, you could use one HDHomeRun and antenna to receive the channels in one direction, and another HDHomeRun and antenna to receive the channels in another. In the case of our hypothetical Niagara Falls viewer, they might point one antenna to the southeast to pick up the Buffalo stations, and another to the northwest to pick up the Toronto stations. For that matter, they could add a third HDHomeRun and antenna to pick up the stations from Hamilton, Ontario, or they could try aiming an antenna halfway between Toronto and Hamilton and connect that to a single HDHomeRun, and hope for the best.

With just a HDHomeRun Dual, you can watch television on any computer or network-connected device in your home, and that includes any TV that’s connected to a computer or compatible home theater PC. But since a TV can already receive signals from an antenna, that may not by itself be too useful. Oh, and by the way, if someone has told you that it is no longer possible to use an antenna to pick up signals now that television has gone digital, there is no polite way to say this: They flat-out LIED to you. And let’s just say that there have been more than a few LIARS among the ranks of cable TV and satellite customer service representatives.

The real magic happen when you pair a HDHomeRun with a software package called MythTV. But before we get into that, let’s first explain a bit about how MythTV works.

There are two components to MythTV, a backend and a one or more frontends. A backend and a frontend can be run on the same computer, but they don’t have to. You can almost think of the backend and frontend as two separate programs that are installed as part of the same package. The frontends depend on having access to a backend. In a way, it’s a little like the relationship between a web page server such as Apache, and a web browser such as Firefox or Chrome. One web page server can serve pages to many web browsers, but a web browser is useless if there are no web servers. In the same way, you can have many MythTV frontends on a local network, but they need to be able to connect to a MythTV backend somewhere on the network.

The backend is what actually receives the signal from any connected tuners, such as the previously-mentioned HDHomeRun Dual. If the signal is being recorded, it is the backend that stores the recorded program to a storage device. It is the backend that actually runs the schedules that record programs. The backend also can receive program guide information, which is then made available to the frontend clients.

The frontend is what runs on your PC (which could be a Home Theater PC), tablet computer, or other device. It lets you view live or recorded TV from the MythTV backend. It also allows you to access the schedule information on the back end, and schedule the recording of future programs.

There is actually a LOT more that both the backend and frontend can do — MythTV is a VERY capable program — but this is simply a high-altitude overview of how the two components relate to each other. It should be noted that certain other home theater programs, notably XBMC, can also act as a MythTV frontend (with somewhat limited capabilities) if it has the correct PVR add-on installed, but that’s beyond the immediate scope of this article.

What many MythTV users might not realize is that the MythTV backend offers a web interface (called MythWeb) that allows you to schedule programs, and do much more, from a web browser on your local network. One thing it offers is the ability to download files of recorded content. So, for example, if you have a recorded TV show that you’d like to watch while you’re riding the bus or train to work, you can simply download it to your phone or tablet before you leave.

This also implies that you don’t necessarily need to run a frontend to get some benefit from the MythTV backend. For example, if all you ever want to do is record shows off the air so you can view them later on your phone or tablet, you can do that by running the backend only, and interacting with it solely via the MythWeb interface.

We have found that the easiest way to get a MythTV installation going is to install Mythbuntu on a dedicated computer, which doesn’t necessarily need to be a high-powered machine. In fact, if you only plan to use it as a backend, the main thing you want to make sure of is that it has a fast network interface – at least 10/100, but if you plan to have more than one HDHomeRun on the network, a gigabit interface would be very desirable. Other than that, as long as the computer isn’t totally ancient, it will probably work. If you also want to use it as a frontend, then the requirements are probably a bit more stringent.

But then again, there are people who run MythTV on a Raspberry Pi (also see this documentdirect PDF link). So maybe the requirements are even lower than what we believe. If it will run reliably on a Raspberry Pi, that implies perhaps that all you would need is a HDHomeRun, a Raspberry Pi, and an external hard drive with plenty of storage (that does not attempt to draw too much power from the Pi’s USB port) and you’d be in business, assuming you’re able to follow the directions.

A few months ago, we mentioned where you could find A complete guide for setting up MythTV from start to finish plus a few other helpful links, and we also told you How to get free TV schedule information for MythTV. So, if you’re in a good reception area, all you have to do is set one or more HDHomeRuns and antennas, and a system running MythTV (particularly the backend) and you’ll be all set. You’ll be able to do pretty much everything you can do with Aereo, with no monthly charge whatsoever!

Method : But what if you’re not in a good reception area, or you can’t put up an antenna?

First you need to understand that a lot of people who think they can’t put up an antenna actually can, under FCC regulations. You’re permitted to install a satellite dish or antenna up to 1 meter in diameter on property that is under your direct control. So, for example, if you live in an apartment building with a balcony, and the balcony is under your direct control (that is, it’s for you only, not shared with your neighbors) then in most cases you can put an antenna there, provided it’s relatively small and unobtrusive and you don’t damage the landlord’s property. The FCC says so (disclaimer: We are not lawyers, so if this matters to you, find a lawyer and ask him for advice – don’t take our word on this). But, not all landlords recognize that federal law allows this, so you may need to pick your battles. And, you do not have the right to place an antenna in an area you do not control, such as the roof of your apartment building.  For more information, see YES YOU CAN: Put a dish or antenna on your apartment balcony.

If you own a home but it is in a development that has deed or covenant restrictions that forbid you from erecting an antenna, we first of all will say that you were very dumb to buy into such a development (but, you probably already realize that!). Keep in mind, though, that the neighborhood busybodies can’t give you grief about your antenna if they don’t know it’s there, so you could get creative and hide it so they can’t see it, or can’t recognize it as an antenna. For example, with a little ingenuity it might be possible to hide a flat antenna underneath vinyl siding, though obviously such mounting would make it difficult to point the antenna at the stations you want to receive. Some people have disguised antennas as a piece of deck furniture, or even as an artistic item.

Sometimes you can place a small indoor antenna such as one of the Mohu Leaf or Terk indoor HDTV antennas in a window or on a wall and get adequate reception (some people have found that less expensive models such as those offered by Homeworx will do the job, but read the reviews before purchasing any indoor antenna).

But if that doesn’t work, what can you do? Well, think about what we said earlier about having have a close family member or good friend, or better yet, another property that you own or control, in a strong reception area. If there’s also a broadband connection available at that location, then you could put a MythTV backend, HDHomeRun, and perhaps an antenna (if they don’t already have one you can tap into) there. If it’s a friend or relative’s home, you could offer to set that person up with a MythTV frontend so they can watch and record shows, thereby giving them some incentive to let you place this equipment in their home.

Then when you want to watch a show that’s not available in your area, all you need to do is log into the MythTV web interface at the remote location, and tell it to record that show. After the show is recorded, you could go back into the MythTV web interface and download the show, and then after it’s downloaded you can delete it off the server to make room for more recordings.

There is an issue with that, though. Quite simply, the recordings are HUGE! For example, we recorded a high definition half hour newscast and the resulting file size was 3.47 GB! And while MythTV has a built-in transcoding option, that is more for changing the container format than shrinking the file size. So, you may want to figure out some way to compress the video prior to downloading it (possibly using ffmpeg or HandBrakeCLI, or maybe you know of something even better). And prior to doing that, you’ll probably want to give the recordings filenames that mean something to humans. We suggest you look at a script that’s often distributed with MythTV called mythlink.pl, after which you can use the video compression utility of your choice to shrink the files to something a bit more manageable. Then you can upload or download the compressed files using SFTP, which works over a ssh connection.
 

Important
Note: For HandBrakeCLI users, we found that a line of this form will compress a 720p or 1080p source file significantly, producing a 720p output and only 2-channel stereo sound:

HandBrakeCLI -i ~/path/to/original_file.mpg -o ~/path/to/compressed_file.mp4 -e x264 -q 20.0 -r 29.97 –pfr –crop 0:0:0:0 -l 720 -w 1280

If anyone can figure out how to make HandBrakeCLI output full multi-channel sound, please let us know in a comment (only after you have tested it, though – we tried some settings that we thought should work, but didn’t).

Another option for compressing the video that might be even easier to implement is Mythbrake, a script that “shall be called as MythTV user job. It transcodes the DVB recordings (mpeg files) using Handbrake.” This script requires that you install the command line (CLI) versions of Handbrake and Mediainfo (so, the package names are handbrake-cli and mediainfo), both of which can be found in the online repository and installed using apt-get or Synaptic. If you want to use this script, be sure to read the entire Wiki page because you WILL need to make some changes to the script, especially if you do not live in Germany.
 
Important
EDIT: As mentioned earlier, simce this article was originally written SiliconDust has released the new HDHomeRun PLUS (Amazon Link), which has the ability to compress the video stream within the hardware itself. However, we do not know if MythTV can handle the compressed stream at this time.  If MythTV has the ability to work with the compressed stream, that might mean that the files sizes would already be reduced and there may not be a need to run additional compression software, and it also introduces the possibility that the compressed stream could be sent to another location in real time.
We don’t know how much Aereo compresses their files, but would suggest that unless you have a very generous bandwidth cap, you don’t plan on watching an entire day’s schedule of soap operas and game shows using this method! If you do, you will probably blow through your bandwidth cap pretty quickly, and we suspect that’s also true for actual Aereo users. You can only compress video just so much before it starts to look like crap. But for that occasional prime time program you just can’t miss, this at least gives you a way to receive it.

Now you are probably wondering, wouldn’t I need to open one or more ports in my friend or relative’s router to be able to access the MythTV backend, and wouldn’t that be a security risk for them? The answer is yes, you do need to open one port only for ssh, and no, it won’t be a security risk if you know what you are doing and pay attention to what we are about to tell you.

When you set up the MythTV backend, we suggest that you don’t simply open port 22 (the standard ssh port) in the router and forward it to the backend machine, unless you are also knowledgable enough to set up a firewall that limits outside access to you and you alone. What we instead suggest is that you forward a different port, such as a higher, more obscure port to port 22 on your backend (alternately you could change the ssh port on the backend if you know how to do that, and then open that port in the router). The idea is that, as far as anyone outside the local network is concerned, you don’t want the common ssh port 22 to be open. That will at least slow down some of the bad guys.

But in addition to doing that, and especially if you don’t do that, be sure you set up ssh public/private key authentication and then disable the use of passwords for ssh logins. That way, a would-be intruder simply cannot ever succeed in cracking your password, because you don’t use one! To do that, on a Ubuntu or Mythbuntu machine (and in many other variants of Linux) open the file /etc/ssh/sshd_config with a text editor (you will need to be root or use sudo) and make sure all the values are set as shown below (add any that aren’t there, and if they are already there, make sure they aren’t commented out):

PubkeyAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

Then either reboot the system or run /etc/init.d/sshd reload from a command prompt. Don’t do this until you have public/private key authentication working, and make sure all those settings are correct (especially PubkeyAuthentication yes), otherwise you will lock yourself out of the system!

Do NOT open port 80 so you can get to the MythWeb page. You should only open the (obscured) ssh port as described above.

Here is how you get to the MythTV backend from a remote location. First, to get to the MythWeb page, open a ssh session using the following syntax:

ssh -C -L <local port>:localhost:<remote port> user@remotedomain:<remote ssh port>

Now that may seem a bit confusing, so let’s break it down. Let’s say that your remote MythTV box is hanging off of a router at internet address 1.2.3.4, and in the router you are forwarding incoming TCP port 12345 to port 22. On the MythTV backend your user name is superadmin, and the MythWeb page is on the standard http port 80 (the default), and you want to be able to access remotely it in your browser by going to http://localhost:8080/mythweb/  —  in that case, you’d use this:

ssh -C -L 8080:localhost:80 superadmin@1.2.3.4:12345

Then, once you have executed that (effectively opening an ssh tunnel from your machine to the other), you can access the MythWeb page by going to http://localhost:8080/mythweb/

Please don’t use 12345 as your actual port number for incoming ssh traffic — make it something a bit more obscure! For more information, see the MythWeb ssh tunnel howto. When you use this method of access, all your traffic between the backend and your web browser travels through a secure and encrypted tunnel, and because you didn’t open any http ports in the router for MythWeb, nobody else outside the local network can get to it. By the way, if your MythTV backend is not at a fixed IP address, you may need to set up an account with a dynamic DNS service such as FreeDNS, so you can find your backend on the Internet. In that case you’d use the dynamic IP address in place of 1.2.3.4 in the above example.

But, what if you need to do some configuration on the MythTV backend? Well, there is a way to do that too, without installing any other software or opening any more ports. First, open the file /etc/ssh/sshd_config on the MythTV backend and make sure the following value is set:

X11Forwarding yes

Assuming that it is, on your local machine open an X terminal program. For example, on a Mac you will want to go to the Utilities folder (in the Applications menu), open Utilities and then run either X11 or (if you have it installed) XQuartz. Under Linux you can probably use a normal terminal window, since Linux supports X windows. Under Windows, the method will depend upon the terminal program you’re using (if you’re using PuTTY, the article Setting up X11 tunneling in PuTTY may be helpful). When that terminal window opens, enter a command in the following format:

ssh -C -X -l username address -p port

For example, again assuming the same specifications we used earlier:

ssh -C -X -l superadmin 1.2.3.4 -p 12345

Note that the syntax varies somewhat from that used to invoke some other types of ssh sessions — we have no idea why.

Once a ssh connection is made to the distant machine, you can then enter:

mythtv-setup

To run the MythTV backend setup program. Note that windows will appear as if they were running on your local machine. For example, on a Mac, the opening window will look like this:

Prompt from MythTV backend on remote server appearing in X window
Prompt from MythTV backend on remote server appearing in X window

The tipoff that this is actually running on a remote server is an X icon in the title bar. Other windows will appear and disappear as you navigate around the program. When you are ready to exit the setup program, navigate to the main menu and press the Esc key. This should close the program, although it may first pop up a window asking if you want to run mythfilldatabase. In most cases you should answer “No” unless you have a specific reason for doing so (be sure to click “No” if you are using the method described in How to get free TV schedule information for MythTV to get your schedule information), and then you can type exit at the X terminal prompt to close the ssh session. When you do it this way, you’re not using the overhead of a remote desktop program (which you don’t have to install), and you don’t need to open any additional ports, plus your entire session is encrypted and compressed.

(Pro tip for Mac users: If you are in an X window and you need to paste text from your local clipboard, click the middle mouse button or wheel.)

By the way, if ever you ever try to run other software using this method, be aware that some programs should be run using sudo and some should not. mythtv-setup should NOT be run using sudo, but something like update-manager should:

sudo update-manager

Although since you are at a command prompt from the remote system anyway, you could just do

sudo apt-get update && sudo apt-get upgrade

to update your software packages.

Obviously there is a lot more that could be said about the procedure for setting up MythTV, but our purpose here is to give you a general idea of how setting up your own substitute for Aereo might be accomplished. And, of course, there are probably other ways to achieve the same result. Some people prefer a program called TVHeadEnd to MythTV, but we don’t because we found it very difficult to configure. Some people prefer to use another type of TV tuner instead of a HDHomeRun, but we like the HDHomeRun Dual because it is small enough that you can put relative close to the antenna (thereby minimizing signal loss) rather than needing to run coaxial cable to the machine running the MythTV backend.

And we know that some of you may be thinking, my friend or relative has cable, couldn’t I… hey, we are not even going there. That opens up another whole can of worms, the main one being that most cable signals are digital nowadays and the HDHomeRun DUAL cannot receive them. There is another model of HDHomeRun, the HDHomeRun Prime (Amazon Link), that uses a CableCard and can receive digital signals, but we have read several articles that indicate that if the cable companies have anything to say about it, the CableCard technology is going away soon. And beyond all that, we suspect that most cable companies would take a very dim view of one of their subscribers slurping up cable signals and then sending them over the Internet to a friend or relative. As we noted earlier, we are not lawyers, so we won’t opine about the legality of it, but we suspect that cable company lawyers might have some strong feelings about it.

EDIT (March, 2014): Is there any other way to get free TV if I live in a poor reception area?

That depends on where you live and whether you have a clear view of the southern sky. If you live in a rural area, or an area where the local code enforcement officials and neighborhood busybodies are not too persnickety, you may be able to install a large C-band satellite dish (sometimes also known as a BUD, which is an acronym for “Big Ugly Dish”, although the newer mesh models aren’t as ugly as the older dishes). We are not talking about one of the smaller dishes here; while a small dish can be used to receive certain signals (notably PBS), most of the network TV signals and feeds to be found will be on C-band.

Receiving C-band (large dish) and Ku-band (smaller dish) is something of a hobby, but the reward is that you can receive several network and non-network stations for free, although the signals do tend to come and go. Stations or signals that are here today may not be available tomorrow, but new ones may appear. If you want to learn more about this, there is a discussion forum at Ricks Satellite. You can also search for information on “Free To Air” satellite receivers and equipment, but be aware that the phrase “Free To Air” has a different meaning in North America than in some other parts of the world (particularly Europe).

Be careful, however, particularly if you live in the U.S. or Canada, because there are some sellers (particularly on eBay) that sell illegal equipment, that can be used to “pirate” scrambled pay TV signals. The problem with this equipment, besides the fact that you are engaging in piracy, is that any television receiving equipment also radiates RF energy for a short distance and therefore it IS possible to tell if you are using this equipment from within a vehicle driving by on the street. But the bigger issue is that very often the sellers of such equipment are caught, and their customer list is confiscated by the FBI or some other federal agency, and then the feds go after the purchasers of such equipment, and you can get a huge fine and even potentially a prison sentence for knowingly using such equipment. The general rule is that if a signal is unscrambled on a satellite it is okay for you to watch it, even if it is a pay TV service, or even if they transmit some ominous sounding warning that it is a feed intended only for a network’s affiliates. But, the moment they scramble the signal it is off limits for those that aren’t paying to receive the signal and using approved equipment (Disclaimer: We are not lawyers, so if this matters to you, you may want to consult with an attorney to get correct, up-to-date information).

The forum mentioned above prohibits the discussion of signal piracy, so you are pretty safe in using any equipment recommended on that site. We will also add that some sites may leave you with the impression that there is nothing available on C-band anymore. While it is true that the days when hundreds of unscrambled signals were available are long gone, if you are in a poor reception area the ability to get a good signal from even one or two stations might make a big difference, and there are a lot more than one or two unscrambled signals available as this is being written. BUT, if you own a home that is in a development that has deed or covenant restrictions that forbid you from erecting a satellite dish, you will not be able to put up a C-band dish, and that’s also true in many cities, and even in some of the more hoity–toity townships.

If you speak any languages other than English, then you have an added incentive to look into Free to Air satellite TV, because many of the stations available (particularly on Ku-band, which can be received using a smaller dish) are in languages other than English. The same is true if you are a news junkie, because often breaking news feeds will be available on satellite. For example, during Hurricane Katrina and the rescue efforts that followed, local TV station coverage from New Orleans was available for viewing on satellite.

A few final thoughts…

You may be thinking, as we often do, that there is no reason people should have to go through all this nonsense to watch TV. It is inevitable that the model for the delivery of video content must change, just as the model for the delivery of music has changed. The only thing that holds it back are the broadcast industry and the networks, who can’t let go of the distribution methods that they have used since the birth of commercial television. The idea that if you live in a certain geographic area, you can only get major network content from a particular group of local broadcasters is an idea that is well past its shelf life. Besides, a lot of people hate their local broadcasters and to a lesser degree the networks, for a number of reasons — for example, the need to plaster their own gaudy graphics over the top of the program you want to watch, and the fact that if they say a program will start at a certain time, it doesn’t always do that. Some people do still like to watch local news, but many stations are now consolidating their news departments so that you are now more likely that ever to get the same news on most or all local channels, just read by different talking heads. And most younger people get their news online (the closest they will come to watching televised news is The Daily Show).

So at some point, Aereo needs to realize that their real value will be in offering people access to channels that they cannot currently get in their local area. We understand why they are not doing that now — they need to fight one legal battle at a time — but only offering customers stations that they can already get off the air with a good antenna is not going to be a sustainable business model forever, particularly as the program producers start to realize that they can bypass the networks and local stations altogether. The change will take time, but the question is when it will take place, not if it will take place. There is a whole generation coming up that hardly watches network television; does anyone really think that when they are old enough to be elected to office or appointed to leadership positions that they will be the slightest bit interested in keeping the major networks/local affiliates model on life support? Or that they will think that geographic restrictions on which stations you can watch are anything other than totally ridiculous?

Why is it that we can tune in an AM or FM radio station from another part of the country, or even another part of the world, and listen all we want, but we can’t even watch an online stream from our local network affiliates — except, perhaps, when they are airing locally originated programming? What makes video so special? In a sane world, a service like Aereo, as it currently exists, shouldn’t even be necessary. The networks, or at very least, the local stations should be streaming their content themselves! The fact that Aereo exists, and is apparently thriving in the places where it offers service, is a testament to how far the established broadcast industry has their heads up their collective posteriors.

Using irrecord to allow LIRC to recognize extra buttons, as from an unused remote and/or a Harmony remote

A few days ago we published an article on Using the Raspberry Pi to control AC electric power. We ended that article by showing how you could control the Raspberry Pi’s GPIO pins using a standard remote associated with a Home Theater PC on the same local network. Actually, come to think of it, there’s nothing to prevent someone from sending such commands across the Internet to a distant system, if one has an application that requires it. But I digress…

One problem that some users might encounter is that there are simply no free buttons on the remote control that can be used for other functions. Or maybe there are extra buttons, but they don’t seem to do anything. Or maybe you have a Logitech Harmony Remote or some other type of universal remote, and you downloaded a configuration for it to match your existing remote and infrared receiver but it added some additional buttons that appear to do nothing. Or, failing all that, maybe you have a spare infrared remote from a no longer utilized or broken device, that you’d like to use to control some additional functions (such as the GPIO pins on the Raspberry Pi, as in the aforementioned article). The question is, can you get your Home Theater PC (the one to which you have the infrared receiver attached) to recognize those additional button presses?

In our experience, the answer is that there’s a high probability, but it seems to depend on whether your infrared receiver can properly receive and decode the additional button presses. Which it just might be able to, even if it’s not doing that now. So, how can you tell what it’s now recognizing, and whether it can be made to recognize additional button presses?

First of all your system must be using the LIRC software for this to work. Most Linux-based home theater software does, so if you have a Home Theater PC and it’s not running some variant of Windows, it probably already has LIRC installed. Note that LIRC is actually a small collection of programs, none of which are actually named lirc, so just doing “which lirc” from a command prompt probably won’t tell you if it’s installed. Instead, you can check for one of the included programs — for example, try “which lircd” (lircd is the lirc background process) and see if it shows a path to that program.

Before you go any further, from a terminal prompt enter this:

irrecord --list-namespace

You may want to copy the output of that command to a text file that you can keep open in another window while you proceed, or just open another terminal window so you can refer back to this one. You could even print out that list if you think it would help. You are probably only going to be concerned with the entries that start with the characters KEY_ (and NOT those that start with BTN_, which may seem counter-intuitive, but that’s just how it is, at least with “MCE” compatible remotes — MCE = Windows “Media Center Edition”, in case you were wondering).

Next you will want to find out which buttons are already recognized. You should do this from a terminal prompt, with none of the software that normally responds to remote control commands running (so kill any instances of XBMC or similar software before doing this). Enter the command “irw” (without the quotes) and then start pressing buttons on the remote. For each button that LIRC recognizes, you will see one or more lines of text appear. Note any buttons that irw doesn’t print out anything for. If you are wanting to add a second remote to get additional usable buttons, see if irw responds to any of those buttons (it’s very unlikely that it will). The buttons that irw does not recognize are the ones we will try to add in the following steps.

Also, as you are pressing buttons and watching the output of irw, note the key names that are already used (they will likely be in the next to last column. Here is why. When you add previously unrecognized keys, you have to give them a name that LIRC understands, which can be any name from the output of “irrecord –list-namespace” that is not already used. If you duplicate an existing button name, one of the buttons won’t work. So, take note of the names already used, and also of the buttons that currently don’t do anything. When you have pressed all the buttons on your remote(s), use Control-C to exit irw.

Now before going any further, take a look at the file /etc/lircd/lircd.conf (at this point we are only going to read it, not write to it, so don’t use sudo):

nano /etc/lirc/lircd.conf

Note that file may contain a bunch of comments, and then a line such as this:

include “/usr/share/lirc/remotes/mceusb/lircd.conf.mceusb”

Whatever file is referenced in that “include” is the file we will be working with, which for simplicity’s sake I will henceforth refer to as the lirc remote configuration file. So close lircd.conf and go to that file:

nano /usr/share/lirc/remotes/mceusb/lircd.conf.mceusb (or whatever file was included in lircd.conf)

You should see some preliminary configuration at the top, and then if you scroll down a bit you should see a line that says “begin codes” — below that, the lines that are not commented out will show key codes that LIRC currently recognizes (even if they do not appear on your remote) followed by hexadecimal values. Now this is where it gets a little confusing. When you are naming buttons in the next steps, you do not want to use any button names that already appear in this file. So the general rule for naming buttons in the following steps are:

1. DO use names that appear in the output of “irrecord –list-namespace”. BUT…
2. DO NOT use names that already appear in the lirc remote configuration file.
3. DO NOT use names that appear when you are using irw to find existing buttons (this should be a subset of ).

Now you are ready to try to add additional buttons to the list that LIRC knows about. The lircd process must NOT be running at this time, so do this:

sudo killall lircd

Now, to see if the additional buttons (or alternate remote) can be used, do this (note this assumes your IR receiver is at /dev/lirc0, which it probably is, but if not you may need to change that reference):

sudo irrecord -d /dev/lirc0 ~/lirctest

The irrecord program will first have you do several things to get some basic information about the remote – this will involve a bit of time and several button presses, so be patient and just follow the on-screen instructions. Then, after it has figured out what it needs to know about your remote, it will ask you to enter a key name — be sure to keep in mind the rules mentioned above! — and after that it will have you press the button on the remote. You can repeat this cycle as often as necessary to get all the buttons you want to add, and at this step you should only add buttons that it doesn’t already know about (ones that did not elicit a response from the irw program). Only do one remote at a time — don’t try to add buttons from different remotes on the same run of irrecord. If, for any reason, you have to quit irrecord before you are finished, delete the file ~/lirctest before you start over.

There may be cases where irrecord simply will not recognize a remote. or does so only with great difficulty. If that is the case, it probably means that either the batteries are dead in that remote, in which case you should restart the irrecord program after changing the batteries, or that the remote is not compatible with your infrared receiver. Different IR devices can operate on different infrared wavelengths, and your IR receiver is probably “tuned” to receive IR commands in a relatively narrow portion of the infrared spectrum. So, don’t be too surprised if some alternate remotes work fine, while others don’t work at all.

After you have run irrecord, the configuration should be in the file ~/lirctest (lirctest in your user directory). What you need to do now is copy the non-comment lines from that file (in other words, the section from begin remote to end remote, including those lines) to the end of the lirc remote configuration file. Before saving the additions, change the name line (right below begin remote) to have a value that is short and meaningful, using all lowercase letters and no spaces (such as name old_vcr if you are adding buttons from an old VCR remote). You may want to save a copy of the original lirc remote configuration file before making any changes, just in case you mess something up. For that matter, I’d also save a copy after you make the additions, since we’re not entirely sure whether the lirc remote configuration file might revert back to the original configuration if an upgrade to lirc comes along. So you may want to keep both a “before” and “after” copy in another directory.

If you want to add buttons from yet another remote, just repeat the process using irrecord. Remember to give the buttons unique names from the list you got when you ran irrecord –list-namespace. Note that the button name you use in irrecord does not need to bear any actual relation to the button name on the remote itself, it just has to be a name that’s not already in use.

Once you have made the additions to the lirc remote configuration file and rebooted the system (to restart lircd and read the new configuration file), run irw again and verify that the new buttons are being recognized. Now you can use those added buttons in your .lircrc file, or in the remote configuration file for a particular piece of software (for example, ~/.mythtv/lircrc for the MythTV frontend, if you are running that).

Readers with Harmony remotes may have noticed that when they looked into the lirc remote configuration file, there was already a lot of buttons defined that do not appear on their remotes, and might have wondered if it is possible to get the Harmony remote to learn those codes. While we have found that getting a Harmony to learn button presses from another remote is relatively easy using the Harmony configuration software — which means it would be easy to add buttons from that old VCR remote, assuming that irrecord was able to recognize it — it’s either difficult or impossible to add raw codes to a Harmony without having another remote that generates them. We tried to figure out if it could be done, but pretty much hit a dead end. If you should figure it out, please feel free to leave a comment explaining the procedure.

Links: A complete guide for setting up MythTV from start to finish

Probably the easiest way to get a MythTV installation up and running quickly is to install Mythbuntu or Mythdora, depending on whether you prefer the Ubuntu or Fedora variant of Linux.  But if you want a bit more hands-on experience, or additional help with configuration, these links might be helpful:

From a Reddit thread:

I’ve been a fan of MythTV for some time, but found that there were very few comprehensive setup guides out there for new users. So, I decided to write one. It’s split into 4 parts (shown below) and covers not just how to set up a MythTV system, but also makes an effort to explain why certain instructions are given along the way.

I hope some of you find it useful, and constructive feedback is of course appreciated. 🙂

Reddit thread with comments
Reddit thread with comments #2

Here is an older MythTV setup guide that we’ve found useful in the past:
Andrew’s MythTV Walkthrough: A Simpler MythTV How-to for Beginners

Don’t forget about the MythTV Wiki. But be aware that if you live in the United States, much of the “official” MythTV documentation will try to push you into paying for a subscription TV schedule service. If you live elsewhere, they are forced to admit there are other alternatives, which there are for U.S. residents as well — yet for some reason they try really hard to push the subscription service to U.S. users.

If you want to get TV listings into MythTV without paying for a subscription service, see How to get free TV schedule information for MythTV.

Why do Western Digital hard drive power supplies leak so much AC voltage?

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog.

We recently changed out a case on a computer power supply.  The new case is metal whereas the old one was plastic, and as I was plugging in a USB cable from a USB hub I got a shock.  Not only that, when I accidentally touched it to the bottom of the computer’s case, the computer power supply completely shut down and would not restart until I physically removed the power cord and plugged it back in.  Since this hub had worked just fine with the old case, it led me to wonder what the issue was.  I put a voltmeter on the shell of the USB cable and measured about 50 volts AC to ground!

To make a long story short, I have four external USB drives plugged into that hub and they are all Western Digital. Every single external hard drive had AC voltage on its USB cable shell (when disconnected from the hub), whereas no other devices had more than a volt or two.

That led me to disconnect the power supplies from each of the hard drives, at which point I made a, um, shocking discovery!

I measured the voltage from the power supply DC plugs to ground.  For this test I plugged them into an outlet on a totally different circuit from the one I plug my computers into, since a friend has suggested that the outlets might be miswired (hot and neutral reversed).  I tested for that possibility and that was not the case, but it was still easier to take them out to the kitchen for this test.  I photographed the results for three of them but a fourth gave similar results.  I’m sorry that the pictures are a bit blurry but if I’d used flash it would have washed out the LED display so the exposure times were a bit longer than I would have liked, given that my hand isn’t all that steady.

Western Digita Power Supply #1 - 44 volts leakage

Western Digita Power Supply #2 - 57 volts leakage

Western Digita Power Supply #3 - 44 volts leakage

EDIT: For a few hours after I first posted this, I had image duplicated as . Sorry about that.

A few observations I noted while testing the voltage:

It didn’t matter which way the AC plug was inserted into the socket – the voltage was the same or very nearly the same (within a couple of volts) either way.

It didn’t matter whether I measured to the center or the shell of the DC plug – the voltage was exactly the same either way (this makes me think the leakage might be through a capacitor or capacitors, since otherwise there would be a DC short).

Whatever voltage I measured at the power supply found its way to the USB plug shell once the power supply was connected to the hard drive.

I measured this on FOUR different power supplies, all ones that came with Western Digital hard drives of various sizes. On three I got the 44 volt reading and on one I got 57 volts.

If it were just one or two power supplies doing this, I’d suspect a flaw in that power supply. But since every single one of them is doing it, I have to think it is something inherent in the design of the switching power supplies used with external hard drives. For some reason this never caused any problem with my old computer or case but this new one (new case) can get really strange if you connect or disconnect the USB hub while it is running and the power cable is connected. I just hate the fact that there is this much stray AC but it must be a problem specific to the hard drive power supplies so I don’t think there is anything I can do about it.

I don’t know of any way to correct this problem, or even if it really is a problem. But I REALLY don’t like it!

By the way, I don’t mean to impugn Western Digital specifically, it’s just that right now all four of the external drives connected to this particular computer are WD’s.  I do NOT know whether or not this problem affects power supplies that come with other makes of hard drives (if anyone wants to test yours and post the results in a comment, I’d appreciate it, but please don’t unless you have worked with electricity enough to know how to do the test safely, since I will not be responsible if you fry yourself or your equipment because you didn’t know how to do the test!).

A Perl script to rewrite the "static" IP address in the FreePBX Asterisk SIP Settings when it is changed by your ISP

 

Important
This is a heavily edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog.

This was originally posted in August, 2011. Unless you are deeply in love with Perl, I suggest you also take a look at the newer article, A Bash script to rewrite the "static" IP address in the FreePBX Asterisk SIP Settings when it is changed by your ISP. Although it is still considered experimental, it is simpler than the script shown here, does not require the installation of additional modules, and the text has been updated somewhat to reflect the changes in FreePBX since this article was written.

This post is going to be a bit long because I first need to explain the “why” behind this script, then how to obtain the prerequisite Perl modules, then the script itself and how to test it after installation.

If you are using a recent version of Asterisk and FreePBX you may be using the Asterisk SIP Settings module (under the “Tools” tab) to automatically set various SIP parameters.  This module is a great help to those who don’t know what they are doing, but there is a trap for the unwary (and in this case it’s NOT the fault of FreePBX – it’s a longstanding bug in Asterisk that’s the problem).

At the top of the Asterisk SIP Settings configuration page, in the NAT Settings section, there are two options that can be set.  The first is NAT and there are four possible choices:

  • yes = Always ignore info and assume NAT
  • no = Use NAT mode only according to RFC3581
  • never = Never attempt NAT mode or RFC3581
  • route = Assume NAT, don’t send rport

In theory, if you have a fixed IP address AND your Asterisk server is not behind an external router that does NAT translation, you should use “no” (and most of the rest of this article will not be relevant to you).  This article is intended more for home and SOHO users that both have their Asterisk server behind a hardware router of some kind, and that get their broadband service from a company that occasionally changes their IP address without warning.  For such users, the preferred setting is “yes”.  I’m not enough of a networking guru to tell you under what circumstances one of the other settings might be appropriate (if you understand this stuff, feel free to leave a comment and enlighten us).

FreePBX: Asterisk SIP Settings page, NAT Settings (Public IP Option)

It’s the next set of settings that can get us into trouble.  This is the IP Configuration and there are three possible choices:

  • Public IP
  • Static IP
  • Dynamic IP

If your IP address never changes AND you aren’t behind a hardware firewall then you can usually just set this to “Public IP” and let it go at that.  You will not be asked to fill in any other values.  But most users that are not in that situation will pick one of the other two choices, and this is where the problem arises.  Conventional wisdom has it that if your ISP ever changes your IP address without advance warning (which is the case for most cable broadband and DSL users), you should use the Dynamic IP setting.  In this case there is an auto-configure button that will fill out the fields for you, although you may need to fill in the Dynamic Host field yourself.  This is the “External FQDN as seen on the WAN side of the router and updated dynamically, e.g. mydomain.dyndns.com” (as explained if you mouse over the words “Dynamic Host”).  You can use a DynDNS address (or an address from a similar service) or an address you have purchased.  But the problem is that for some users, THIS METHOD SIMPLY DOES NOT WORK.

FreePBX: Asterisk SIP Settings page, NAT Settings (Dynamic IP Option)

If you try to use Dynamic IP and it won’t work for you, what happens is you will get all sorts of weird errors.  You may get one way audio, some calls may disconnect for no apparent reason after about five seconds, and you will see other weird errors in your CLI.  If you change this setting to “Static IP” and click the auto-configure button and then submit the changes, the problems magically go away – UNTIL your ISP changes your IP address, at which point you suddenly have no connectivity to the outside world.  If you ask for help, everybody and their brother will tell you to use the Dynamic IP setting, and the minute you try that you’ll get all the weird errors again.

FreePBX: Asterisk SIP Settings page, NAT Settings (Static IP Option)

So if that’s your situation, you need this Perl script.  Coupled with a cron job, it goes out and checks your IP address every five minutes and if it notices it has changed, it changes it in the MySQL database (same as if you entered it into the External IP text box on the Asterisk SIP Settings configuration page) and then reloads Asterisk.  Therefore, you can use the Static IP method and it hopefully it will work reliably.  If and when your IP address changes, you should only be down for about five to ten minutes at most (hopefully your broadband provider usually does such changes in the middle of the night!).

Prerequisites:

You still have to use a Dynamic DNS service to keep track of your IP address if you want external extensions to be able to find your server on the Internet.  It’s not required for this script to work, though, so I won’t say any more about that except to note that if you use a recent vintage hardware router, it probably has DDNS support built in.

You may have to install some Perl modules on your system.  This script uses two or three: WWW::Mechanize (only if you use the first variation of the script shown below), Data::Validate::IP, and DBD::mysql.  There are typically two ways to install any missing Perl modules on your system.  One is to do this from the Linux command prompt:

perl -MCPAN -e shell

This will put you into a Perl CPAN shell and if it’s the very first time you’ve ever run this, it may ask you to do some configuration first.  Go ahead and do it.  If you don’t know how to answer a particular question, accepting the default is usually a pretty safe bet (if you disagree with me on this, then you know enough to know how to answer the questions, so you don’t need my help). However there are a couple questions related to buffers where you have the option to not create one, and I usually don’t because I don’t spend much time in the Perl shell.  Just read the questions and either use the default answer, or another suggested answer that fits your preferences.  When it comes time to pick servers (from which you will download modules), just pick two or three that are close to you.

After you’ve done the configuration, just install each module (if you already have it, it may say “nothing to do” and stop).  Alternately, if you configured Perl to ask before downloading dependencies, you may need to answer “yes” a few times to allow dependencies to be downloaded and installed. To install the required modules from within the CPAN shell, just do these, one at a time:

install WWW::Mechanize (only if you use the first variation of the script)
install Data::Validate::IP
install DBD::mysql   (you might already have this).

To quit the CPAN shell, just type quit and press Enter.

Alternately, in some distributions you can get certain Perl modules from the distribution’s repository.  For example, in Centos you may be able to use:

yum install perl-WWW-Mechanize.noarch (only if you use the first variation of the script)
yum install perl-Data-Validate-IP.noarch
yum install perl-DBD-MySQL.noarch

Or in any Debian-based Linux, including Ubuntu Server, try these:

sudo apt install libwww-mechanize-perl (only if you use the first variation of the script)
sudo apt install libdata-validate-ip-perl
sudo apt install libdbd-mysql-perl

It’s likely you already have the Mysql module. Depending on your distro you may have to leave off the .noarch, or find a specific version in an appropriate repository.  Installing from the CPAN shell make take a bit more time for the initial configuration, and some people find the CPAN shell difficult to use, but you will always get the correct version of the module.

Note that if you use Webmin, there is a third way – you can install modules from the Other | Perl Modules | Install Module page.  BUT, that may not work correctly until you have configured CPAN as mentioned above.  Don’t let that stop you from trying it, though!

The Script:

There are now two versions of this script. One uses WWW::Mechanize to get your IP address from a web site that returns only your IP address, while the second uses a dig command to get your IP address. We recommend the second one, since public sites that return only your IP address have a nasty habit of disappearing. Note that as always, these WILL overflow the lines in WordPress, so you will want to cut and paste your preferred script into a text editor.  Also note that WordPress MAY change apostrophes and quotes into “prettified” versions, and if it does that will totally mess up Perl.  I’m going to put this in a preformatted text block so hopefully WordPress won’t change anything (it doesn’t appear that it has), but you never know.  One final note, don’t confuse backticks (`) with apostrophes (‘) – backticks are used to run a command that would normally be run from a Linux command prompt.

These scripts were written for use with FreePBX 2.11; there are a couple of lines that need to be changed for FreePBX 12 and above which will be posted below the main scripts:

#!/usr/bin/perl

# This program gets the current IP address (as assigned by the ISP) from
# a web page and modifies the FreePBX Asterisk SIP settings if the
# external IP address has changed. Invoke it as cron job that runs every 5 minutes.

use strict;
use warnings;
use WWW::Mechanize;
use Data::Validate::IP qw(is_public_ipv4);

# GET CURRENT IP ADDRESS
my $mech = WWW::Mechanize->new( autocheck => 1 );

# NOTE THE http QUERY IN THE NEXT LINE - PLEASE PASTE THIS INTO YOUR WEB
# BROWSER AND MAKE SURE IT RETURNS YOUR IP ADDRESS AND NOTHING ELSE.
$mech->get('http://some_web_site_that_returns_your_IP_address');
$mech->success or die 'Cannot connect to web site';
my ($ip) = ($mech->content() =~ /(d+.d+.d+.d+)/);

# VALIDATE RESULT RECEIVED

if (is_public_ipv4($ip)) {

	# SET UP TO CONNECT TO MySQL DATABASE
	use DBI();

	# CONNECT TO DATABASE
	my $connect = DBI->connect("DBI:mysql:database=asterisk;host=localhost", "user", "pw", {'RaiseError' => 1});

	# GET IP ADDRESS FROM DATABASE
	my ($externip) = $connect->selectrow_array("SELECT data FROM sipsettings WHERE keyword like ?", undef, "externip_val");

	# COMPARE IP ADDRESSES

	if ($externip ne $ip) {

		# WAIT 5 SECONDS AND RECHECK IP TO AVOID FALSE POSITIVES

		sleep 5;
		$mech->get('http://some_web_site_that_returns_your_IP_address');
		$mech->success or die 'Cannot connect to web site';
		my ($ip) = ($mech->content() =~ /(d+.d+.d+.d+)/);
		if ($externip ne $ip) {

			# IP HAS CHANGED SO UPDATE IP ADDRESS IN DATABASE
			$connect->do("UPDATE sipsettings SET data = ? WHERE keyword = ?", undef, "$ip", "externip_val");

			# WRITE CONFIG FILES AND RELOAD ASTERISK
			`/var/lib/asterisk/bin/module_admin reload`;

			# OPTIONAL SEND EMAIL TO SYSTEM ADMINISTRATOR(S)

			# my $mailstring = 'echo "This is an automated message - please do not reply. Either we had a power or Internet outage (in which case there is a slight chance you may receive this message even if our IP address is unchanged), or our Internet Service Provider has changed the IP address of our phone server to ' . $ip . '" | mail -s "ISP may have changed our IP address" someaddress@gmail.com,anotheraddress@somewhere.com';
			# system($mailstring);
		};
	};
};

Variation (recommended) – note, do NOT confuse backticks and apostrophes, since both are used in this script and they are NOT interchangeable!

#!/usr/bin/perl

# This program gets the current IP address (as assigned by the ISP) from
# OpenDNS and modifies the FreePBX Asterisk SIP settings if the external IP
# address has changed. Invoke it as cron job that runs every 5 minutes.

use strict;
use warnings;
use Data::Validate::IP qw(is_public_ipv4);

my $dig = 'dig +short myip.opendns.com @resolver1.opendns.com';
my $ip=`$dig`;
chomp $ip;
if ($ip=~/((\d){1,3}\.){3}(\d){1,3}/) {
	if (is_public_ipv4($ip)) {

		# SET UP TO CONNECT TO MySQL DATABASE
		use DBI();

		# CONNECT TO DATABASE
		my $connect = DBI->connect("DBI:mysql:database=asterisk;host=localhost", "user", "pw", {'RaiseError' => 1});

		# GET IP ADDRESS FROM DATABASE
		my ($externip) = $connect->selectrow_array("SELECT data FROM sipsettings WHERE keyword like ?", undef, "externip_val");

		# COMPARE IP ADDRESSES

		if ($externip ne $ip) {

			# WAIT 5 SECONDS AND RECHECK IP TO AVOID FALSE POSITIVES

			sleep 5;
			$ip=`$dig`;
			chomp $ip;
			if ($ip=~/((\d){1,3}\.){3}(\d){1,3}/) {
				if (is_public_ipv4($ip)) {
					if ($externip ne $ip) {

						# IP HAS CHANGED SO UPDATE IP ADDRESS IN DATABASE
						$connect->do("UPDATE sipsettings SET data = ? WHERE keyword = ?", undef, "$ip", "externip_val");

						# WRITE CONFIG FILES AND RELOAD ASTERISK
						`/var/lib/asterisk/bin/module_admin reload`;

						# OPTIONAL SEND EMAIL TO SYSTEM ADMINISTRATOR(S)

						# my $mailstring = 'echo "This is an automated message - please do not reply. Either we had a power or Internet outage (in which case there is a slight chance you may receive this message even if our IP address is unchanged), or our Internet Service Provider has changed the IP address of our phone server to ' . $ip . '" | mail -s "ISP may have changed our IP address" someaddress@gmail.com,anotheraddress@somewhere.com';
						# system($mailstring);

					};
				};
			};
		};
	};
};

NOTES on the above scripts, including THINGS YOU MUST CHANGE:

In the first script, change both occurrences of http://some_web_site_that_returns_your_IP_address to a web address that returns only your IP address and nothing else. Enter the link into a web browser to make sure you get the expected result — it should show your external IP address and nothing else. These services tend to come and go, and you’ll need to find one that returns your IP address, and ONLY your IP address, with no extraneous HTML formatting or text. If you don’t know of such a source, then try the second variation.

These rest of this applies to both scripts:

Note the two bolded variables user and pw. These must be changed to the correct values for YOUR system. You will usually find these in one of two places. You can look in /etc/amportal.conf and look for the variables AMPDBUSER and AMPDBPASS — these will usually be near the bottom of the file in newer installs, in a “— CATEGORY: Bootstrapped or Legacy Settings —” section, but they can be anywhere in the file.

Another place they may be found is in the file /etc/freepbx.conf — in that file, look for lines similar to:

$amp_conf[‘AMPDBUSER’] = ‘freepbxuser’;
$amp_conf[‘AMPDBPASS’] = ‘password’;

Those will give you the values to insert into the user and pw variables in the script. YOU MUST INSERT THE CORRECT VALUES OR THE SCRIPT WILL NOT WORK! By the way, if you have both of the above-mentioned files, make sure that the AMPDBUSER and AMPDBPASS variables are set to the same respective values in both files, otherwise your CDR Reports page may not work.

Finally, if you want an e-mail notification when your IP address has changed, uncomment the two lines under “# OPTIONAL SEND EMAIL TO SYSTEM ADMINISTRATOR(S)” and modify the first line appropriately (make sure you use one or more valid e-mail addresses!). BE CAREFUL NOT TO DELETE THE TRAILING APOSTROPHE (just before the semicolon). Yeah, I did that once. 🙁

IF YOUR ARE RUNNING FREEPBX 12 (NOT FreePBX 14, see below), it appears they have changed the location where the IP address is stored in the database. In that case, two sections of the script need to be changed:

Change this:

		# GET IP ADDRESS FROM DATABASE
		my ($externip) = $connect->selectrow_array("SELECT data FROM sipsettings WHERE keyword like ?", undef, "externip_val");

To this:

		# GET IP ADDRESS FROM DATABASE
		my ($externip) = $connect->selectrow_array("SELECT val FROM kvstore WHERE `key` = ?", undef, "externip");

Change this:

						# IP HAS CHANGED SO UPDATE IP ADDRESS IN DATABASE
						$connect->do("UPDATE sipsettings SET data = ? WHERE keyword = ?", undef, "$ip", "externip_val");

To this:

						# IP HAS CHANGED SO UPDATE IP ADDRESS IN DATABASE
						$connect->do("UPDATE kvstore SET val = ? WHERE `key` = ?", undef, "$ip", "externip");

IF YOU ARE RUNNING FREEPBX 14, it appears they have changed the location again where the IP address is stored in the database. In that case, two sections of the script need to be changed:

Change this:

		# GET IP ADDRESS FROM DATABASE
		my ($externip) = $connect->selectrow_array("SELECT data FROM sipsettings WHERE keyword like ?", undef, "externip_val");

To this:

		# GET IP ADDRESS FROM DATABASE
		my ($externip) = $connect->selectrow_array("SELECT val FROM kvstore_Sipsettings WHERE `key` = ?", undef, "externip");

Change this:

						# IP HAS CHANGED SO UPDATE IP ADDRESS IN DATABASE
						$connect->do("UPDATE sipsettings SET data = ? WHERE keyword = ?", undef, "$ip", "externip_val");

To this:

						# IP HAS CHANGED SO UPDATE IP ADDRESS IN DATABASE
						$connect->do("UPDATE kvstore_Sipsettings SET val = ? WHERE `key` = ?", undef, "$ip", "externip");

(Thanks to “Tony” for posing the FreePBX 14 changes in the comment section.)

Regardless of which version you are running (12 or 14), BE CAREFUL, in both of the above lines the word keyword (without quotes) is changed to `key` (with backtick quotes). If you leave out the backticks, or change them to something else such as apostrophes, IT WILL NOT WORK.

Save your script to either the /root directory or the /var/lib/asterisk/agi-bin directory, or to another location of your choosing. I named it checkip.pl, solely because that was the name of a previous script I had run and I had already created a cron job for it. You must make the script executable, for example:

chmod u+rx /var/lib/asterisk/agi-bin/checkip.pl

Of course you will specify the correct filename and directory. Now it’s time to test the script. From the Linux command prompt, navigate to the directory where you stored the script:

cd /var/lib/asterisk/agi-bin

Now run the script from the command prompt:

./checkip.pl

Hopefully you won’t see any error messages. Remember it’s going out to do a query to get your external IP address, so don’t get concerned if it takes a second or two. If you had an incorrect address stored in your FreePBX Asterisk SIP Settings configuration, it will take longer because it will reload the FreePBX configuration. The script has a couple of different checks to make sure it only stores a real IP address (and not something invalid like an error message) in the database, so if it appears to not be working, make sure the underlying call to the web server or the dig command (depending on which variation you use) is returning a valid IP address.

Usually if you do see errors they will fall into one of two categories. The first is a missing Perl module, which you will need to obtain as described above. The second is a syntax error, which you should not get if you cut and pasted the script, and made the changes noted above. If you get a permissions error, you probably forgot to make the script executable!

Setting up a cron job:

Once it runs without errors, you will want to create a cron job so it runs automatically every five minutes. Do NOT run it more often than that, or the lookup service may ban your IP address, and you don’t want that to happen (whatismyip.com would do that, which is another reason not to use them), and besides, it’s not polite to hog the resources of someone else’s server! And if you are running it on multiple servers at the same IP address, then adjust the polling speed so that the total polling from all servers doesn’t exceed once every five minutes. An occasional additional test is probably not an issue, but if you try to poll every minute you just might get banned!

The usual way to add a cron job is to run this command:

crontab -e

(If you’re not currently running as root use sudo crontab -e instead)

This will open a text editor showing your current cron jobs. Just add a new line to the bottom of the file with your new cron job. To run the script every five minutes, you could use something like this:

*/5 * * * * /var/lib/asterisk/agi-bin/checkip.pl

Or to be more specific as to when the script runs (this will run it exactly on the hour, at five minutes after the hour, at ten minutes after the hour, and so on):

0,5,10,15,20,25,30,35,40,45,50,55 * * * * /var/lib/asterisk/agi-bin/checkip.pl

Just save the changed file when you are finished. The alternate method is to use Webmin’s System | Scheduled Cron Jobs module to set up your cron job.

Final testing:

The easiest way to test to make sure this is all working is to wait until a time that there are no active calls on the system, then go to the Asterisk SIP Settings configuration page and change the External IP address to something invalid (just change the last digit of the current address and Submit Changes, then do the usual orange bar reload). On the next five minute interval, the script should detect that the external IP address doesn’t match the one stored in the database, and it will write the correct value to the database and reload Asterisk. If you watch the Asterisk CLI during this time, you should actually see the reload take place. After that, if you go back to the Asterisk SIP Settings configuration page, the correct IP address should be there. To be extra safe, you should also view the contents of the file /etc/asterisk/sip_general_additional.conf and make sure that the externip= line shows the correct IP address.

Now you don’t have to worry about frantic calls from users at inopportune times because your ISP changed your IP address and none of the phones are working, and you also won’t have any of the problems associated with the Dynamic IP method!

I want to thank Moshe Brevda for giving me the information I needed to do the MySQL database write, after a particularly frustrating middle of the night session (not helped by bumping into a truly arrogant bastard on an IRC channel), and also for one correction to this article (see my comment in the comments section below). If any “Perl purists” are reading this and you want to offer a constructive comment without giving me any attitude, I’m fine with that. But if you are like some of your I-know-it-all-and-your-coding-sucks brethren in the IRC channel, don’t even waste your time posting a comment, because I won’t approve it. No, you really DON’T need to use any other Perl database modules to do this simple task, and no, I DON’T want to learn your philosophy of writing Perl code (there are some really sucky mom’s-basement-dwellers inhabiting the IRC channel — some of those folks really need to get professional help, and that is all I will say about that). EDIT: Credit to the article Quickly Get an External IP Address from the Command Line (OS X Daily) for revealing the method of using dig with OpenDNS to get your IP address.

NOTE: As usual, there are no warranties — we’re experimenters here, and sometimes we don’t catch all the bugs, especially on the first go around! However, I would assume that anyone who is running a “professional” installation would pay their ISP for a true static IP address (one that never changes), and therefore wouldn’t need one of these scripts in the first place.