Radio streaming with Album Art, Artist and Track Name

I have been using @Bob_NL’s radio script for a while.
The issue I have is that this is not an audio stream that comes from an official app so there is no album art.
and there’s no way to programmatically add an album art to a media_player as this is not an available service.
image

With the arrival of lovelace, I thought I could create a card that has the missing information. It’s not perfect yet but I’m rather pleased with the outcome:

Here is what I had to do:

configuration.yaml:

downloader:
  download_dir: www

cameras:

- platform: generic
  name: RTL2_Pic
  still_image_url: '{{states.sensor.rtl2_pic.state}}'

Sensors:

- platform: scrape
  resource: https://www.rtl2.fr/direct
  name: RTL2_Pic
  select: 'img[class="pic img-echo timeline-media--music__img"]'
  attribute: data-src

- platform: scrape
  resource: https://www.rtl2.fr/direct
  name: RTL2_Artist
  select: 'span[class="timeline-media--music__artist"]'
  value_template: '{{ value | title }}'

- platform: scrape
  resource: https://www.rtl2.fr/direct
  name: RTL2_Track
  select: 'strong[class="timeline-media--music__title"]'
  value_template: '{{ value | title }}'

- platform: template
  sensors:
    current_speaker:
      value_template: >
        {% if is_state("input_select.chromecast_radio", "Kitchen") %} Kitchen
        {% elif is_state("input_select.chromecast_radio", "Onkyo") %} Onkyo
        {% elif is_state("input_select.chromecast_radio", "Conservatory") %} Conservatory
        {% elif is_state("input_select.chromecast_radio", "House") %} House
        {% endif %}
      friendly_name: Speaker
      icon_template: 'mdi:speaker'

scripts:

play_rtl2:
  alias: Play RTL2 Radio on Selected Chromecast Speakers
  sequence:
    - service: input_select.select_option
      data:
        entity_id: input_select.radio_station
        option: RTL2
    - service: script.turn_on
      entity_id: script.radio538

automation:

- alias: Get RTL2 Pic
  trigger:
    platform: state
    entity_id: sensor.rtl2_pic
  action:
    service: downloader.download_file
    data_template:
      url: '{{states.sensor.rtl2_pic.state}}'
      filename: 'RTL2_Pic.jpg'
      overwrite: 'yes'

switches:

- platform: template
  switches:
    chromecast_radio_mute:
      icon_template: '{% if states("switch.chromecast_radio_mute") %}mdi:volume-off{% else %}mdi:volume-high{% endif %}'
      value_template: >
        {% if is_state("input_select.chromecast_radio", "Conservatory") %} {% if states.media_player.conservatory.attributes.is_volume_muted %}on{% else %}off{% endif %}
        {% elif is_state("input_select.chromecast_radio", "Kitchen") %} {% if states.media_player.kitchen.attributes.is_volume_muted %}on{% else %}off{% endif %}
        {% elif is_state("input_select.chromecast_radio", "Onkyo") %} {% if states.media_player.onkyo_txnr656.attributes.is_volume_muted %}on{% else %}off{% endif %}
        {% elif is_state("input_select.chromecast_radio", "House") %} {% if states.media_player.house.attributes.is_volume_muted %}on{% else %}off{% endif %}
        {% else %}off
        {% endif %}
      turn_on:
        service: media_player.volume_mute
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio", "House") %} media_player.house
            {% endif %}
          is_volume_muted: >
            {% if is_state("input_select.chromecast_radio", "Conservatory") %} {% if states.media_player.conservatory.attributes.is_volume_muted %}false{% else %}true{% endif %}
            {% elif is_state("input_select.chromecast_radio", "Kitchen") %} {% if states.media_player.kitchen.attributes.is_volume_muted %}false{% else %}true{% endif %}
            {% elif is_state("input_select.chromecast_radio", "Onkyo") %} {% if states.media_player.onkyo_txnr656.attributes.is_volume_muted %}false{% else %}true{% endif %}
            {% elif is_state("input_select.chromecast_radio", "House") %} {% if states.media_player.house.attributes.is_volume_muted %}false{% else %}true{% endif %}
            {% endif %}
      turn_off:
        service: media_player.volume_mute
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio", "House") %} media_player.house
            {% endif %}
          is_volume_muted: >
            {% if is_state("input_select.chromecast_radio", "Conservatory") %} {% if states.media_player.conservatory.attributes.is_volume_muted %}false{% else %}true{% endif %}
            {% elif is_state("input_select.chromecast_radio", "Kitchen") %} {% if states.media_player.kitchen.attributes.is_volume_muted %}false{% else %}true{% endif %}
            {% elif is_state("input_select.chromecast_radio", "Onkyo") %} {% if states.media_player.onkyo_txnr656.attributes.is_volume_muted %}false{% else %}true{% endif %}
            {% elif is_state("input_select.chromecast_radio", "House") %} {% if states.media_player.house.attributes.is_volume_muted %}false{% else %}true{% endif %}
            {% endif %}

    chromecast_radio_vol_up:
      icon_template: 'mdi:volume-plus'
      value_template: 'on'
      turn_on:
        service: media_player.volume_up
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio", "House") %} media_player.house
            {% endif %}
      turn_off:
        service: media_player.volume_up
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio", "House") %} media_player.house
            {% endif %}

    chromecast_radio_vol_down:
      icon_template: 'mdi:volume-minus'
      value_template: 'on'
      turn_on:
        service: media_player.volume_down
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio", "House") %} media_player.house
            {% endif %}
      turn_off:
        service: media_player.volume_down
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio", "House") %} media_player.house
            {% endif %}

    chromecast_radio_rtl2_on:
      icon_template: 'mdi:power'
      value_template: >
        {% if is_state("input_select.chromecast_radio", "Conservatory") %} {% if states.media_player.conservatory.state == "playing" %}on{% else %}off{% endif %}
        {% elif is_state("input_select.chromecast_radio", "Kitchen") %} {% if states.media_player.kitchen.state == "playing" %}on{% else %}off{% endif %}
        {% elif is_state("input_select.chromecast_radio", "Onkyo") %} {% if states.media_player.onkyo_txnr656.state == "playing" %}on{% else %}off{% endif %}
        {% elif is_state("input_select.chromecast_radio", "House") %} {% if states.media_player.house.state == "playing" %}on{% else %}off{% endif %}
        {% else %}off
        {% endif %}
      turn_on:
        service: script.turn_on
        entity_id: script.play_rtl2
      turn_off:
        service: media_player.turn_off
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio", "House") %} media_player.house
            {% endif %}

Save a copy of the RTL2 Logo in the www folder:

and last but not least, lovelace card:

    cards:
      - type: vertical-stack
        cards:
        - type: picture-glance
          camera_image: camera.rtl2_pic
          entities:
            - entity: switch.chromecast_radio_rtl2_on
            - entity: switch.chromecast_radio_vol_down
            - entity: switch.chromecast_radio_mute
            - entity: switch.chromecast_radio_vol_up
        - type: entities
          show_header_toggle: false
          entities:
            - type: divider
              style:
                height: 50px
                margin: 4px 0
                background: center / contain url("/local/RTL2.jpg") no-repeat
            - entity: sensor.rtl2_artist
              name: Artist
              icon: mdi:account
            - entity: sensor.rtl2_track
              name: Track
              icon: mdi:file-music
            - entity: sensor.current_speaker
              name: Playing On
              icon: mdi:speaker
5 Likes

Very nice. Would be awesome if this can be done for all my favorite streams. Will have to dive in the scrape sensor sometime.

Thanks. Planning on adding others now that I know publish album art and track details

Made a lot of improvements to the point where I have to provide the whole code again.
Improvements include:

  • template the radio stream and allow other stations to work too
    (currently works with 3 radios (RTL2, Absolute Radio, Absolute Radio Classic Rock) for artist and track, others come up as unavailable or as hard coded values
  • added/moved radio stream and speaker selection to buttons on main album art picture
  • added proper play/stop buttons (not pause for now as most streams would then be out of sync with artist/track/album data. will need to add special conditions for podcasts which need a pause button)
  • I’ve also simplified a few things.

Here is a view of the latest card:
image

The full list of components (including original components for the radio to work)
Scrape sensors:

- platform: scrape
  resource: https://www.rtl2.fr/direct
  name: RTL2_Pic
  select: 'img[class="pic img-echo timeline-media--music__img"]'
  attribute: data-src

- platform: scrape
  resource: https://www.rtl2.fr/direct
  name: RTL2_Artist
  select: 'span[class="timeline-media--music__artist"]'
  value_template: '{{ value | title }}'

- platform: scrape
  resource: https://www.rtl2.fr/direct
  name: RTL2_Track
  select: 'strong[class="timeline-media--music__title"]'
  value_template: '{{ value | title }}'

- platform: scrape
  resource: https://absoluteradio.co.uk/classic-rock/music/
  name: Absolute_Radio_CR_Pic
  select: '.song-artist-image img'
  attribute: src

- platform: scrape
  resource: https://absoluteradio.co.uk/classic-rock/music/
  name: Absolute_Radio_CR_Artist
  select: '.song-artist-image img'
  attribute: alt

- platform: scrape
  resource: https://absoluteradio.co.uk/classic-rock/music/
  name: Absolute_Radio_CR_Track
  select: '.song-title a'

- platform: scrape
  resource: https://absoluteradio.co.uk/absolute-radio/music/
  name: Absolute_Radio_Pic
  select: '.song-artist-image img'
  attribute: src

- platform: scrape
  resource: https://absoluteradio.co.uk/absolute-radio/music/
  name: Absolute_Radio_Artist
  select: '.song-artist-image img'
  attribute: alt

- platform: scrape
  resource: https://absoluteradio.co.uk/absolute-radio/music/
  name: Absolute_Radio_Track
  select: '.song-title a'

- platform: scrape
  resource: https://hasspodcast.io/feed/podcast
  name: ha_podcast
  select: 'enclosure:nth-of-type(1)'
  attribute: url

- platform: scrape
  resource: https://hasspodcast.io/feed/podcast
  name: ha_podcast_track
  select: 'title:nth-of-type(3)'

- platform: scrape
  resource: https://iotpodcast.com/feed/
  name: internet_of_things_podcast
  select: 'enclosure:nth-of-type(1)'
  attribute: url

- platform: scrape
  resource: https://iotpodcast.com/feed/
  name: internet_of_things_podcast_track
  select: 'title:nth-of-type(3)'


- platform: template
  sensors:
    stream_artist:
      entity_id:
        - sensor.rtl2_artist
        - sensor.absolute_radio_cr_artist
        - sensor.absolute_radio_artist
      value_template: >
        {% if is_state("input_select.radio_station", "RTL2") %} {{states.sensor.rtl2_artist.state}}
        {% elif is_state("input_select.radio_station", "Absolute Radio") %} {{states.sensor.absolute_radio_artist.state}}
        {% elif is_state("input_select.radio_station", "Absolute Radio Classic Rock") %} {{states.sensor.absolute_radio_CR_artist.state}}
        {% elif is_state("input_select.radio_station", "Hit West") %} N/A
        {% elif is_state("input_select.radio_station", "HA Podcast") %} Phil & Rohan
        {% elif is_state("input_select.radio_station", "IoT Podcast") %} Stacey & Kevin
        {% elif is_state("input_select.radio_station", "Chill") %} N/A
        {% elif is_state("input_select.radio_station", "Custom Station") %} N/A
        {% endif %}
      friendly_name: Artist
      icon_template: 'mdi:account'
    stream_track:
      entity_id:
        - sensor.rtl2_track
        - sensor.absolute_radio_track
        - sensor.absolute_radio_cr_track
        - sensor.ha_podcast_track
        - sensor.internet_of_things_podcast_track
      value_template: >
        {% if is_state("input_select.radio_station", "RTL2") %} {{states.sensor.rtl2_track.state}}
        {% elif is_state("input_select.radio_station", "Absolute Radio") %} {{states.sensor.absolute_radio_track.state}}
        {% elif is_state("input_select.radio_station", "Absolute Radio Classic Rock") %} {{states.sensor.absolute_radio_CR_track.state}}
        {% elif is_state("input_select.radio_station", "Hit West") %} N/A
        {% elif is_state("input_select.radio_station", "HA Podcast") %} {{states.sensor.ha_podcast_track.state}}
        {% elif is_state("input_select.radio_station", "IoT Podcast") %} {{states.sensor.internet_of_things_podcast_track.state}}
        {% elif is_state("input_select.radio_station", "Chill") %} N/A
        {% elif is_state("input_select.radio_station", "Custom Station") %} N/A
        {% endif %}
      friendly_name: Artist
      icon_template: 'mdi:account'

cameras:

- platform: generic
  name: chromecast_radio_pic
  still_image_url: >
    {% if is_state("input_select.chromecast_radio_station", "RTL2") %} {{states.sensor.rtl2_pic.state}}
    {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio") %} {{states.sensor.absolute_radio_pic.state}}
    {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio Classic Rock") %} {{states.sensor.absolute_radio_CR_pic.state}}
    {% elif is_state("input_select.chromecast_radio_station", "Hit West") %} https://upload.wikimedia.org/wikipedia/fr/b/bd/HitWestLogo.jpg
    {% elif is_state("input_select.chromecast_radio_station", "HA Podcast") %} https://secureimg.stitcher.com/feedimageswide/480x270_176113.jpg
    {% elif is_state("input_select.chromecast_radio_station", "IoT Podcast") %} https://is1-ssl.mzstatic.com/image/thumb/Music62/v4/b3/d6/64/b3d664ab-0560-f24d-2379-d01142267f94/source/1200x630bb.jpg
    {% elif is_state("input_select.chromecast_radio_station", "Chill") %} http://images.radio.orange.com/radios/large_helpmechill.png
    {% elif is_state("input_select.chromecast_radio_station", "Custom Station") %} https://www.holyscripturesandisrael.com/images/radio/radio-icon.png
    {% endif %}

script:

play_chromecast_radio:
  alias: Cast Selected Radio on Chromecast Speakers
  sequence:
    - service: media_player.volume_set
      data_template:
        entity_id: >
          {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
          {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
          {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo
          {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
          {% endif %}
        volume_level: '{{  states.input_number.volume_radio.state  }}' 
    - service: media_player.play_media
      data_template:
        entity_id: >
          {% if is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
          {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo
          {% elif is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
          {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
          {% endif %}
        media_content_id: >
          {% if is_state("input_select.chromecast_radio_station", "RTL2") %} http://streaming.radio.rtl2.fr:80/rtl2-1-44-96
          {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio") %} http://icy-e-bab-04-cr.sharp-stream.com/absoluteradio.mp3
          {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio Classic Rock") %} http://icy-e-bab-04-cr.sharp-stream.com/absoluteclassicrock.mp3
          {% elif is_state("input_select.chromecast_radio_station", "Hit West") %} http://broadcast.infomaniak.ch/hitwest-high.mp3
          {% elif is_state("input_select.chromecast_radio_station", "HA Podcast") %} {{states.sensor.ha_podcast.state}}
          {% elif is_state("input_select.chromecast_radio_station", "IoT Podcast") %} {{states.sensor.internet_of_things_podcast.state}}
          {% elif is_state("input_select.chromecast_radio_station", "Chill") %} http://media-the.musicradio.com/ChillMP3
          {% elif is_state("input_select.chromecast_radio_station", "Custom Station") %} {{states.input_text.custom_station.state}}
          {% endif %}
        media_content_type: 'audio/mp4'

stop_chromecast_radio:
  alias: Stop Playing Radio on ChomeCast 
  sequence:
    - service: media_player.turn_off
      data_template:
        entity_id: >
          {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
          {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
          {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo
          {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
          {% endif %}

switches:

- platform: template
  switches:
    chromecast_radio_mute:
      icon_template: '{% if states("switch.chromecast_radio_mute") %}mdi:volume-off{% else %}mdi:volume-high{% endif %}'
      value_template: >
        {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} {% if states.media_player.conservatory.attributes.is_volume_muted %}on{% else %}off{% endif %}
        {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} {% if states.media_player.kitchen.attributes.is_volume_muted %}on{% else %}off{% endif %}
        {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} {% if states.media_player.onkyo_txnr656.attributes.is_volume_muted %}on{% else %}off{% endif %}
        {% elif is_state("input_select.chromecast_radio_speakers", "House") %} {% if states.media_player.house.attributes.is_volume_muted %}on{% else %}off{% endif %}
        {% else %}off
        {% endif %}
      turn_on:
        service: media_player.volume_mute
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
            {% endif %}
          is_volume_muted: true
      turn_off:
        service: media_player.volume_mute
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
            {% endif %}
          is_volume_muted: false

    chromecast_radio_vol_up:
      icon_template: 'mdi:volume-plus'
      value_template: 'on'
      turn_on:
        service: media_player.volume_up
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
            {% endif %}
      turn_off:
        service: media_player.volume_up
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
            {% endif %}

    chromecast_radio_vol_down:
      icon_template: 'mdi:volume-minus'
      value_template: 'on'
      turn_on:
        service: media_player.volume_down
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
            {% endif %}
      turn_off:
        service: media_player.volume_down
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_txnr656
            {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
            {% endif %}

    chromecast_radio_play:
      icon_template: 'mdi:play'
      value_template: 'on'
      turn_on:
        service: script.turn_on
        entity_id: script.play_chromecast_radio
      turn_off:
        service: script.turn_on
        entity_id: script.play_chromecast_radio

    chromecast_radio_stop:
      icon_template: 'mdi:stop'
      value_template: 'on'
      turn_on:
        service: script.turn_on
        entity_id: script.stop_chromecast_radio
      turn_off:
        service: script.turn_on
        entity_id: script.stop_chromecast_radio

Input Selects:

chromecast_radio_station:
  name: 'Select Radio Station:'
  options:
    - Absolute Radio
    - Absolute Radio Classic Rock
    - Chill
    - Hit West
    - HA Podcast
    - IoT Podcast
    - RTL2
    - Custom Station
  icon: mdi:radio

chromecast_radio_speakers:
  name: 'Select Speakers:'
  options:
    - Conservatory
    - House
    - Kitchen
    - Onkyo
  initial: House
  icon: mdi:speaker-wireless

Input Text:

custom_station:
  name: Radio URL
  icon: mdi:link-variant

lovelace-ui:

  - title: Radio Stream
    icon: mdi:radio
    cards:
      - type: vertical-stack
        cards:
        - type: picture-glance
          camera_image: camera.chromecast_radio_pic
          entities:
            - entity: input_select.chromecast_radio_station
            - entity: input_text.custom_station
            - entity: input_select.chromecast_radio_speakers
            - entity: switch.chromecast_radio_vol_down
            - entity: switch.chromecast_radio_mute
            - entity: switch.chromecast_radio_vol_up
            - entity: switch.chromecast_radio_stop
            - entity: switch.chromecast_radio_play
        - type: entities
          show_header_toggle: false
          entities:
            - entity: sensor.stream_artist
              name: Artist
              icon: mdi:account
            - entity: sensor.stream_track
              name: Track
              icon: mdi:disc
3 Likes

Awesome work pinching this thanks @lolouk44

1 Like

wow madness, does anyone manage to scrape the album cover? Please!

https://www.kronehit.at/

Not sure it’s possible the first thing I see when I click on your link is this:


Which, without clicking on okay, doesn’t go anywhere…

Yes thats the problem

you won’t be able to go round that. The scrape sensor “reads” the html code off the page, then you apply filters to return only the bits you want. It will not allow you to click on cookie disclaimers or even click on the play button to start playing the radio.

@lolouk44 Would also need help for a website:
http://zamg.ac.at/warnmobil/index.php?type=w0&state=noe&district=Hollabrunn

for this information:
class = “warndescription yellow”

My configuration does not work or I do not understand that with the scrape sensor.

Please Help me …
greetings johann

- platform: scrape
    resource: http://zamg.ac.at/warnmobil/index.php?type=w0&state=noe&district=Hollabrunn
    name: Wetterwarnungen
    select: '[class="warndescription yellow"]'
    value_template: '{{ value.split("(")[1].split(")")[0] }}'

I can’t see any yellow bit, just green
image

Based on this, you can try this:

sensor:
  - platform: scrape
    resource: http://zamg.ac.at/warnmobil/index.php?type=w0&state=noe&district=Hollabrunn
    name: Warntyp
    select: ".warndescription"
1 Like

Hi @lolouk44 I’m trying to extract the various information on this site:
https://www.parsifal.it/desktop/

this is the code that I insert to extract the cover, for example, but it doesn’t work:

- platform: scrape
  resource: https://www.parsifal.it/desktop/
  name: Radio_Parsifal_Pic
  select: "#xp-cover-wrapper img"
  attribute: src

Log:

(SyncWorker_15) [homeassistant.components.scrape.sensor] Unable to extract data from HTML

I can’t even extract artist name and song title

hello everyone I tried this fantastic solution to play music in my house, I created a PKG the volumes change, the mute works, the stop also but when I do Play it doesn’t play anything, I just changed my media players. how can i solve? thanks

I attach the code:

#################################################################
#                                                               #
#                           Radio                               #
#                                                               #
#################################################################

sensor:
#################################################################
  - platform: scrape
    resource: https://www.rtl2.fr/direct
    name: RTL2_Pic
    select: 'img[class="pic img-echo timeline-media--music__img"]'
    attribute: data-src
  
  - platform: scrape
    resource: https://www.rtl2.fr/direct
    name: RTL2_Artist
    select: 'span[class="timeline-media--music__artist"]'
    value_template: '{{ value | title }}'
  
  - platform: scrape
    resource: https://www.rtl2.fr/direct
    name: RTL2_Track
    select: 'strong[class="timeline-media--music__title"]'
    value_template: '{{ value | title }}'
  
  - platform: scrape
    resource: https://absoluteradio.co.uk/classic-rock/music/
    name: Absolute_Radio_CR_Pic
    select: '.song-artist-image img'
    attribute: src
  
  - platform: scrape
    resource: https://absoluteradio.co.uk/classic-rock/music/
    name: Absolute_Radio_CR_Artist
    select: '.song-artist-image img'
    attribute: alt
  
  - platform: scrape
    resource: https://absoluteradio.co.uk/classic-rock/music/
    name: Absolute_Radio_CR_Track
    select: '.song-title a'
  
  - platform: scrape
    resource: https://absoluteradio.co.uk/absolute-radio/music/
    name: Absolute_Radio_Pic
    select: '.song-artist-image img'
    attribute: src
  
  - platform: scrape
    resource: https://absoluteradio.co.uk/absolute-radio/music/
    name: Absolute_Radio_Artist
    select: '.song-artist-image img'
    attribute: alt
  
  - platform: scrape
    resource: https://absoluteradio.co.uk/absolute-radio/music/
    name: Absolute_Radio_Track
    select: '.song-title a'
  
  - platform: scrape
    resource: https://hasspodcast.io/feed/podcast
    name: ha_podcast
    select: 'enclosure:nth-of-type(1)'
    attribute: url
  
  - platform: scrape
    resource: https://hasspodcast.io/feed/podcast
    name: ha_podcast_track
    select: 'title:nth-of-type(3)'
  
  - platform: scrape
    resource: https://iotpodcast.com/feed/
    name: internet_of_things_podcast
    select: 'enclosure:nth-of-type(1)'
    attribute: url
  
  - platform: scrape
    resource: https://iotpodcast.com/feed/
    name: internet_of_things_podcast_track
    select: 'title:nth-of-type(3)'
  
  
  - platform: template
    sensors:
      stream_artist:
        entity_id:
          - sensor.rtl2_artist
          - sensor.absolute_radio_cr_artist
          - sensor.absolute_radio_artist
        value_template: >
          {% if is_state("input_select.radio_station", "RTL2") %} {{states.sensor.rtl2_artist.state}}
          {% elif is_state("input_select.radio_station", "Absolute Radio") %} {{states.sensor.absolute_radio_artist.state}}
          {% elif is_state("input_select.radio_station", "Absolute Radio Classic Rock") %} {{states.sensor.absolute_radio_CR_artist.state}}
          {% elif is_state("input_select.radio_station", "Hit West") %} N/A
          {% elif is_state("input_select.radio_station", "HA Podcast") %} Phil & Rohan
          {% elif is_state("input_select.radio_station", "IoT Podcast") %} Stacey & Kevin
          {% elif is_state("input_select.radio_station", "Chill") %} N/A
          {% elif is_state("input_select.radio_station", "Custom Station") %} N/A
          {% endif %}
        friendly_name: Artist
        icon_template: 'mdi:account'
      stream_track:
        entity_id:
          - sensor.rtl2_track
          - sensor.absolute_radio_track
          - sensor.absolute_radio_cr_track
          - sensor.ha_podcast_track
          - sensor.internet_of_things_podcast_track
        value_template: >
          {% if is_state("input_select.radio_station", "RTL2") %} {{states.sensor.rtl2_track.state}}
          {% elif is_state("input_select.radio_station", "Absolute Radio") %} {{states.sensor.absolute_radio_track.state}}
          {% elif is_state("input_select.radio_station", "Absolute Radio Classic Rock") %} {{states.sensor.absolute_radio_CR_track.state}}
          {% elif is_state("input_select.radio_station", "Hit West") %} N/A
          {% elif is_state("input_select.radio_station", "HA Podcast") %} {{states.sensor.ha_podcast_track.state}}
          {% elif is_state("input_select.radio_station", "IoT Podcast") %} {{states.sensor.internet_of_things_podcast_track.state}}
          {% elif is_state("input_select.radio_station", "Chill") %} N/A
          {% elif is_state("input_select.radio_station", "Custom Station") %} N/A
          {% endif %}
        friendly_name: Artist
        icon_template: 'mdi:account'


camera:
#################################################################
  - platform: generic
    name: chromecast_radio_pic
    still_image_url: >
      {% if is_state("input_select.chromecast_radio_station", "RTL2") %} {{states.sensor.rtl2_pic.state}}
      {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio") %} {{states.sensor.absolute_radio_pic.state}}
      {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio Classic Rock") %} {{states.sensor.absolute_radio_CR_pic.state}}
      {% elif is_state("input_select.chromecast_radio_station", "Hit West") %} https://upload.wikimedia.org/wikipedia/fr/b/bd/HitWestLogo.jpg
      {% elif is_state("input_select.chromecast_radio_station", "HA Podcast") %} https://secureimg.stitcher.com/feedimageswide/480x270_176113.jpg
      {% elif is_state("input_select.chromecast_radio_station", "IoT Podcast") %} https://is1-ssl.mzstatic.com/image/thumb/Music62/v4/b3/d6/64/b3d664ab-0560-f24d-2379-d01142267f94/source/1200x630bb.jpg
      {% elif is_state("input_select.chromecast_radio_station", "Chill") %} http://images.radio.orange.com/radios/large_helpmechill.png
      {% elif is_state("input_select.chromecast_radio_station", "Custom Station") %} https://www.holyscripturesandisrael.com/images/radio/radio-icon.png
      {% endif %}


script:
#################################################################
  play_chromecast_radio:
    alias: Cast Selected Radio on Chromecast Speakers
    sequence:
      - service: media_player.volume_set
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Salotto") %} media_player.googlehome3627
            {% elif is_state("input_select.chromecast_radio_speakers", "Bagno") %} media_player.bagno
            {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} media_player.googlehome5227
            {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} media_player.gruppo_casa_3
            {% endif %}
          volume_level: '{{  states.input_number.volume_radio.state  }}' 
      - service: media_player.play_media
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Bagno") %} media_player.bagno
            {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} media_player.googlehome5227
            {% elif is_state("input_select.chromecast_radio_speakers", "Salotto") %} media_player.googlehome3627
            {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} media_player.gruppo_casa_3
            {% endif %}
          media_content_id: >
            {% if is_state("input_select.chromecast_radio_station", "RTL2") %} http://streaming.radio.rtl2.fr:80/rtl2-1-44-96
            {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio") %} http://icy-e-bab-04-cr.sharp-stream.com/absoluteradio.mp3
            {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio Classic Rock") %} http://icy-e-bab-04-cr.sharp-stream.com/absoluteclassicrock.mp3
            {% elif is_state("input_select.chromecast_radio_station", "Hit West") %} http://broadcast.infomaniak.ch/hitwest-high.mp3
            {% elif is_state("input_select.chromecast_radio_station", "HA Podcast") %} {{states.sensor.ha_podcast.state}}
            {% elif is_state("input_select.chromecast_radio_station", "IoT Podcast") %} {{states.sensor.internet_of_things_podcast.state}}
            {% elif is_state("input_select.chromecast_radio_station", "Chill") %} http://media-the.musicradio.com/ChillMP3
            {% elif is_state("input_select.chromecast_radio_station", "Custom Station") %} {{states.input_text.custom_station.state}}
            {% endif %}
          media_content_type: 'audio/mp4'
  
  stop_chromecast_radio:
    alias: Stop Playing Radio on ChomeCast 
    sequence:
      - service: media_player.turn_off
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Salotto") %} media_player.googlehome3627
            {% elif is_state("input_select.chromecast_radio_speakers", "Bagno") %} media_player.bagno
            {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} media_player.googlehome5227
            {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} media_player.gruppo_casa_3
            {% endif %}


switch:
#################################################################
  - platform: template
    switches:
      chromecast_radio_mute:
        icon_template: '{% if states("switch.chromecast_radio_mute") %}mdi:volume-off{% else %}mdi:volume-high{% endif %}'
        value_template: >
          {% if is_state("input_select.chromecast_radio_speakers", "Salotto") %} {% if states.media_player.googlehome3627.attributes.is_volume_muted %}on{% else %}off{% endif %}
          {% elif is_state("input_select.chromecast_radio_speakers", "Bagno") %} {% if states.media_player.bagno.attributes.is_volume_muted %}on{% else %}off{% endif %}
          {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} {% if states.media_player.googlehome5227.attributes.is_volume_muted %}on{% else %}off{% endif %}
          {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} {% if states.media_player.gruppo_casa_3.attributes.is_volume_muted %}on{% else %}off{% endif %}
          {% else %}off
          {% endif %}
        turn_on:
          service: media_player.volume_mute
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Salotto") %} media_player.googlehome3627
              {% elif is_state("input_select.chromecast_radio_speakers", "Bagno") %} media_player.bagno
              {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} media_player.googlehome5227
              {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} media_player.gruppo_casa_3
              {% endif %}
            is_volume_muted: true
        turn_off:
          service: media_player.volume_mute
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Salotto") %} media_player.googlehome3627
              {% elif is_state("input_select.chromecast_radio_speakers", "Bagno") %} media_player.bagno
              {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} media_player.googlehome5227
              {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} media_player.gruppo_casa_3
              {% endif %}
            is_volume_muted: false
  
      chromecast_radio_vol_up:
        icon_template: 'mdi:volume-plus'
        value_template: 'on'
        turn_on:
          service: media_player.volume_up
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Salotto") %} media_player.googlehome3627
              {% elif is_state("input_select.chromecast_radio_speakers", "Bagno") %} media_player.bagno
              {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} media_player.googlehome5227
              {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} media_player.gruppo_casa_3
              {% endif %}
        turn_off:
          service: media_player.volume_up
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Salotto") %} media_player.googlehome3627
              {% elif is_state("input_select.chromecast_radio_speakers", "Bagno") %} media_player.bagno
              {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} media_player.googlehome5227
              {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} media_player.gruppo_casa_3
              {% endif %}
  
      chromecast_radio_vol_down:
        icon_template: 'mdi:volume-minus'
        value_template: 'on'
        turn_on:
          service: media_player.volume_down
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Salotto") %} media_player.googlehome3627
              {% elif is_state("input_select.chromecast_radio_speakers", "Bagno") %} media_player.bagno
              {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} media_player.googlehome5227
              {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} media_player.gruppo_casa_3
              {% endif %}
        turn_off:
          service: media_player.volume_down
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Salotto") %} media_player.googlehome3627
              {% elif is_state("input_select.chromecast_radio_speakers", "Bagno") %} media_player.bagno
              {% elif is_state("input_select.chromecast_radio_speakers", "Studio") %} media_player.googlehome5227
              {% elif is_state("input_select.chromecast_radio_speakers", "Casa") %} media_player.gruppo_casa_3
              {% endif %}
  
      chromecast_radio_play:
        icon_template: 'mdi:play'
        value_template: 'on'
        turn_on:
          service: script.turn_on
          entity_id: script.play_chromecast_radio
        turn_off:
          service: script.turn_on
          entity_id: script.play_chromecast_radio
  
      chromecast_radio_stop:
        icon_template: 'mdi:stop'
        value_template: 'on'
        turn_on:
          service: script.turn_on
          entity_id: script.stop_chromecast_radio
        turn_off:
          service: script.turn_on
          entity_id: script.stop_chromecast_radio


input_select:
#################################################################
  chromecast_radio_station:
    name: 'Select Radio Station:'
    options:
      - Absolute Radio
      - Absolute Radio Classic Rock
      - Chill
      - Hit West
      - HA Podcast
      - IoT Podcast
      - RTL2
      - Custom Station
    icon: mdi:radio
  
  chromecast_radio_speakers:
    name: 'Select Speakers:'
    options:
      - Salotto
      - Casa
      - Bagno
      - Studio
    initial: Casa
    icon: mdi:speaker-wireless


input_text:
#################################################################
  custom_station:
    name: Radio URL
    icon: mdi:link-variant

Hi @sadek

You won’t be able to scrape that page because the data is loaded via scripts
(try to show the page source and search for the artist name, you won’t find it)

is this for all stations?
RTL2, Chill and Absolute Radio have changed their web page since I posted this.
I’ve also moved away from HA Scrape sensors and created my own script to retrieve the data more often (every 15sec) as opposed to every minute (default in HA)
I’ll try and create a package with the new data.

hello and thanks for the answer, yes for all the stations the code I posted is correct in your opinion? if you do some new package let me know that I’m interested

any help for me?

found what’s wrong. You don’t have the input_number in your package (which to be fair I think I forgot in my earlier posts)
Anyway I’ve updated your package file with the latest data from my current setup. I think I have everything.
Please note I’ve not created packages before so you probably will need to “personalise” some things

Package Code
#################################################################
#                                                               #
#                           Radio                               #
#                                                               #
#################################################################



#################################################################
automation:
  - alias: Chromecast - Set Radio Volume
    initial_state: true
    trigger:
      platform: state
      entity_id: input_number.volume_radio
    action:
      service: media_player.volume_set
      data_template:
        entity_id: >
          {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
          {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
          {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo_TX_NR656_2") %} media_player.onkyo_tx_nr656
          {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
          {% endif %}
        volume_level: '{{  states("input_number.volume_radio")  }}'

  - alias: Start RadioStream Scrape At Startup
    initial_state: true
    trigger:
      - platform: homeassistant
        event: start
    action:
    - service: shell_command.stop_radiostream_sensors
    - delay: 00:00:02
    - service: shell_command.start_radiostream_sensors

#################################################################
binary_sensor:
  - platform: template
    sensors:
      radio_is_streaming:
        entity_id:
          - media_player.conservatory
          - media_player.house
          - media_player.kitchen
          - media_player.onkyo
          - media_player.onkyo_tx_nr656_2
        value_template: >
          {% set myval = namespace(found=0) %}
          {%- for state in states.media_player -%}
          {%- if state.entity_id in ["media_player.conservatory", "media_player.house", "media_player.kitchen", "media_player.onkyo", "media_player.onkyo_tx_nr656_2"] -%}
          {% if state_attr(state.entity_id, "media_content_id") in ["http://streaming.radio.rtl2.fr:80/rtl2-1-44-96", "http://icy-e-bab-04-cr.sharp-stream.com/absoluteradio.mp3", "http://icy-e-bab-04-cr.sharp-stream.com/absoluteclassicrock.mp3", "http://broadcast.infomaniak.ch/hitwest-high.mp3", states("sensor.ha_podcast"), states("sensor.internet_of_things_podcast"), "http://media-the.musicradio.com/ChillMP3", "http://peridot.streamguys.com:7150/RFTwo?play", states("input_text.custom_station")] -%}{% set myval.found = myval.found + 1%}{%- endif -%}
          {%- endif -%}  
          {%- endfor %}
          {{ myval.found > 0 }}

#################################################################
input_number:
  volume_radio:
    name: Volume
    icon: mdi:volume-high
    initial: 0.4
    min: 0
    max: 1
    step: 0.05

#################################################################
input_select:
  chromecast_radio_station:
    name: 'Select Radio Station'
    options:
      - Absolute Radio
      - Absolute Radio Classic Rock
      - Chill
      - Hit West
      - HA Podcast
      - IoT Podcast
      - Navtarang
      - Radio Fiji Two
      - RTL2
      - Custom Station
    icon: mdi:radio

  chromecast_radio_speakers:
    name: 'Select Speakers'
    options:
      - Conservatory
      - House
      - Kitchen
      - Onkyo_TX_NR656_2
    icon: mdi:speaker-wireless

#################################################################
input_text:
  custom_station:
    name: Radio URL
    icon: mdi:link-variant

#################################################################
script:
  play_chromecast_radio:
    alias: Cast Selected Radio on Chromecast Speakers
    sequence:
      - service: media_player.volume_set
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo_TX_NR656_2") %} media_player.onkyo_tx_nr656_2
            {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
            {% endif %}
          volume_level: '{{  states("input_number.volume_radio")  }}' 
      - service: media_player.play_media
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo_TX_NR656_2") %} media_player.onkyo_tx_nr656_2
            {% elif is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
            {% endif %}
          media_content_id: >
            {% if is_state("input_select.chromecast_radio_station", "RTL2") %} http://streaming.radio.rtl2.fr:80/rtl2-1-44-96
            {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio") %} http://icy-e-bab-04-cr.sharp-stream.com/absoluteradio.mp3
            {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio Classic Rock") %} http://icy-e-bab-04-cr.sharp-stream.com/absoluteclassicrock.mp3
            {% elif is_state("input_select.chromecast_radio_station", "Hit West") %} http://broadcast.infomaniak.ch/hitwest-high.mp3
            {% elif is_state("input_select.chromecast_radio_station", "HA Podcast") %} {{states("sensor.ha_podcast")}}
            {% elif is_state("input_select.chromecast_radio_station", "IoT Podcast") %} {{states("sensor.internet_of_things_podcast")}}
            {% elif is_state("input_select.chromecast_radio_station", "Chill") %} http://media-the.musicradio.com/ChillMP3
            {% elif is_state("input_select.chromecast_radio_station", "Radio Fiji Two") %} http://peridot.streamguys.com:7150/RFTwo?play
            {% elif is_state("input_select.chromecast_radio_station", "Navtarang") %} http://192.111.142.176:8000/NAVTARANG
            {% elif is_state("input_select.chromecast_radio_station", "Custom Station") %} {{states("input_text.custom_station")}}
            {% endif %}
          media_content_type: 'audio/mp4'

  stop_chromecast_radio:
    alias: Stop Playing Radio on ChomeCast 
    sequence:
      - service: media_player.turn_off
        data_template:
          entity_id: >
            {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
            {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
            {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo_TX_NR656_2") %} media_player.onkyo_tx_nr656_2
            {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
            {% endif %}

#################################################################
sensor:
  - platform: mqtt
    name: "RTL2_Pic"
    state_topic: "RadioStream/RTL2/pic_url"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "RTL2_Artist"
    state_topic: "RadioStream/RTL2/artist"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "RTL2_Track"
    state_topic: "RadioStream/RTL2/track"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "Chill_Pic"
    state_topic: "RadioStream/Chill/pic_url"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "Chill_Artist"
    state_topic: "RadioStream/Chill/artist"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "Chill_Track"
    state_topic: "RadioStream/Chill/track"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "Absolute_Radio_Pic"
    state_topic: "RadioStream/Absolute_Radio/pic_url"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "Absolute_Radio_Artist"
    state_topic: "RadioStream/Absolute_Radio/artist"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "Absolute_Radio_Track"
    state_topic: "RadioStream/Absolute_Radio/track"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "Absolute_Radio_CR_Pic"
    state_topic: "RadioStream/Absolute_Radio_CR/pic_url"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "Absolute_Radio_CR_Artist"
    state_topic: "RadioStream/Absolute_Radio_CR/artist"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "ha_podcast"
    state_topic: "RadioStream/Hass Podcast/mp3_url"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "ha_podcast_track"
    state_topic: "RadioStream/Hass Podcast/track"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "Absolute_Radio_CR_Track"
    state_topic: "RadioStream/Absolute_Radio_CR/track"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "internet_of_things_podcast"
    state_topic: "RadioStream/IoT Podcast/mp3_url"
    value_template: "{{ value }}"

  - platform: mqtt
    name: "internet_of_things_podcast_track"
    state_topic: "RadioStream/IoT Podcast/track"
    value_template: "{{ value }}"


  - platform: template
    sensors:
      stream_artist:
        entity_id:
          - sensor.rtl2_artist
          - sensor.absolute_radio_cr_artist
          - sensor.absolute_radio_artist
          - sensor.rtl2_track
          - sensor.absolute_radio_track
          - sensor.absolute_radio_cr_track
          - sensor.ha_podcast_track
          - sensor.rtl2_pic
          - sensor.absolute_radio_cr_pic
          - sensor.absolute_radio_pic
          - input_select.chromecast_radio_station
          - input_select.chromecast_radio_speakers
        value_template: >
          {% if is_state("input_select.chromecast_radio_station", "RTL2") %} {{states("sensor.rtl2_artist")}}
          {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio") %} {{states("sensor.absolute_radio_artist")}}
          {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio Classic Rock") %} {{states("sensor.absolute_radio_CR_artist")}}
          {% elif is_state("input_select.chromecast_radio_station", "Hit West") %} N/A
          {% elif is_state("input_select.chromecast_radio_station", "HA Podcast") %} Phil & Rohan
          {% elif is_state("input_select.chromecast_radio_station", "IoT Podcast") %} Stacey & Kevin
          {% elif is_state("input_select.chromecast_radio_station", "Chill") %} {{states("sensor.chill_artist")}}
          {% elif is_state("input_select.chromecast_radio_station", "Navtarang") %} N/A
          {% elif is_state("input_select.chromecast_radio_station", "Radio Fiji Two") %} N/A
          {% elif is_state("input_select.chromecast_radio_station", "Custom Station") %} N/A
          {% endif %}
        friendly_name: Artist
        icon_template: 'mdi:account'
      stream_track:
        entity_id:
          - sensor.rtl2_artist
          - sensor.absolute_radio_cr_artist
          - sensor.absolute_radio_artist
          - sensor.rtl2_track
          - sensor.absolute_radio_track
          - sensor.absolute_radio_cr_track
          - sensor.ha_podcast_track
          - sensor.rtl2_pic
          - sensor.absolute_radio_cr_pic
          - sensor.absolute_radio_pic
          - sensor.internet_of_things_podcast_track
          - input_select.chromecast_radio_station
          - input_select.chromecast_radio_speakers
        value_template: >
          {% if is_state("input_select.chromecast_radio_station", "RTL2") %} {{states("sensor.rtl2_track")}}
          {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio") %} {{states("sensor.absolute_radio_track")}}
          {% elif is_state("input_select.chromecast_radio_station", "Absolute Radio Classic Rock") %} {{states("sensor.absolute_radio_CR_track")}}
          {% elif is_state("input_select.chromecast_radio_station", "Hit West") %} N/A
          {% elif is_state("input_select.chromecast_radio_station", "HA Podcast") %} {{states("sensor.ha_podcast_track")}}
          {% elif is_state("input_select.chromecast_radio_station", "IoT Podcast") %} {{states("sensor.internet_of_things_podcast_track")}}
          {% elif is_state("input_select.chromecast_radio_station", "Chill") %} {{states("sensor.chill_track")}}
          {% elif is_state("input_select.chromecast_radio_station", "Navtarang") %} N/A
          {% elif is_state("input_select.chromecast_radio_station", "Radio Fiji Two") %} N/A
          {% elif is_state("input_select.chromecast_radio_station", "Custom Station") %} N/A
          {% endif %}
        friendly_name: Artist
        icon_template: 'mdi:account'

#################################################################
shell_command:
  stop_radiostream_sensors: /config/shell_scripts/stop_radiostream_sensors.sh
  start_radiostream_sensors: /config/shell_scripts/start_radiostream_sensors.sh

#################################################################
switch:
  - platform: template
    switches:
      chromecast_radio_mute:
        icon_template: '{% if states("switch.chromecast_radio_mute") %}mdi:volume-off{% else %}mdi:volume-high{% endif %}'
        value_template: >
          {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} {% if state_attr("media_player.conservatory","is_volume_muted") %}on{% else %}off{% endif %}
          {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} {% if state_attr("media_player.kitchen","is_volume_muted") %}on{% else %}off{% endif %}
          {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} {% if state_attr("media_player.onkyo_tx_nr656","is_volume_muted") %}on{% else %}off{% endif %}
          {% elif is_state("input_select.chromecast_radio_speakers", "House") %} {% if state_attr("media_player.house","is_volume_muted") %}on{% else %}off{% endif %}
          {% else %}off
          {% endif %}
        turn_on:
          service: media_player.volume_mute
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
              {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
              {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_tx_nr656
              {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
              {% endif %}
            is_volume_muted: true
        turn_off:
          service: media_player.volume_mute
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
              {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
              {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_tx_nr656
              {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
              {% endif %}
            is_volume_muted: false

      chromecast_radio_vol_up:
        icon_template: 'mdi:volume-plus'
        value_template: 'on'
        turn_on:
          service: media_player.volume_up
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
              {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
              {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_tx_nr656
              {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
              {% endif %}
        turn_off:
          service: media_player.volume_up
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
              {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
              {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_tx_nr656
              {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
              {% endif %}

      chromecast_radio_vol_down:
        icon_template: 'mdi:volume-minus'
        value_template: 'on'
        turn_on:
          service: media_player.volume_down
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
              {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
              {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_tx_nr656
              {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
              {% endif %}
        turn_off:
          service: media_player.volume_down
          data_template:
            entity_id: >
              {% if is_state("input_select.chromecast_radio_speakers", "Conservatory") %} media_player.conservatory
              {% elif is_state("input_select.chromecast_radio_speakers", "Kitchen") %} media_player.kitchen
              {% elif is_state("input_select.chromecast_radio_speakers", "Onkyo") %} media_player.onkyo_tx_nr656
              {% elif is_state("input_select.chromecast_radio_speakers", "House") %} media_player.house
              {% endif %}

      chromecast_radio_play:
        icon_template: 'mdi:play'
        value_template: 'on'
        turn_on:
          service: script.turn_on
          entity_id: script.play_chromecast_radio
        turn_off:
          service: script.turn_on
          entity_id: script.play_chromecast_radio

      chromecast_radio_stop:
        icon_template: 'mdi:stop'
        value_template: 'on'
        turn_on:
          service: script.turn_on
          entity_id: script.stop_chromecast_radio
        turn_off:
          service: script.turn_on
          entity_id: script.stop_chromecast_radio

You also need a few scripts. Mine are saved in the shell_scripts folder. Make sure you change the MQTT credentials in the python file…

start_radiostream_sensors.sh
cd /config/shell_scripts/ && python HA_Scrape.py
stop_radiostream_sensors.sh
pkill -f HA_Scrape &> /dev/null
HA_Scrape.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

from bs4 import BeautifulSoup
from urllib.request import urlopen
import paho.mqtt.client as mqtt
import time
from threading import Thread

import secrets

MQTT_Host = secrets.MQTT_Host
MQTT_Port = secrets.MQTT_Port
MQTT_User = secrets.MQTT_User
MQTT_Password = secrets.MQTT_Password

client = mqtt.Client("HA_Scraper") # must be unique on MQTT network
client.username_pw_set(str(MQTT_User),str(MQTT_Password))
client.connect(MQTT_Host, port=MQTT_Port, keepalive=60)
client.loop_start()



class Radio:

	# Initializer / Instance Attributes
	def __init__(self, name, url, pic, pic_sel, pic_att, artist, artist_sel, artist_att, track, track_sel, track_att):
		self.name = name
		self.url = url
		self.pic = pic
		self.pic_sel = pic_sel
		self.pic_att = pic_att
		self.artist = artist
		self.artist_sel = artist_sel
		self.artist_att = artist_att
		self.track = track
		self.track_sel = track_sel
		self.track_att = track_att



class Podcast:

	# Initializer / Instance Attributes
	def __init__(self, name, url, track, track_sel, track_att, mp3_url, mp3_sel, mp3_att):
		self.name = name
		self.url = url
		self.track = track
		self.track_sel = track_sel
		self.track_att = track_att
		self.mp3_url = mp3_url
		self.mp3_sel = mp3_sel
		self.mp3_att = mp3_att


RTL2 = Radio("RTL2", "https://www.6play.fr/rtl2/quel-est-ce-titre", "", ".ecfper-2", "src", "", ".ecfper-6", "", "", ".ecfper-5", "")
Absolute_Radio_CR = Radio("Absolute_Radio_CR", "https://planetradio.co.uk/absolute-radio-60s/player/", "", ".station-cards .station-card:nth-of-type(2) a .main-img", "style", "", ".station-cards .station-card:nth-of-type(2) a .text-wrapper .text .artist", "", "", ".station-cards .station-card:nth-of-type(2) a .text-wrapper .text .track", "")
Absolute_Radio = Radio("Absolute_Radio", "https://planetradio.co.uk/absolute-radio-60s/player/", "", ".station-cards .station-card:nth-of-type(1) a .main-img", "style", "", ".station-cards .station-card:nth-of-type(1) a .text-wrapper .text .artist", "", "", ".station-cards .station-card:nth-of-type(1) a .text-wrapper .text .track", "")
IoT_Podcast = Podcast("IoT Podcast", "https://iotpodcast.com/feed/", "", "item:nth-of-type(1) title", "", "","enclosure:nth-of-type(1)", "url")
Hass_Podcast = Podcast("Hass Podcast", "https://hasspodcast.io/feed/podcast", "", "item:nth-of-type(1) title", "", "","enclosure:nth-of-type(1)", "url")
Chill = Radio("Chill", "https://www.smoothradio.com/chill/radio/playlist/", "", ".js-lazy", "data-src", "", ".now-playing__text-content__details__artist", "", "", ".now-playing__text-content__details__track", "")




def bs_get_value_radio(radio):
	content = urlopen(radio.url).read()

	try:
		raw_data = BeautifulSoup(content,"html.parser")
	except Exception as e:
		print("%s Unable to get BS from URL" % e)
	try:
		if(radio.pic != raw_data.select(radio.pic_sel)[0][radio.pic_att]):
			radio.pic = raw_data.select(radio.pic_sel)[0][radio.pic_att].replace("background-image:url(", "").replace(")", "")
			client.publish("RadioStream/"+radio.name+"/pic_url",radio.pic.encode('ascii'), qos=0, retain=True)

	except Exception as e:
		print ("Can't get "+radio.name+" Image")
	try:
		if (radio.artist_att):
			if(radio.artist != raw_data.select(radio.artist_sel)[0][radio.artist_att]):
				radio.artist = raw_data.select(radio.artist_sel)[0][radio.artist_att]
				client.publish("RadioStream/"+radio.name+"/artist",radio.artist, qos=0, retain=True)
		else:
			if(radio.artist != raw_data.select(radio.artist_sel)[0].text.title()):
				radio.artist = raw_data.select(radio.artist_sel)[0].text.title().strip()
				client.publish("RadioStream/"+radio.name+"/artist",radio.artist, qos=0, retain=True)
	except Exception as e:
		print ("Can't get "+radio.name+" Artist")

	try:
		if (radio.track_att):
			if(radio.track != raw_data.select(radio.track_sel)[0][radio.track_att]):
				radio.track = raw_data.select(radio.track_sel)[0][radio.track_att]
				client.publish("RadioStream/"+radio.name+"/track",radio.track, qos=0, retain=True)
		else:
			if(radio.track != raw_data.select(radio.track_sel)[0].text.title()):
				radio.track = raw_data.select(radio.track_sel)[0].text.title().strip()
				client.publish("RadioStream/"+radio.name+"/track",radio.track, qos=0, retain=True)
	except Exception as e:
		print ("Can't get "+radio.name+" Track")

def bs_get_value_podcast(podcast):
	content = urlopen(podcast.url).read()

	try:
		raw_data = BeautifulSoup(content,"html.parser")
	except Exception as e:
		print("%s Unable to get BS from URL" % e)

	try:
		if (podcast.mp3_att):
			if(podcast.mp3_url != raw_data.select(podcast.mp3_sel)[0][podcast.mp3_att]):
				podcast.mp3_url = raw_data.select(podcast.mp3_sel)[0][podcast.mp3_att]
				client.publish("RadioStream/"+podcast.name+"/mp3_url",podcast.mp3_url, qos=0, retain=True)
		else:
			if(podcast.mp3_url != raw_data.select(podcast.mp3_sel)[0].text.title()):
				podcast.mp3_url = raw_data.select(podcast.mp3_sel)[0].text.title().strip()
				client.publish("RadioStream/"+podcast.name+"/mp3_url",podcast.mp3_url, qos=0, retain=True)
	except Exception as e:
		print ("Can't get "+podcast.name+" MP3 URL")

	try:
		if (podcast.track_att):
			if(podcast.track != raw_data.select(podcast.track_sel)[0][podcast.track_att]):
				podcast.track = raw_data.select(podcast.track_sel)[0][podcast.track_att]
				client.publish("RadioStream/"+podcast.name+"/track",podcast.track, qos=0, retain=True)
		else:
			if(podcast.track != raw_data.select(podcast.track_sel)[0].text.title()):
				podcast.track = raw_data.select(podcast.track_sel)[0].text.title().strip()
				client.publish("RadioStream/"+podcast.name+"/track",podcast.track, qos=0, retain=True)
	except Exception as e:
		print ("Can't get "+podcast.name+" Track")

Refresh_Timer = 0
while(True):

	Thread(target=bs_get_value_radio, args=[RTL2]).start()
	Thread(target=bs_get_value_radio, args=[Absolute_Radio_CR]).start()
	Thread(target=bs_get_value_radio, args=[Absolute_Radio]).start()
	Thread(target=bs_get_value_podcast, args=[IoT_Podcast]).start()
	if(Refresh_Timer == 240):
		Thread(target=bs_get_value_podcast, args=[Hass_Podcast]).start()
		Refresh_Timer = 0
	Thread(target=bs_get_value_radio, args=[Chill]).start()
	time.sleep(15)
	Refresh_Timer = Refresh_Timer + 1

Lovelace Card
  - type: custom:vertical-stack-in-card
    cards:
    - type: picture-glance
      camera_image: camera.chromecast_radio_pic
      entities:
        - entity: input_select.chromecast_radio_station
        - entity: input_text.custom_station
        - entity: input_select.chromecast_radio_speakers
        - entity: switch.chromecast_radio_vol_down
        - entity: switch.chromecast_radio_mute
        - entity: switch.chromecast_radio_vol_up
        - entity: switch.chromecast_radio_stop
        - entity: switch.chromecast_radio_play
    - type: conditional
      conditions:
        - entity: binary_sensor.radio_is_streaming
          state: "on"
      card:
        type: entities
        show_header_toggle: false
        entities:
          - entity: sensor.stream_artist
            name: Artist
            icon: mdi:account
          - entity: sensor.stream_track
            name: Track
            icon: mdi:disc

I think that’s everything…

Hi.
I have a problem with your exemple:

Error running command: `/config/script/stop_radiostream_sensors.sh`, return code: 1
0:00:09 – shell_command (ERROR) - message first occurred at 0:00:05 and shows up 2 times
Log Details (ERROR)
Logger: homeassistant.components.shell_command
Source: /usr/src/homeassistant/homeassistant/components/shell_command/__init__.py:97
Integration: shell_command (documentation, issues)
First occurred: 23:49:58 (2 occurrences)
Last logged: 23:50:03

Error running command: `/config/script/stop_radiostream_sensors.sh`, return code: 1
Error running command: `/config/script/start_radiostream_sensors.sh`, return code: 1
NoneType: None

Could you help me?

I have not mentioned it but you need to make sure the bash scripts are set to be executables
sudo chmod +x [filename]