🖼️ WallPanel Addon - Wall panel mode for your Home Assistant Dashboards

I’ve had fair luck with it for crafting automations, no dashboards.

I’m trying to get the clock/weather to move around on the screen, but the only way it works is that the clock moves diagonally down to the right out of the picture and then nothing else happens. I have these settings for just this. info_animation_duration_x: 25
info_animation_duration_y: 15
info_animation_timing_function_x: ease-in-out
info_animation_timing_function_y: ease-in-out
info_move_pattern: corners
info_move_interval: 10
info_move_fade_duration: 2
info_update_interval: 30

I have a new dashboard with just a wall panel configuration. It is pointed to a samba share media source through home assistant. I have attempted to configure it to exclude any .heic files, but it still tries to load them occasionally and errors out. It is totally possible it’s a misconfiguration, as I’m new to wallpanel.

I’ve tried .heic$, \.heic$, .HEIC$, and \.HEIC$ to no effect. I’ve also tried it with the older image_excludes property.

Can anyone help? It shows an error and a black screen whenever it randomly chooses an heic file :frowning:

views:
  - title: Home
wallpanel:
  enabled: true
  hide_toolbar: false
  hide_sidebar: true
  fullscreen: false
  idle_time: 3
  image_url: media-source://media_source/local/MobilePhotos
  display_time: 8
  media_order: random
  screensaver_entity: input_boolean.screensaver
  media_list_update_interval: 3600
  debug: false
  exclude_filenames:
    - \\.heic$
    - \\.HEIC$
  exclude_media_types:
    - video
  image_fit_landscape: contain
  image_fit_portrait: contain

Hello. This is the Wall Panel I made. The cards pop up when music plays or the vacuum cleaner cleans. Maybe someone else might find it useful.

wallpanel:
  enabled: true
  hide_sidebar: false
  hide_toolbar: false
  fullscreen: true
  idle_time: 5
  image_url: media-source://media_source/local/ocean
  cards:
    - type: picture-elements
      wp_style:
        width: 400px
        grid-row: 1
        grid-column: 4
      elements:
        - type: image
          entity: select.vacuum_lamp
          state_image:
            'on': /local/imades/vacuumanim.gif
            'off': /local/imades/vacuum.png
          style:
            left: 50%
            top: 50%
            width: 70%
        - type: state-label
          entity: sensor.datchik_t_h_temperature
          style:
            left: 9%
            top: 10%
            transform: scale(2,2)
      image: /local/images/vacuum_lamp.png
      entity: cover.blinds_curtain
      card_mod:
        style: >
          ha-card {

          background-color: rgba(0, 0, 0, 0); border: solid rgba(0, 0,0,0);

          display: {% if is_state('select.vacuum_lamp', 'idle') or

          is_state('select.vacuum_lamp', 'off') %} none {% else %} block {%
          endif%};

          }
    - type: custom:mediocre-massive-media-player-card
      entity_id: media_player.kolonka
      mode: card
      action: {}
      options:
        always_show_power_button: true
        use_volume_up_down_for_step_buttons: true
      card_mod:
        style: |
          ha-card {

            display: {% if is_state('media_player.kolonka_2', 'idle') or
            is_state('media_player.kolonka_2', 'off') %} none {% else %} block {% endif
            %};

            background: url('/local/radio/music.jpg');

            background-color: #30254f; border: solid 2px white; box-shadow: none;
            border: solid 3px white; box-shadow: none;

            align-items: center;

            j ustify-content: center;

            height: 100%;

            overflow: hidden;   

            --accent-color: pink;

            --primary-color: white;

            --secondary-text-color: white;

            --secondary-background-color: pink;

           }
    - type: custom:digital-clock
      timeFormat: HH:mm
      dateFormat: cccc, d LLLL
      card_mod:
        style: |
          ha-card {
            display: {% if is_state('media_player.kolonka_2', 'idle') or
            is_state('media_player.kolonka_2', 'off') %} none {% else %} block {% endif%};
            position: absolute;
            z-index: 1;
            text-align: left !important;
            background-color: transparent !important;
            border: none !important;
            padding-left: 1200px !important;
            padding-top: 20px !important;
          }
          .first-line {
            font-size: 100px !important;
            letter-spacing: -5px;
            font-weight: 500;
            font-family: "Roboto", sans-serif;
            color: #FFFFFF;
            text-shadow: 5px 5px 5px #000000;
          }
          .second-line {
            font-size: 60px !important;
            font-weight: 600;
            font-family: "Roboto", sans-serif;
            color: #FFFFFF;
            text-shadow: 5px 5px 5px #000000;
          }
    - type: custom:digital-clock
      wp_style:
        width: 400px
        grid-row: 1
        grid-column: 2
      timeFormat: HH:mm
      dateFormat: cccc, d LLLL
      card_mod:
        style: |
          ha-card {
            position: absolute;
            z-index: 1;
            text-align: left !important;
            background-color: transparent !important;
            border: none !important;
            padding-left: 600px !important;
            padding-top: 800px !important;
          }
          .first-line {
            font-size: 100px !important;
            letter-spacing: -5px;
            font-weight: 500;
            font-family: "Roboto", sans-serif;
            color: #FFFFFF;
            text-shadow: 5px 5px 5px #000000;
          }
          .second-line {
            font-size: 60px !important;
            font-weight: 600;
            font-family: "Roboto", sans-serif;
            color: #FFFFFF;
            text-shadow: 5px 5px 5px #000000;
          }
      view_layout:
        grid-area: photo

Hi,

I’m struggling to get the screensaver working with a local media source. After several attempts with Synology PhotoStation, I’ve now created an immich server in Docker. I’ve now successfully integrated the immich integration in Home Assistant. So I know the immich API is working. I’m currently getting the error message below, someone any tips?

Wallpanel error {“0”:“immich api processing failed:”,“1”:{}}

Immich version 2.4.0

code:

wallpanel:
  enabled: true
  hide_toolbar: false
  hide_sidebar: false
  fullscreen: false
  debug: true
  idle_time: 10
  black_screen_after_time: 600
  media_list_update_interval: 60
  show_image_info: true
  image_url: immich+http://192.168.1.3:2283/api
  immich_api_key: XXXXXXXXXXXXXX
  immich_shared_albums: true
  immich_album_names:
    - Wallpanel
  immich_resolution: preview

I have Synology working with the following yaml:

wallpanel:
  enabled: true
  hide_toolbar: false
  hide_sidebar: true
  fullscreen: true
  idle_time: 30
  image_url: media-source://synology_dsm/##############/10_
  camera_motion_detection_enabled: true

I’m using the following configuration to run the WallPanel screensaver every 40 seconds:

wallpanel:
  enabled: true
  profiles:
    device.tablet:
      enabled: true
  hide_toolbar: false
  hide_sidebar: false
  fullscreen: false
  idle_time: 40
  display_time: 10
  screensaver_entity: input_boolean.screensaver
  image_url: /

I also created an input_boolean called input_boolean.screensaver and assigned it to the screensaver_entity option.
This allows me to manually start or stop the screensaver by turning the boolean on or off.

However, when I turn off input_boolean.screensaver, the screensaver still starts again automatically after 40 seconds, because idle_time is set to 40.

What I would like instead is:

  • To be able to disable the screensaver completely
  • And only enable it when I explicitly turn on input_boolean.screensaver

In other words, I don’t want the screensaver to start automatically based on idle_time when the boolean is off.

UPDATE:
I think I managed to fix this issue by defining two separate profiles and a script, which is called upon clicking a card on the dashboard.

Does anyone here know how to retrieve images from album X in Immich?

For camera motion detection the docs say An HTTPS connection to the Home Assistant is required to enable access to the camera. Is there any more information on how to enable an HTTPS connection?

Hi, this is a great add-on, thanks. I’m trying to configure a Lightroom web gallery but can’t get the web gallery url to work in WallPanel. I’d really appreciate some help with this if anyone can shed some light. I’m not a programmer / coder so trying to parse the url / feed to get it to work in WallPanel is a bit beyond me.

Here’t a test gallery in Lightroom that I was trying to get to work with WallPanel: https://lightroom.adobe.com/shares/dbf880cd2e4840b5923baa9fe36d6522

In WallPanel I get a “Failed to update media” error message.

Hello @j-a-n

I'm trying to use a camera entity for the background of the screensaver images. That would display images from Google Photos. The integration is called Album slideshow. The WallPanel Addon works with another camera but not this one. Do you have a suggestion how I could make it working?

I referenced the custom camera entity the following way:
media-entity-video://camera.album_slideshow_slides

Could you maybe help why the custom google photos camera entity doesn't work there?

Thanks in advance for your help.

@attilan
Are you trying to achieve something like this?

Did you try like this:

image_url: media-entity-image://camera.YOUR_ENTITY_NAME

This helped @benjakigor. I used "media-entity-video" but it works with "media-entity-image"
Thank you very much for the recommendation!

No bother at all :grinning_face: I'm using as I said for my wall tablet screensaver pulling google photos album. It's very handy to add pictures my family want to put on screensaver

can you get it to auto refresh? 'I'm constantly standing in fromt of my fridge awaiting it loading

Is it possible to have a You Tube stream as the screensaver instead of pictures?

the answer is yes. I wish i could take credit but Claude has a lot to do in this process I just needed to tell the bot in what direction I wanted to go. I am not a specialist just an enthousiastic amateur. If you don’t understand the following explanation, I won’t be much help - I had to go through many trials and errors before it worked, it took some times.

1. Create the helper page

  • Get to the folder. Home Assistant serves anything in the www folder of its config directory at the address /local/…. You can reach that folder with the File editor or Studio Code Server add-on, or over the network with the Samba add-on (\\homeassistant.local\config\www).
  • Create the file. Make a screensaver folder inside www, and in it a file named youtube.html with this content:

html

<!doctype html>
<html >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>YouTube screensaver</title>
<style>
  html, body { margin: 0; height: 100%; background: #000; overflow: hidden; }
  iframe { position: fixed; inset: 0; width: 100vw; height: 100vh; border: 0; }
  #msg { color: #888; font: 2vh sans-serif; position: fixed; inset: 0; display: grid; place-items: center; }
</style>
</head>
<body>
<div id="msg"></div>
<script>
  // Usage: /local/screensaver/youtube.html?v=VIDEO_ID[&speed=0.5]
  //   v      YouTube video ID (the part after watch?v= or youtu.be/)
  //   speed  playback speed: 0.25, 0.5, 0.75, 1 (default), 1.25, 1.5, 1.75, 2
  // Home Assistant sends "Referrer-Policy: no-referrer" on every page, and YouTube
  // refuses embeds without a referrer (error 153). The referrerpolicy attribute on
  // this iframe overrides that for the YouTube request only.
  var q = new URLSearchParams(location.search);
  var id = q.get('v') || '';
  var speed = parseFloat(q.get('speed') || '1');
  if (!(speed >= 0.25 && speed <= 2)) speed = 1;
  window.__ytRate = null; // last playback rate reported by the player (for debugging)

  if (!/^[A-Za-z0-9_-]{6,20}$/.test(id)) {
    document.getElementById('msg').textContent = 'Missing or invalid ?v=VIDEO_ID';
  } else {
    var params = new URLSearchParams({
      autoplay: '1', mute: '1', loop: '1', playlist: id, controls: '0',
      rel: '0', playsinline: '1', iv_load_policy: '3', disablekb: '1', fs: '0',
      enablejsapi: '1', origin: location.origin
    });
    var f = document.createElement('iframe');
    f.src = 'https://www.youtube.com/embed/' + id + '?' + params.toString();
    f.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin');
    f.setAttribute('allow', 'autoplay; encrypted-media; picture-in-picture');
    f.setAttribute('title', 'YouTube');
    document.body.appendChild(f);

    var send = function (msg) {
      try { f.contentWindow.postMessage(JSON.stringify(msg), 'https://www.youtube.com'); } catch (e) {}
    };
    // Track what the player reports, so the speed can be re-applied if it resets
    // (after an ad, a loop back to the start, or a reload).
    window.addEventListener('message', function (ev) {
      if (ev.origin !== 'https://www.youtube.com') return;
      try {
        var d = typeof ev.data === 'string' ? JSON.parse(ev.data) : ev.data;
        if (d && d.info && typeof d.info.playbackRate === 'number') window.__ytRate = d.info.playbackRate;
      } catch (e) {}
    });
    f.addEventListener('load', function () { send({ event: 'listening', id: 'wp' }); });
    if (speed !== 1) {
      setInterval(function () {
        send({ event: 'listening', id: 'wp' });
        if (window.__ytRate !== speed) send({ event: 'command', func: 'setPlaybackRate', args: [speed] });
      }, 2000);
    }
  }
</script>
</body>
</html>

Now it time set up the source of your video in the Raw Configuraion Editor :
the source of your video become the following line : (in my example i used an halloween theme ambiance video) / I don’t know yet how it handles commercials.

image_url: iframe+/local/screensaver/youtube.html?v=F-yvdn3aWFY
video_volume: 0
video_loop: true
display_time: 3600
image_animation_ken_burns: false
iframe_interaction: false
  • Save. Saving here applies immediately. I always restart anyway.

3. Test

  • Test the page alone first. Open http://homeassistant.local:8123/local/screensaver/youtube.html?v=F-yvdn3aWFY in a browser. If the video plays there, the helper page works

in my example I played with playback speed I am sure there might be other options you can play with as well I did not explore yet.

Good Luck
.