PJSIP Edition – How to use an Obihai 200 series VoIP device as a gateway between Google Voice and FreePBX

TelephoneA year ago we published an article entitled “How to use an Obihai 200 series VoIP device as a gateway between Google Voice and FreePBX” and in that article we noted that we were using chan_sip even though chan_sip is being deprecated. So on the one-year anniversary of that article we thought we’d show you how to do the same thing, but using PJSIP. This article is actually a duplicate of that original article, but with all the parts that used chan_sip now changed to use PJSIP, plus a bit of additional text.

This article is intended for a specific, probably rather narrow group of readers. It is for people who have experience setting up and configuring FreePBX, and who also currently own an Obihai 200 series device (200 or 202), and that are using standard Obihai firmware and use Obihai’s “OBi Dashboard” to configure your device. It is specifically not intended as an inducement for anyone to go out and buy a new Obihai device, because in our opinion Obihai hasn’t been treating its customers very well lately, and we have no reason to think that will change. And it is also not for those who like to run custom firmware, or that think that the “OBi Dashboard” is in some way evil – although if you do, this method will probably work just as well on a locally-configured Obihai. But if you happen to have an Obihai 200 series device lying around, and you are running FreePBX, you can put it to good use. This method might also work on an unlocked 300-series device running certain custom firmware but we have no experience at all with that, so we aren’t saying it will or won’t work in such a case, and we don’t support such usage. This method will not work with older Obihai 100-series devices, though you can still use those for FreePBX extensions or other types of SIP connections.

As always we are telling you how we did this, which is not necessarily how you should do it. Any changes you make to your Obihai or FreePBX configuration are at your own risk, and we assume you know what you’re doing. If you somehow manage to really screw things up, that’s on you, not us. We don’t guarantee that this will work for everyone, we just know it did for us.

Some other technical information: The method we show here uses PJSIP, not the older chan_sip, for the connection to FreePBX. We note that chan_sip is being deprecated in the newest versions of Asterisk but we suspect that it will more than likely continue to work for years to come. Nevertheless, some have chosen to bite the bullet and convert to PJSIP now, so this revision of the article is for those folks. We assume that you have already set up your extensions and trunks to use PJSIP rather than chan_sip, and therefore we won’t go over the basics of PJSIP configuration, except as they relate to this specific use.

We do suggest that if your Obihai device has previously been configured, you follow this procedure to start over with a clean configuration:

  • Completely remove the device from the “OBi Dashboard”, as you would if you planned to transfer ownership to someone else.
  • Then do a hard reset of the Obihai device – dial ***8 from a connected phone and follow the prompts to restore the factory default settings.
  • If there were previously one or more Google Voice accounts configured on the device and you plan to continue using any of those same accounts, log into those Google Voice accounts and remove the Obihai device as a destination. If you don’t do this, then after following this procedure you will see two Obihai device destinations in each Google Voice account, only one of which will be valid, and it will be difficult to tell which one is the correct one. Also, keeping an old invalid Obihai destination in your Google Voice account configuration may stop incoming calls from getting to your Obihai.
  • Then add the device back to the “OBi Dashboard”, as you would if you had just purchased it new.

This is entirely optional, but it does help make sure that you don’t have any settings from an old configuration messing things up.

Also, you need to have the latest firmware. Dial ***1 to find out the local IP address of your device and go to that page and see if it comes up with the Polycom logo – note that if you cannot access the device, you may need to dial ***0 and then 30# and follow the prompts to enable WAN access. Login using “admin” as the username, and use the password shown under “Webpage Admin Password” on the “OBi Dashboard” at Obihai’s site – on that site you may need to click the gear icon next to your device to see the Webpage Admin Password. If it’s still the default password, this might be a good time to change it to something a bit more secure, but if you do be sure to make a note of it, because you will need it later in these instructions.

If your device’s web pages still come up with the old Obihai logo, dial ***6 to see if new firmware is available, and if so let it install. If it does not find new firmware, then go to System Management/Auto Provisioning, and look to see if there is a value entered for the FirmwareURL setting. You may need to change this to point to a more recent firmware version. For example, our device currently shows this in that field:

IF ( $FWV < 3.2.2.5921 ) FWU http://fw.obihai.com/OBi202-3-2-2-5921EX-332148940.fw

That is all one line even if it is split on this page. We are not telling you to copy that verbatim to your device, just that this field is what seems to control what version of the firmware you receive. Normally if that field is set correctly, your device should grab the latest firmware after a reboot, though you may need to dial ***6 to get it started. Do not unplug or even touch the Obihai while it is upgrading firmware or you may brick it! After a successful upgrade the device’s web pages should be branded Polycom rather than Obihai.

One other thing we very strongly suggest is that you set your Obihai device to a fixed IP address on your local network. This can either be done in the Obihai’s device settings, under System Management/WAN Settings, or in your router’s configuration – it doesn’t matter as long as your Obihai is always at the same local IP address. If you don’t do this you will not be able to use parts of this method.

The assumption we make here is as follows: An Obihai 200-series device can support up to four “service providers”, up to three of which can be Google voice accounts, and one of which is in this method a FreePBX extension. There are technical reasons for this limitation but we won’t go into those here. The point is that any given Obihai 200-series device can bridge up to three Google Voice accounts to FreePBX, and we assume those will be designated as Service Provider 1 (SP1), Service Provider 2 (SP2), and Service Provider 3 (SP3) in the Obihai configuration. Your FreePBX extension will be on SP4. In the case of an OBi202, which has two phone ports, you can have a FreePBX extension associated with each phone port. If you are connecting your OBi202 to only one or two Google Voice accounts, then your two extensions can be on SP3 and SP4. But if you are connecting to three Google Voice accounts and still want to let each phone port on an OBi202 be on a different extension, then assign the extension you want associated with Phone Port 1 to SP4, and we’ll tell you later how to configure the extension you want associated with Phone Port 2.

If you do not use SP4 for at least one of your FreePBX extensions then these instructions probably won’t work for you, since we have assumed throughout that SP4, and by association, ITSP Profile D will be used with your FreePBX extension (or at least with one of them if you have an OBi202). You could modify the instructions to take this into account, but chances are you’re going to miss something and it won’t work as intended.

We assume you know how to configure a FreePBX extension, by selecting a “Generic Service Provider” in the “OBi Dashboard” and then pointing it at your FreePBX server. Once again, just be sure to use SP4 for your FreePBX extension, or the configuration examples shown here won’t work without modification. Note that you may need to modify the phone port’s DigitMap and OutboundCallRoute settings to allow calls to other extensions, but that is beyond the scope of this article. You can make SP4 the Primary Line for Phone Port 1, but if you have an OBi202 we recommend that you do NOT make ANY of the service providers the Primary Line for Phone Port 2, at least not yet. OBi200 users don’t need to worry about this; it won’t affect you because you only have a single phone port.

You can configure your Google Voice account(s) in the normal manner using the “OBi Dashboard”, in fact if there’s a way to do it without using the Dashboard we don’t know about it, at least not without using custom third-party firmware which is beyond the scope of this article. Get everything set up and working normally – get your first Google Voice account set up on SP1 and make sure it is working, then if you have additional accounts add them on SP2 and if necessary, SP3. Make sure that you can make and receive calls on your Google Voice account(s) before you go any further. Note that you can use dialing prefixes to make test calls using a particular Service Provider without setting it as your Primary Line – for example **1 followed by the number you are calling will send the call through the account associated with Service Provider 1 in the Obihai configuration, and the **2 and **3 prefixes will do the same with regard to Service Providers 2 and 3.

So now that you have your FreePBX extension working and your Google Voice accounts set up and configured, there are two things that need to happen. One is to redirect all incoming Google Voice calls to a FreePBX PJSIP trunk, which will be used for incoming calls only. And the other is to send all outgoing calls to a Custom trunk, and configure the Obihai to correctly route them to the correct Google Voice accounts. Some users may not need both of these – for example, if your main reason for wanting to route calls through FreePBX is so you can use its blacklist and other call screening features on incoming calls, then you may not need the outbound connectivity. But we’ll show you how to do both.

Preliminary FreePBX Configuration for PJSIP users:

In FreePBX’s settings please check your Asterisk SIP settings, PJSIP tab, and look to see what the Endpoint Identifier Order is set to. The Default order as of this writing is as follows:

  • ip
  • username
  • anonymous
  • header
  • auth_username

But this order will prevent proper operation if you have two or more things registering or sending traffic from the same IP address. So, for example, if you are using an Obihai as both an Asterisk extension (for a phone plugged into the phone port) and as an Asterisk trunk, all incoming traffic will be considered as one or the other if you are using the default Endpoint Identifier Order, because all that traffic is coming from the same IP address. So we recommend changing the order to this:

  • auth_username
  • username
  • ip
  • anonymous
  • header

What you don’t want is for it to match on the IP address first. If you’ve been having problems getting PJSIP to work generally, changing this order from the default to our recommended order may cure several ills. If you are converting from chan_sip, it’s rare that you’d want to first match on the IP address! Note that after you make this change and you reload FreePBX, you must also restart Asterisk for it to take effect (use “core restart gracefully” or “core restart when convenient” from the Asterisk CLI).

Handling incoming Google Voice calls:

☞ These changes must be made using the OBi Dashboard’s Expert Configuration option.

Go to Voice Services/Gateways & TrunkGrps – we’ll be changing the settings for Voice Gateway1 (vg1). You can use any unused Voice Gateway, but the examples here assume the use of vg1. Start by unchecking the checkboxes under “OBiTALK Settings” for these values: Name, AccessNumber, AuthUserID, and AuthPassword. Then click “Submit” at the bottom of the page. If any of the checkboxes in the “Device Default” column for those settings are now checked, uncheck them and click “Submit” again. You need to do this or the page won’t let you enter the new values. This is true anyplace we make changes to any of the settings in the OBi Dashboard – if either of those boxes are checked, they must be unchecked and “Submit” clicked before you can make changes.

Now you can enter the new settings for vg1:
Name: Anything you like to identify it, such as FreePBX trunk
AccessNumber: SP4(192.168.x.x) – replace 192.168.x.x with the fixed IP address of your FreePBX server
AuthUserID: The FreePBX trunk name, we’ll use gvgateway in this example
AuthPassword: The password (or as FreePBX calls it, the Secret) that will be used with the Asterisk trunk. Do not leave this blank!

When you have these the way you want them, click Submit. Note that for the AccessNumber setting we specified SP4, which should be your FreePBX extension. This isn’t actually using SP4, but rather it is telling the device that this voice gateway uses the same technology (SIP) as SP4, so don’t worry that FreePBX will confuse calls on vg1 with calls from your extension.

We are using a password in this configuration because we had problems when we tried not using one, and also for a bit of additional security. In addition, we’ll be limiting the trunk to only accepting calls from the IP address of your Obihai device. For now we’re assuming the Obihai device is on the same local network as the FreePBX server, or at least that it’s at a fixed IP address.

Next, we must configure the Google Voice accounts to send incoming calls to this Voice Gateway.

Go to Voice Services/SP1 Service and find the setting X_InboundCallRoute near the top of the page. In order to configure this properly you need to know the Google Voice number associated with this Google Voice account, so if you don’t know what it is then log into the Google Voice account and find it there. Now change this setting as follows:

X_InboundCallRoute: vg1(XXXXXXXXXX/$1)

Replace XXXXXXXXXX with the ten digit Google Voice number, and click “Submit”. Do not under any circumstances change any other settings on the page! If you do you may screw up the configuration so badly you’ll have to start over with the factory reset again. If you have more than one Google Voice account then do the same thing under SP2 Service and if necessary, SP3 Service, using the Google Voice number associated with that particular Google Voice account in place of the XXXXXXXXXX.

Now we need to increase the maximum number of sessions between the device and the FreePBX server.

Go to Voice Services/SP4 Service and find the “Calling Features” section, and under that the setting for MaxSessions. We suggest increasing this number from the default, to at least 6. We used 10, but the Obihai may not be able to handle that many simultaneous connections. Don’t forget to click “Submit”.

That concludes the changes you need to make on the Obihai to handle incoming calls.

☞ These changes must be made on the FreePBX server.

Next we must turn our attention to FreePBX. The first thing we need to do is edit /etc/asterisk/extensions_custom.conf, so in a ssh session enter this – you can use your text editor of choice, we like nano:

nano /etc/asterisk/extensions_custom.conf

Add the following to the end of the file (note that some lines are wrapped, so you may wish to cut and paste them into a text editor in order to view them correctly):

[custom-from-obihai]
exten => _X!,1,Set(CALLERID(num)=${CUT(EXTEN,/,2)})
exten => _X!,n,Set(CALLERID(ani)=${CALLERID(num)})
exten => _X!,n,Set(CALLERID(name)=${SHELL(curl --silent --digest --user admin:obipassword http://192.168.X.X/callstatus.htm --stderr - | grep -n "<td>Peer Number<td>${CALLERID(num)}" | grep -o -P '(?<=<td>Peer Name<td>).*?(?=<td>)' | tr -d '\n')})
exten => _X!,n,ExecIf($["${CALLERID(name)}"="${CALLERID(num)}"]?Set(CALLERID(name)=))
exten => _X!,n,Set(CDR(did)=${CUT(EXTEN,/,1)})
exten => _X!,n,Goto(from-pstn-e164-us,${CUT(EXTEN,/,1)},1)
exten => h,1,Macro(hangupcall,)

Replace obipassword with the password you use to log into your Obihai device’s web interface when you log in locally (this is admin, unless you have changed it as we suggested earlier in this article). This is probably not the same as the password you use when you log into your Obitalk account, so don’t confuse the two. Also, replace 192.168.X.X with the local IP address of the Obihai device.

This is used to get the Caller ID number on incoming calls, and it also attempts to get the Caller ID name on the rare occasion when Google Voice sends one. Note this only works if, on the Obihai device, the X_InboundCallRoute setting in the Service Provider settings for Google Voice account(s) contains the /$1 appendage, in case you were wondering what that was for. And also, the curl command must be installed and working on the Asterisk server; usually this is installed by default but you can check by typing “which curl” at the Linux command prompt – it should return a path, typically /usr/bin/curl. Note that attempting to get the Caller ID name from the Obihai device does take a small amount of time, because it’s actually querying the device’s web interface, since there’s no other way to get it. But, you probably won’t notice any delay when the Obihai device is on the same local network as the Asterisk server. If you don’t care about trying to get a Caller ID name from the Obihai device, just omit the two lines that contain references to the CALLERID(name) variable.

Next, using the FreePBX web interface, create a new PJSIP Trunk. Under the General tab the only things you need to fill in are the Maximum Channels and the Trunk Name, which must match the AuthUserID you used for Voice Gateway1 on the Obihai – we suggested gvgateway:

Trunk Name: gvgateway
Maximum Channels: 6
Disable Trunk: No

Skip the other settings on that page, other than if you like you can fill in an Outbound CallerID to stop FreePBX from complaining, even though this trunk will not be used for outgoing calls. Next, under the pjsip Settings tab, General tab:

Username: Leave blank (it will change to “Username is trunk name”) as you change the other settings
Secret: The password you used for AuthPassword in the Obihai’s Voice Gateway settings
Authentication: Inbound
Registration: None
SIP Server: 192.168.X.X (replace with the local IP address of the Obihai device)
Context: custom-from-obihai

Leave all the other settings under the pjsip Settings tab, General tab at their defaults unless you have some reason to change them. Then, under the pjsip Settings tab, Advanced tab, leave all settings at the defaults EXCEPT for the following (depending on which version of FreePBX you are running, some of these settings may already be the defaults):

Permanent Auth Rejection: No
Forbidden Retry Interval: 30
Fatal Retry Interval: 30
Max Retries: 10000
Qualify Frequency : 0
Match (Permit): 192.168.X.X
(replace with the local IP address of the Obihai device).

Leave all the other settings under the pjsip Settings tab, Advanced tab at their defaults unless you have some reason to change them. Then, under the pjsip Settings tab, Codecs tab, the only codecs that should be enabled are ulaw and (if you have it installed) opus, with ulaw at the top of the list. Google Voice does use the opus protocol, but we are not sure if the Obihai device will use it, however it doesn’t hurt anything to enable it if you have it available.

As you see there are several places where you need to replace 192.168.X.X with the local IP address of the Obihai device in these instructions. This is why we strongly urged you to assign a fixed IP address to the Obihai.

Don’t forget to click the Submit button before leaving the PJSIP Trunk configuration page, or you’ll get to start over and do it all again!

Finally you need to create your Inbound Route(s). You need one for each of your 10-digit Google voice numbers that are coming in via the Obihai. When creating them, under the “Advanced” tab you may want to set “Force Answer” to Yes – this causes the call to be answered immediately when it comes in, so that it will not go to Google Voice’s voicemail. In rare circumstances this may cause a problem where calls come in and when you answer there is no one there, but the caller continues to hear ringing and then winds up at Google Voice’s voicemail. We have not experienced this issue in recent firmware releases, but if you do then set the “Pause Before Answer” setting to 1, which delays one second before answering the call. Also, if you have configured CallerID Superfecta, you may want to enable that on the Inbound Route, in the “Other” tab, because Google Voice seldom provides Caller ID name information on incoming calls.

In your Inbound Route you can make the destination whatever you like, including but not limited to the FreePBX extension served by the Obihai device, in order to take advantage of FreePBX’s various features.

After you have made all these changes don’t forget to apply the configuration in FreePBX! Now any calls made to one of your Google Voice numbers should come into FreePBX and be routed according to the Inbound Route specifications.

Sending outgoing calls to Google Voice:

☞ These changes must be made using the OBi Dashboard’s Expert Configuration option.

Some users may not care about doing this but for those that do, here’s how it is done.

Go to Service Providers/ITSP Profile D/SIP and look for the X_AccessList setting. This should be filled in with the local IP address of your FreePBX server, so that your Obihai will not accept connections from any other IP address via SP4. Note that we are assuming here that ITSP Profile D is associated with SP4, which will always be the case unless you have gone out of your way to change it.

While you are on this page, make sure that the setting X_UseRefer is enabled – check the box if it isn’t – and that X_SessionRefresh is disabled – uncheck that box if necessary. Then Submit the changes. So to recap, these are the settings to change if necessary:

X_UseRefer: Checked
X_SessionRefresh: Unchecked
X_AccessList:
Set to IP address of FreePBX

Next, go back to Voice Services/SP4 Service and change the X_InboundCallRoute setting. The following is how it might be set for three Google Voice accounts on SP1 through SP3:

{>(<**10:0>11x.|<**11:1>xxxxxxxxxx):sp1},{>(<**20:0>11x.|<**21:1>xxxxxxxxxx):sp2},{>(<**30:0>11x.|<**31:1>xxxxxxxxxx):sp3},{>(ext1):ph},{>(ext2):ph2}

This is just an example, and in any case you’d need to replace ext1 and ext2 with the extension numbers of your Phone Ports. But don’t just copy and paste that – instead, you should construct this setting according to your particular configuration. So here is an explanation of each part, and keep in mind that each part starts with a { and ends with a } and that the parts are separated by commas. Use only the parts you need!

{>(<**10:0>11x.|<**11:1>xxxxxxxxxx):sp1}

The above will route all calls prefixed with **1 that fit the pattern of 11 digit calls starting with “1”, or international calls starting with 011, to the Google Voice account on SP1. Note that it is the FreePBX trunk that will be applying the **1 prefix, not the person making the call. If you don’t want to allow international calls, then use this instead:

{>(<**11:1>xxxxxxxxxx):sp1}

The next part does the same thing for calls prefixed with **2, routing them to SP2. Of course this assumes you have a second Google Voice account; if not you’d omit this entirely:

{>(<**20:0>11x.|<**21:1>xxxxxxxxxx):sp2}

And as before, if you don’t want to allow international:

{>(<**21:1>xxxxxxxxxx):sp2}

And if you have a third Google Voice account then you should include one of these two parts:

{>(<**30:0>11x.|<**31:1>xxxxxxxxxx):sp3}
or
{>(<**31:1>xxxxxxxxxx):sp3}

The next part deals with incoming routing to extensions. If you have an Obi200 and therefore only one phone port, you’d use this at the end:

{>(ext1):ph}

Replacing ext1 with the actual extension number you are using in FreePBX. However, if you have an OBi202, and you have three Google Voice accounts but you want each phone port to be on a separate extension, so that both extensions have to share a Service Provider connection, then you’d also use this to route the second extension’s calls to phone port 2:

{>(ext2):ph2}

Where ext2 would be the extension number you want associated with phone port 2.

Note that specifying the extension numbers this way adds a bit of security, because any calls that may arrive at your Obihai that are not addressed to a valid extension number or Google Voice number will be rejected. There is, by design, no “default route” for calls that do not match one of the expected patterns.

So for an OBi200 with three Google Voice accounts on SP1 to SP3, and FreePBX extension 123 on SP4, the X_InboundCallRoute setting would be:

{>(<**10:0>11x.|<**11:1>xxxxxxxxxx):sp1},{>(<**20:0>11x.|<**21:1>xxxxxxxxxx):sp2},{>(<**30:0>11x.|<**31:1>xxxxxxxxxx):sp3},{>(123):ph}

But if it were an OBi202 with the same configuration but also an extension 124 going to phone port 2:

{>(<**10:0>11x.|<**11:1>xxxxxxxxxx):sp1},{>(<**20:0>11x.|<**21:1>xxxxxxxxxx):sp2},{>(<**30:0>11x.|<**31:1>xxxxxxxxxx):sp3},{>(123):ph},{>(124):ph2}

By the way, we realize that some very astute readers may question why we’re replacing either a 0 or a 1 with the same character – the answer is, when we didn’t use any replacement character it didn’t work! It’s as simple as that. This may be a firmware bug, because previously it worked without needing to have at least one replacement character.

While on this page, make note of but don’t change the X_UserAgentPort setting – it will probably be either 5063 or 5083, but in any case you’ll need to know it later in these instructions. Also, check that the X_EnforceRequestUserID setting is not checked – this is very important; if you don’t do this then outgoing calls may not work. And you may also want to verify that MaxSessions is set to something higher than the default. So, these are the changes on this page:

X_InboundCallRoute: See discussion above
X_UserAgentPort: Make note of but don’t change
X_EnforceRequestUserID: Unchecked
MaxSessions:
At least 6, we use 10 but that may be too many.

Don’t forget to submit your changes. Before logging out of the “OBi Dashboard”, it may be a good idea to go back to the main Dashboard page at this point and click on the gear icon for your device, and look under the Phone Port Configuration Summary to make sure that the “Primary Line for Outgoing Calls Route to:” setting is correct for each of your phone ports. Specifically, you probably want it to be set to SP4 for Phone Port 1, and “Not Configured” for Phone Port 2 (for now), assuming that you plan on routing all your outgoing calls through FreePBX. You change this by clicking on the gear icon next to the service provider you wish to choose as the primary, then when the page refreshes and you have dismissed any popups, check the appropriate checkbox next to “Primary Line for Outgoing Calls” to select that Service Provider. But do keep in mind that anything you put in the OutboundCallRoute setting for a phone port may override this setting.

That’s all of the changes you need to make on the Obihai to handle outgoing calls, except for a couple that unfortunately cannot be made from the “OBi Dashboard” at this time.

☞ These changes must be made using the Obihai device’s web interface.

Log into your Obihai device’s web interface and go to Service Providers/ITSP Profile D/General and make sure that the following two settings are enabled:

X_ICEEnable: Checked
X_EarlyICEEnableIn: Checked

Click Submit, wait for the page to reload, and then click the Reboot button in the upper right corner of the page. This fixes a specific issue with outgoing calls. This assumes that ITSP Profile D is associated with SP4, which will always be the case unless you have gone out of your way to change it.

☞ These changes must be made on the FreePBX server.

Go into the FreePBX web configuration and create one new Custom Trunk – note Custom, not SIP or PJSIP – for each of your Google Voice accounts. Here’s how they are configured:

• General tab:

Trunk Name: Whatever you want
Outbound CallerID: The 10 digit Google Voice number for the account
CID Options: Force Trunk CID
Maximum Channels: 2
Disable Trunk: No
(It’s important to check this setting if you have copied the configuration from another trunk!)

• Dialed Number Manipulation Rules tab – Dial patterns:

**1+1NXXNXXXXXX
**11+NXXNXXXXXX
**11areacode+NXXXXXX

If your area does not have 7 digit dialing of local calls then omit the last one; but if it does then replace areacode with the actual 3 digit area code. If you wish to allow international calls, then also add this pattern:

**1+011X.

This is set to use the Google Voice account on Service Provider 1 on the Obihai, but if you replace all instances of **1 with **2 or **3 then it will use the Google Voice accounts associated with SP2 or SP3 respectively. We chose this method because it is the exact same pattern you’d use to select a particular service provider when dialing from a phone connected to the Obihai.

● Custom Settings tab – Custom Dial String:

PJSIP/gvgateway/sip:$OUTNUM$@ip_address_of_obihai:X_UserAgentPort

This is why we said to take note of the X_UserAgentPort setting earlier. So if, for example, your Obihai is at 192.168.1.123 and the X_UserAgentPort was set to 5083, you’d use this:

PJSIP/gvgateway/sip:$OUTNUM$@192.168.1.123:5083

Note that “gvgateway” is the name of the PJSIP trunk we created in the previous section. This must be a valid PJSIP trunk name on your system – PJSIP is different from chan_sip, in that when specifying a dial string in chan_sip you don’t need to include the name of a chan_sip trunk in this way, but under PJSIP you do need to include the name of a PJSIP trunk. We don’t know why; it makes no sense to us, but we just do it the way that works.

That’s it – submit your changes. Repeat the process for any additional Google Voice accounts on that Obihai. Remember that it is the **n prefix that selects the Google Voice account that the call goes out on, so if instead of using multiple trunks you wanted to use a single trunk and make the Google Voice account selection in your Outbound Routes you could probably do that, although we imagine that it would be a lot more complicated to do it that way.

After you’ve created your custom trunks, don’t forget to apply the configuration. Now you can select those trunks in your Outbound Routes, as usual in FreePBX.

OBi202 users only: How to use one Service Provider connection for two FreePBX extensions

As we mentioned earlier, Obi202 devices have two phone ports, and maybe you’d like to have a separate FreePBX extension associated with each phone port. If you are already using SP1 through SP3 for other purposes, such as Google Voice connections, then you are only left with SP4 to use for both extensions. So as we said above, what you want to do in that case is configure SP4 as the extension that will be associated with Phone Port 1 (ph1), and you do that in the normal manner using the “OBi Dashboard”, although you may need to make some additions to the default DigitMap and OutboundCallRoute settings to allow extension to extension calls. Since we don’t know how extensions are numbered on your system, we can’t really explain how to do that, but we are aware that there is a tool called OBiCfg (this is a .zip file that expands to a Windows-compatible program) that may help you configure those settings. If you don’t use Windows, the program will probably run under WINE on Linux or MacOS based systems. Some time back we were able to convert this program to a Mac application, more or less, using a Mac program called Wineskin but that’s not exactly a straightforward process, and we haven’t tried to do it recently.

But the main thing is that you should get your Phone Port 1 working as a FreePBX extension, and make sure that it can make and receive calls. Then, and only then, can you configure Phone Port 2. Here is how, starting with the Obihai configuration.

☞ These changes must be made using the OBi Dashboard’s Expert Configuration option.

Go to Service Providers/ITSP Profile D/General. In your browser, place your cursor inside the text field for the DigitMap setting, and select the entire field and copy it. This assumes that ITSP Profile D is associated with SP4, which will always be the case unless you have gone out of your way to change it, and that SP4 is used for the FreePBX extension associated with Phone Port 1, which you have already configured. You may wish to temporarily paste the copied text into a text editor if you don’t use a clipboard manager, so that you don’t accidentally copy something else over it.

Go to Voice Services/Gateways & TrunkGrps – we’ll be changing the settings for Voice Gateway2 (vg2), since we’ve already used vg1. You can use any unused Voice Gateway, but we assume the use of vg2 in these instructions. We’ll be changing the Name, AccessNumber, DigitMap, AuthUserID, and AuthPassword settings, as follows:

Name: The extension number you wish to use for this extension
AccessNumber: SP4(192.168.x.x) – replace 192.168.x.x with the fixed IP address of your FreePBX server
DigitMap: The DigitMap that you copied from ITSP Profile D
AuthUserID: The extension number you wish to use for this extension again
AuthPassword: The password (or as FreePBX calls it, the Secret) that will be used with this extension. Do not leave this blank!

Then click Submit.

Go to Physical Interfaces/PHONE 1. In your browser, place your cursor inside the text field for the OutboundCallRoute setting, and select the entire field and copy it. Paste it into any plain text editor you have handy – this is just for your convenience so you can see the entire setting. We are going to modify this slightly and the use it as the OutboundCallRoute for Phone Port 2. Without knowing exactly what you have there now, we can’t just give you a replacement to paste in – you need to edit what’s there now. But note that we are not changing this setting in Phone Port 1 at all, so don’t try to edit it in place – copy it to a text editor so you won’t accidentally save it to the wrong Phone Port configuration.

Before we continue, please note the following:

These instructions assume that you want to send all calls from Phone Port 2 to your FreePBX server, and that if the call is ultimately destined for a Google Voice connection then FreePBX will send it back to your Obihai. In other words, you want your FreePBX extension to be your “Primary Line”. If that is NOT the case, and you want the Primary Line for Phone Port 2 to be a Google Voice account, then you can set that up in the “OBi Dashboard” in the normal manner. In this case you will not want to make any of the changes shown below in your DigitMaps or in the OutboundCallRoute, EXCEPT that if you have added a rule that routes calls to other extensions to sp4, you’ll want to change that to point to vg2. So make that change only if appropriate, and then paste the entire text into Phone Port 2’s OutboundCallRoute, click Submit, and then skip down to the paragraph that begins with “We’ve already showed you above how to route incoming calls for a particular extension to Phone Port 2” and continue from there. But if you DO want your FreePBX extension to be your “Primary Line”, which we recommend, then continue on from here.

There are two basic things you need to do in the OutboundCallRoute setting you just copied:

First, replace any references to pli (typically part of the text Mpli) with vg2. You need to do this because pli stands for “Primary Line” but you can’t select a Voice Gateway as a primary line in the “OBi Dashboard”, so this makes that change in the Phone Port configuration. Typically there will be two rules that need to be changed:

{([1-9]x?*(Mpli)):pp} is changed to {([1-9]x?*(Mvg2)):pp} – this is near the beginning of the text.
{(Mpli):pli} is changed to {(Mvg2):vg2} – this is near the end of the text, and note there are two replacements in this rule.

Next, you need to change any existing references to sp4 to point to vg2, EXCEPT for the rule that looks like this: {(<**4:>(Msp4)):sp4}. Don’t change that one, but any other references to sp4 should be changed to vg2, unless you have some specific reason for leaving them set to sp4. When making changes, note that rules are enclosed in {curly braces} and then separated by commas, so be careful not to accidentally delete a curly brace or comma. Just make sure that nothing remains routed to sp4 other than the single rule for the **4 prefix mentioned above; otherwise some calls from Phone Port 2 may appear to be coming from Phone Port 1’s extension when they arrive at FreePBX.

Once you have the OutboundCallRoute text modified as described above, go to Physical Interfaces/PHONE 2 – make sure you are not still in PHONE 1 where you copied the settings from; you must now be in the PHONE 2 configuration – and paste your modified settings into the OutboundCallRoute setting there, and Submit.

There are two other settings on this page that needs to be changed, DigitMap, which is just above the OutboundCallRoute setting, and CallReturnDigitMaps, which is just below it. It would be safest to copy those over from Physical Interfaces/PHONE 1, make the necessary changes, and then paste them in to the equivalent fields in Physical Interfaces/PHONE 2, but typically each of these fields will by default be the same as their equivalents in Phone Port 1 anyway.

What you need to do in both the DigitMap and CallReturnDigitMaps is replace any references to pli with vg2. In the DigitMap setting this will typically need to be changed in two places:

[1-9]x?*(Mpli) is changed to [1-9]x?*(Mvg2) – this is near the beginning of the text.
(Mpli) is changed to (Mvg2) – this is near the end of the text.

And in the CallReturnDigitMaps there is typically only one replacement that needs to be made:

{pli:(xx.)} is changed to {vg2:(xx.)} – this is near the beginning of the text.

Again, when making these changes make sure you don’t accidentally delete a curly brace or comma, and don’t forget to click Submit when you are finished.

Before leaving the “OBi Dashboard”, go back out to the main Dashboard page and click on the gear icon for your device, and look under the Phone Port Configuration Summary to make sure that the “Primary Line for Outgoing Calls Route to:” setting for Phone 2 says “Not Configured”. If, instead, it shows a service provider (SP1, SP2, SP3, or SP4) then look in the section just above, “Configure Voice Service Providers (SP)”, and click the gear icon next to that Service Provider, dismiss the popup, and then on the line “Primary Line for Outgoing Calls”, UNCHECK the checkbox next to Phone 2. This should leave Phone 2 with no configured Primary Line, meaning it should only use the rules in the settings we configured above. It would be great if we could simply set the Primary Line for Phone Port 2 to Voice Gateway 2, but the “OBi Dashboard” doesn’t allow it, which is why we had to change all those instances of pli to vg2.

If, after making these changes and setting up the configuration in FreePBX as described below, you find that you are having problems making some calls, check to see if you have the same issue on Phone Port 1. The reason we said to copy the DigitMap setting from Service Providers/ITSP Profile D/General to Voice Gateway2’s DigitMap was because we assumed that the DigitMap in ITSP Profile D, which should be associated with Phone Port 1 if you have followed these instructions from the beginning, would allow outgoing calls as configured for Service Provider 4 in the “OBi Dashboard”. So if, for example, you allowed 7 digit dialing to a particular area code when you set up SP4, then by copying the ITSP Profile D DigitMap to Voice Gateway2 those same rules should be followed by Phone Port two, PROVIDED you made all the replacements of pli to vg2 and sp4 to vg2 that we documented above.

We’ve already showed you above how to route incoming calls for a particular extension to Phone Port 2, using the X_InboundCallRoute setting under Voice Services/SP4 Service – once again, there needs to be a rule there of the form {>(ext2):ph2} where ext2 is the extension number associated with Phone Port 2.

That’s all you need to do in the Obihai device configuration.

☞ These changes must be made on the FreePBX server.

In FreePBX we need to make a Custom Extension and a new PJSIP trunk. When you create the extension, make sure you specify that it is Custom and not SIP or PJSIP! The details for the Custom Extension are as follows:

Under the General tab, set the User Extension, Display Name and Outbound CID as you normally would – obviously, the User Extension must match the Obihai device settings you used for the Name and AuthUserID for Voice Gateway 2, and especially with the extension number you associated with Phone Port 2 in the X_InboundCallRoute setting under Voice Services/SP4 Service. For all the other tabs, in most cases you can use the same settings that you would if you were creating a PJSIP extension. The major exception to this is in the Advanced tab, Edit Extension section, Dial setting. For that you want to use something like this:

PJSIP/extension_number/sip:extension_number@ip_address_of_obihai:X_UserAgentPort

In both places where you see extension_number, replace it with the number of this extension, and use the actual ip_address_of_obihai. The X_UserAgentPort is the same one we had you make a note of earlier, that was used in the Custom Dial String for the trunk(s) you created for outgoing calls to each of your Google Voice accounts. So if, for example, your extension number is 124, your Obihai is at 192.168.1.123 and the X_UserAgentPort was set to 5083, you’d use this as your Dial setting:

PJSIP/124/sip:124@192.168.1.123:5083

When you finish your custom extension configuration, don’t forget to click Submit. Note that this custom extension is used for calls going TO Phone Port 2 on the Obihai only, although there is one important exception to that – if you set an Emergency CID in the Advanced tab, Extension Options section, it will be used for calls FROM the extension that are routed through an “Emergency” outbound route, provided that the extension number you use in the trunk settings in the next section exactly matches the custom extension’s number.

For calls coming FROM Phone Port 2 we need to create a new PJSIP Trunk – this may sound strange, but it’s the easiest way to handle this. So, create a new PJSIP Trunk. Under the General tab use the following settings:

Trunk Name: MUST exactly match the extension number for the extension, and only the extension number with no additional characters! If FreePBX complains about this, go to the FreePBX Advanced Settings page, System Setup section, and make sure that the “Aggresively Check for Duplicate Extensions” setting is set to “No”.
Outbound CallerID: Set this in the same way you would set a Caller ID for a regular extension, with the Caller ID name and number.
CID Options: Force Trunk CID
Maximum Channels: 3
Disable Trunk: No

Skip the other settings on that page. Next, under the pjsip Settings tab, General tab:

Username: Leave blank (it will change to “Username is trunk name”) as you change the other settings
Secret: The password you used for AuthPassword in the Obihai’s Voice Gateway settings for the extension
Authentication: Inbound
Registration: None
SIP Server: 192.168.X.X (replace with the local IP address of the Obihai device).
SIP Server Port: X_UserAgentPort (replace with the same port number we had you make a note of earlier, that was used in the Custom Dial String for the trunk(s) you created for outgoing calls to each of your Google Voice accounts)
Context: from-internal

Leave all the other settings under the pjsip Settings tab, General tab at their defaults unless you have some reason to change them. Then, under the pjsip Settings tab, Advanced tab, leave all settings at the defaults EXCEPT for the following (depending on which version of FreePBX you are running, some of these settings may already be the defaults):

Permanent Auth Rejection: No
Forbidden Retry Interval: 30
Fatal Retry Interval: 30
Max Retries: 10000
Qualify Frequency : 0
(Optional, only needed if “pjsip show endpoints” shows extension as unavailable)
Match (Permit): 192.168.X.X (replace with the local IP address of the Obihai device)
Trust RPID/PAI: Yes
Send RPID/PAI: Send P-Asserted-Identity header

Leave all the other settings under the pjsip Settings tab, Advanced tab at their defaults unless you have some reason to change them. Then, under the pjsip Settings tab, Codecs tab, the only codecs that should be enabled are ulaw and (if you have it installed) opus, with ulaw at the top of the list. Google Voice does use the opus protocol, but we are not sure if the Obihai device will use it, however it doesn’t hurt anything to enable it if you have it available.

Don’t forget to click the Submit button before leaving the PJSIP Trunk configuration pages, or you’ll get to start over and do it all gain!

Final thoughts

We realize that there are many different ways to do this, and that some work better than others. These are what worked for us. If they work for you, great! PJSIP seems a bit more finicky than chan_sip at this point in time and therefore it was harder to convert these settings to PJSIP than we think it should have been, but at least everything is working now and we aren’t using chan_sip at all anymore, so our system should be fine until the Asterisk folks decide to change up something else.

One that that really gave us fits at first was understanding the difference between registration and authentication in PJSIP trunks. You would think this should have been obvious (and it probably is obvious to real full-time tech guys that work with this stuff all the time), since the concepts are the same as when using chan_sip, but in PJSIP trunk configuration the two settings for Authentication and Registration are shown one right under the other, whereas in chan_sip configuration you need to go to a separate tab in the trunk settings to enter a registration string. Registration is something a device or server does periodically (every few minutes, usually). FreePBX registers with commercial VoIP providers, extensions register with FreePBX, etc.

But, and this is the important part, our understanding is that Voice Gateways on an Obihai device do NOT register. The OBi Device Administration Guide seens to indicate this as well, since when it discusses Voice Gateways it says “that when using a SP trunk to access a (SIP) gateway, the device will … Use the gateway’s AuthUserID and AuthPassword for authentication.” (emphasis added). So, if you fill in a username and password in a Voice Gateway configuration, they use that to authenticate, not to register. Authentication happens on a per-call basis and it is not the same thing as registration. This is why you set the Authentication to Inbound, and the Registration to None on trunks that receive calls from Voice Gateways on an Obihai device. Note that the Voice Gateways only send calls from the Obihai to FreePBX – traffic that flows in the opposite direction uses a different mechanism.

Configuring an Obihai device isn’t the easiest thing to do, and that’s why we stick to using the “OBi Dashboard” – it makes configuration a lot easier. But if you need help understanding dialplans and other internal workings of the Obihai, we suggest you download the OBi Device Administration Guide – it’s a 220 page PDF file. It’s what we used to come up with most of this method, along with a few tricks we’ve picked up in various forums here and there.

One final thought – if you happen to also have an older OBi100 or OBi110 device, keep in mind that it can still be used as a FreePBX extension even though it can no longer connect with Google Voice. But it’s entirely possible to place or receive calls that go through FreePBX, to or from the 200-series device, because those devices still work fine with PJSIP connections, so in a roundabout manner you could still use Google Voice with such devices. It’s also possible to use the Obitalk network as an intermediary instead of FreePBX for such calls, but if you have a FreePBX server we don’t really see much point in doing that, and in any case that’s beyond the scope of this article.

How to use an Obihai 200 series VoIP device as a gateway between Google Voice and FreePBX

TelephoneNOTE: There is a newer version of this article for those who are using PJSIP rather than chan_sip in FreePBX. If you have already converted to PJSIP, please go directly to PJSIP Edition – How to use an Obihai 200 series VoIP device as a gateway between Google Voice and FreePBX.

This article is intended for a specific, probably rather narrow group of readers. It is for people who have experience setting up and configuring FreePBX, and who also currently own an Obihai 200 series device (200 or 202), and that are using standard Obihai firmware and use Obihai’s “OBi Dashboard” to configure your device. It is specifically not intended as an inducement for anyone to go out and buy a new Obihai device, because in our opinion Obihai hasn’t been treating its customers very well lately, and we have no reason to think that will change. And it is also not for those who like to run custom firmware, or that think that the “OBi Dashboard” is in some way evil – although if you do, this method will probably work just as well on a locally-configured Obihai. But if you happen to have an Obihai 200 series device lying around, and you are running FreePBX, you can put it to good use. This method might also work on an unlocked 300-series device running certain custom firmware but we have no experience at all with that, so we aren’t saying it will or won’t work in such a case, and we don’t support such usage. This method will not work with older Obihai 100-series devices, though you can still use those for FreePBX extensions or other types of SIP connections.

As always we are telling you how we did this, which is not necessarily how you should do it. Any changes you make to your Obihai or FreePBX configuration are at your own risk, and we assume you know what you’re doing. If you somehow manage to really screw things up, that’s on you, not us. We don’t guarantee that this will work for everyone, we just know it did for us.

Some other technical information: The method we show here uses chan_sip, not the newer pjsip, for the connection to FreePBX. The reason is that we are running FreePBX on a Raspberry Pi and as best we can tell, it does not have pjsip installed. We realize that chan_sip is being deprecated in the newest versions of Asterisk but we suspect that it will more than likely continue to work for years to come.

We do suggest that if your Obihai device has previously been configured, you follow this procedure to start over with a clean configuration:

  • Completely remove the device from the “OBi Dashboard”, as you would if you planned to transfer ownership to someone else.
  • Then do a hard reset of the Obihai device – dial ***8 from a connected phone and follow the prompts to restore the factory default settings.
  • If there were previously one or more Google Voice accounts configured on the device and you plan to continue using any of those same accounts, log into those Google Voice accounts and remove the Obihai device as a destination. If you don’t do this, then after following this procedure you will see two Obihai device destinations in each Google Voice account, only one of which will be valid, and it will be difficult to tell which one is the correct one. Also, keeping an old invalid Obihai destination in your Google Voice account configuration may stop incoming calls from getting to your Obihai.
  • Then add the device back to the “OBi Dashboard”, as you would if you had just purchased it new.

This is entirely optional, but it does help make sure that you don’t have any settings from an old configuration messing things up.

Also, you need to have the latest firmware. Dial ***1 to find out the local IP address of your device and go to that page and see if it comes up with the Polycom logo – note that if you cannot access the device, you may need to dial ***0 and then 30# and follow the prompts to enable WAN access. Login using “admin” as the username, and use the password shown under “Webpage Admin Password” on the “OBi Dashboard” at Obihai’s site – on that site you may need to click the gear icon next to your device to see the Webpage Admin Password. If it’s still the default password, this might be a good time to change it to something a bit more secure, but if you do be sure to make a note of it, because you will need it later in these instructions.

If your device’s web pages still come up with the old Obihai logo, dial ***6 to see if new firmware is available, and if so let it install. If it does not find new firmware, then go to System Management/Auto Provisioning, and look to see if there is a value entered for the FirmwareURL setting. You may need to change this to point to a more recent firmware version. For example, our device currently shows this in that field:

IF ( $FWV < 3.2.2.5921 ) FWU http://fw.obihai.com/OBi202-3-2-2-5921EX-332148940.fw

That is all one line even if it is split on this page. We are not telling you to copy that verbatim to your device, just that this field is what seems to control what version of the firmware you receive. Normally if that field is set correctly, your device should grab the latest firmware after a reboot, though you may need to dial ***6 to get it started. Do not unplug or even touch the Obihai while it is upgrading firmware or you may brick it! After a successful upgrade the device’s web pages should be branded Polycom rather than Obihai.

One other thing we very strongly suggest is that you set your Obihai device to a fixed IP address on your local network. This can either be done in the Obihai’s device settings, under System Management/WAN Settings, or in your router’s configuration – it doesn’t matter as long as your Obihai is always at the same local IP address. If you don’t do this you will not be able to use parts of this method.

The assumption we make here is as follows: An Obihai 200-series device can support up to four “service providers”, up to three of which can be Google voice accounts, and one of which is in this method a FreePBX extension. There are technical reasons for this limitation but we won’t go into those here. The point is that any given Obihai 200-series device can bridge up to three Google Voice accounts to FreePBX, and we assume those will be designated as Service Provider 1 (SP1), Service Provider 2 (SP2), and Service Provider 3 (SP3) in the Obihai configuration. Your FreePBX extension will be on SP4. In the case of an OBi202, which has two phone ports, you can have a FreePBX extension associated with each phone port. If you are connecting your OBi202 to only one or two Google Voice accounts, then your two extensions can be on SP3 and SP4. But if you are connecting to three Google Voice accounts and still want to let each phone port on an OBi202 be on a different extension, then assign the extension you want associated with Phone Port 1 to SP4, and we’ll tell you later how to configure the extension you want associated with Phone Port 2.

If you do not use SP4 for at least one of your FreePBX extensions then these instructions probably won’t work for you, since we have assumed throughout that SP4, and by association, ITSP Profile D will be used with your FreePBX extension (or at least with one of them if you have an OBi202). You could modify the instructions to take this into account, but chances are you’re going to miss something and it won’t work as intended.

We assume you know how to configure a FreePBX extension, by selecting a “Generic Service Provider” in the “OBi Dashboard” and then pointing it at your FreePBX server. Once again, just be sure to use SP4 for your FreePBX extension, or the configuration examples shown here won’t work without modification. Note that you may need to modify the phone port’s DigitMap and OutboundCallRoute settings to allow calls to other extensions, but that is beyond the scope of this article. You can make SP4 the Primary Line for Phone Port 1, but if you have an OBi202 we recommend that you do NOT make ANY of the service providers the Primary Line for Phone Port 2, at least not yet. OBi200 users don’t need to worry about this; it won’t affect you because you only have a single phone port.

You can configure your Google Voice account(s) in the normal manner using the “OBi Dashboard”, in fact if there’s a way to do it without using the Dashboard we don’t know about it, at least not without using custom third-party firmware which is beyond the scope of this article. Get everything set up and working normally – get your first Google Voice account set up on SP1 and make sure it is working, then if you have additional accounts add them on SP2 and if necessary, SP3. Make sure that you can make and receive calls on your Google Voice account(s) before you go any further. Note that you can use dialing prefixes to make test calls using a particular Service Provider without setting it as your Primary Line – for example **1 followed by the number you are calling will send the call through the account associated with Service Provider 1 in the Obihai configuration, and the **2 and **3 prefixes will do the same with regard to Service Providers 2 and 3.

So now that you have your FreePBX extension working and your Google Voice accounts set up and configured, there are two things that need to happen. One is to redirect all incoming Google Voice calls to a FreePBX SIP trunk, which will be used for incoming calls only. And the other is to send all outgoing calls to a Custom trunk, and configure the Obihai to correctly route them to the correct Google Voice accounts. Some users may not need both of these – for example, if your main reason for wanting to route calls through FreePBX is so you can use its blacklist and other call screening features on incoming calls, then you may not need the outbound connectivity. But we’ll show you how to do both.

Handling incoming Google Voice calls:

☞ These changes must be made using the OBi Dashboard’s Expert Configuration option.

Go to Voice Services/Gateways & TrunkGrps – we’ll be changing the settings for Voice Gateway1 (vg1). You can use any unused Voice Gateway, but the examples here assume the use of vg1. Start by unchecking the checkboxes under “OBiTALK Settings” for these values: Name, AccessNumber, and AuthUserID. Then click “Submit” at the bottom of the page. If any of the checkboxes in the “Device Default” column for those settings are now checked, uncheck them and click “Submit” again. You need to do this or the page won’t let you enter the new values. This is true anyplace we make changes to any of the settings in the OBi Dashboard – if either of those boxes are checked, they must be unchecked and “Submit” clicked before you can make changes.

Now you can enter the new settings for vg1:
Name: Anything you like to identify it, such as FreePBX trunk
AccessNumber: SP4(192.168.x.x) – replace 192.168.x.x with the fixed IP address of your FreePBX server
AuthUserID: The FreePBX trunk name, we’ll use gvgateway in this example

When you have these the way you want them, click Submit. Note that for the AccessNumber setting we specified SP4, which should be your FreePBX extension. This isn’t actually using SP4, but rather it is telling the device that this voice gateway uses the same technology (SIP) as SP4, so don’t worry that FreePBX will confuse calls on vg1 with calls from your extension.

We are not using a password in this configuration; instead we’ll be limiting the trunk to only accepting calls from the IP address of your Obihai device. This makes configuration a bit easier. But if the Obihai were on a different local network than your FreePBX server then you might need to configure an AuthPassword for additional security, and configure the trunk to look for it. For now we’re assuming the Obihai device is on the same local network as the FreePBX server, or at least that it’s at a fixed IP address.

Next, we must configure the Google Voice accounts to send incoming calls to this Voice Gateway.

Go to Voice Services/SP1 Service and find the setting X_InboundCallRoute near the top of the page. In order to configure this properly you need to know the Google Voice number associated with this Google Voice account, so if you don’t know what it is then log into the Google Voice account and find it there. Now change this setting as follows:

X_InboundCallRoute: vg1(XXXXXXXXXX/$1)

Replace XXXXXXXXXX with the ten digit Google Voice number, and click “Submit”. Do not under any circumstances change any other settings on the page! If you do you may screw up the configuration so badly you’ll have to start over with the factory reset again. If you have more than one Google Voice account then do the same thing under SP2 Service and if necessary, SP3 Service, using the Google Voice number associated with that particular Google Voice account in place of the XXXXXXXXXX.

Now we need to increase the maximum number of sessions between the device and the FreePBX server.

Go to Voice Services/SP4 Service and find the “Calling Features” section, and under that the setting for MaxSessions. We suggest increasing this number from the default, to at least 6. We used 10, but the Obihai may not be able to handle that many simultaneous connections. Don’t forget to click “Submit”.

That concludes the changes you need to make on the Obihai to handle incoming calls.

☞ These changes must be made on the FreePBX server.

Next we must turn our attention to FreePBX. The first thing we need to do is edit /etc/asterisk/extensions_custom.conf, so in a ssh session enter this – you can use your text editor of choice, we like nano:

nano /etc/asterisk/extensions_custom.conf

Add the following to the end of the file (note that some lines are wrapped, so you may wish to cut and paste them into a text editor in order to view them correctly):

[custom-from-obihai]
exten => _X!,1,Set(CALLERID(num)=${CUT(EXTEN,/,2)})
exten => _X!,n,Set(CALLERID(ani)=${CALLERID(num)})
exten => _X!,n,Set(CALLERID(name)=${SHELL(curl --silent --digest --user admin:obipassword http://192.168.X.X/callstatus.htm --stderr - | grep -n "Peer Number
${CALLERID(num)}" | grep -o -P '(?<=
Peer Name
).*?(?=
)' | tr -d '\n')})
exten => _X!,n,ExecIf($["${CALLERID(name)}"="${CALLERID(num)}"]?Set(CALLERID(name)=))
exten => _X!,n,Set(CDR(did)=${CUT(EXTEN,/,1)})
exten => _X!,n,Goto(from-pstn-e164-us,${CUT(EXTEN,/,1)},1)
exten => h,1,Macro(hangupcall,)

Replace obipassword with the password you use to log into your Obihai device’s web interface when you log in locally (this is admin, unless you have changed it as we suggested earlier in this article). This is probably not the same as the password you use when you log into your Obitalk account, so don’t confuse the two. Also, replace 192.168.X.X with the local IP address of the Obihai device.

This is used to get the Caller ID number on incoming calls, and it also attempts to get the Caller ID name on the rare occasion when Google Voice sends one. Note this only works if, on the Obihai device, the X_InboundCallRoute setting in the Service Provider settings for Google Voice account(s) contains the /$1 appendage, in case you were wondering what that was for. And also, the curl command must be installed and working on the Asterisk server; usually this is installed by default but you can check by typing “which curl” at the Linux command prompt – it should return a path, typically /usr/bin/curl. Note that attempting to get the Caller ID name from the Obihai device does take a small amount of time, because it’s actually querying the device’s web interface, since there’s no other way to get it. But, you probably won’t notice any delay when the Obihai device is on the same local network as the Asterisk server. If you don’t care about trying to get a Caller ID name from the Obihai device, just omit the two lines that contain references to the CALLERID(name) variable.

Next, using the FreePBX web interface, create a new PJSIP Trunk. Under the General tab the only things you need to fill in are the Maximum Channels and the Trunk Name, which must match the AuthUserID you used for Voice Gateway1 on the Obihai – we suggested gvgateway:

Trunk Name: gvgateway
Maximum Channels: 6
Disable Trunk: No

Skip the other settings on that page, other than if you like you can fill in an Outbound CallerID to stop FreePBX from complaining, even though this trunk will not be used for outgoing calls. Next, in the sip Settings tab, Outgoing tab:

Trunk Name: gvgateway     (yes you have to fill it in here again)

PEER Details:

type=friend
permit=192.168.X.X/255.255.255.255
nat=no
host=192.168.X.X
dtmfmode=rfc2833
disallow=all
directmedia=no
deny=0.0.0.0/0.0.0.0
context=custom-from-obihai
allow=ulaw

Replace the two instances of 192.168.X.X with the local IP address of the Obihai device. This is why we don’t need to use a password, because access to this trunk is only allowed from the Obihai’s IP address. This is why we strongly urged you to assign a fixed IP address to the Obihai. Also, omit the line nat=no if the Obihai device is not on the same local network as the FreePBX server, or if you experience issues with one-way audio.

Don’t forget to click the Submit button before leaving the Trunk configuration page, or you’ll get to start over and do it all again!

Finally you need to create your Inbound Route(s). You need one for each of your 10-digit Google voice numbers that are coming in via the Obihai. When creating them, under the “Advanced” tab you may want to set “Force Answer” to Yes – this causes the call to be answered immediately when it comes in, so that it will not go to Google Voice’s voicemail. In rare circumstances this may cause a problem where calls come in and when you answer there is no one there, but the caller continues to hear ringing and then winds up at Google Voice’s voicemail. We have not experienced this issue in recent firmware releases, but if you do then set the “Pause Before Answer” setting to 1, which delays one second before answering the call. Also, if you have configured CallerID Superfecta, you may want to enable that on the Inbound Route, in the “Other” tab, because Google Voice seldom provides Caller ID name information on incoming calls.

In your Inbound Route you can make the destination whatever you like, including but not limited to the FreePBX extension served by the Obihai device, in order to take advantage of FreePBX’s various features.

After you have made all these changes don’t forget to apply the configuration in FreePBX! Now any calls made to one of your Google Voice numbers should come into FreePBX and be routed according to the Inbound Route specifications.

Sending outgoing calls to Google Voice:

☞ These changes must be made using the OBi Dashboard’s Expert Configuration option.

Some users may not care about doing this but for those that do, here’s how it is done.

Go to Service Providers/ITSP Profile D/SIP and look for the X_AccessList setting. This should be filled in with the local IP address of your FreePBX server, so that your Obihai will not accept connections from any other IP address via SP4. Note that we are assuming here that ITSP Profile D is associated with SP4, which will always be the case unless you have gone out of your way to change it.

While you are on this page, make sure that the setting X_UseRefer is enabled – check the box if it isn’t – and that X_SessionRefresh is disabled – uncheck that box if necessary. Then Submit the changes. So to recap, these are the settings to change if necessary:

X_UseRefer: Checked
X_SessionRefresh: Unchecked
X_AccessList:
Set to IP address of FreePBX

Next, go back to Voice Services/SP4 Service and change the X_InboundCallRoute setting. The following is how it might be set for three Google Voice accounts on SP1 through SP3:

{>(<**10:0>11x.|<**11:1>xxxxxxxxxx):sp1},{>(<**20:0>11x.|<**21:1>xxxxxxxxxx):sp2},{>(<**30:0>11x.|<**31:1>xxxxxxxxxx):sp3},{>(ext1):ph},{>(ext2):ph2}

This is just an example, and in any case you’d need to replace ext1 and ext2 with the extension numbers of your Phone Ports. But don’t just copy and paste that – instead, you should construct this setting according to your particular configuration. So here is an explanation of each part, and keep in mind that each part starts with a { and ends with a } and that the parts are separated by commas. Use only the parts you need!

{>(<**10:0>11x.|<**11:1>xxxxxxxxxx):sp1}

The above will route all calls prefixed with **1 that fit the pattern of 11 digit calls starting with “1”, or international calls starting with 011, to the Google Voice account on SP1. Note that it is the FreePBX trunk that will be applying the **1 prefix, not the person making the call. If you don’t want to allow international calls, then use this instead:

{>(<**11:1>xxxxxxxxxx):sp1}

The next part does the same thing for calls prefixed with **2, routing them to SP2. Of course this assumes you have a second Google Voice account; if not you’d omit this entirely:

{>(<**20:0>11x.|<**21:1>xxxxxxxxxx):sp2}

And as before, if you don’t want to allow international:

{>(<**21:1>xxxxxxxxxx):sp2}

And if you have a third Google Voice account then you should include one of these two parts:

{>(<**30:0>11x.|<**31:1>xxxxxxxxxx):sp3}
or
{>(<**31:1>xxxxxxxxxx):sp3}

The next part deals with incoming routing to extensions. If you have an Obi200 and therefore only one phone port, you’d use this at the end:

{>(ext1):ph}

Replacing ext1 with the actual extension number you are using in FreePBX. However, if you have an OBi202, and you have three Google Voice accounts but you want each phone port to be on a separate extension, so that both extensions have to share a Service Provider connection, then you’d also use this to route the second extension’s calls to phone port 2:

{>(ext2):ph2}

Where ext2 would be the extension number you want associated with phone port 2.

Note that specifying the extension numbers this way adds a bit of security, because any calls that may arrive at your Obihai that are not addressed to a valid extension number or Google Voice number will be rejected. There is, by design, no “default route” for calls that do not match one of the expected patterns.

So for an OBi200 with three Google Voice accounts on SP1 to SP3, and FreePBX extension 123 on SP4, the X_InboundCallRoute setting would be:

{>(<**10:0>11x.|<**11:1>xxxxxxxxxx):sp1},{>(<**20:0>11x.|<**21:1>xxxxxxxxxx):sp2},{>(<**30:0>11x.|<**31:1>xxxxxxxxxx):sp3},{>(123):ph}

But if it were an OBi202 with the same configuration but also an extension 124 going to phone port 2:

{>(<**10:0>11x.|<**11:1>xxxxxxxxxx):sp1},{>(<**20:0>11x.|<**21:1>xxxxxxxxxx):sp2},{>(<**30:0>11x.|<**31:1>xxxxxxxxxx):sp3},{>(123):ph},{>(124):ph2}

By the way, we realize that some very astute readers may question why we’re replacing either a 0 or a 1 with the same character – the answer is, when we didn’t use any replacement character it didn’t work! It’s as simple as that. This may be a firmware bug, because previously it worked without needing to have at least one replacement character.

While on this page, make note of but don’t change the X_UserAgentPort setting – it will probably be either 5063 or 5083, but in any case you’ll need to know it later in these instructions. Also, check that the X_EnforceRequestUserID setting is not checked – this is very important; if you don’t do this then outgoing calls may not work. And you may also want to verify that MaxSessions is set to something higher than the default. So, these are the changes on this page:

X_InboundCallRoute: See discussion above
X_UserAgentPort: Make note of but don’t change
X_EnforceRequestUserID: Unchecked
MaxSessions:
At least 6, we use 10 but that may be too many.

Don’t forget to submit your changes. Before logging out of the “OBi Dashboard”, it may be a good idea to go back to the main Dashboard page at this point and click on the gear icon for your device, and look under the Phone Port Configuration Summary to make sure that the “Primary Line for Outgoing Calls Route to:” setting is correct for each of your phone ports. Specifically, you probably want it to be set to SP4 for Phone Port 1, and “Not Configured” for Phone Port 2 (for now), assuming that you plan on routing all your outgoing calls through FreePBX. You change this by clicking on the gear icon next to the service provider you wish to choose as the primary, then when the page refreshes and you have dismissed any popups, check the appropriate checkbox next to “Primary Line for Outgoing Calls” to select that Service Provider. But do keep in mind that anything you put in the OutboundCallRoute setting for a phone port may override this setting.

That’s all of the changes you need to make on the Obihai to handle outgoing calls, except for a couple that unfortunately cannot be made from the “OBi Dashboard” at this time.

☞ These changes must be made using the Obihai device’s web interface.

Log into your Obihai device’s web interface and go to Service Providers/ITSP Profile D/General and make sure that the following two settings are enabled:

X_ICEEnable: Checked
X_EarlyICEEnableIn: Checked

Click Submit, wait for the page to reload, and then click the Reboot button in the upper right corner of the page. This fixes a specific issue with outgoing calls. This assumes that ITSP Profile D is associated with SP4, which will always be the case unless you have gone out of your way to change it.

☞ These changes must be made on the FreePBX server.

Go into the FreePBX web configuration and create one new Custom Trunk – note Custom, not SIP – for each of your Google Voice accounts. Here’s how they are configured:

• General tab:

Trunk Name: Whatever you want
Outbound CallerID: The 10 digit Google Voice number for the account
CID Options: Force Trunk CID
Maximum Channels: 2
Disable Trunk: No
     (It’s important to check this setting if you have copied the configuration from another trunk!)

• Dialed Number Manipulation Rules tab – Dial patterns:

**1+1NXXNXXXXXX
**11+NXXNXXXXXX
**11areacode+NXXXXXX

If your area does not have 7 digit dialing of local calls then omit the last one; but if it does then replace areacode with the actual 3 digit area code. If you wish to allow international calls, then also add this pattern:

**1+011X.

This is set to use the Google Voice account on Service Provider 1 on the Obihai, but if you replace all instances of **1 with **2 or **3 then it will use the Google Voice accounts associated with SP2 or SP3 respectively. We chose this method because it is the exact same pattern you’d use to select a particular service provider when dialing from a phone connected to the Obihai.

● Custom Settings tab – Custom Dial String:

sip/$OUTNUM$@ip_address_of_obihai:X_UserAgentPort

This is why we said to take note of the X_UserAgentPort setting earlier. So if, for example, your Obihai is at 192.168.1.123 and the X_UserAgentPort was set to 5083, you’d use this:

sip/$OUTNUM$@192.168.1.123:5083

That’s it – submit your changes. Repeat the process for any additional Google Voice accounts on that Obihai. Remember that it is the **n prefix that selects the Google Voice account that the call goes out on, so if instead of using multiple trunks you wanted to use a single trunk and make the Google Voice account selection in your Outbound Routes you could probably do that, although we imagine that it would be a lot more complicated to do it that way.

After you’ve created your custom trunks, don’t forget to apply the configuration. Now you can select those trunks in your Outbound Routes, as usual in FreePBX.

OBi202 users only: How to use one Service Provider connection for two FreePBX extensions

As we mentioned earlier, Obi202 devices have two phone ports, and maybe you’d like to have a separate FreePBX extension associated with each phone port. If you are already using SP1 through SP3 for other purposes, such as Google Voice connections, then you are only left with SP4 to use for both extensions. So as we said above, what you want to do in that case is configure SP4 as the extension that will be associated with Phone Port 1 (ph1), and you do that in the normal manner using the “OBi Dashboard”, although you may need to make some additions to the default DigitMap and OutboundCallRoute settings to allow extension to extension calls. Since we don’t know how extensions are numbered on your system, we can’t really explain how to do that, but we are aware that there is a tool called OBiCfg (this is a .zip file that expands to a Windows-compatible program) that may help you configure those settings. If you don’t use Windows, the program will probably run under WINE on Linux or MacOS based systems. Some time back we were able to convert this program to a Mac application, more or less, using a Mac program called Wineskin but that’s not exactly a straightforward process, and we haven’t tried to do it recently.

But the main thing is that you should get your Phone Port 1 working as a FreePBX extension, and make sure that it can make and receive calls. Then, and only then, can you configure Phone Port 2. Here is how, starting with the Obihai configuration.

☞ These changes must be made using the OBi Dashboard’s Expert Configuration option.

Go to Service Providers/ITSP Profile D/General. In your browser, place your cursor inside the text field for the DigitMap setting, and select the entire field and copy it. This assumes that ITSP Profile D is associated with SP4, which will always be the case unless you have gone out of your way to change it, and that SP4 is used for the FreePBX extension associated with Phone Port 1, which you have already configured. You may wish to temporarily paste the copied text into a text editor if you don’t use a clipboard manager, so that you don’t accidentally copy something else over it.

Go to Voice Services/Gateways & TrunkGrps – we’ll be changing the settings for Voice Gateway2 (vg2), since we’ve already used vg1. You can use any unused Voice Gateway, but we assume the use of vg2 in these instructions. We’ll be changing the Name, AccessNumber, DigitMap, and AuthUserID settings, as follows:

Name: The extension number you wish to use for this extension
AccessNumber: SP4(192.168.x.x) – replace 192.168.x.x with the fixed IP address of your FreePBX server
DigitMap: The DigitMap that you copied from ITSP Profile D
AuthUserID: The extension number you wish to use for this extension again

Then click Submit.

Go to Physical Interfaces/PHONE 1. In your browser, place your cursor inside the text field for the OutboundCallRoute setting, and select the entire field and copy it. Paste it into any plain text editor you have handy – this is just for your convenience so you can see the entire setting. We are going to modify this slightly and the use it as the OutboundCallRoute for Phone Port 2. Without knowing exactly what you have there now, we can’t just give you a replacement to paste in – you need to edit what’s there now. But note that we are not changing this setting in Phone Port 1 at all, so don’t try to edit it in place – copy it to a text editor so you won’t accidentally save it to the wrong Phone Port configuration.

Before we continue, please note the following:

These instructions assume that you want to send all calls from Phone Port 2 to your FreePBX server, and that if the call is ultimately destined for a Google Voice connection then FreePBX will send it back to your Obihai. In other words, you want your FreePBX extension to be your “Primary Line”. If that is NOT the case, and you want the Primary Line for Phone Port 2 to be a Google Voice account, then you can set that up in the “OBi Dashboard” in the normal manner. In this case you will not want to make any of the changes shown below in your DigitMaps or in the OutboundCallRoute, EXCEPT that if you have added a rule that routes calls to other extensions to sp4, you’ll want to change that to point to vg2. So make that change only if appropriate, and then paste the entire text into Phone Port 2’s OutboundCallRoute, click Submit, and then skip down to the paragraph that begins with “We’ve already showed you above how to route incoming calls for a particular extension to Phone Port 2” and continue from there. But if you DO want your FreePBX extension to be your “Primary Line”, which we recommend, then continue on from here.

There are two basic things you need to do in the OutboundCallRoute setting you just copied:

First, replace any references to pli (typically part of the text Mpli) with vg2. You need to do this because pli stands for “Primary Line” but you can’t select a Voice Gateway as a primary line in the “OBi Dashboard”, so this makes that change in the Phone Port configuration. Typically there will be two rules that need to be changed:

{([1-9]x?*(Mpli)):pp} is changed to {([1-9]x?*(Mvg2)):pp} – this is near the beginning of the text.
{(Mpli):pli} is changed to {(Mvg2):vg2} – this is near the end of the text, and note there are two replacements in this rule.

Next, you need to change any existing references to sp4 to point to vg2, EXCEPT for the rule that looks like this: {(<**4:>(Msp4)):sp4}. Don’t change that one, but any other references to sp4 should be changed to vg2, unless you have some specific reason for leaving them set to sp4. When making changes, note that rules are enclosed in {curly braces} and then separated by commas, so be careful not to accidentally delete a curly brace or comma. Just make sure that nothing remains routed to sp4 other than the single rule for the **4 prefix mentioned above; otherwise some calls from Phone Port 2 may appear to be coming from Phone Port 1’s extension when they arrive at FreePBX.

Once you have the OutboundCallRoute text modified as described above, go to Physical Interfaces/PHONE 2 – make sure you are not still in PHONE 1 where you copied the settings from; you must now be in the PHONE 2 configuration – and paste your modified settings into the OutboundCallRoute setting there, and Submit.

There are two other settings on this page that needs to be changed, DigitMap, which is just above the OutboundCallRoute setting, and CallReturnDigitMaps, which is just below it. It would be safest to copy those over from Physical Interfaces/PHONE 1, make the necessary changes, and then paste them in to the equivalent fields in Physical Interfaces/PHONE 2, but typically each of these fields will by default be the same as their equivalents in Phone Port 1 anyway.

What you need to do in both the DigitMap and CallReturnDigitMaps is replace any references to pli with vg2. In the DigitMap setting this will typically need to be changed in two places:

[1-9]x?*(Mpli) is changed to [1-9]x?*(Mvg2) – this is near the beginning of the text.
(Mpli) is changed to (Mvg2) – this is near the end of the text.

And in the CallReturnDigitMaps there is typically only one replacement that needs to be made:

{pli:(xx.)} is changed to {vg2:(xx.)} – this is near the beginning of the text.

Again, when making these changes make sure you don’t accidentally delete a curly brace or comma, and don’t forget to click Submit when you are finished.

Before leaving the “OBi Dashboard”, go back out to the main Dashboard page and click on the gear icon for your device, and look under the Phone Port Configuration Summary to make sure that the “Primary Line for Outgoing Calls Route to:” setting for Phone 2 says “Not Configured”. If, instead, it shows a service provider (SP1, SP2, SP3, or SP4) then look in the section just above, “Configure Voice Service Providers (SP)”, and click the gear icon next to that Service Provider, dismiss the popup, and then on the line “Primary Line for Outgoing Calls”, UNCHECK the checkbox next to Phone 2. This should leave Phone 2 with no configured Primary Line, meaning it should only use the rules in the settings we configured above. It would be great if we could simply set the Primary Line for Phone Port 2 to Voice Gateway 2, but the “OBi Dashboard” doesn’t allow it, which is why we had to change all those instances of pli to vg2.

If, after making these changes and setting up the configuration in FreePBX as described below, you find that you are having problems making some calls, check to see if you have the same issue on Phone Port 1. The reason we said to copy the DigitMap setting from Service Providers/ITSP Profile D/General to Voice Gateway2’s DigitMap was because we assumed that the DigitMap in ITSP Profile D, which should be associated with Phone Port 1 if you have followed these instructions from the beginning, would allow outgoing calls as configured for Service Provider 4 in the “OBi Dashboard”. So if, for example, you allowed 7 digit dialing to a particular area code when you set up SP4, then by copying the ITSP Profile D DigitMap to Voice Gateway2 those same rules should be followed by Phone Port two, PROVIDED you made all the replacements of pli to vg2 and sp4 to vg2 that we documented above.

We’ve already showed you above how to route incoming calls for a particular extension to Phone Port 2, using the X_InboundCallRoute setting under Voice Services/SP4 Service – once again, there needs to be a rule there of the form {>(ext2):ph2} where ext2 is the extension number associated with Phone Port 2.

That’s all you need to do in the Obihai device configuration.

☞ These changes must be made on the FreePBX server.

In FreePBX we need to make a Custom Extension and a new SIP trunk. When you create the extension, make sure you specify that it is Custom and not SIP! The details for the Custom Extension are as follows:

Under the General tab, set the User Extension, Display Name and Outbound CID as you normally would – obviously, the User Extension must match the Obihai device settings you used for the Name and AuthUserID for Voice Gateway 2, and especially with the extension number you associated with Phone Port 2 in the X_InboundCallRoute setting under Voice Services/SP4 Service. For all the other tabs, in most cases you can use the same settings that you would if you were creating a SIP extension. The major exception to this is in the Advanced tab, Edit Extension section, Dial setting. For that you want to use something like this:

sip/extension_number@ip_address_of_obihai:X_UserAgentPort

Replace extension_number with the number of this extension, and use the actual ip_address_of_obihai. The X_UserAgentPort is the same one we had you make a note of earlier, that was used in the Custom Dial String for the trunk(s) you created for outgoing calls to each of your Google Voice accounts. So if, for example, your extension number is 124, your Obihai is at 192.168.1.123 and the X_UserAgentPort was set to 5083, you’d use this as your Dial setting:

sip/124@192.168.1.123:5083

When you finish your custom extension configuration, don’t forget to click Submit. Note that this custom extension is used for calls going TO Phone Port 2 on the Obihai only, although there is one important exception to that – if you set an Emergency CID in the Advanced tab, Extension Options section, it will be used for calls FROM the extension that are routed through an “Emergency” outbound route, provided that the extension number you use in the trunk settings in the next section exactly matches the custom extension’s number.

For calls coming FROM Phone Port 2 we need to create a new SIP Trunk – this may sound strange, but it’s the easiest way to handle this. So, create a new SIP (chan_sip) Trunk. Under the General tab use the following settings, but note that the Trunk Name can be whatever you want, for example:

Trunk Name: Extension_124_from_Obihai
Maximum Channels: 3
Disable Trunk: No

Skip the other settings on that page, other than if you like you can fill in the Outbound CallerID to stop FreePBX from complaining. Next, in the sip Settings tab, Outgoing tab, use the extension number as the Trunk name (this is what must exactly match the custom extension’s number for the Emergency CID setting to be honored), and then fill in the PEER Details as shown below:

Trunk Name: The extension number, such as 124

PEER Details:

deny=0.0.0.0/0.0.0.0
callerid=Caller ID name and number (see below)
context=from-internal
directmedia=no
dtmfmode=rfc2833
host=192.168.X.X
port=X_UserAgentPort
nat=no
permit=192.168.X.X/255.255.255.255
qualify=yes
qualifyfreq=60
sendrpid=pai
transport=udp
trustrpid=yes
type=friend

Replace the information in the callerid= item with the correct user name and extension number, in the same way you would set a Caller ID for a regular extension, and replace the two instances of 192.168.X.X with the local IP address of the Obihai device. Once again, for the port= item replace X_UserAgentPort with the same port number we had you make a note of earlier, that was used in the Custom Dial String for the trunk(s) you created for outgoing calls to each of your Google Voice accounts. Omit the line nat=no if the Obihai device is not on the same local network as the FreePBX server, or if you experience issues with one-way audio.

Note that you can adjust the PEER Details settings as necessary. If you are trying to figure out what settings to use, you can always look in the file /etc/asterisk/sip_additional.conf and look at the settings for an actual SIP extension in FreePBX that is similar to this one, perhaps the settings for the extension associated with Phone Port 1, and use similar settings in the PEER Details here. However, the host= and port= settings must contain the IP address and X_UserAgentPort number of the Obihai device. We found that you don’t need to use every single setting that FreePBX would use when creating a SIP extension – the subset shown above worked well for us.

In case you are wondering, for us FreePBX didn’t complain about having a Custom Extension and a SIP Trunk Name set to the same extension number. If it does complain about it for you, go to the FreePBX Advanced Settings page, System Setup section, and make sure that the “Aggresively Check for Duplicate Extensions” setting is set to “No”.

Final thoughts

We realize that there are many different ways to do this, and that some work better than others. These are what worked for us. If they work for you, great! One thing we do notice is that we do not seem to experience the spontaneous rebooting of the Obihai device that some users of other methods have reported. We don’t know whether we’ve just been lucky, or whether the latest firmware fixed that problem, or whether there really is something different about our method, but we thought we’d put it out there as another possible way to do this that may work for some where other methods have failed.

Configuring an Obihai device isn’t the easiest thing to do, and that’s why we stick to using the “OBi Dashboard” – it makes configuration a lot easier. But if you need help understanding dialplans and other internal workings of the Obihai, we suggest you download the OBi Device Administration Guide – it’s a 220 page PDF file. It’s what we used to come up with most of this method, along with a few tricks we’ve picked up in various forums here and there.

One final thought – if you happen to also have an older OBi100 or OBi110 device, keep in mind that it can still be used as a FreePBX extension even though it can no longer connect with Google Voice. But it’s entirely possible to place or receive calls that go through FreePBX, to or from the 200-series device, because those devices still work fine with SIP connections, so in a roundabout manner you could still use Google Voice with such devices. It’s also possible to use the Obitalk network as an intermediary instead of FreePBX for such calls, but if you have a FreePBX server we don’t really see much point in doing that, and in any case that’s beyond the scope of this article.

Convert an older model USB printer to a networked printer using a Raspberry Pi or other Linux-based computer — also works well for making an older printer compatible with a newer version of MacOS

We originally set out to do this because we were having problems getting an older model laser printer, specifically a Konica Minolta PP1350W, to work with MacOS High Sierra (10.13).  With previous versions of MacOS we’d been able to connect the printer directly to the computer, and with some fiddling with drivers and other software, get it to work.  But newer versions of MacOS seem to be far less tolerant of this, and we had a spare Raspberry Pi, so the idea came to us to use the Raspberry Pi as a bridge between the printer and any computers on the local network from which we wanted to be able to print.  The bonus is that the printer is no longer tethered to a single machine, but instead can potentially be used by any computer on the local network.

You do not need to have a Raspberry Pi to make this work – any computer that can run Linux will do.  And of course the Raspberry Pi or other Linux computer can be used for other purposes besides this.  We do not guarantee that this technique will work for every older printer out there, but this will work with a surprising number of them.

If you use a Raspberry Pi, it should already have some version of Raspbian installed, but it can be either Raspbian Lite or the full version of Raspbian.  If you use a different type of computer, be aware that our instructions are geared toward users of Debian, Raspbian, Ubuntu, Linux Mint, or similar Debian-based distributions, though we imagine that with a little modification they could be adapted to other Linux distributions.

Because the Raspberry Pi is so (relatively) inexpensive, from here on we will just refer to the Raspberry Pi, but if you are using a different computer running Linux that term applies to your computer as well.

Assuming your operating system is already installed, we also suggest that if you have not done so, you give your Raspberry Pi a static IP address on your network.  This can be done in your router settings, by reserving a specific IP address for your Raspberry Pi’s MAC address, or by changing the networking settings on the Raspberry Pi itself.  If you don’t do this, other computers on your network may not be able to find your Raspberry Pi when you want to print something, if its IP address has changed.

With that out of the way, here is how you make this work.  Commands shown below are entered in the terminal program, or in a ssh session (in other words you must be at a Linux command prompt):

1. Install CUPS:

sudo apt upgrade
sudo apt install cups

This will install CUPS (the Common Unix Printing System) and several dependencies.  Okay, a LOT of dependencies.  Just let them all install.

2. Look to see if there is a specific driver for your printer:

apt-cache search printer-driver

This will return a list of available printer drivers.  Look though the list and see if any of them look like ones that might be used with your printer.  For example, we found this:

printer-driver-min12xxw - printer driver for KonicaMinolta PagePro 1[234]xxW

Since this definitely covers our model PP1350W printer, we installed it using:

sudo apt install printer-driver-min12xxw

Of course you would substitute the driver for your printer, if one is available.  Alternately, some printer manufacturers may offer a Linux printer driver on their web sites, but you may need to compile it yourself, or they may provide a script that will compile it for you.  In any case, it is almost always better to install the printer driver for your printer, because then CUPS can find and use it.  Otherwise it may try to use a more generic printer driver that doesn’t work as well (or at all).

If all else fails, try putting “Linux printer driver for (your make and model of printer)” into a search engine and see if anything relevant is returned.  But beware of installing pre-compiled printer drivers on a Raspberry Pi – you would need a version built for an ARM-based device, not one built for a standard Intel/AMD CPU architecture.

3. Add your user to the lpadmin group:

sudo usermod -a -G lpadmin username

Replace username with your user name.  For example, on a Raspberry Pi, you would probably use sudo usermod -a -G lpadmin pi unless you have created another user.  The “-a -G” options add the user to the supplementary group, in this case the lpadmin group.

4. (Optional) At this point you could edit the CUPS configuration in a web browser on your Raspberry Pi, if you are running a desktop version of Raspbian.  But if you want to be able to modify the CUPS configuration from another computer on your network, you need edit the /etc/cups/cupsd.conf file to allow it:

sudo nano /etc/cups/cupsd.conf

Feel free to use any text editor of your choosing if you don’t care for nano.  Here are the sections that need to be modified – the modifications are shown in red:

# Only listen for connections from the local machine.
# Listen localhost:631
Port 631
Listen /var/run/cups/cups.sock

Please note that the line “Listen localhost:631” has been commented out. Then, a bit further down in the file:

# Restrict access to the server...
<Location />
Order allow,deny
Allow @local
</Location>

# Restrict access to the admin pages...
<Location /admin>
Order allow,deny
Allow @local
</Location>

# Restrict access to configuration files...
<Location /admin/conf>
AuthType Default
Require user @SYSTEM
Order allow,deny
Allow @local
</Location>

5. (Optional unless you have performed step 4, or made any other changes to the cupsd.conf file) Restart the CUPS server:

sudo /etc/init.d/cups restart

6. In a web browser go to one of the following addresses.  If you are using a web browser on the Raspberry Pi itself, go to:

https://localhost:631

If you are using a web browser on any other machine on your local network (and assuming you completed steps 4 and 5), go to:

https://ip address or host name of raspberry pi:631

Note that your browser will probably complain about the site being insecure because you have a self-signed certificate – just go ahead and tell the browser it’s okay to connect to this site.  You actually can connect to the main page using http rather than https, but the moment you try to do any actual configuration it will force you to switch to https, so you may as well start out there.

7. Configure your printer.  If you haven’t already done so, you should power up your printer now. You should be at a page that looks something like this:

CUPS home page
You want to click the Administration link, which is highlighted in yellow above.  On the next page you will see this at the top:

Top of CUPS administration page
On that page you want to click the Add Printer button, which again we have highlighted in yellow. You may be asked to login at this point, if so, use the username and password you’d use to login to your Raspberry Pi. Next, you should see something like this:

CUPS - first add printer screen
Hopefully you will see your printer as shown above — if not, try rebooting the Raspberry Pi while the printer remains powered up.  When you do see it, select it and click the Continue button, and then you should see something like this:

CUPS - second add printer screen
The two things you need to do on the above screen are fill in the location, which can be anything you want, but the most important thing is to check the “Share This Printer” checkbox, which we have highlighted in yellow above. Then click Continue, and you should get a screen like this:

CUPS - third add printer screen
All you have to do in this screen is pick the make of your printer from the list and click Continue.  If you wonder why ours is in ALL CAPS, that’s because we installed printer-driver-min12xxw back up in step 2, and that’s what CUPS is finding here.  You want to use the entry associated with any printer driver you might have installed, which hopefully will be this obvious.  Then you click Continue.  An alternative is to upload a PPD (PostScript Printer Description) file on this page, but we didn’t need to do that.  After you click Continue, you may see another screen such as this:

CUPS - fourth add printer screen
The purpose of the above screen is to allow you to pick a specific model printer.  You should pick the one that corresponds to your printer.  This screen also gives you one more opportunity to provide a PPD file, in case your printer model isn’t listed.  After you have selected your printer, you click the Add Printer button. At that point you will have the opportunity to set your default printer options:

CUPS set default printer options
Most of these options will probably be filled in correctly but one or two might not be – for us, the page size was set to A4 and we had to change it to Letter.  Set them as you wish, but keep in mind that most software with printing capabilities can override the defaults if you instruct the software to do so in a printer setup dialog.  After you have made any changes, click the Set Default Options button.  After you do that, the system may display an intermediate page but then should take you to the Printers page:

CUPS Printers page
This shows that your printer has been set up. You could use it now from the Raspberry Pi itself, but of course the goal it to use it from other computers on your local network. In most cases, this should be very easy – you just go to your system’s printers dialog and add the printer. For example, in MacOS you would go to System Preferences, then Printers & Scanners. Then click the + at the bottom of the printers list, and your printer should appear in a panel like the one shown below, assuming that the Raspberry Pi and the printer are both powered up:

MacOS add printer dialog
Click on the printer to select it, and the fields at the bottom of the panel should populate with the printer information:

MacOS add printer dialog - printer selected
Just click the Add button and now the printer should show up in your printers list, and be available for use:

Mac OS Printers Panel showing added printer
Be sure to select your newly added printer as the Default printer, if that’s what you want.  Note there is a “Share this printer on the network” checkbox, but you should NOT check that because the printer is not being shared from your Mac, it is being shared by the Raspberry Pi.

The procedure for adding the printer would likely be similar on a Windows or Linux machine.  In fact you may not need to do anything; on one Ubuntu system we checked the printer just appeared and was available from printing applications without any additional action on our part.

We hope this will give some added life to some of those USB-connected printers that still are capable of working quite well, but that are no longer directly supported by modern operating systems.

How we made a Raspberry Pi controlled 8-outlet power box

Raspberry PI8 outlet power box

Have you ever wanted to be able to control AC power outlets through your local network or the Internet?  We did, and found a use for an old Raspberry Pi in the process.  Many people probably have one of the original Raspberry Pi single board computers that they have since replaced with a more powerful model, but for this application an older Raspberry Pi works perfectly well. Of course you could use a newer model, but the pinouts might be a bit different.

Also, it would certainly be possible to build this project using the less expensive Raspberry Pi Zero, though once again the pinouts may not be exactly the same. However, the Raspberry Pi Zero does not have a wired Ethernet port, which may be important for some types of usage. While it may be possible to add a USB Ethernet Adapter, assuming one can find a compatible unit, a possibly better and less expensive approach would be to add a ENC28J60 Ethernet Module. One major downside to using a Pi Zero and an Ethernet Module is that you will need to find a way to keep both units physically separated from each other, and also separated from the relay module and the rest of the wiring, which might require building some kind of custom case. We preferred using an older original model Raspberry Pi, which of course already has a built-in Ethernet connector, and for which we already had a case.

Before we begin, though, please note the following:  The title of this article is “How we made a Raspberry Pi controlled 8-outlet power box” and the use of the word “we” is deliberate.  Just because we did this doesn’t necessarily mean you should.  Here are some reasons you should not do what we did:

1. If you don’t understand that electricity is dangerous and can cause death, serious injury, or property damage, you should not do this.

2. If you have no knowledge of good electrical wiring practices, or if you would call an electrician to replace a defective light switch or outlet, you should not do this. If you want to learn good electrical wiring practices, we recommend the latest edition of the book “Wiring Simplified” by Frederic P Hartwell and Herbert P. Richter.  It is updated for each new edition of the National Electrical Code and explains how to correctly wire switches, outlets, light fixtures and so on.

3. If you are the type of person who cannot accept responsibility for your own actions and mistakes, and would even think of suing someone else because you did not know what you were doing and injured yourself or burned down your house, you most definitely should not do this.  The authors specifically disclaim any responsibility if you try to do what we did.  Only you know if you have enough knowledge to safely work with electricity, and if you’re not absolutely certain that you do, then you should not do this!

4.  If you don’t know your local electrical codes, you probably should not do this.  We have no way of knowing if building one of these would be legal where you live.  We’re not even 100% certain it would be technically legal to build one of these anywhere (after all, we didn’t pay any certification agency for their stamp of approval, not that we think we could get one for this type of homemade project).

In short, if you are the sort of person that wants some guarantee of safety, please look elsewhere.  We are just showing what we did.  If you choose to try and emulate what we did, that’s on you and you alone.  Once again, electricity is dangerous and can cause death, serious injury, or property damage if you don’t know what you are doing!

We did try to achieve a measure of safety by putting only the relay control board inside the electrical box with the outlets, and leaving the Raspberry Pi outside, so that insofar as is possible the high voltage AC wiring (the stuff that can kill you) is all contained inside the electrical box, while all the low voltage wiring other than the 10-wire ribbon making the connection between the Raspberry Pi and the relay board are outside the electrical box.

Here are the parts we used:

A Raspberry Pi (we used an original model 1) with SD Card, power supply, and case.  Note the case must have a slot that permits access to the GPIO pins.

Raspberry Pi attached to side of outlet box

An 8 Channel DC 5V Relay Module with Optocoupler – the one we used is sold on Amazon as an “ELEGOO 8 Channel DC 5V Relay Module with Optocoupler for Arduino UNO R3 MEGA 2560 1280 DSP ARM PIC AVR STM32 Raspberry Pi“. Note that the relay contacts can only handle 10 Amps, so we can’t use these outlets to control any high current appliances or equipment.  Sorry, but it’s not safe to control a window air conditioner with these relays.

8 Channel DC 5V Relay Module with Optocoupler

ADDED NOTE about these modules:  We strongly suggest you only purchase from a place that makes it easy to return a module if it is found to be defective.  We have noticed that recently a number of these modules have been sold with one or more relays that don’t work correctly (they may be permanently stuck in one position).  If you are into electronics it may be possible to repair the defective relay (sometimes it’s just a bad LED on the board), but often if they are going to fail they will either do so right from the start or after only a few uses.  Therefore, we suggest that you test the module as soon as possible after you receive it, and return it for replacement if one or more of the relays isn’t working correctly.

Also, since we first published this article, we have discovered that Sequent Microsystems sells stackable relay cards for the Raspberry Pi. These are quite a bit more expensive than the modules shown above, but should allow for easier and neater construction. We have never used one of their cards, so cannot give any specific details on their usage, but just wanted to mention that they exist. Anyway, continuing with our parts list…

A four-gang “old work” electrical box, cover plate, and four electrical outlets – I am grouping these together because chances are that if anyone were trying to buy these they would buy them all at the same place, but note that 4-gang boxes can be a little pricey, and it may not be easy to find a four-gang cover at all without buying it online (Amazon sells one here). We don’t favor any particular make or model of these items but we did use an “old work” type electrical box because it is easy to remove the four “ears” that would normally hold the box in behind an old wall, and then we had a nice rectangular box with no protrusions. And while on the subject, just because we used an electrical box for this project does NOT mean that this project can be mounted into a wall or used in any kind of permanent installation. Don’t even think of doing that, it would be illegal in most areas and it would be unsafe, because someone who did not know any better might mistake the outlets for normal ones and plug in a high amperage appliance, which would burn out the relay contacts and in an extreme case could even start a fire.

Electrical box, cover plate and outlets

Outlet showing tab between brass screws that needs to be removedWhen buying electrical outlets, we made sure they had the small tab between the two brass-colored screws that can be broken off to “split” the two outlets onto separate circuits.  We have not seen an outlet made in the past 50 years that does not have this tab, but that doesn’t mean that one doesn’t exist somewhere.  For this project we had to break that tab off, so that each outlet could be controlled separately.  Note that we did NOT break the tab by the nickel (silver) colored screws (where the white wire attaches); it was only necessary to break the one by the brass colored screws.

A heavy duty grounded power cord, and an electrical clamp to hold the power cord in place. We used a power cord from an old major appliance, but could just as easily have used one from a dead UPS or really any grounded power cord rated for 15 amps or more. The clamp was left over from a previous electrical project; they are only sold in packages of ten in our neck of the woods.  It would have been better and safer to use some kind of non-metallic (non-conductive of electricity) strain relief for the power cord, but we didn’t have such a thing so we just made sure that none of the “hot” wires inside the box touched the clamp.  If we had used a cord from something that had a plastic strain relief, such as the aforementioned dead UPS, we would have tried to remove and reuse that strain relief rather than the metal clamp.  Note that the plug in the picture below is for the Raspberry Pi’s power supply.

Side of electrical box showing cord and clamp

We used some leftover #14 solid electrical wire to make the high voltage connections (“high voltage” being standard household current, as opposed to the “low voltage” being the 5 volts or less used by the Raspberry Pi and the control circuitry on the relay board), a few wire nuts to make connections, and a ten pin ribbon cable to connect the relay board to the Raspberry Pi. Since both the Raspberry Pi and the relay board have pin connectors for the interconnection, we needed ribbon cable with female connectors on both ends. We had previously purchased this jumper wires/ribbon connectors kit from Amazon, but only because we could not find a package that only contained female-to-female connectors at a reasonable price.

Ribbon cable entering electrical box

And finally, some tie wraps and packaging tape to attach the Raspberry Pi to the outside of the electrical box.  Note that this assumes that we are not going to place this box anyplace where physical damage or stress is likely to occur.  As can be seen above, there is really nothing protecting the ribbon cable, but that’s okay for us because the box isn’t going to be moved around once it’s where we need it.  If there were any serious risk of the ribbon cable being damaged or pulled, we might have tried to use some additional protection, such as using silicone sealant/caulk at the hole where the ribbon cable enters the box, and/or wrapping the cable in some kind of protective sheath.

How we built it:

We drilled a ¾” hole in the side of the electrical box  for the clamp, making sure to place it so that it would not interfere with mounting the outlets but also so that when tightening down the retaining nut there would not be a box rib in the way.  You can see in one of the photos above where we placed it.  We suggest taping a piece of masking tape over the box prior to drilling and then drilling through the tape – this will keep the drill point from wandering and also help avoid any possibility of the box cracking.  We did need to work the drill around just a little bit to enlarge the hole slightly before the clamp would go through (a round file could also be used).

We stripped the insulation off the ends of three wires of the power cord, twisted the strands of each wire so they would be less likely to fray, and carefully passed the cord through the clamp and tightened the clamp to hold the cord in place.  When doing this we found that we had to pass a bit more through the clamp than we originally thought, because not having quite enough made it very difficult to make connections.

We then took a length of leftover electrical cable containing #14 wire (14/2 with ground) and removed the individual wires to use for wiring the outlets. We took the bare ground wire and ran it from ground terminal to ground terminal (the green screws) on each of the outlets, and connected that to the green ground wire of the power cord using an orange wire nut. When doing this we were careful not to leave too much excess in the loop from outlet to outlet, since we didn’t want the bare ground wire getting anywhere near the relays.

We also ran the white wire from the nickel (silver) colored screws on each outlet to the white wire of the power cord. We stripped the insulation in such a way that we could run one wire from outlet to outlet and then connect it to the power cord using an orange wire nut, but you could as easily run a separate wire from one of the nickel colored screws of each outlet and connect them all together with the white wire from the power cord using a red wire nut.  As long as the break off tab on the side of the outlet where the white wire connects has not been broken off, only one connection to one of the nickel colored screws on each outlet is necessary.

Then we cut about a five inch long piece of black wire for each brass colored screw (eight wires in total) and connected them to the brass colored screws on the outlets.  Once again, remember that we had to break the tab that connects the brass colored screws together at each outlet, so that each outlet can be controlled separately.  These wires are a bit tricky to prepare because one end must have enough of the insulation  stripped enough to loop around the screws on the outlets, while the other end must be stripped just enough to fit under the screw terminals on the relay board, preferably without leaving much excess bare copper showing. These wires connect to the normally open terminal of each relay.

In addition we prepared 8 wires about 4½ inches long, with one end stripped to go into a wire nut, and the other stripped just enough to connect to the relay board.  These wires connect to the center terminals of each relay.

The basic wiring of a single outlet is shown here.  This only shows two of the relays, and we simply duplicated this when connecting the other outlets to the other relays:

Diagram or wiring coinnections to an outlet and relays

The colors indicated are the colors of the electrical cord coming into the box, although we actually used black wires for all our connections to the relay contact terminals – we only used red wires in this illustration to make it obvious which wires connect to the black (hot) wire of the cord.  As it happened, the cord we used did not color code the neutral and hot wires, so we (VERY CAREFULLY!!!) used a voltmeter  to determine which was the hot wire – it was the one that gave us a reading of standard household voltage (usually 110 to 120 volts in the USA and Canada) relative to the ground wire.  Of course we had to be very careful not to let any of the exposed wires touch each other, or us or any other object (other than the voltmeter probes) when doing this test.  And of course this assumed that our household outlets are wired correctly.

There are a couple of other ways we could have determined which is the hot wire in a flat cord such as the one we used.  A close examination of an outlet such as the one pictured above shows that the two rectangular slots are slightly different lengths.  The shorter of the two is the hot side of the line, and you can see that the black wires to the relays are connected to that side in the above illustration.  If you can see which wire of the cord would be connected to the prong of the plug that would go into that shorter slot, if the plug were plugged into that outlet, then you know which is the hot wire of the cord.  Another way to determine which wire is which may be to use the sense of touch – if one of the wires has small ribs or grooves in it, that’s the neutral wire, while the opposite side of the cable would be the hot wire. Again, we’re assuming electrical standards used in the USA and Canada here; cords may well be different in other parts of the world.

After we had all the power cord and all the outlets and relays connected, but before we stuffed everything into the box, it looked like this:

Outlets connected to relays

Here’s another view:

Outlets connected to relays alternate view

You may note that there are two red wire nuts.  We found that it was impossible to fit nine wires (the eight going to the relays plus the hot wire of the power cord) under a single wire nut, so under one wire nut we connected four of the wires that connect to the center screw terminals of the relays, and a short jumper wire.  Then, under the other wire nut we connected the other four wires that connect to the center screw terminals of the relays, the other end of the jumper wire, and the hot wire from the power cord.

Just as an aside, we wonder why the manufacturers of these relays don’t offer a model where only one connection is needed to feed power to all the center terminals of all the relays?  It would save a lot of time if such a model were available, and it would probably be a lot safer as well since we’d have fewer total connections to make.

Connecting the relay board to the Raspberry Pi:

Once all the power connections are made and everything is secure, before carefully stuffing everything into the electrical box we connected the ribbon cable to the relay board.  We needed ten wires with female connectors on both ends. Near the center of the relay board, on the opposite edge from the relay contact connections, there should see a ten pin strip labelled as follows:

GND  IN1  IN2  IN3  IN4  IN5  IN6  IN7  IN8  VCC

We simply connected the ten wire ribbon cable up in straight sequence (no criss-crossing wires or anything like that) and made a note of which color wire connected to GND, and which connected to VCC.  Other may prefer to use specific colors with specific pins, but we just found it easier to not mix up the order of the wires.  Once the ribbon cable is connected and routed out of the box through one of the knockout holes (see the pictures above) we were able to get the relay board and all the wiring stuffed into the box.  We tried to get the relay board as close to the bottom of the box as possible, which meant we had to carefully bend the black wires to allow that to happen, but we also had to keep in mind that the relay board is rather fragile and to not put too much pressure on the board itself.  As we were pushing the board down we could gently pull more of the ribbon cable out of the knockout hole.  We took a little time with this process because if we had just tried to jam the relay board into the box there’s a good chance it would either have broken, or would not have pushed all the way down to the bottom of the box.  We especially wanted to make sure that the bare ground wires could not touch the relay board, particularly the relay screw terminals, since that would have probably caused a rather spectacular flash as the electricity short-circuited!  And also, we wanted to keep a little distance between the relay board and that metal clamp that holds the power cord in place, since the last thing we wanted was the hot side of the electrical line touching that clamp – that would be an electrocution hazard waiting to happen!

When pulling the ribbon cable out of the knockout hole we had to make sure that it didn’t bind, since we were essentially pulling it the wrong way through the hole, and also that we didn’t pull too much and bend the pins on the relay board.

Once we had everything into the box, we could connect the ribbon cable to the Raspberry Pi.  This diagram attempts to show the way we connected the cable, though the colors picked for this illustration are completely arbitrary:

Ribbon cable wiring

Here is how each of the pins on the relay board connected to the pins on the Raspberry Pi Model 1 that we used, starting with GND and ending with VCC:

GND to Pin 25 (GND)
IN1 to Pin 22 (GPIO25)
IN2 to Pin 18 (GPIO24)
IN3 to Pin 16 (GPIO23)
IN4 to Pin 15 (GPIO22)
IN5 to Pin 13 (GPIO27 or GPIO21, depending on model)
IN6 to Pin 12 (GPIO18)
IN7 to Pin 11 (GPIO17)
IN8 to Pin 7  (GPIO4)
VCC to Pin 2  (5 V)

This is what our ribbon cable actually looks like at the Raspberry Pi end:

Ribbon cable connection to Raspberry Pi

You may wonder why we made the ribbon cable connections in what appears to be reverse order, for example using GPIO25 for IN1 and GPIO4 for IN8.  The reason is that if you look at how we wired the outlets to the relay board, the leftmost outlet is actually wired to the relays associated with IN8 and IN7.  So the lowest numbered GPIO actually controls the top left outlet, and the highest numbered GPIO controls the bottom right outlet.  But also, it makes the ribbon cable connections a little neater at the Raspberry Pi, because the connections for +5 V and GND are at the right ends of the cable.

As for why we used the particular GPIO ports that we did, we chose to use only the eight GPIO pins that cannot be used for other purposes.  While there are additional GPIO pins on the Raspberry Pi, the ones we did not use can be used for other purposes.  If you look at this Raspberry Pi Pinout Diagram, we used the pins that are color coded green.

Here’s one more picture we took just before installing the cover plate over the outlets.  You can’t really see it but the relay board fits nicely in the bottom of the box, and since this box is not going to be moved around we figured the stiffness of the #14 solid copper wires would be sufficient to hold the board in place.  If the box were going to be subjected to vibration or movement, we would have mounted the relay board to the bottom of the box with screws and standoffs, and maybe covered the relay screw terminals with some kind of insulating material after all the connections were made, or at least used a strip of good quality electrical tape across the tops of the screw terminals.  If we were to ever attempt to build such a unit for someone else to use, we would certainly make some attempt to secure the relay board to the bottom of the box, but realistically given the light weight of the relay board and all those #14 copper wires holding it in place, and the way it fits in the bottom of the box, we seriously doubt it’s going anywhere.

Outlet box before cover plate installed

In case you are wondering, we did decide to have the main power plug for the unit, and the Raspberry Pi’s power supply, plug into separate outlets rather than trying to cram the Raspberry Pi’s power supply inside the electrical box and somehow attempt to safely connect it to the power cord. While it is certainly possible to do something like that, we don’t like cramming too much inside the box and we don’t have a problem with plugging the Raspberry Pi into a separate power strip that has a built in surge suppressor. Also, the power supply we used with a Raspberry Pi might fail someday, and it would be far more difficult to replace a failed power supply if we had to partially disassemble the unit to get to it.

We just want to note once more that the maximum load that can be connected to any one outlet is 10A, since that’s all the relay contacts are rated for.  Using the formula volts X amps = watts, that means that if the household voltage is 110V then we can only connect a maximum of 110 volts X 10 amps = 1100 watts of purely resistive load.  A purely resistive load would be something like incandescent lights, or a small heater with no fan or any other kind of motor.  However, motors, transformers, and other inductive loads can draw many times their rated current for a split second during startup – this is why the lights may dim momentarily when any appliance with a large motor starts up.  So, when connecting an inductive load, it probably should not draw anywhere near that 1100 watts maximum.  A desktop computer is probably safe – normally they don’t draw anywhere near the wattage rating of their power supplies, unless perhaps a lot of peripherals are attached.  But we would not even think of trying to control a window air conditioning unit with one of these – that would at the very least fry the relay contacts in a fairly short time.

And also, the maximum overall rating of connected equipment to ALL of the outlets cannot exceed the current-carrying capacity of the power cord, nor the circuit that the device is plugged into.  The power cord we used has #14 wires, so it would handle 15A, or about 1650 watts (110 volts X 15 amps) safely.  If we had a power cord with #12 wires, it could handle up to 20A, or about 2200 watts, but it’s fairly rare to find an AC power cord with #12 wires.

One more time, we want to emphasize that all of the above is what we did. We are NOT suggesting or implying that you should do what we did. If you choose to attempt to emulate what we did, YOU and YOU ALONE are responsible for the results, be they good or bad. Please re-read the cautionary paragraphs at the beginning of this article, and don’t even think of trying to emulate what we did if you are not absolutely certain that you can do it safely.

Controlling the outlets

Assuming that Raspbian has been installed on the Raspberry Pi, and that it has been configured using raspi-config, it is fairly easy to control the GPIO pins on the Raspberry Pi.  Unfortunately many sites will tell you to install a lot of unnecessary software.  A prime example is something called WiringPi, which is written in the C language. Anyone that has used it before and is comfortable with it can certainly use it for this type of project, but it’s overkill because the GPIO pins can be controlled perfectly well using simple bash scripts. And besides, WiringPi has been deprecated by the author.

There is one set of scripts that should go into the Pi’s root directory, since they must be run as root (or using sudo).  Anyone can download these scripts using this link (click the “Download” button).  The procedure would then be to copy the root_dir_gpio_scripts.zip file to the Raspberry Pi, and then move the scripts into the root directory and make them executable using these commands (replace /path/to/ with the actual path to the downloaded zip file):

sudo su
cd /root
unzip /path/to/root_dir_gpio_scripts.zip
chmod +x gpio*.sh

Feel free to examine the scripts using any standard text editor if you like, then enter

exit

to stop being the root user. These scripts can be run on their own to control the GPIO pins. For example, entering

/root/gpio4.sh on

should turn on the outlet associated with GPIO4, or

/root/gpio4.sh off

should turn that same outlet off. The other available options are toggle, which will turn the outlet on if it is currently off, or off if it is currently on, or reboot, which will turn off the outlet for 30 seconds and then turn it back on. If 30 seconds is too long to wait, the “sleep 30” command in each of the scripts could be changed to a more preferable time delay.

Please note that scripts are included for both GPIO21 and GPIO27, since some Raspberry Pi’s assign Pin 13 as GPIO21 and some as GPIO27. One or the other should control pin 13 of the Raspberry Pi. It is safe to delete whichever of the two does nothing on a particular Raspberry Pi.

While controlling the outlets using these scripts is possible, it can get a bit cumbersome, especially since the user would have to remember which outlet (and the device plugged into that outlet) is controlled by which GPIO pin. Fortunately, there’s an easier way, though it does depend on the scripts from the root_dir_gpio_scripts.zip package having been installed correctly. It begins with downloading the script from this link. The procedure is the same as for the previous zip file, except this installs to the user’s home directory. So do this:

cd ~
unzip /path/to/powercontrol.zip
chmod +x power.sh

The script is run by entering:

./power.sh

Or if that’s too much effort, this line can be added to the end of the user’s .bashrc file:

alias power="/home/pi/power.sh"

After that, simply entering the word power at a command prompt should be sufficient to run the script. One thing to note about the power.sh script is that it assumes the use of GPIO27 rather than GPIO21 for Pin 13.   If the Raspberry Pi uses GPIO21 to control Pin 13, then run this to change the GPIO designation in the script:

sed -i -e 's/27/21/g' ~/power.sh

When you run the power.sh script you should see something similar to this:

PowerPi Control

Outlet 1 (Outlet 1) is currently ON
Outlet 2 (Outlet 2) is currently OFF
Outlet 3 (Outlet 3) is currently ON
Outlet 4 (Outlet 4) is currently OFF (UNINITIALIZED)
Outlet 5 (Outlet 5) is currently OFF (UNINITIALIZED)
Outlet 6 (Outlet 6) is currently OFF
Outlet 7 (Outlet 7) is currently ON
Outlet 8 (Outlet 8) is currently OFF

Enter action to take (On, Off, Reboot, Toggle, or Rename) followed by outlet number, for example OFF 1 or ON 2. You can also enter QUIT or EXIT:

As you can see, it will show the state of each outlet at the time the script is run.  There are three possible states: OFF (UNINITIALIZED), OFF, and ON.  An outlet that is OFF will only have the (UNINITIALIZED) after it if no commands have been sent to it since the last reboot.  (UNINITIALIZED) is only an informational tag; the outlet is still off.

Note that Rename n (where n is an outlet number) can be used to change the name associated with an outlet, which is what is shown between the parentheses on each line.  It’s also possible to change the outlet name manually by editing the contents of the associated outletnamen file, which is in the same directory as the power.sh script.

The scripts above can be run from a terminal window on the Raspberry Pi itself, or through a ssh connection from another machine on your local network.  If you find you cannot ssh into your Raspberry Pi, run sudo raspi-config and then select “5  Interfacing Options  Configure connections to peripherals“, and then select “P2  SSH  Enable/Disable remote command line access to your Pi using SSH” and enable ssh access from there.

Anyone could write their own software to control this board, and it’s certainly possible to call the gpion.sh scripts from other scripts or software. However, one thing we found is that apparently the logical signals received by the relay board do the opposite of what might be expected. In other words, when a GPIO pin is at logical zero, the associated relay will turn on, and then when that GPIO pin goes to logical 1, the relay will turn back off. The scripts we used take this into account, but other Raspberry Pi GPIO pin control software might not. Therefore, if other software is used, it could return a false indication of the current state of the relays, or controls might do the opposite of what is expected.

We hope this article gives someone the inspiration to make something better than what we made! Once again, please be safe when working with electricity, and seek expert assistance if you don’t know what you’re doing!