TV favorites with ESPHome?

Hi

I’m thinking about how to design at best and easier way some TV favorites with HA. Here is the concept: Satellite box controlled by Infrared with ESPHome. I want to add some buttons in Lovelace for my favorites TV Channel that when I push it dials automatically in infrared the channel number on satellite box.
IR control with ESPHome works already perfect.
I’m looking now for the best and easier way to implement that between HA and ESPHome :wink: I have created a link between HA and ESPHome so I get the channel number requested straight in ESPHome.
Now I need to handle that value to get separately the hundred, tenth and units numbers separately so I can dial appropriate IR codes. Is it possible to do such manipulation in ESPHome or might be too complicated ?

Sorry forgot to paste my current sketch, here it is below :wink:

substitutions:
  friendly_name: irblaster

esphome:
  name: $friendly_name

esp32:
  board: esp32dev
  framework:
    type: arduino

logger:

web_server:

ota:

wifi:
  networks:
  - ssid: !secret wifi_ssid
    password: !secret wifi_passwd
  ap:
    ssid: $friendly_name
  manual_ip:
    static_ip: 172.16.2.82
    gateway: 172.16.1.1
    subnet: 255.255.252.0

captive_portal:

globals:
   - id: digit_to_dial
     type: int
     restore_value: no
     initial_value: '0'

api:
  reboot_timeout: 120min
  services:
    - service: Channel_favorites
      variables:
        my_favorite: int
      then:
        - switch.execute: script_principal
  
sensor:
  - platform: wifi_signal
    name: $friendly_name WiFi Signal
    update_interval: 60s
  - platform: uptime
    name: $friendly_name Uptime
    filters:
      - lambda: return x / 60.0;
    unit_of_measurement: minutes

remote_receiver:
  id: ir_receiver
  pin:
    number: GPIO23
    inverted: True
  idle: 25ms
  dump: all
  tolerance: 50%

remote_transmitter:
  pin: GPIO2
  carrier_duty_percent: 50%
  
script:
  - id: script_principal
    mode: restart
    max_runs: 1
    then:
      - if:
      	  condition:
      	    number.in_range:
      	    	id: my_favorite
      	    	above: 99.0
      	    then:
      	      - lambda: |-
		  id(digit_to_dial) = my_favorite/100;

script:
  - id: composition
    mode: restart
    max_runs: 1

switch:
  - platform: template
    name: "Power"
    id: Sky_Power
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0059 0015 06C3"
  - platform: template
    name: "1"
    id: Sky_1
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015D 0056 0017 06C3"
  - platform: template
    name: "2"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "3"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "4"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015C 0057 0017 06C3"
  - platform: template
    name: "5"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "6"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "7"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015B 0059 0015 06C3"
  - platform: template
    name: "8"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015D 0056 0016 06C3"
  - platform: template
    name: "9"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "0"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "Info"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Settings"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Mute"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "Vol+"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "Vol-"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Apps"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "USB"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Page+"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Page-"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Menu"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "Exit"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Up"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Down"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Left"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "Right"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015B 0059 0015 06C3"
  - platform: template
    name: "OK"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Star"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Star+"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Setup"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Search"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0017 06C3"
  - platform: template
    name: "Previous"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Play / Pause"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "Next"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015B 0059 0015 06C3"
  - platform: template
    name: "Rewind"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015D 0056 0017 06C3"
  - platform: template
    name: "Forward"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Stop"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "Record"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "Red / TV"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Green / VOD"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"
  - platform: template
    name: "Yellow / Music"
    turn_on_action:
    -  remote_transmitter.transmit_pronto:
        data: "0000 006D 0002 0000 015B 0058 0015 06C3"
  - platform: template
    name: "Blue / Radio"
    turn_on_action:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0002 0000 015C 0057 0016 06C3"

Thanks for your ideas and suggestions :wink:

Vincèn

Is it number or string?
If it’s number then it’s fairly easy to just
floor(num/100) to get hundreds.
floor(num/10) - hundreds/10 to get tens
num - hundreds - tens to get singles.

If it’s text then you just need to substring it.

It’s a number and thanks for your message, realised I had forgotten to include my sketch in my first post :see_no_evil:
I’m trying to build logic in ESPHome to send the proper IR codes but ESPhome refuses the number.in_range parameter although it’s listed as a valid command in ESPHome documentation :confused:

Like this?

Screenshot 2022-05-15 at 19-34-55 Overview – Home Assistant

Uses button-card and hui-element:

entities:
  - card_type: horizontal-stack
    cards:
      - entity: script.lounge_tv_ch_abc
        entity_picture: /local/tv_logos/abc.png
        tap_action:
          service: script.lounge_tv_ch_abc
        template: picture_button
        type: custom:button-card
      - entity: script.lounge_tv_ch_sbs
        entity_picture: /local/tv_logos/sbs.png
        tap_action:
          service: script.lounge_tv_ch_sbs
        template: picture_button
        type: custom:button-card
      - entity: script.lounge_tv_ch_sbs_vice
        entity_picture: /local/tv_logos/sbs-vice.png
        tap_action:
          service: script.lounge_tv_ch_sbs_vice
        template: picture_button
        type: custom:button-card
      - entity: script.lounge_tv_ch_sthnx
        entity_picture: /local/tv_logos/southern-cross-television.png
        tap_action:
          service: script.lounge_tv_ch_sthnx
        template: picture_button
        type: custom:button-card
    type: custom:hui-element
  - card_type: horizontal-stack
    cards:
      - entity: script.lounge_tv_ch_nine
        entity_picture: /local/tv_logos/nine.png
        tap_action:
          service: script.lounge_tv_ch_nine
        template: picture_button
        type: custom:button-card
      - entity: script.lounge_tv_ch_gem
        entity_picture: /local/tv_logos/gem.png
        tap_action:
          service: script.lounge_tv_ch_gem
        template: picture_button
        type: custom:button-card
      - entity: script.lounge_tv_ch_go
        entity_picture: /local/tv_logos/go.png
        tap_action:
          service: script.lounge_tv_ch_go
        template: picture_button
        type: custom:button-card
      - entity: script.lounge_tv_ch_7mate
        entity_picture: /local/tv_logos/seven-mate.png
        tap_action:
          service: script.lounge_tv_ch_7mate
        template: picture_button
        type: custom:button-card
    type: custom:hui-element
  - card_type: horizontal-stack
    cards:
      - entity: script.lounge_tv_ch_7two
        entity_picture: /local/tv_logos/seven-two.png
        tap_action:
          service: script.lounge_tv_ch_7two
        template: picture_button
        type: custom:button-card
      - entity: script.lounge_tv_ch_win
        entity_picture: /local/tv_logos/win.png
        tap_action:
          service: script.lounge_tv_ch_win
        template: picture_button
        type: custom:button-card
      - entity: script.lounge_tv_ch_one
        entity_picture: /local/tv_logos/one.png
        tap_action:
          service: script.lounge_tv_ch_one
        template: picture_button
        type: custom:button-card
      - entity: script.lounge_tv_ch_eleven
        entity_picture: /local/tv_logos/eleven.png
        tap_action:
          service: script.lounge_tv_ch_eleven
        template: picture_button
        type: custom:button-card
    type: custom:hui-element
show_header_toggle: false
title: TV Channels
type: entities

Button card template:

button_card_templates:
  picture_button:
    aspect_ratio: 4/3
    color_type: icon
    hold_action:
      action: none
    layout: vertical
    show_entity_picture: true
    show_icon: false
    show_label: false
    show_name: false
    show_state: false
    styles:
      card:
        - border-radius: 10px
        - border: solid 1px var(--primary-color)
        - box-shadow: none
        - padding: 6px 6px
        - margin: 0px 0px
        - '--ha-card-background': rgba(0, 0, 0, 0)
      entity_picture:
        - width: 100%
        - height: 100%
        - object-fit: contain
    tap_action:
      action: call-service

Example scripts (adjust to use your IR commands):

lounge_tv_ch_sthnx:
  sequence:
  - choose:
    - conditions:
      - condition: state
        entity_id: media_player.viera_st50_series
        state: 'off'
      sequence:
      - service: script.lounge_tv_on
  - service: script.lounge_tv_input_tv
  - service: remote.send_command
    data:
      entity_id: remote.viera_st50_series
      command: 'NRC_D6-ONOFF'
  - service: remote.send_command
    data:
      entity_id: remote.viera_st50_series
      command: 'NRC_ENTER-ONOFF'

lounge_tv_ch_sbs:
  sequence:
  - choose:
    - conditions:
      - condition: state
        entity_id: media_player.viera_st50_series
        state: 'off'
      sequence:
      - service: script.lounge_tv_on
  - service: script.lounge_tv_input_tv
  - service: remote.send_command
    data:
      entity_id: remote.viera_st50_series
      command: 'NRC_D3-ONOFF'
  - delay: 1
  - service: remote.send_command
    data:
      entity_id: remote.viera_st50_series
      command: 'NRC_D0-ONOFF'
  - delay: 1
  - service: remote.send_command
    data:
      entity_id: remote.viera_st50_series
      command: 'NRC_ENTER-ONOFF'

Yep exactly that :ok_hand: Thanks for the share about how you did the UI, going to reuse some parts of it a lot :smiley:
Would you mind to detail how you implemented the dialing of numbers ? Looks like you did everything in HA ? I had started here with most of dialing work done in ESPHome :wink:

In the scripts. e.g. this is digit “6” using the Viera remote integration:

  - service: remote.send_command
    data:
      entity_id: remote.viera_st50_series
      command: 'NRC_D6-ONOFF'

That’s the bit you would replace with your ESP remote commands.

ah oki but in fact it’s not “real” favorites I would say as you dial only one digit :smiley: mine I have 2/3 digits for each channel to dial :frowning:

You can put as many digit in the sequence as you need. I have two in the sbs script:

  - service: remote.send_command
    data:
      entity_id: remote.viera_st50_series
      command: 'NRC_D3-ONOFF'
  - delay: 1
  - service: remote.send_command
    data:
      entity_id: remote.viera_st50_series
      command: 'NRC_D0-ONOFF'
  - delay: 1
  - service: remote.send_command
    data:
      entity_id: remote.viera_st50_series
      command: 'NRC_ENTER-ONOFF'

Thanks for the details and got it :wink: Just have to encode my hundred of TV favorites in scripts :smiley:

If the command accepts templates and the commands are named with some logic then perhaps you can do it with a template

I imagine it can be done but well above my abilities right now :innocent: :see_no_evil: Can you do some mathematical processes in a script ? such as separating hundreds, tenths, units of the number and then some tests on it to send the proper command at device ?