Unfortunately picture entity cards often start showing no stream but the broken image icon.
If I refresh dashboard for up to 10 times it shows the streams as expected
Here is the dashboard code:
views:
- title: Kameras
type: custom:grid-layout
layout:
grid-template-columns: 50% 50%
grid-template-rows: auto auto
grid-template-areas: |
"a b"
"c d"
cards:
- type: vertical-stack
view_layout:
grid-area: a
cards:
- show_state: false
show_name: false
camera_view: live
type: picture-entity
entity: camera.cam1
tap_action:
action: none
hold_action:
action: none
- type: entities
entities:
- entity: binary_sensor.blue_iris_kamera_01_eingang
type: custom:template-entity-row
name: Person
state: '{{ "Erkannt" if is_state(config.entity, "on") else "Keine" }}'
icon: >-
{{ "mdi:motion-sensor" if is_state(config.entity, "on") else
"mdi:motion-sensor-off" }}
- type: vertical-stack
view_layout:
grid-area: b
cards:
- show_state: false
show_name: false
camera_view: live
type: picture-entity
entity: camera.cam2
tap_action:
action: none
hold_action:
action: none
- type: entities
entities:
- entity: binary_sensor.blue_iris_kamera_02_terrasse
type: custom:template-entity-row
name: Person
state: '{{ "Erkannt" if is_state(config.entity, "on") else "Keine" }}'
icon: >-
{{ "mdi:motion-sensor" if is_state(config.entity, "on") else
"mdi:motion-sensor-off" }}
- type: vertical-stack
view_layout:
grid-area: c
cards:
- show_state: false
show_name: false
camera_view: live
type: picture-entity
entity: camera.cam3
tap_action:
action: none
hold_action:
action: none
- type: entities
entities:
- entity: binary_sensor.blue_iris_kamera_03_garten
type: custom:template-entity-row
name: Person
state: '{{ "Erkannt" if is_state(config.entity, "on") else "Keine" }}'
icon: >-
{{ "mdi:motion-sensor" if is_state(config.entity, "on") else
"mdi:motion-sensor-off" }}
type: masonry
So my idea is to auto refresh dashboard or even better reload images up to 10 times until the streams are visible.
Made some investigations and came up with a solution from Dumitru Glavan that can be inspected here: https://github.com/doomhz/jQuery-Image-Reloader/tree/master
After modifying the code for Home Assistant compatibility, I just need to add this HTML code in the <body></body> section of the dashboard:
<link href="https://ha.hoehn.nl/local/image_reloader.css" rel="stylesheet" type="text/css" media="screen" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script type="text/javascript" src="https://ha.hoehn.nl/local/jquery.imageReloader.js"></script>
<script type="text/javascript">
if (window.jQuery) {
$("img").addClass("slow-images");
$(".slow-images").imageReloader();
} else console.log("jQuery not available!");
</script>
Please try out this full HTML sample page:
<html>
<head>
<title>jQuery Image Reloader</title>
</head>
<body>
<h1>jQuery Image Reloader</h1>
<p>Below are two images. The first one is non-existent. The browser tries to load them both, but it fails. The Image Reloader plugin retries to load the non-existent image 10 times by default. In case that the image could not be loaded, it displays the browser's default broken image with an alt attribute.</p>
<img src="http://dumitruglavan.com/non_existent_image.jpg" alt="Image not loaded!" width="155" height="200">
<img src="https://ha.hoehn.nl/local/Portrait_Manfred_Hoehn_2022.jpg" width="155" height="200">
<p><br>This plugin is effective when you load images from a cloud (i.e. Amazon S3) and the CDN has a delay until the image is accessible. The browser will display a broken image icon instead and won't retry to reload it. jQuery Image Reloader will take care of that.</p>
<h2>Plugin code</h2>
<p>The only code you need to activate the plugin is this:</p>
<code>
$(".slow-images").imageReloader();
</code>
<h2>Options:</h2>
<dl>
<dt><b>loadingClass</b>: "loading-image"</dt>
<dd>
The plugin hides the original image until it's successfully loaded and replaces it with a DIV that will take this CSS class.
</dd>
<dt><b>reloadTime</b>: 1500</dt>
<dd>
Set up the time between the reload attempts.
</dd>
<dt><b>maxTries</b>: 10</dt>
<dd>
Set up how many reload attempts should be made until the broken icon is displayed.
</dd>
</dl>
<link href="https://ha.hoehn.nl/local/image_reloader.css" rel="stylesheet" type="text/css" media="screen" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script type="text/javascript" src="https://ha.hoehn.nl/local/jquery.imageReloader.js"></script>
<script type="text/javascript">
if (window.jQuery) {
$("img").addClass("slow-images");
$(".slow-images").imageReloader();
} else console.log("jQuery not available!");
</script>
</body>
</html>
How can this be achieved elegantly?
As far as I read documentation and community content themes/skins could be a suitable route to go.
What I couldn’t find is how and from where I can copy the default theme and how exactly to insert body HTML code.
Another question is if themes and skins are synonyms?
Second approach I figured out is to have custom JavaScript code in Home Assistant but I don’t know how to determine when to inject HTML code and how to hook with DOM parsing phases.
A third approach could be to create a custom card or custom picture entity card to inject HTML body code.
What is your experience or opinion and what would be the best way to go?