Building an SMS gateway for openHAB (on Linux)

Hi

I saw this post and thought that it might be a really nice option to add to a system.

I originally considered a dedicated GSM Gateway, which would enable SIP based phone systems to use the voice service too.

For a simpler option, you could always throw an old Android phone in a cupboard and use an SMS Gateway app like this

https://play.google.com/store/apps/details?id=com.icecoldapps.smsgatewayultimate

Or

Or a search for “SMS gateway ultimate APK” and found this…

https://www.apkmonk.com/download-app/com.icecoldapps.smsgatewayultimate/2_com.icecoldapps.smsgatewayultimate_97667_2013-04-08.apk/


I like that it has a web server and that it can push an incoming SMS somewhere else.


Update - March 5th 2019

I’ve found a few minutes to test this… and it works :smile:

It is really easy to setup the outgoing SMS.

All I did was run the SMS Gateway Ultimate (Free) app on a very old Samsung S2, with a live SIM.

Once I setup a server on it and got the port number, I wrote / adapted a quick rule that captures a String Item and pushes the text into the SMS gateway.

The only minor detail is that any " " characters needs to be replaced with “+”

Rule looks like this…

rule "TTS VoiceCommand"
when
Item VoiceCommand received update

then
val String message = VoiceCommand.state.toString.replace(" ", "+")
	
say(VoiceCommand.state, "voicerss:enAU", "webaudio")

sendHttpGetRequest("http://192.168.1xx.xxx:39424/send.html?smsto=07860xxxxxx&smsbody="+message+"&smstype=sms") // Where the IP is that of the phone running the APP and the 'smsto' is the receiving phone number

end 

The keen eyed will notice the &smstype=sms at the end of the command, you could change that to &smstype=email and get the phone to send out an email?
I’m not sure how it would cope in the event of a WAN / DSL internet connection failure, would it fail completely or would it roll back to it’s own mobile data connection???

??? The real question is… how do I force such a situation to test it?

So now any changes to my VoiceCommand string Item gets

  • announced by any instance of paperUI or habpanel.
  • sent as an SMS to any recipients I care to add to the rule


It is possible to create a Rule within SMS Gateway Ultimate that will forward any (matching?) incoming SMS to

  1. A new SMS recipient
  2. An email
  3. A HTTP GET command

What I can’t seem to do is place the attributes of an incoming SMS into the body of a POST command.
I’ve emailed the developer to ask if this is possible, but I haven’t heard back as yet.

Available attributes are –

  • %from%
  • %body%
  • %timestamp%
  • %time%
  • %timenow%
  • %timenowstring%
  • %pseudosubject%
  • %servicecenteraddress%
  • %devicemodel%
  • %device%

Update - March 13th 2019

I’ve stumbled across a work-around to enable the Android App to “PUT” the incoming SMS into openHAB2.

(It’s not pretty, but it works, so if anyone has a better solution please give (lots of) guidance.

What I found was that the ClassicUI supports GET requests via CMD?

So, I installed the ClassicUI user interface for openHAB2, via the paperUI addons section.

Then from a browser, I tried this command, to mimic an incoming SMS, where SMSRX is the String item I created to accept the SMS

http://{openhab2_IP:Port}/classicui/CMD?SMSRX=123456789:does%20this%20work

So the next thing I did was to add this command into a “Rule” within the SMS Gateway Ultimate App.

http://{openhab2_IP:Port}/classicui/CMD?SMSRX=%from%:%body%

With this rule, I can now spit out the sender of the SMS and the message.

// Var's at top of rule
var String SMSRXNumber = null
var String SMSRXBody = null


rule "SMS receive"

when
Item SMSRX received update
then

var String smsincoming = SMSRX.state.toString

var SMSRXNumber 	= (smsincoming.split(':').get(0))
var SMSRXBody 		= (smsincoming.split(':').get(1))

logInfo("SMS RX","Sender = "+SMSRXNumber+" Message = "+SMSRXBody)

end

Update - March 21st 2019

I’ve just tweaked the rule to allow me to send commands to my home via SMS.

To prove the idea, I created a “Say” and “Display” command.

to trigger these, I simply send a text in this format

say:Hello World

or

display:Put some text on the displays

or

display:clear

The Say command pushes the SMSRXCommand variable to my ChromeCast devices and the Display command pushes the SMSRXCommand variable to the Oled displays of my Velbus glass panels.
There is also a filter in the Display command that sends an empty string to the OLED panels to clear the screen/s.

// Top of file - add this line to make the variable available to the whole rule
var String SMSRXCommand = null


// Annouce stuff

	if (SMSRXBody.trim == "Say" || SMSRXBody.trim == "SAY" || SMSRXBody.trim == "say" ){
	
	SMSRXCommand	= (smsincoming.split(':').get(2))
	say(SMSRXCommand, "voicerss:enGB", "webaudio")
	logInfo("SMS RX","SMS Sender Name = "+SMSRXName+" Sender Number  = "+SMSRXNumber+" Code = "+SMSRXBody+", Message = "+SMSRXCommand)
	say(SMSRXCommand, "voicerss:enGB", "chromecast:audio:3f5b31d2c7d792037ef036c498c40a1c")			// Bathroom
	say(SMSRXCommand, "voicerss:enGB", "chromecast:chromecast:dc1c3cdca7c119edda07b157b89213ed")	// Cabin
	say(SMSRXCommand, "voicerss:enGB", "chromecast:chromecast:9fcd8320e1763a302be40c2accd5decf")	// Lounge	
	say(SMSRXCommand, "voicerss:enGB", "chromecast:chromecast:aa06742fcb32f738f264f256ad1540c7")	// TV Room
//	say(SMSRXCommand, "voicerss:enGB", "chromecast:audiogroup:fda9a2ef-25e9-4ac6-bbfa-74acc2f5902b")	// ChromeCast Audio Group	
	}
	
// Send the Command to the OLED panels
	
	if (SMSRXBody.trim == "Display" || SMSRXBody.trim == "DISPLAY" || SMSRXBody.trim == "display" ){
	
	SMSRXCommand	= (smsincoming.split(':').get(2))
	
	logInfo("SMS RX","SMS Sender Name = "+SMSRXName+" Sender Number  = "+SMSRXNumber+" Code = "+SMSRXBody+", Message = "+SMSRXCommand)
	
	if (SMSRXCommand == "clear"){
	
	BackBedroomGPO_OledDisplay_Memo.sendCommand("")
	Thread::sleep(150)
	Cabin_Memo_Text.sendCommand("")
	Thread::sleep(150)
	LoungeGPO_OledDisplay_Memo.sendCommand("")
	Thread::sleep(150)
	TVRoomGPO_OledDisplay_Memo.sendCommand("")
	
	return
	}


	BackBedroomGPO_OledDisplay_Memo.sendCommand(SMSRXCommand)
	Thread::sleep(150)
	Cabin_Memo_Text.sendCommand(SMSRXCommand)
	Thread::sleep(150)
	LoungeGPO_OledDisplay_Memo.sendCommand(SMSRXCommand)
	Thread::sleep(150)
	TVRoomGPO_OledDisplay_Memo.sendCommand(SMSRXCommand)

	}
2 Likes