HA to ring SIP/IP Phone?

We are trying to find a solution to be able to ring a SIP/IP Phone from HA.

Our scenario is that we would like our handsfree IP phones to ring once when someone opens the front door to reception. I have the smart door sensor part worked out just not the ringing an IP phone part.

Some ideas we have had so far are:

  • Install a standalone door bell setup (bells/speakers in ceilings) - Not ideal as we could be out of the building and might be out of ear shot. Also no automation possible.
  • Use notifications - Also not ideal as we can have unreliable internet, so would miss customers coming into reception. Also notifications are not immediate enough (can be significant delay in delivery).
  • Flash an arduino to be able to call SIP server directly - This seems very cumbersome (LOTS of coding) and is specific to the SIP Server. So not a good general solution.

Our current idea is find a software client that can be run from command line. Hopefully as a HASS.IO add-on. Then using Node-Red to create an automation so when the door sensor is triggered, Node-Red will run a command to make a call to the SIP server and hang up after 2 seconds or so.

Has anyone had any experience with something similar? Or have any suggestions.

3 Likes

if your “front door” happens to be a DoorBird, there is actually a way to do this in the app, just wont work through HA sadly. Don’t really know how it works or what it can do. Hope you find an answer, i want to use HA with a SIP phone too.
Edit: this post may be helpful: SIP Client

I would also be interested in this as I run a SIP server in my home and it would be a nice addition.

Hi, what kind of SIP server are you running?

I am running (Asterisk) on FreePBX at home and managed to ring extensions from Home Assistant. What I did was to make a small script that runs as an MQTT client which I installed on the FreePBX server. The client subscribes to an MQTT topic and listens for commands. When a command is recognized the script places an Asterisk-formatted file in an Asterisk folder. From there the following actions are standard functionality. The file placed in the folder contains the extension or group that needs to be called and points to a sound file configured in FreePBX. Asterisk immediately notices the new file in the folder and starts dialing the number. When someone picks up the sound file is played.

For my use case this was the most convenient solution. In FreePBX you can do all sorts of advanced configuration like for example if the extension does not pickup forward the call to a mobile phone. So perhaps if you or others are using Asterisk this would be the way to go.

2 Likes

We are currently using 3CX. I’m not sure if this functionality exists for 3CX but I will investigate. Thanks for the tip!

Hi Frank,

Please are you able to share the script you mentioned?

Thanks

Sure.

First of all I use a Python library called Paho-MQTT, you can find more information about it and how to install it here: https://pypi.org/project/paho-mqtt/.

Then I run the following script which I call mqtt_client.py continuously. When the FreePBX server boots I run the script using nohup with the following command: nohup python /pathtofile/mqtt_client.py &

mqtt_client.py contents:

import paho.mqtt.client as mqtt
import json
import os

directory = os.path.dirname(os.path.abspath(__file__))

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

    # The MQTT topic to subscribe to
    client.subscribe("/mqtttopic/to/subscribe/to")

def on_message(client, userdata, msg):
    list = json.loads(msg.payload)
    for key,value in list.iteritems():
      if key == "name":
        if value == "Call":
          for key,value in list.iteritems():
            if key == "status":
              if value == "Phonenumber1":
                print "Dialing the first phone number"
                # Get the systempath and call the script
                os.system(directory+'/./call.sh call first')
              elif value == "Phonenumber2":
                print "Dialing the second phone number"
                os.system(directory+'/./call.sh call second')


client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

# MQTT credentials
username = "USERNAME"
passw = "PASSWORD"

client.username_pw_set(username,passw)
client.connect("PUT IP ADDRESS HERE", PORT NUMBER, 60)

client.loop_forever()

As you can see the script above only handles the MQTT subscription and incoming (JSON-formatted) requests. The script below manages the creation of the file and placement in the Asterisk folder:

call.sh contents:

#!/bin/bash

if [ "$1" == "call" ] && [ "$2" == "first" ]; then

FILE="/var/spool/asterisk/outgoing/callfirst.call"
/bin/cat <<EOM >$FILE
channel: Local/700@from-internal
callerid: "HomeAssistant" <9998>
application: playback
data: sound-file-with-a-name
SetVar: CHANNEL(language)=en/custom
MaxRetries: 2
RetryTime: 30
WaitTime: 20
EOM

elif [ "$1" == "call" ] && [ "$2" == "second" ]; then

FILE2="/var/spool/asterisk/outgoing/callsecond.call"
/bin/cat <<EOM >$FILE2
channel: SIP/Cheap Connect/0031600000000
callerid: "HomeAssistantExternal" <31600000000>
application: playback
data: sound-file-with-a-name
SetVar: CHANNEL(language)=en/custom
MaxRetries: 2
RetryTime: 30
WaitTime: 20
EOM

else
        echo 'Not doing anything'
fi

When the file is placed in the folder Asterisk will do the rest. Of course in the script above I refer to a sound file which is uploaded using the FreePBX GUI. If you wish I can try to make a better tutorial about how to configure it all when I have a bit more time.

2 Likes

Hi @frankv,

Just wondering if you can help me on this one.
Just trying to publish that specific json on MQTT but having no luck on the script catching it. Have you got a json example you publish in this case?

Thanks!

emontes - recommend using node-red if you’re having trouble with paho-mqtt. I couldn’t get it to work either and node-red is flawless for this. Happy to share my flow if needs be. I do the exact same thing as frankv but via different route.

daneboom - Appreciate if you can share it, just trying to get this one working and having some trouble with it.

No worries. This is the flow. Script is movefile.sh. There are two scripts because depending on the payload the ‘switch’ runs two different scripts. Need the callfile too?

Nice one, daneboom, many thanks, I will work on this one to see if I can get it done!
The call file is fine, I tested mine and it’s working as intended.

daneboom, just managed to get it working with python, the one from frankv wasn’t working for me, I changed some things there:

I added "from future.utils import iteritems " , changed list.iteritems() to iteritems(list) and added the parenthesis on the print statements (removed it all later on) ,and it did work:

def on_message(client, userdata, msg):
    list = json.loads(msg.payload)
    print (list)
    for key,value in iteritems(list):
      if key == "name":
        if value == "Call":
          for key,value in iteritems(list):
            if key == "status":
              if value == "first_number":
                print ("Dialing the first phone number")
                # Get the systempath and call the script
                os.system(directory+'/./call.sh call first')
              elif value == "2nd_number":
                print ("Dialing the second phone number")
                os.system(directory+'/./call.sh call second')

I will, anyway, do it also with node-red to learn and check which one of them I will implement.
I do appreciate the help, though!

1 Like

Hi d1wepn.
Did you have the chance to make it work with 3CX. SC license now is for free and it’s a good alternative to Asterisk.
Thanks in advance.
Regards.

Very nice discussion !
Just a question, is that possible to know if somebody use a phone line ?
I monitor the internet speed and want to disable the periodic test when somebody use the line.
Is that possible ? Can freePbx send a mqtt message when somebody use the line ?

Regards