Send SMS with USB GSM modem when alarm triggered

Whilst this work is all great, there are many variables to consider… especially considering the type of dongle/bearer etc…

I would push for a Gammu Addon instead… https://github.com/pajikos/sms-gammu-gateway … use the right tools for the right job and don’t try to re-invent the wheel… or do, but then don’t complain about breaking changes down the line… but as i started off by saying… well done on the hard work and getting this working…

The problem with Gammu is that it does not uses an async approach to talk to the modem, it locks
for every single call to the modem.

The goals will be to use the async serial interface for python to make sure we don’t use the global python lock which if used in Home Assistant will block.

I do agree, however, maybe we should create another python async friendly library to abstract SMS commands and then have a hass specific extension on top of that.

Today I completed my migration to hassio.
However, I ran into a problem in how Alpine recognizes the Hauwei USB stick, it refuses to install the usb serial driver for it.
In other Linux distros you are supposed to run usb_switch, however running this in hass.io give me the following error:

core-ssh:~# usb_modeswitch -v 12d1 -p 14fe -M 55534243123456780000000000000011062000000101000100000000000000
Error: Failed to initialize libusb. LIBUSB_ERROR_OTHER (-99)

I will follow up with a new issue on hassio

I have created a fix for hassio here

This is a version of a python script compatible with hassio:

import serial
import sys
import getopt
import logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

DEST=sys.argv[1]
#MD="/dev/ttyUSB2"
MD="COM10"
if (len(sys.argv) > 2):
    message=sys.argv[2]
else:
    message = ''
    for line in sys.stdin:
        message+=line

logging.debug('Sending message '+message+' to '+DEST)

logging.debug('Opening serial port '+MD)
ser = serial.Serial(MD)  # open serial port
ser.write(b'\x1a') # Flush any previuos attempts to send message
ser.flush()

logging.debug('Sending AT+CMGF command')

line = b''
ser.write(b'AT+CMGF=1\r')
while line!=b'OK\r\n':
  line = ser.readline()
  logging.debug('Response '+str(line))

ser.flush()

logging.debug('Sending AT+CMGS command')
line = b''
phoneAsAscii = bytes(DEST, 'ascii')
ser.write(b'AT+CMGS="'+phoneAsAscii+b'"\r')
while line!=b'> \r\n':
  line = ser.readline()
  logging.debug('Response '+str(line))

ser.flush()
logging.debug('Sending message')
messageAsAscii = bytes(message, 'ascii')
ser.write(messageAsAscii + b'\x1a')
line = b''
while line!=b'OK\r\n':
  line = ser.readline()
  logging.debug('Response '+str(line))

ser.close() 

Another good reason to have a native SMS integration.

1 Like

Hey Oscar,

I have just updated the Hassos and see that your PR was merged. It would be great to understand how this will work for:

  • Internet failover
  • SMS Send/Receive (hopefully with the possibility of easily itegrating sensors from the MT’s

Let me know if you need any help testing…

Thanks for all your hard work…

My python script needs some work, so I switched back to a bash shell:

/config/send_sms.sh
#!/bin/bash

DEST=$1
MD="/dev/ttyUSB2"

if [ -z "$2" ]
then
read message
else
message="$2"
fi

echo "Sending $message to $DEST"

apk add ppp

stty -F $MD 9600 min 100 time 2 -hupcl brkint ignpar -opost -onlcr -isig -icanon -echo

chat TIMEOUT 10 "" "AT+CMGF=1" "OK" > $MD < $MD
chat TIMEOUT 10 "" "AT+CMGS=\"$DEST\"" "OK" > $MD < $MD
chat TIMEOUT 10 "" "$message^Z" "OK" > $MD < $MD

Also, if you are using a RPI4, I found that you need a udev rule in the config USB stick, for me this config was:

udev\10-gsm-modem.rules
ACTION=="add" \
, ATTRS{idVendor}=="12d1" \
, ATTRS{idProduct}=="14fe" \
, RUN+="/sbin/usb_modeswitch -X -v 12d1 -p 14fe"

You get the vendor id and product id from the output of lsusb

I have changed my mind and reusing gammu gateway in a docker style from @pajikos makes more sense than trying to reimplement all SMS handling code.

I have created a new custom integration for home assistant here

My approach is:

1. Variant

  • gsm modem on linux (in my case host of hassio docker)
  • install gammu-smsd
  • configure stored data in sql database (install/configuration of sql server needed)
  • configure gammu-smsd to call script after received sms (curl command to call homeassistant webhook with json data from sms)
#!/bin/sh

from=$SMS_1_NUMBER
message=$SMS_1_TEXT

curl --request POST \
     --url 'https://homeassistanturl/api/webhook/incomingsms' \
     --header 'content-type: application/json' \
     --data "$( jq -nc --arg dela "$from" --arg mesaj "$message" '{"from": $dela, "smsmesaj":  $mesaj }' )"
  • generate ssh key in /homeassistant/config (to be persistent) and copy ssh keys to sistem host.
  • issue rest_command from home assistant

trimitesms: ssh -i /config/ssh/id_rsa -o StrictHostKeyChecking=no [email protected] 'gammu-smsd-inject TEXT {{ numarsms }} -text "{{ textsms }}"'

  • make sql sensor to read recieved and send sms data from gammu
  • make a custom lovelace card to display all data

gsm-lovelace-card

2. Variant (easy one)

esphome:
  name: gsm_esp32
  platform: ESP32
  board: esp-wrover-kit

wifi:
  ssid: ''
  password: ''

logger:
  level: debug
  # baud_rate: 0

ota:

api:
  services:
  - service: send_sms
    variables:
      recipient: string
      message: string
    then:
    - sim800l.send_sms:
        recipient: !lambda 'return recipient;'
        message: !lambda 'return message;'

uart:
  baud_rate: 9600
  tx_pin: 27
  rx_pin: 26

switch:
  - platform: gpio
    id: "key_pin"
    pin: 4
    restore_mode: ALWAYS_OFF
  - platform: gpio
    id: "reset_pin"
    pin: 5
    restore_mode: ALWAYS_ON
  - platform: gpio
    id: "power_pin"
    pin: 23
    restore_mode: ALWAYS_ON

sim800l:
  on_sms_received:
    - lambda: |-
        id(sms_sender).publish_state(sender);
        id(sms_message).publish_state(message);
    - logger.log:
        format: "Received '%s' from %s"
        args: [ 'message.c_str()', 'sender.c_str()' ]

text_sensor:
- platform: template
  id: sms_sender
  name: "Sms Sender"
- platform: template
  id: sms_message
  name: "Sms Message"

I use both variants to send critical alerts about my sistem. (Even if i have no power/internet).

3 Likes

I am planning on using python gammu natively as a notify component in home-assistant.

The actual code to send a SMS is very simple:

import gammu

sm = gammu.StateMachine()
sm.ReadConfig()
sm.Init()

message = {
    'Text': 'python-gammu testing message', 
    'SMSC': {'Location': 1},
    'Number': '+420800123465',
}

sm.SendSMS(message)

I like that this is a simpler setup.

Yes, for sending you can use this. But i don’t have found a solution for receiving.
I want to work both way. To send and receive sms :slight_smile:

Gammu also have a nice python interface to receive SMS notifications, it will be relate easy to add once I have an integration that works for sending.

Thank you so much for the esphome code …
been having trouble with this for a while …
worked like a charm on the 1st go …

thank you also @reliable

I am happy to announce that with version 0.105.0, SMS notifications (via Gammu) are officially supported.

Here is more info

3 Likes

Hi Thats Really Great!

I’ve first question about it.
Ubuntu 18.04 server/docker, Hassio 105.1, Gammu installed, sending sms from putty without any error.

Configuration file:

 sms:
   device: /dev/ttyUSB3
 notify:
   - platform: sms
     name: sms_mxx
     recipient: +NNNNNN
   - platform: sms
     name: sms_mxxx
     recipient: +NNNNNN

Im getting:
Configuration invalidCHECK CONFIG

Invalid config for [sms]: No device at /dev/ttyUSB3 found for dictionary value @ data['sms']['device']. Got '/dev/ttyUSB3'. (See /config/configuration.yaml, line 210).

Go to your ssh session and type:

ls -l /dev/*tty*

Do you see your modem? Then make sure you are sharing that serial device with the container. (I am not an expert in docker but there is a way to do this)

If this work please share the solution to update the documentation :slight_smile:

SOLVED
I needed libgammu-dev installed at the base system level.

Leaving my post below for reference…

================================
Thanks for your work on this @Oscar_Calvo.

I’m looking forward to replacing my existing sms integration call gammu through a parameterised shell_command.

Unfortunately I’m unable to get python-gammu installed on my Python3.7 venv running on Ubuntu 18.04 when the sms integration is configured.

Running the install command under the homeassistant user within the activated venv gives me some clues as to what is going on:

(homeassistant) [email protected]:~/.homeassistant$ python3.7 -m pip install python-gammu
Collecting python-gammu
  Using cached python-gammu-2.12.tar.gz (135 kB)
    ERROR: Command errored out with exit status 100:
     command: /srv/homeassistant/bin/python3.7 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-ea2vl0z7/python-gammu/setup.py'"'"'; __file__='"'"'/tmp/pip-install-ea2vl0z7/python-gammu/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-install-ea2vl0z7/python-gammu/pip-egg-info
         cwd: /tmp/pip-install-ea2vl0z7/python-gammu/
    Complete output (9 lines):
    Package gammu was not found in the pkg-config search path.
    Perhaps you should add the directory containing `gammu.pc'
    to the PKG_CONFIG_PATH environment variable
    No package 'gammu' found
    Package gammu-smsd was not found in the pkg-config search path.
    Perhaps you should add the directory containing `gammu-smsd.pc'
    to the PKG_CONFIG_PATH environment variable
    No package 'gammu-smsd' found
    Can not find supported Gammu version using pkg-config!
    ----------------------------------------
ERROR: Command errored out with exit status 100: python setup.py egg_info Check the logs for full command output.

gammu-smsd is installed (with sudo apt install gammu-smsd) but I’m guessing that the above is related to permissions?

I’m rather out of my depth at this point so would appreciate any pointers you could provide.

hi,
I’m a noob with home assistant, and I’m coming from domoticz. I installed hass.io, and I’m trying to install gammu (I write a python script to control domoticz via SMS : start alarm, stop alarm, send SMS when something happened etc… and I need to do something like this). But I don’t understand what is my problem, and what I need to do to install this addon. Only modification in configuration.yaml? must I install some script? must I install gammu (apk)?
If somebody can help, it will be really nice :slight_smile:
Thanks a lot
my conf: hassos 3.9 on rasberry pi 3B home assistant 0.105.2

In theory only your yaml configuration file.
What model and brand is your gsm modem?

Huawei E3531 Surf Stick (HSPA +, USB, HSUPA, Edge/GPRS)
It works nice with domoticz and gammu

I will try to see logs via ssh. (hassio don’t start when I add config in configuration.yaml)