[SOLVED] How can I get my dashboard to refresh automatically, instead of showing the "Refresh?" prompt?

alias: Refresh iPad when Lovelace is updated
description: Ensure the view refreshes when I make changes to a Lovelace dashboard
trigger:
  - platform: event
    event_type: lovelace_updated
condition: []
action:
  - service: browser_mod.refresh
    data: {}
    target:
      device_id: 7c29959dc26a200be0d4811f9eaa49d6
mode: single

Dude. This just changed my life. Thank you! Thank you!

3 Likes

Glad to be of service. I had enough of having to run around the home to reload panels by hand. Push save, receive bacon. That is how things ought to be.

2 Likes

Wellā€¦yes and no. When i make (small) modifications of my lovelaces i open a page and ā€œleave itā€ as backup. So if i do anything wrong i have a previous version without making a copy of lovelace before. With auto-refresh iā€™d loose that. Thus saidā€¦i miss any sort of history hereā€¦ or should i say CTRL+Zā€¦
Yeah, i knowā€¦ it IS available if i would edit in yaml mode. But i rather edit single card at a time, because itā€™s less code, more clear and easier to edit than whole yaml.

Alsoā€¦auto refresh refreshes all cards and all views, while manual press on ā€œrefreshā€ refreshes only that page - itā€™s somewhat quicker.
I just made shortcuts for all my tablets so i donā€™t have auto refresh, but i can refresh them remotely when iā€™m done or when itā€™s needed.

I like the idea, and i think it can be even more simple:

// Modified ideas from: https://community.home-assistant.io/t/solved-how-can-i-get-my-dashboard-to-refresh-automatically-instead-of-showing-the-refresh-prompt/357842/29
const ReloadDashboardCheckInterval = 30000; // ms

const ReloadDashboardStrings = [
  "Refresh",
  "Obnovit"
];

function refreshOnLovelaceChange()
{
    const ha = document.querySelector("home-assistant")
    if (!ha || !ha.shadowRoot) return
    const nm = ha.shadowRoot.querySelector("notification-manager")
    if (!nm || !nm.shadowRoot) return
    const ht = nm.shadowRoot.querySelector("ha-toast")
    if (!ht || !ht.shadowRoot || ht.style.display === "none") return
    const label = ht.children[0].__label
    if (!label) return

    const result = ReloadDashboardStrings.findIndex(item => label === item)
    
    if (result >= 0)
    {
        ht.children[0].click()
    }
}

setInterval(refreshOnLovelaceChange, ReloadDashboardCheckInterval);
1 Like

I like your idea! For all of us just starting, where does this yaml code go? is this in the confuguration.yaml?

It would have to go as a custom JS resource.

OK, think I will leave this until I get much better at HA. Still learning everything. Got lots to figure out as it is.

I had the same requirement for a wall-mounted tablet. I wanted to avoid the approach of string matching so Iā€™ve patched the code that handles the change event.

I have the following javascript in a custom module that seems to do what I need. Youā€™re welcome to copy-paste if itā€™s any use.

  // Patch the _lovelaceChanged handler in LovelacePanel to automatically
  // refresh, instead of showing a message
  const LovelacePanel = customElements.get("ha-panel-lovelace");
  LovelacePanel.prototype._lovelaceChanged = function(){
    // Log the reload happening
    console.log("Lovelace changed, automatically reload", this);

    // Logic copied from the origional _lovelaceChanged function
    if (this._ignoreNextUpdateEvent) {
      this._ignoreNextUpdateEvent = false;
      return;
    }
    if (!this.isConnected) {
      this._fetchConfigOnConnect = true;
      return;
    }

    // Show a message for 1 second to announce the automatic reload
    const notificationEvent = new Event("hass-notification", {
      bubbles: true,
      composed: true,
      cancelable: false
    });
    notificationEvent.detail = {
      message: "Automatically reloading config...",
      duration: 1000,
      dismissable: true
    };
    this.dispatchEvent(notificationEvent);

    // Do the reload after one second
    setTimeout(() => this._fetchConfig(false), 1000);
  };

  // log that the code has run
  console.log("āœ… setup automatically reloading");

UPDATE: Nevermind - it did work!

@zapthedingbat

Hi-

Iā€™m a bit confused how to use this. I added it a a custom JS resource under the dashboard page. What do I need to do for this to work?

Do I need to reference it inside the dashboard somewhere?

Thanks

M

How did you do it?

did you create a new file under /www/custom.js and add the below code?

This was a brilliant starting point! Since I use FullyKiosk, I amended the example to reload the start page on the kiosk.

This is YAML for an automation. You can also create the same automation manually in the UI using a Manual Event trigger for event type ā€œlovelace_updatedā€ and a Service Call action to press the load start url ā€œbuttonā€ entity registered by the FullyKiosk integration.

alias: Reload kiosk when lovelace is updated
description: ""
trigger:
  - platform: event
    event_type: lovelace_updated
condition: []
action:
  - service: button.press
    data: {}
    target:
      entity_id: button.dash_kiosk_load_start_url
mode: single
2 Likes

Not working for me. Not sure what Iā€™m missing. I have this snippet in a file under config/www/custom.js.

Then I have the following in my config:

frontend:
  extra_module_url:
    - /local/custom.js

Finally, to test Iā€™m opening up my dashboard in two tabs. I make a change in one tab and save it then go back to the other tab. I see the usual ā€œYour dashboard was updated. Refresh to see changes?ā€ message, but it doesnā€™t auto refresh. Whatā€™s the deal?

What if I just want to refresh the dashboard every hour?

Try this:

frontend:                                                                                                                   
  themes: !include_dir_merge_named themes                                                                                   
  extra_js_url_es5:                                                                                                         
    - /local/custom.js                                                                                                      
  extra_module_url:                                                                                                         
    - /local/custom.js  

Then open browser console (Inspector), check for errors (syntax errors may stop loading custom.js silently when loaded via extra_module_url). Add console.log('custom.js loaded'); on the beginning of custom.js file.

Edit JS, remove the last check whether notification is present and contains expected information and just do the reload. Change value in setInterval(refreshOnLovelaceChange, 500); accordingly (3600 * 1000).

My version of custom.js being a mix of some ideas from this thread, working as of 2024.02:

console.log("custom.js loaded!");

function refreshOnLovelaceChange() { 
    // uncomment for Kiosk mode ('kiosk' param must be in the url, tho)
    //var urlSearchParams = new URLSearchParams(window.location.search);
    //if (urlSearchParams.get('kiosk') !== 'true') return;

    var ha = document.querySelector("home-assistant");
    if (!ha || !ha.shadowRoot) return;
    var nm = ha.shadowRoot.querySelector('notification-manager');
    if (!nm || !nm.shadowRoot) return;
    var haToast = nm.shadowRoot.querySelector('ha-toast');
    if (!haToast) return;

    // uncomment to refresh for a given user name only (name as seen in UI)
    /*var userNameToRefresh = 'user-for-dashboard';
    try {
        var userName = ha.shadowRoot.querySelector('home-assistant-main').shadowRoot.
            querySelector('ha-drawer').querySelector('ha-sidebar').shadowRoot.
            querySelector('a[class*=profile]').querySelector('paper-icon-item').
            querySelector('span[class=item-text]').textContent.trim();
           if (userName !== userNameToRefresh) {                                                                                                                              
               return;                                                                                                                                                        
           } 
    } catch (error) {                                                                                                                                                  
        //console.error(error);                                                                                                                                        
    }*/                                                                                                                                                                 

    if (haToast.opened && haToast.text.includes('dashboard was updated')) {
        console.log("Refreshing page...");
        try {
            haToast.querySelector("mwc-button").shadowRoot.querySelector("#button > span.mdc-button__label").click();
        } catch (error) {
            console.error(error);
            console.log("Going to reload whole page instead...");
            location.reload();
        }
    }
}
setInterval(refreshOnLovelaceChange, 1000); 

If you update the script, then you need to clear browser cache (reload hard). It also works in the Companion app (you will need to clear its data to pick up the changes - you will need to login and configure the app tho).

Update for 2024.4.2 down there: [SOLVED] How can I get my dashboard to refresh automatically, instead of showing the "Refresh?" prompt? - #66 by psko

1 Like

On my office computer I have a screen that has a dashboard that shows my security cameras.
I installed that page as an app in Edge and set it to auto-refresh once an hour. There is an add-on for that.
On a pc reboot, it will automatically load that dashboard for me also.
Not much good for an android tablet thoughā€¦

Solution to refresh Raspberry Pi 400 running chromium kiosk with 15" uPerfect touch screen Display. Via Node Red and SSH command to XDOTOOL.

CHROMIUM KIOSK Mark Watt Tech Tutorial.

uPerfect unify y Vertical Monitor

My Home Assistant Server runs on a Home Assistant Blue. My Raspberry pi400 utilises the full screen kiosk (above) to log into the server via Nabu Casa.

  1. INSTALL XDOTOOL
  2. INSTALL NODE RED if you do not already have it installed.
  3. INSTALL node-red-contrib-ssh-v3 node in Node Red.

The flow is very simple, consists of an inject node that injects the SSH command via msg.payload, every 10 minutes. This is so my Ventusky weather map shows the latest data, running in iFrame.

Below is the setup for the inject node.

msg.payload is set to (string)

The full SSH command is: Insert your own username.

export XAUTHORITY=/home/INSERT USERNAME/.Xauthority; export DISPLAY=:0; xdotool key ctrl+r

The part of the above that completes the virtual key press of ctrl+r is xdotool key ctrl+r

I discovered this command works directly after my other attempts failed. See this website XDOTOOL fails. Error: Canā€™t open display: (null)
Failed creating new xdo instance

I set repeat interval to 10mins.

Setup for the SSH V3 node is as below.
Hostname: The IP address of your Raspberry Pi
Port: 22 (default setting)
Username: The username you use to log into your Pi
Password: The password you use to log into your Pi
Ssh: Leave this as the default grey text, the msg.payload from the inject node needs no other file path.

Works perfectly. Basically my Home Assistant Blue, running Node Red is sending a keyboard shortcut ctrl+r to my Pi 400 every 10 minutes.

xdotool works properly for you with Wayland/Wayfire (default on Raspberry OS Bookworm), because I had no luck with it.

I am using Debian GNU/Linux 12 (bookworm). I just checked raspi.config and I am running X11 Openbox window manager with X11 backend. I am unsure if you can set that and have your Pi run correctly?

See the below links for Wayland.
https://www.reddit.com/r/linuxquestions/comments/u5mxzi/xdotool_alternative_for_wayland/