So I use a standard webcam as a baby monitor. It was far cheaper than any proprietary solution and I can view the rtsp feed from it in Home Assistant, Kodi or my any other computer connected to my network/VPN. It has built in motion & audio detection which works just fine in Home Assistant, as well as the ability to physically move to preset viewpoints. All in all, pretty spiffy.

We tend to view the camera feed on our TV, which works super well. However, the audio from the feed comes through to our connected speakers loudly. This is less than ideal. There are two options:

  1. Remember to turn the volume right down, or the speakers off, when viewing the camera feed.
  2. Fuck about in Home Assistant and write an automation.

The answer is obvious. Here’s how I did it.

1. Starting the camera feed from Home Assistant.

Sometimes I want to hit a button in the Home Assistant UI as part of a TV remote. This is relatively straightforward and can be achieved in a Home Assistant script.

In this example, media_player.living_room is my speaker. I use Kef LSX’s (which I really like), but other network connected speakers may well report their status to Home Assistant and be able to achieve the same thing. media_player.kodi is my Kodi entity. If anyone is reading this and wants to do something similar, remember to adjust the aforementioned entities, as well as your own rtsp stream.

alias: Play BabyCam on TV
sequence:
  - if:
      - condition: state
        entity_id: media_player.living_room
        state: 'on'
      - condition: state
        entity_id: media_player.living_room
        attribute: source
        state: Opt
    then:
      - target:
          entity_id: media_player.kodi
        data:
          method: Gui.ShowNotification
          title: KEF Speakers
          message: Turning off speakers before opening BabyCam
        action: kodi.call_method
      - target:
          entity_id: media_player.living_room
        action: media_player.turn_off
  - delay:
      seconds: 1
  - target:
      entity_id: media_player.kodi
    data:
      media:
        media_content_id: >-
          rtsp://<The RTSP Stream Url from your webcam>
        media_content_type: video
        metadata: {}
    action: media_player.play_media
mode: single

Then just call the script with a buton press from Lovelace in Homg Assistant.

2. Do it from Kodi

Sometimes I want to use the Kodi interface to open the stream. This was previously straightforward enough to launch in Kodi - just a custom command from the Kodi GUI. However, I want the speaker check I get with the previous script, so this method instead sends a webhook to Home Assistant to activate the aforementioned script. In essence, Kodi sends a message to Home Assistant, which performs the speaker check and then sends a command back to Kodi (and the speakers if they need to be turned off).

A note for windows Kodi installs - This is possible in a .bat file, but it will make Kodi momentarily minimise & restore as it's running an external command. We can be better. Let's do something in Python instead.

First lets make a scripts folder in Kodi (if one doesn’t already)

mkdir ~/AppData/Roaming/Kodi/userdata/scripts

Then create a python script to send the webhook. Call it something obvious! I went with babycam.py. Also remember add your Home Assistant install IP.

import urllib.request

url = "http://<IP of your Home Assistant install>:8123/api/webhook/kodi_babycam" ###This url bit will become important!

try:
    req = urllib.request.Request(url, method="POST")
    urllib.request.urlopen(req, timeout=3).read()
except Exception:
    pass

Now in Kodi set a link or button to execute RunScript("~AppData/Roaming/Kodi/userdata/scripts/babycam.py"). Kodi will now be sending a webhook to the Home Assistant Url endpoint in the script whenever it is run. However, make sure the kodi_babycam bit of the webhook Url is the same as what is given a webhook_id as the trigger in the Home Assistant automation.

alias: Kodi BabyCam Webhook
triggers:
  - webhook_id: kodi_babycam
    local_only: true
    trigger: webhook
    allowed_methods:
      - POST
      - PUT
conditions: []
actions:
  - if:
      - condition: state
        entity_id: media_player.living_room
        state: 'on'
      - condition: state
        entity_id: media_player.living_room
        attribute: source
        state: Opt
    then:
      - target:
          entity_id: media_player.Kodi
        data:
          method: Gui.ShowNotification
          title: Speakers are on!
          message: Turning off speakers before opening camera feed
        action: kodi.call_method
      - target:
          entity_id: media_player.living_room
        action: media_player.turn_off
      - delay:
          milliseconds: 500
  - target:
      entity_id: media_player.kodi
    data:
      media:
        media_content_id: >-
          rtsp://<The RTSP Stream Url from your webcam>
        media_content_type: video
        metadata: {}
    action: media_player.play_media
mode: single

The webhook_id trigger is really what makes this work. It would probably be wise to make the id very long and garbled if you expose your Home Assistant install to the outside world, but I only connect via VPN so it’s comparatively safe to have something potentially guessable.

From there, the conditions check if the speakers are on and set to the Opt input. If so they get turned off. I even put in a notification to be displayed in Kodi stating that the speakers are being turned off, partly because the notification will come before the camera feed due to a small delay put in.

Then the final action is sending the command to Kodi to play the rtsp stream.

Simples!