Control TV channels using slots

Hi everyone!

Upfront: Thanks to all the great people out here providing support to people like me, who aren’t professional in coding!!

My goal is to control my kodi-tv channels (running on a seperate raspi 3) via voice command.
It already works fine with this simple setup (example for two channels):
In a config/custom_sentences/de/TVchannels.yaml I defined the intents:

#file: config/custom_sentences/de/TVchannels.yaml
language: "de"
intents:
  Das Erste:
    data:
      - sentences:
        - "Das Erste"
        - "ARD"
  Das Zweite:
     data:
      - sentences:
        - "Das Zweite"
        - "ZDF"

… and in the configuration.yaml I defined the intents_scripts:

intent_script:
  Das Erste:
    action:
      service: media_player.play_media
      data:
        media_content_id: "1621"
        media_content_type: CHANNEL
      target:
        entity_id: media_player.raspi3
  Das Zweite:
    action:
      service: media_player.play_media
      data:
        media_content_id: "1604"
        media_content_type: CHANNEL
      target:
        entity_id: media_player.raspi3

as you can see I use the media_content_id to select the correct channel and it works.

But now I wonder if this could be made more elegant and easier to maintain.
My idea is to use a slot for the spoken TV-channel and somehow map this to the media_content_id. I tried e.g.:

in the TVchannels.yaml:

intents:
  channels:
    data:
      - sentences:
        - "Sender {channel}"
        - "Kanal {channel}"

lists:
  channels:
    values:
      - in: "(Das Erste | ARD)"
        out: "1621"
      - in: "(Das Zweite | ZDF)"
        out: "1604"

(Side-question: I tried to use the lists:-part directly in the configuration.yaml (not in the TVchannels.yaml, but I got the error: Integration “lists” is not known… would be interesting for me to know why…).

and in the configuration.yaml:

intent_script:
  channels:
    action:
      service: media_player.play_media
      data:
        media_content_id:
          data:
            value: "{{slots.channels}}" # <- not sure what belongs here, I tried also trigger.slots.channels
        media_content_type: CHANNEL
      target:
        entity_id: media_player.raspi3

But in many way I tried I get an error about “slots” not defined or “trigger” not defined.

Am I going in the right direction or is there a complete other way to set this up?

Many thanks for advice!
Flo

Just waking up, but willing to share. When i created a UI set of buttons to change TV channels, I found defining Helpers for each button press to greatly simplify the task.

Hi and good morning. Thanks for the hint! Yes, I guess this would a way to go. But how? Defining input_numbers as helpers and try to set them according to the required content_id?

In my case i defined an input_button helper for each channel number, i.e.: 27 - WXYZ - SKY. Then have the UI call an automation triggered by that helper when the input_button is pressed. It moves the tedious part out of the UI into an automation tied to the helper. It also allows using that helper in multiple manners, such as voice assist. But you do have to expose the helper to Voice Assist. Finally, this example is specific to my LG television, which has an integration in Home Assistant. If you have defined your device as a media_player in HA, you should be able to use automations.

alias: Downstairs TV to ABC 9
description: Change channel to 9-1 WSOC
trigger:
  - platform: state
    entity_id:
      - input_button.downstairs_tv_abc_9
condition:
  - condition: state
    entity_id: media_player.lg_tv_uh615a_living_room
    state: "on"
action:
  - service: media_player.play_media
    data:
      media_content_type: channel
      media_content_id: 9-1
    target:
      entity_id: media_player.lg_tv_uh615a_living_room
mode: single

Thanks for the detailed input!
Yes, my Kodi-TV is also fully integrated (even with mqtt) and my “hard coded” implementation already works. As UI I use the app Yatze to control the TV. My HA runs more like a background service, I don’t use Dashboards a lot.

What I’m looking for is a way to code it more flexible, e.g. using only one automation that:

  1. If I say: “Channel RTL”, the “RTL” part is captured as a template, which can be achieved by using intent slots: Channel {channel}.

  2. The further process must convert the slot {channel} (“RTL” in this example) into the right media_content_id, e.g “1206”
    Then set the media_content_id
    Then start the player with the media_content_id

This I don’t know exactly who to do this.
Can I use if/else for the slot value, e.g.
If {{channel}} == “RTL” then set media_content_id to 1206

Hi, for anyone interested… I found a solution that was actually easier than I thought and works like a charm.

Here I have a neat list of channel ↔ media_content_id mapping:

#file: config/custom_sentences/de/TVchannels.yaml
language: "de"
  
intents:
  channels:
    data:
      - sentences:
        - "Kanal {channels}"
        

lists:
  channels:
    values:
      - in: "(Das Erste | ARD)"
        out: "1621"
      - in: "(Das Zweite | ZDF | 2)"
        out: "1604"
      - in: "(Das Dritte | BR | Dritte)"
        out: "1581"
      - in: "(30 | 3% | Drei sat | Dreisat | Dreissat | Drei ist er | breisert | 300)"
        out: "1606"
      - in: "Arte"
        out: "1541"
      - in: "(ZDF Neo | Das zweite neo | neo)"
        out: "1551"
      - in: "(One | 1 | ein)"
        out: "1619"
      - in: "(Tele 5 | Kele 5)"
        out: "1577"
      - in: "(HR | Hessischer Rundfunk)"
        out: "1595"
      - in: "(Sat 1 | Satt 1 | 3-1)"
        out: "1502"
      - in: "(Pro 7 | Pro sieben)"
        out: "1516"
      - in: "(RTL | RKL)"
        out: "1605"
      - in: "Vox"
        out: "1515"
      - in: "Kabel 1"
        out: "1616"
      - in: "RTL2"
        out: "1587"
      - in: "Super RTL"
        out: "1501"
      - in: "Nitro"
        out: "1546"
      - in: "(sixx | 6)"
        out: "1557"
      - in: "(WDR | VDR | Westdeutscher Rundfunk)"
        out: "1547"  
      - in: "(Pro7 Max| Max)"
        out: "1622"
      - in: "(RTL up | RTL App)"
        out: "1529"
      - in: "(Comedy Central | Comedy)"
        out: "1593"
      - in: "(MDR | Mitteldeutscher Rundfunk)"
        out: "1503"
      - in: "Kika"
        out: "1574"
      - in: "Nickelodeon"
        out: "1525"
      - in: "(Toggo | Toggo plus | Turbo plus | Togo)"
        out: "1543"
      - in: "(NDR | Norddeutscher Rundfunk)"
        out: "1584"
      - in: "SR"
        out: "1500"
      - in: "(ZDF info | 6)"
        out: "1507"
      - in: "(Disney Channel | Disney)"
        out: "1539"                    

And the intents_script in the configuration.yaml:

conversation:
intent_script:
  channels:
    action:
      service: media_player.play_media
      data:
        media_content_id: "{{channels}}"
        media_content_type: CHANNEL
      target:
        entity_id: media_player.raspi3   

I love this stuff…

3 Likes