Home Assistant онлайн ТВ и Радио

3 сентября, 2025

Есть несколько приставок Xiaomi и Amazon, а так же медиасистема Bose SoundTouch 300, соответственно есть сервер HomeAssistant. Хотелось бы управлять всем из Хомеассистент, что будет описано ниже.

Для простоты я всегда переименовываю идентификатор объекта поскольку даваемый автоматически на основе имени не очень удобен в использовании, у меня есть следующие Медиаплееры:

Интеграция Android TV Remote:
media_player.xiaomi1
media_player.xiaomi2
media_player.xiaomi3

интеграция Android Debug Bridge
media_player.firetv

интеграция Bose SoundTouch
media_player.soundtouch

собственно на них и будем отправлять потоки и скармливать УРЛ-ы

Через HACS установлены следующие интеграции: Button Card, card-mod 3, layout-card, multiline-text-input-card, browser_mod 2 (его так же надо добавить через настройки — Устройства и службы — Интеграции)

Я слелал управление всеми ТВ приставками на одной вкладке

Как видно вверху пульт управления и меню выбора приставки, внизу список ТВ каналов, для управления медиасистемой я использовал ещё одну вкладку

Однако запуск потоков делается с помошью одного скрипта, сначала добавим список выбора медиаплеера, для этого зайдите в меню Настройки — Устройства и службы — вкладка Вспомогательное, нажмите Создать вспомогательный объект, выбарите тип Список и задайте ему идентификатор объекта: input_select.tv_player и добавьте свои варианты выбора медиаплеера

теперь добавьте скрипт (Настройки — Автоматизации и сцены — вкладка СкриптыСоздать скрипт), перейдите в текстовый редактор (три точки в верзнем правом углу — Текстовый редактор) и вставьте туда следующее содержимое

alias: play
mode: restart
fields:
  url:
    name: URL/Media
    description: Ссылка или media-source (например, media-source://radio_browser/UUID)
  type:
    name: Content type
    description: application/vnd.apple.mpegurl, audio/mpeg, music, url и т.п.
    default: url
  player:
    name: Media player
    description: entity_id медиаплеера (если не задан — возьмём из input_select.tv_player)
sequence:
  - variables:
      sel: "{{ states('input_select.tv_player') }}"
      target_player: |-
        {% if player %}
          {{ player }}
        {% else %}
          {% if sel == 'Xiaomi Kitchen' %} media_player.xiaomi1
          {% elif sel == 'Xiaomi Dining' %} media_player.xiaomi2
          {% elif sel == 'Xiaomi Bedroom' %} media_player.xiaomi3
          {% elif sel == 'Amazon Sitting' %} media_player.firetv
          {% elif sel == 'SoundTouch' %} media_player.soundtouch
          {% else %} media_player.soundtouch
          {% endif %}
        {% endif %}
      ctype: "{{ (type | default('url')) }}"
  - target:
      entity_id: "{{ target_player }}"
    action: media_player.turn_on
    data: {}
  - target:
      entity_id: "{{ target_player }}"
    data:
      media_content_id: "{{ url }}"
      media_content_type: "{{ ctype }}"
    action: media_player.play_media
description: ""

замените названия медиаплееров из ранее созданного списка и идентефикаторы объектов

В Dashboard Home Assistant я использую шаблоны чтобы не писать одно и тоже в каждой карточке, для этого заходим в интерфейс Lovelace, нажимаем редактировать и дальше нажимаем три точки в верхнем правом углу и выбираем Текстовый редактор

Вставляем шаблоны кнопок

button_card_templates:
  tv_tile:
    variables:
      url: null
      img: null
      title: null
      type: null
      player: null
    show_name: '[[[ return !!variables.title ]]]'
    show_entity_picture: '[[[ return !!variables.img ]]]'
    name: '[[[ return variables.title ? variables.title : null ]]]'
    entity_picture: '[[[ return variables.img || null ]]]'
    aspect_ratio: 1/1
    tap_action:
      action: call-service
      service: script.play
      data:
        url: '[[[ return variables.url ]]]'
        player: '[[[ return variables.player || null ]]]'
        type: '[[[ return variables.type || "url" ]]]'
    styles:
      grid:
        - grid-template-areas: |-
            [[[
              if (variables.img && variables.title) {
                return '"i" "n"'
              } else if (variables.img) {
                return '"i"'
              } else {
                return '"n"'
              }
            ]]]
        - grid-template-rows: |-
            [[[
              (variables.img && variables.title) ? '1fr min-content' : '1fr'
            ]]]
        - grid-template-columns: 1fr
      img_cell:
        - display: '[[[ return variables.img ? "grid" : "none" ]]]'
        - align-items: center
        - justify-content: center
      icon:
        - width: 100%
        - height: 100%
        - object-fit: contain
        - object-position: center
        - border-radius: 8px
      name:
        - display: '[[[ return variables.title ? "block" : "none" ]]]'
        - font-size: '[[[ return (variables.img && variables.title) ? "10px" : "10px" ]]]'
        - white-space: normal
        - word-break: break-word
        - line-height: 1.2
        - text-align: center
        - padding: 0 6px
        - align-self: center
        - justify-self: center
      card:
        - padding: 8px
  remote_key:
    aspect_ratio: 9/7
    show_name: false
    styles:
      card:
        - padding: 8px
        - opacity: |-
            [[[
              const sel = states['input_select.tv_player']?.state;
              const map = {
                'Xiaomi Kitchen': 'remote.xiaomi1',
                'Xiaomi Dining': 'remote.xiaomi2',
                'Xiaomi Bedroom':  'remote.xiaomi3',
                'Amazon FireTV':  'remote.firetv'
              };
              return map[sel] ? 1 : 0.5;
            ]]]
      icon:
        - width: 60%
    variables:
      _remote: |-
        [[[
          const sel = states['input_select.tv_player']?.state;
          const map = {
            'Xiaomi Kitchen': 'remote.xiaomi1',
            'Xiaomi Dining': 'remote.xiaomi2',
            'Xiaomi Bedroom':  'remote.xiaomi3',
            'Amazon FireTV':  'remote.firetv'
          };
          return map[sel] || 'remote.xiaomi1';
        ]]]
    tap_action:
      action: call-service
      service: remote.send_command
      target:
        entity_id: '[[[ return variables._remote ]]]'
      data:
        command: '[[[ return variables.cmd ]]]'
    hold_action:
      action: call-service
      service: remote.send_command
      target:
        entity_id: '[[[ return variables._remote ]]]'
      data:
        command: '[[[ return variables.cmd ]]]'
        num_repeats: 3
        delay_secs: 0.2

Сохраняем и нам осталось добавить карточки, заходим в Lovelace, входим в режим редактирования и добавляем карточку, выбираем тип: ручная настройка и вставляем туда следующий код: 

type: vertical-stack
cards:
  - square: false
    type: grid
    cards:
      - type: vertical-stack
        cards:
          - square: false
            type: grid
            columns: 3
            cards:
              - type: custom:button-card
                template: remote_key
                icon: mdi:power
                variables:
                  cmd: MENU
                styles:
                  icon:
                    - color: |-
                        [[[
                          const sel = states['input_select.tv_player']?.state;
                          const map = {
                            'Xiaomi Kitchen': 'media_player.xiaomi1',
                            'Xiaomi Dining': 'media_player.xiaomi2',
                            'Xiaomi Bedroom': 'media_player.xiaomi3',
                            'Amazon FireTV':  'media_player.firetv',
                            'SoundTouch':     'media_player.soundtouch'
                          };
                          const player = map[sel] || 'media_player.soundtouch';
                          const st = states[player]?.state || 'off';
                          return (st === 'on') ? '#2e7d32' : '#c62828';   // зелёный если on, иначе красный
                        ]]]
              - type: custom:button-card
                template: remote_key
                icon: mdi:play-pause
                variables:
                  cmd: MEDIA_PLAY_PAUSE
              - type: custom:button-card
                template: remote_key
                icon: mdi:volume-mute
                variables:
                  cmd: VOLUME_MUTE
          - square: false
            type: grid
            columns: 3
            cards:
              - type: custom:button-card
                aspect_ratio: 9/7
                name: <img draggable="false" role="img" class="emoji" alt="✏️" src="https://s.w.org/images/core/emoji/16.0.1/svg/270f.svg"> URL
                tap_action:
                  action: fire-dom-event
                  browser_mod:
                    service: browser_mod.popup
                    data:
                      title: Введите URL
                      target: this
                      content:
                        type: vertical-stack
                        cards:
                          - type: custom:lovelace-multiline-text-input-card
                            entity: input_text.tv_player_text
                            placeholder_text: Вставьте URL/плейлист
                            title: ""
                            autosave: true
                            max_length: 255
                            buttons:
                              clear: false
                              paste: false
                              save: false
                          - type: custom:button-card
                            name: OK
                            icon: mdi:check
                            tap_action:
                              action: fire-dom-event
                              browser_mod:
                                service: browser_mod.close_popup
                            styles:
                              card:
                                - padding: 0px
                              icon:
                                - width: 20%
              - type: custom:button-card
                aspect_ratio: 9/7
                name: null
                icon: mdi:play-circle
                tap_action:
                  action: call-service
                  service: script.player_play
                  data:
                    url: >-
                      [[[ return (states["input_text.tv_player_text"]?.state ||
                      "").trim() ]]]
                    type: url
                styles:
                  card:
                    - padding: 0px
                  icon:
                    - width: 60%
              - type: custom:button-card
                template: remote_key
                icon: mdi:dots-grid
                variables:
                  cmd: MENU
          - type: entities
            entities:
              - entity: input_select.tv_player
                name: Плеер ТВ
                card_mod:
                  style:
                    .: |
                      :host {
                      --paper-item-icon-width: 0;
                      --mdc-select-fill-color: var(--card-background-color);
                      --mdc-icon-size: 0px;
                      --mdc-typography-subtitle1-font-size: 12px !important; 
                      --mdc-list-item-graphic-size: 0;
                      }
                    hui-generic-entity-row$: |
                      state-badge, ha-state-icon, .icon {
                        display: none !important;
                        width: 0 !important;
                        min-width: 0 !important;
                      }
                      .info,
                      .mdc-list-item__primary-text,
                      .primary,
                      .text {
                        margin-left: 0 !important;
                      }
                      #wrapper,
                      .mdc-list-item {
                        padding-left: 0 !important;
                      }
                      .mdc-list-item {
                      min-height: 20px !important;
                      height: 20px !important;
                      }
                    hui-generic-entity-row ha-select$: >
                      #label { display: none; } .mdc-select__anchor { height:
                      18px !important; } .mdc-select__anchor::before { height:
                      0px !important; } .mdc-select__dropdown-icon {
                      margin-left: 0 !important; margin-right: 0 !important; }
                      .mdc-line-ripple::before, .mdc-line-ripple::after {
                      border-bottom-style: none !important; }
                      .mdc-select__anchor {
                       height: 20px !important;
                       padding: 0 0px !important;
                       }
            show_header_toggle: false
      - square: false
        type: grid
        columns: 3
        cards:
          - type: custom:button-card
            template: remote_key
            icon: mdi:arrow-left
            variables:
              cmd: BACK
          - type: custom:button-card
            template: remote_key
            icon: mdi:chevron-up
            variables:
              cmd: DPAD_UP
          - type: custom:button-card
            template: remote_key
            icon: mdi:home
            variables:
              cmd: HOME
          - type: custom:button-card
            template: remote_key
            icon: mdi:chevron-left
            variables:
              cmd: DPAD_LEFT
          - type: custom:button-card
            template: remote_key
            icon: mdi:circle
            variables:
              cmd: DPAD_CENTER
          - type: custom:button-card
            template: remote_key
            icon: mdi:chevron-right
            variables:
              cmd: DPAD_RIGHT
          - type: custom:button-card
            template: remote_key
            icon: mdi:volume-minus
            variables:
              cmd: VOLUME_DOWN
          - type: custom:button-card
            template: remote_key
            icon: mdi:chevron-down
            variables:
              cmd: DPAD_DOWN
          - type: custom:button-card
            template: remote_key
            icon: mdi:volume-plus
            variables:
              cmd: VOLUME_UP
    columns: 2
  - square: false
    type: grid
    columns: 5
    cards:
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://raw.githubusercontent.com/UzunMuhalefet/streams/main/myvideo-az/arb.m3u8
          img: /local/icon/arb.jpg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://raw.githubusercontent.com/UzunMuhalefet/streams/main/myvideo-az/arb-24.m3u8
          img: /local/icon/arb24.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://raw.githubusercontent.com/UzunMuhalefet/streams/main/myvideo-az/arb-gunes.m3u8
          img: /local/icon/arbg.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://cdn10-alvinchannel.yayin.com.tr/alvinchannel/alvinchannel/playlist.m3u8
          img: /local/icon/Alvin.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: http://rtmp.apa.tv/@pagroup!23.m3u8
          img: /local/icon/apa.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://str.yodacdn.net/aztv/index.m3u8
          img: /local/icon/aztv.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://stream.atv.az/WebRTCAppEE/streams/780339739845112514894920_adaptive.m3u8
          img: /local/icon/atv.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://live.livestreamtv.ca/azstar/amlst:azstar/playlist.m3u8
          img: /local/icon/azstar.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://raw.githubusercontent.com/UzunMuhalefet/streams/refs/heads/main/myvideo-az/baku-tv.m3u8
          img: /local/icon/bakutv.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://mn-nl.mncdn.com/cbcsports_live/cbcsports/playlist.m3u8
          img: /local/icon/cbc.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://raw.githubusercontent.com/UzunMuhalefet/streams/refs/heads/main/myvideo-az/kanal-s.m3u8
          img: /local/icon/s.jpg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://str.yodacdn.net/medeniyyet/index.m3u8
          img: /local/icon/m.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://raw.githubusercontent.com/UzunMuhalefet/streams/main/myvideo-az/xezer-tv.m3u8
          img: /local/icon/xezar.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://edge50.dc.beltelecom.by/ngtrk/smil:belarus1.smil/chunklist_b5160000_sleng.m3u8
          img: /local/icon/Belarus_1_logo.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://edge50.dc.beltelecom.by/ngtrk/smil:informacionnyy.smil/chunklist_b5160000_sleng.m3u8
          img: /local/icon/1bel.jpg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://serv25.vintera.tv/1pnk/prnk/chunks.m3u8
          img: /local/icon/prnk.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: http://live-3.otcnet.ru/congresstv/index.m3u8
          img: /local/icon/tvc.svg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: http://tvoetv.space:8080/tvoetv_humor/video.m3u8
          img: /local/icon/tvoey.jpg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: http://tvoetv.space:8080/tvoetv/video.m3u8
          img: /local/icon/tvoe.jpg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: http://178.217.72.66:8080/5_Kanal/index.m3u8
          img: /local/icon/5.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://cdn-evacoder-tv.facecast.io/evacoder_hls_hi/CkxfR1xNUAJwTgtXTBZTAJli/index.m3u8
          img: /local/icon/360.jpg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: http://catchup.videoline.ru/cinema/playlist.m3u8
          img: /local/icon/cin.svg
          title: null
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://vgtrkregion-reg.cdnvideo.ru/vgtrk/0/russia1-hd/index.m3u8
          img: /local/icon/2415.png
          title: null
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://vgtrkregion-reg.cdnvideo.ru/vgtrk/0/russia24-sd/index.m3u8
          img: /local/icon/2702.png
          title: null
      - type: custom:button-card
        template: tv_tile
        entity_picture: /local/icon/1826.png
        variables:
          url: https://vgtrkregion-reg.cdnvideo.ru/vgtrk/0/kultura-hd/index.m3u8
          img: /local/icon/1826.png
          title: null
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://edge1.1internet.tv/dash-live2/streams/1tv-dvr/1tvdash.mpd
          img: /local/icon/1can.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://tvc-hls.cdnvideo.ru/tvc-res/smil:vd9221_2.smil/playlist.m3u8
          img: /local/icon/3185.png
          title: null
      - type: custom:button-card
        template: tv_tile
        entity_picture: /local/icon/3015.png
        variables:
          url: >-
            http://hls.mirtv.cdnvideo.ru/mirtv-parampublish/mir24_2500/playlist.m3u8
          img: /local/icon/3015.png
      - type: custom:button-card
        template: tv_tile
        entity_picture: /local/icon/2837.png
        variables:
          url: >-
            http://hls.mirtv.cdnvideo.ru/mirtv-parampublish/mirtv_2500/playlist.m3u8
          img: /local/icon/2837.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://live-echotv.cdnvideo.ru/echotv/echotv.sdp/playlist.m3u8
          img: /local/icon/2117.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: https://svoetv.mediacdn.ru/cdn/svoetv/playlist_hdhigh.m3u8
          title: Своё ТВ
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            http://live-vestikaliningrad.cdnvideo.ru/vestikaliningrad/vestikaliningrad.sdp/playlist.m3u8
          title: Запад 24
      - type: custom:button-card
        template: tv_tile
        variables:
          url: http://online.video.rbc.ru/online2/rbctv_1080p/index.m3u8
          title: РБК
      - type: custom:button-card
        template: tv_tile
        variables:
          url: http://trk555.tv:8888/live
          title: ТРК 555
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            http://cdn1.live-tv.od.ua:8081/31chod/31chod-abr/31chod/31chod/playlist.m3u8
          title: Репортер укр
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            http://tvchannelstream1.tvzvezda.ru/cdn/tvzvezda/playlist_hdhigh.m3u8
          title: Звезда
      - type: custom:button-card
        template: tv_tile
        variables:
          url: >-
            https://qcpdqumitwf.a.trbcdn.net/livemastersrt/pr4mw_lvie-vmesterf-srt.smil/playlist.m3u8
          title: Вместе:РФ

для Медиапроигрывателя BOSE и включения онлайн радио вставьте следующую карточку

type: vertical-stack
cards:
  - type: custom:mini-media-player
    entity: media_player.soundtouch
    group: true
    volume_stateless: false
    toggle_power: true
    artwork: none
  - square: false
    type: grid
    columns: 5
    cards:
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/4ba75473-8d53-4a71-b797-9a73798265c4
          player: media_player.soundtouch
          img: /local/icon/logo-europa-plus.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/c2f91214-b1ee-11e9-acb2-52543be04c81
          player: media_player.soundtouch
          img: /local/icon/ept.jpeg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/960b1967-0601-11e8-ae97-52543be04c81
          player: media_player.soundtouch
          img: https://www.nashe.ru/favicons/apple-touch-icon.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/ff45c6e7-ca6c-4e72-82d3-3b438b48a0ef
          player: media_player.soundtouch
          img: >-
            https://relax-fm.ru/design/images/img_for_design/icons/touch-icon-ipad.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/133a4c16-f338-11e9-a96c-52543be04c81
          player: media_player.soundtouch
          img: /local/icon/essentielradio.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/0a364b59-56b6-11e9-aa33-52543be04c81
          player: media_player.soundtouch
          img: /local/icon/Dorozhnoe_logo.jpg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/f796d445-4314-4eb6-a09d-bcac5d474661
          player: media_player.soundtouch
          img: /local/icon/diskotekasssr.jpg
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/9d0d21cd-9562-4436-801f-e4700d626894
          player: media_player.soundtouch
          img: /local/icon/bakurfm.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/3396f826-a6d4-40fd-b9e4-04db9687f719
          player: media_player.soundtouch
          img: /local/icon/Baku_hit_fm.png
      - type: custom:button-card
        template: tv_tile
        variables:
          url: media-source://radio_browser/0ad8350d-7d03-4f0d-9f35-b38cc42c40af
          player: media_player.soundtouch
          img: /local/icon/asan2.png