Building an SMS gateway for openHAB (on Linux)

tutorial
sms
gammu
Tags: #<Tag:0x00007f1e56744e80> #<Tag:0x00007f1e56744cf0> #<Tag:0x00007f1e56744bb0>
(Dan) #1

It’s useful to have an SMS gateway for openHAB in case the home internet goes down, or you’re travelling somewhere with mobile phone reception but no internet. Aim is to have a system which can provide SMS notifications and respond to SMS requests.

Steps (tested on Ubuntu 14.04):

  1. This is the most difficult bit. Buy the right kind of USB modem. Important you get an old one which behaves as a modem from the get go, e.g. Huawei E169. The newer ones all include flash memory with drivers on it, and it’s difficult to switch them into modem mode on Ubuntu 14 (there’s a utility called usb_modeswitch but me and many others have found it won’t work with newer versions of Ubuntu). I wasted hours on the newer models, and strongly recommend you go to ebay or somewhere and pick up an E169.

  2. Of course get a suitable SIM card, e.g. giffgaff in the UK.

  3. Install the gammu and gammu daemon SMS software:

sudo apt-get install gammu gammu-smsd

  1. Plug in the modem and lsub. You should see a line like:

Bus 002 Device 008: ID 12d1:1001 Huawei Technologies Co., Ltd. E169/E620/E800 HSDPA Modem

  1. Look in the /dev/serial/by-id directory and you’ll see something like:

usb-0658_0200-if00
usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0
usb-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_HUAWEI_Mobile-if00-port0
usb-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_HUAWEI_Mobile-if01-port0
usb-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_HUAWEI_Mobile-if02-port0

(a smarter person than me would use a symlink at this point)

  1. edit the gammu config file /etc/gammu-smsdrc to look like this :

# Configuration file for Gammu SMS Daemon

# Gammu library configuration, see gammurc(5)
[gammu]
# Please configure this!
port = /dev/serial/by-id/usb-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_HUAWEI_Mobile-if00-port0
connection = at115200
# Debugging
logformat = textall
logfile = /var/log/gammu.log

# SMSD configuration, see gammu-smsdrc(5)
[smsd]
PIN=9999
service = files

logfile = /var/log/gammu-smsd.log
RunOnReceive = /etc/openhab2/utils/receivesms.sh
# Increase for debugging information
debuglevel = 1

# Paths where messages are stored
inboxpath = /var/spool/gammu/inbox/
outboxpath = /var/spool/gammu/outbox/
sentsmspath = /var/spool/gammu/sent/
errorsmspath = /var/spool/gammu/error/
  1. Test this - make sure the daemon isn’t running and check the status:

sudo service gammu-smsd stop
sudo gammu identity

You should see something like:

Device : /dev/serial/by-id/usb-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_HUAWEI_Mobile-if00-port0
Manufacturer : Huawei
Model : E169G (E169G)
Firmware : 11.314.10.51.156
IMEI : [number]
SIM IMSI : [number]

  1. Start the gammu daemon

sudo service gammu-smsd start

It should restart automatically when the system boots

  1. Check you can send SMSs:

gammu-smsd-inject TEXT 0044999999999 -text "Test message"

(note you will need to provide the 00, then the country code, then the number)

  1. Assuming that works, you can now create the /etc/openhab2/utils/receivesms.sh script that will pass incoming SMSs to openhab. To make life simple, my script converts all incoming messages to lower case and strips out spaces. It also provides very basic logging:

    #!/bin/sh
    from=$SMS_1_NUMBER
    message=$SMS_1_TEXT
    
    echo "`date`: SMS from $from reading $message" >> /etc/openhab2/utils/SMS.log
    
    #put message into lower case
    message=`perl -e "print lc('$message');"`
     
    #delete blank spaces
    message="$(echo "${message}" | tr -d '[[:space:]]')"
    
    #delete initial + from number and add two zeros
    from="00$(echo "${from}" | cut -c 2-)"
    
    wget -qO- http://localhost:8080/classicui/CMD?SMStext=$message &> /dev/null
    wget -qO- http://localhost:8080/classicui/CMD?SMSnumber=$from &> /dev/null
    wget -qO- http://localhost:8080/classicui/CMD?SMSreceived=ON &> /dev/null
    
  2. Then create openHAB items:

    Switch 	SMSreceived
    String	SMStext
    String	SMSnumber
    
  3. And a basic rule to process received SMSs:

    rule "SMS processor"
    when
    	Item SMSreceived received command ON
    then
    	
    	logInfo("SMS", "SMS received - pausing before processing")
    	
    	Thread::sleep (1000)
    
    	logInfo("SMS", "SMS received from {}:{}",SMSnumber.state,SMStext.state)
     
    //	Text from either of us
    	if ((SMSnumber.state =="0044123456789]") || (SMSnumber.state =="0044123456789")) {
    		logInfo("SMS", "Confirmed text from one of us")
    
    		if (SMStext.state=="open") {
    			logInfo("SMS", "Opening door")
    			DoorSwitch.sendCommand(ON)
    		}
    
    //		etc etc
    	}
    
    //	Tidy up
    
    	SMSnumber.sendCommand("")
    	SMStext.sendCommand("")
    	SMSreceived.sendCommand(OFF)
    	logInfo("SMS", "Done processing SMS")
    end
    
    1. Sending SMSs from within a rule is easy (using the impenetrable executecommandline format):

executeCommandLine("gammu-smsd-inject@@TEXT@@0044123456789@@-text@@\"This is an example message\"")

That’s it!

Dan

Edit: to use a symlink, I created a file /etc/udev/rules.d/99-usb-serial.rules with the following line:

SUBSYSTEM=="tty", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1001", SYMLINK+="usb_modem"

then the relevant line in the gammu config file will read:

port = /dev/usb_modem
8 Likes

Some questions
(Dries) #2

Interesting!

Currently I send SMS messages using the API of a network provider.

0 Likes

(Dan) #3

I used to do that, but of course doesn’t help if internet goes down…

0 Likes

(Dries) #4

That is indeed a weak point. :slight_smile:

2 Likes

(Tommy Sharp) #5

Would it make sense to have an old Android phone at home with Tasker that sends and receives the SMS messages?

1 Like

(marcel_erkel) #6

Please be aware of SMS spoofing. I for sure would not unlock my door based on the originating number. It’s not safe!

0 Likes

(Dan) #7

Good point - real rule has password plus “open”. Any hacker that can intercept that is going to be too busy hacking the CIA to bother with my house.

1 Like

(Dan) #8

Interesting suggestion re. a phone - if you can remove the battery then presumably it could run 24/7 without any problems?

0 Likes

(Fabien) #9

@dan12345 thanks a lot for the detailed tutorial !

At the moment, I can send sms by the command line with my raspberry. But if I use the executeCommandLine command placed in a rule I do not receive any sms.
The log viewer says that everything is fine and that the commandline was excuted but nothing.

Is it possible that the PIN code of the SIM card is stopping openhab from sending an sms ?

0 Likes

(Dan) #10

More likely the openHAB user is not in the dialout or tty group.

Try:

sudo adduser openhab dialout
sudo adduser openhab tty   # ?

Dan

0 Likes

(Fabien) #11

I tried and openhab was already a user of both groups…

0 Likes

(Dan) #12

have you tried running openHAB as root, to eliminate permissions as being a problem?

0 Likes

(Fabien) #13

No didn’t try this.
And I cannot find the way to do it with openhab2. Found with openhab but the given files for the USER_AND_GROUP permissions is not located at the same place.
Could you direct me with this? Thanks again

0 Likes

(Dan) #14

edit /etc/default/openhab2 and add: USER_AND_GROUP=“root:root”

0 Likes

(Fabien) #15

I tried to edit the openhab2 file, but as openhabian user I have no write permission.

0 Likes

(Dan) #16

sorry, not familiar with openhabian, but can’t you sudo?

0 Likes

(marcolino) #17

Hi,
I use this kind of method since 3 years, bu I use this gateway:
http://smstools3.kekekasvi.com/

in order to avoid spoofing I setup into the inbound script a simple rule that accept only command from a specifica number, other message are send to my mailbox, to avoid to loose carrier related sms
Marco

0 Likes

(Dan) #18

good to know there are other options.

I may be naive, but seems to me that it would take serious hacking to get past (1) nobody else knowing the SMS number, (2) only accepting commands from designated numbers; (3) commands requiring a password. Local burglars are more likely to be drug-addicted teenagers than Tom Cruise from Mission Impossible.

0 Likes

(Christer Palm) #19

Nice!

I’m a total OpenHAB newbie and I too need two-way sms integration without involving an internet-based gateway, so this will be a great start. I’ve ordered one of those cheap gsm modules that uses a plain serial port to talk to the host using standard GSM AT-commands, so the host integration should be simple enough.

However, I’m thinking that it would be rather easy to create an add-on for this - the point being that it would enable a slicker integration (or at least, so I like to think :-)). I’m primarily thinking about the way incoming commands are handled. It would be nice if I could have a generic interface without having to write a ton of rules. For example:
"{password} GET {item ID}" and it would respond with the current value, and
"{password} SET {item ID} {Value}" and it would respond with a confirmation message.

But I don’t know if the OpenHAB add-on API would allow for this kind of integration (?)
I suppose it would act as a kind of user interface rather than anything else?
Of course, it would also need to provide a “send” action to send sms’s from rules.

Anyway, if anyone wants to collaborate on this, please post your thoughts, ideas, requirements and use-cases, etc.

0 Likes

(Fabien) #20

Thank you @dan12345 for your help.

I finally found the solution to my issue.
In the rules, with the exec command the following code needs to be used:

	val results = executeCommandLine("gammu@@sendsms@@TEXT@@12345678@@-text@@\"This is an example message\"")

With the addition of the “val results” command all is working fine now and I can send sms.

0 Likes