Blocking SPAM phone calls with Home Assistant

What

SPAM phone calls (or Robocalls) are events that occur in our homes and are becoming very popular in the country where I live. I describe here an attempt to get rid off these undesired events.

(my usual) Disclaimer

I’m a computer hobbyist, self-learner, and with proficiency in copy-paste tool. What I describe here has worked for me. I’m not even sure that I can provide you with some help in the case you find issues following these steps. As you may have guessed, my mother language is not English so sorry for any vocabulary inaccuracies.

Why

I had several reasons to build this:

  • SPAM calls are not welcome in my house
  • Robocall blocker devices are expensive and country-dependant (citation needed)
  • After automating lights, covers, thermostat, printer ink levels, etc., my family challenged me (can’t you block these phone calls, dad?, oh, you’re a looser)
  • If you search these topics (robocall, call blocker, SPAM call) in HA forum I couldn’t find anything
  • I cannot use callattendant because you need a raspberry pi for that (and I’m running HA in a NUC)
  • I managed to install callblocker in my supervised HA installation but I wanted to explore a solution using HA only

Material

  • Hardware: A USB modem that works. I guess this is the tricky part. I bought this one and it works out of the box. You’ll also need a free USB port in the computer you are running HA
  • Software: A running Home Assistant instalation (pretty obvious if you are reading this)

How

Hardware installation

This is pretty straightforward. Just connect the phone-modem to an available USB port in the machine you are running HA (a NUC in my case). Connect the phone-modem to your router in one connection and your phone in the other connection. The phone-modem I bought had two connections; if yours only has one, you’ll need a splitter.

Software setup

In my case, HA autodiscovered the device when it was connected and I was led to install the Phone Modem integration. (For future evaluation: at the time of writting this, up to 9 active installations run this integration.)

Now we need two ingredients:

  • An automation that detects an incoming phone call
  • A python script to evaluate if it is a SPAM call

The automation

When an incoming call occurs the sensor.phone_modem state changes from idle to callerid. In the action part we call the call_blocker service (explained in the next section).
This works for me:

alias: Incoming phone call detection
description: ''
trigger:
  - platform: state
    entity_id: sensor.phone_modem
    to: callerid
condition: []
action:
  - service: python_script.call_blocker
    data:
      entity_id: sensor.phone_modem
mode: single

The python script

You have to activate the python scripts integration in your configuration file. You’ll have to create a <config>/python_scripts/ folder too (this was not done automatically in my case and I got an error when I added python_script: to my configuration file and the folder didn’t exist). Then, in that folder, create a file (call_blocker.py in my case; :warning: HA will create a service with the same name than the python script file name; do you remember the service that we used in the action section of the automation? ok, cool.) with the following:

# call_blocker.py

# List of allowed phones (you have to manually add the phones here):
whitelistedphones = ['123456789', '987654321', '123454321']

# entity_id: sensor.phone_modem
inputEntity = data.get('entity_id')
inputStateObject = hass.states.get(inputEntity)
inputState = inputStateObject.state
inputAttributesObject = inputStateObject.attributes.copy()
phonenumber = inputAttributesObject['cid_number']
# All these logger lines work OK and have been used during the script development
#logger.info(hass.states.get(inputEntity).state)
#logger.info(inputEntity)
#logger.info(inputStateObject)
#logger.info(inputState)
#logger.info(inputAttributesObject)
#logger.info(inputAttributesObject['cid_number'])
# Check if the incoming call is not in the whitelist of phones
if phonenumber not in whitelistedphones:
    service_data = {"entity_id": inputEntity}
    # Reject the call
    hass.services.call("modem_callerid", "reject_call", service_data, False)
    # Populate the HA logs
    logger.info("%s not in whitelisted phones. Blocked!", phonenumber)

Is this finished?

Not at all. Features that would be nice:

  • Not even ring a single tone. Now my phone rings once and then hangs. Not critical but…
  • Improved management of blacklists and whitelists. I’m happy with my current setup: just a whitelist strategy; but if you need something more complex this current setup is unacceptable
  • Smart things you may propose

Thanks for reading! And thanks to HA devs (it was a great surprise when HA autodiscovered the phone modem and created the entity sensor.phone_modem and the service modem_callerid.reject_call out of the box)!

5 Likes