Saturday, 26 April 2014

Raspberry Pi as an SMS Gateway

Today was one of those days where I thought I'd find something useful for my Raspberry Pi to do, rather than sit in a box unloved.

I was thinking how we send a lot of monitoring notifications as emails and how bad email is as a single method notification, especially if what you are monitoring is your connection to the internet... Internet connection goes down, how do you send the notification out?

I had a 3G USB dongle also sitting around doing nothing, so as a test I stuck a Pay+Go simcard in, made sure it had some credit and connected it to my Raspberry Pi.

This is how I got it to send an SMS (Will likely expand this post as I add features).

What library to use?

First off I had to work out the best existing library to interact with the 3G dongle. I could remember using Gnokii many years ago, but figured that something better was likely available these days.

I came across Gammu, which started as a fork of Gnokii. Gammu also has a daemon service to interact with the dongle/phone and a Python library.

Thankfully Gammu provides packages so installing it on Raspbian was nice and simple:

$ sudo apt-get update
$ sudo apt-get install -y gammu-smsd gammu python-gammu usb-modeswitch vim

Get the 3G dongle working!

Lets check that the 3G dongle is actually recognised:

$ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 12d1:1c0b Huawei Technologies Co., Ltd. E173s 3G broadband stick (modem off)

Looks positive, but "modem off" is a bit concerning. How do I turn it on?

USB-ModeSwitch is a handy utility to deal with USB dongles that sometimes start off as a USB storage device, then switch over to 3G modem mode using a Windows driver. Do see the link in the references for a nice tutorial on getting your dongle into modem mode you may or may not need to follow it, skip ahead and see if it works anyway.

After following this usb-modeswitch tutorial I had the product and vendor codes for storage and modem mode, I'd edited the /etc/usb_modeswitch.conf file and now had the following:

$ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 005: ID 12d1:1c05 Huawei Technologies Co., Ltd. E173s 3G broadband stick (modem on)

Next I needed to figure out which device to interact with. This Gammu tutorial suggested it was likely to be /dev/ttyUSB0, so following the instructions I got:

$ dmesg | grep tty
[    0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=1824 bcm2708_fb.fbheight=984 bcm2708.boardrev=0xd bcm2708.serial=0xfabd9bb1 smsc95xx.macaddr=B8:27:EB:BD:9B:B1 sdhci-bcm2708.emmc_clock_freq=250000000 vc_mem.mem_base=0x1ec00000 vc_mem.mem_size=0x20000000  dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
[    0.000000] console [tty1] enabled
[    0.529958] dev:f1: ttyAMA0 at MMIO 0x20201000 (irq = 83) is a PL011 rev3
[    0.872185] console [ttyAMA0] enabled
[   15.210185] usb 1-1.3: GSM modem (1-port) converter now attached to ttyUSB0
[   15.279909] usb 1-1.3: GSM modem (1-port) converter now attached to ttyUSB1
[   15.327694] usb 1-1.3: GSM modem (1-port) converter now attached to ttyUSB2

I had 3 ttys listed... Nevermind I'll stick with trying the first one as suggested and ran gammu-config, set the port to /dev/ttyUSB0, left everything as defaults and saved.

  │ Current Gammu configuration             │
  │                                         │
  │  P Port                 (/dev/ttyUSB0)  │
  │  C Connection           (at19200)       │
  │  M Model                ()              │
  │  D Synchronize time     (yes)           │
  │  F Log file             ()              │
  │  O Log format           (nothing)       │
  │  L Use locking          ()              │
  │  G Gammu localisation   ()              │
  │  H Help                                 │
  │  S Save                                 │
  │                                         │
  │                                         │
  │        <Ok>            <Cancel>         │
  │                                         │

This created a file in my home directory ~/.gammurc

I noticed that /dev/ttyUSB0 had some interesting permissions set:
$ ls -l /dev/ttyUSB*
crw-rw---T 1 root dialout 188, 0 Apr 26 13:10 /dev/ttyUSB0
crw-rw---T 1 root dialout 188, 1 Apr 26 12:54 /dev/ttyUSB1
crw-rw---T 1 root dialout 188, 2 Apr 26 12:54 /dev/ttyUSB2

You will need to ensure that whichever user is using Gammu is a member of the dialout group, thank fully I already was:
$ id
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),5(tty),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),105(netdev),999(input),1002(spi),1003(gpio)

But you can add a user to a group with:
$ sudo usermod -a -G dialout pi

Lets send a message!

One way to test that Gammu is working is:
$ gammu getallsms

0 SMS parts in 0 SMS sequences

You can try sending a message with something like the following:
$ echo "test from gammu" | gammu sendsms TEXT 07xxxxxxxx9
If you want break, press Ctrl+C...
Sending SMS 1/1....waiting for network answer..OK, message reference=7

If all is well you should have received a message from Gammu, sent from your Raspberry Pi!

How about using the SMSD service?

To use with the SMSD service, you'll need to configure up /etc/gammu-smsdrc with the same port as ~/.gammurc and restart the service:
$ sudo service gammu-smsd restart

Check it is working with:
$ sudo gammu-smsd-monitor

And send a message with:
$ echo "All your base are belong to us" | sudo -u gammu gammu-smsd-inject TEXT 07xxxxxxxx9
gammu-smsd-inject[2858]: Warning: No PIN code in /etc/gammu-smsdrc file
gammu-smsd-inject[2858]: Created outbox message OUTC20140326_145849_00_07xxxxxxxx9_sms0.smsbackup
Written message with ID /var/spool/gammu/outbox/OUTC20140326_145849_00_07xxxxxxxx9_sms0.smsbackup

Any issues?

Note that the /var/spool/gammu/outbox directory is owned by the gammu user, hence running gammu-smsd-inject with sudo.
If you want other users to send messages, add them to the dialout group and try:
$ sudo chgrp -R dialout /var/spool/gammu/

Also note that while the gammu-smsd service is running you may not be able to use gammu, other that through the service
$ gammu getallsms
Error opening device. Unknown, busy or no permissions.
$ sudo service gammu-smsd stop
[ ok ] Stopping Gammu SMS Daemon: gammu-smsd.
$ gammu getallsms

0 SMS parts in 0 SMS sequences

How do you use Gammu SMSD with Python?

Like this :)

Alternatives (golang)

This golang project looks pretty interesting as an alternative: It even has a http api


USB ModeSwitch (3G dongles) -
Gammu tutorial -
Gammu Docs -
SMSD Python example -


  1. This comment has been removed by the author.

  2. Thanks for giving great information about bulk SMS ..
    I am also using Bulk SMS service and this blog is so helpful for me you share good information about API SMS .

  3. This is certainly a very interesting way, but as for me is not very reliable. I'd better take advantage of using this company and will be absolutely full confidence in the result.