Skip to content

Instantly share code, notes, and snippets.

@ciotlosm ciotlosm/Readme.md
Last active Aug 19, 2019

Embed
What would you like to do?
Kiosk mode for lovelace

Kiosk mode

Installation

Add kiosk.js file with the content below to your www folder in config.

Like any other custom script, use ui-lovelace.yaml resources section to reference the kiosk.js file.

Make sure you add kiosk somewhere in your URL. You can use it in the id of your view or in the query string.

Examples:

/lovelace/0?kiosk
views:
  - title: Kiosk
    icon: mdi:heart
    id: kiosk_alarm

Keep tabs

If you still want to keep the Lovelace tabs and hide everything else use add show_tabs in your URL as query string.

/lovelace/0?kiosk&show_tabs

Note

If this is your first file in www make sure you restart Home Assistant.

if (window.location.href.indexOf('kiosk') > 0)
setTimeout(function () {
try {
const root = document.querySelector('home-assistant').shadowRoot;
const main = root.querySelector('home-assistant-main').shadowRoot;
const drawer_layout = main.querySelector('app-drawer-layout');
const drawer = drawer_layout.querySelector('app-drawer');
drawer_sidebar = drawer.querySelector('ha-sidebar').shadowRoot;
const app_toolbar = drawer_sidebar.querySelector('app-toolbar');
const pages = drawer_layout.querySelector('partial-panel-resolver').shadowRoot;
const lovelace = pages.querySelector('ha-panel-lovelace').shadowRoot;
const huiroot = lovelace.querySelector('hui-root').shadowRoot;
const header = huiroot.querySelector('app-header');
const toolbar = huiroot.querySelector('app-toolbar');
if (window.location.href.indexOf('show_tabs') > 0) {
toolbar.style.display = 'none';
} else {
header.style.display = 'none';
}
app_toolbar.querySelector('paper-icon-button').click();
window.dispatchEvent(new Event('resize'));
}
catch (e) {
console.log(e);
}
}, 200);
resources:
- url: /local/kiosk.js
type: js
- url: /local/custom-lovelace/thermostat-card/thermostat-card.js?v=0.1
type: module
title: Lovelace Demo
views:
- title: Home
icon: mdi:heart
id: kiosk_thermostat
panel: true
cards:
- type: custom:thermostat-card
title: HVAC
entity: climate.hvac
@zvennis

This comment has been minimized.

Copy link

commented Dec 15, 2018

I use this one, and it is really great. After updating hassio to 0.84 (and use yaml mode), there is a new empty area between the tabs and the content. Anthing kiosk.js can do with this?
image

@brahmafear

This comment has been minimized.

Copy link

commented Dec 18, 2018

Same as @zvennis, After upgrade to 0.84 and enabling lovelace yaml mode, I get a white bar between tabs and view. (This is the white section in the screenshot below.
screen shot 2018-12-18 at 3 41 54 pm

@Galtwise

This comment has been minimized.

Copy link

commented Dec 19, 2018

Echoing the above, I get the white bar between the tabs and the webview now as well.

@MarkyMarc35

This comment has been minimized.

Copy link

commented Dec 19, 2018

I have the same issue, and the left menu bar is also visible.

@raystream

This comment has been minimized.

Copy link

commented Dec 21, 2018

that is because of hiding the top bar after loading the page.
the cards are on the same position as if you are not using kiosk mode.

the top padding of the content-container must be changed and the content-container moved higher.

my javascript knowledge is too bad to fix it.

@Zemoj

This comment has been minimized.

Copy link

commented Dec 22, 2018

EDIT
Figured out the issue, and condensed the query selectors a bit.

if (window.location.href.indexOf('kiosk') > 0)
    setTimeout(function () {
        try {
            const drawer_layout = document
                    .querySelector('home-assistant').shadowRoot
                    .querySelector('home-assistant-main').shadowRoot
                    .querySelector('app-drawer-layout');
            const huiroot = drawer_layout
                    .querySelector('partial-panel-resolver').shadowRoot
                    .querySelector('ha-panel-lovelace').shadowRoot
                    .querySelector('hui-root').shadowRoot;
            
            const header = huiroot.querySelector('app-header');
            const toolbar = huiroot.querySelector('app-toolbar');
            const button_menu = toolbar
                    .querySelector('ha-menu-button').shadowRoot;

            if (window.location.href.indexOf('show_tabs') > 0) {
                toolbar.style.display = 'none';
            } else {
                header.style.display = 'none';
            }
            button_menu.querySelector('paper-icon-button').click();
            window.dispatchEvent(new Event('resize'));
        }
        catch (e) {
            console.log(e);
        }
    }, 200);
@brahmafear

This comment has been minimized.

Copy link

commented Dec 23, 2018

@Zemoj
Thanks. New JS working for me after browser JS cache refresh.

@brahmafear

This comment has been minimized.

Copy link

commented Dec 24, 2018

One additional bug I'm seeing -- the sidebar seems to be hidden by calling .click() on paper-icon-button from the JS, but if sidebar is already hidden and page is reloaded, this causes sidebar to reappear. Is there any way to only click when sidebar is shown? or to hide sidebar in another form? My JS-fu isn't good enough to figure this out. Tried.

@jessylenne

This comment has been minimized.

Copy link

commented Dec 30, 2018

Hey,

I had a problem using a background-image on the view: Hidding the app-header made a blank line of 64px at the bottom of the page

I solved it by setting the minHeight at 100vh for the view component:

if (window.location.href.indexOf('kiosk') > 0) {
    setTimeout(function () {
        try {
            const root = document.querySelector('home-assistant').shadowRoot;
            const main = root.querySelector('home-assistant-main').shadowRoot;
            const drawer_layout = main.querySelector('app-drawer-layout');
            const drawer = drawer_layout.querySelector('app-drawer');
            drawer_sidebar = drawer.querySelector('ha-sidebar').shadowRoot;
            const app_toolbar = drawer_sidebar.querySelector('app-toolbar');
            const pages = drawer_layout.querySelector('partial-panel-resolver').shadowRoot;
            const lovelace = pages.querySelector('ha-panel-lovelace').shadowRoot;
            const huiroot = lovelace.querySelector('hui-root').shadowRoot;
            const view = huiroot.querySelector('.tabs-hidden');
            const header = huiroot.querySelector('app-header');
            const toolbar = huiroot.querySelector('app-toolbar');
            if (window.location.href.indexOf('show_tabs') > 0) {
                toolbar.style.display = 'none';
            } else {
                header.style.display = 'none';
                view.style.minHeight = "100vh";
            }
            app_toolbar.querySelector('paper-icon-button').click();
            window.dispatchEvent(new Event('resize'));
        }
        catch (e) {
            console.log(e);
        }
    }, 2000);
}
@Zemoj

This comment has been minimized.

Copy link

commented Dec 30, 2018

@brahmafear haha i was just thinking about this also.

Add this new variable:

const app_drawer = drawer_layout.querySelector('app-drawer');

Then enclose the click part:

if(app_drawer.hasAttribute("opened")){
    button_menu.querySelector('paper-icon-button').click();
}

You can see my full file here https://gist.github.com/Zemoj/d2893f6be8ac5b7c58541ff92eeea54b
I also extended the time because the tablet I'm using take a little longer to load the first page.

@lolouk44

This comment has been minimized.

Copy link

commented Jan 1, 2019

Thanks @Zemoj, that's perfect :)

@koying

This comment has been minimized.

Copy link

commented Jan 2, 2019

Alternative way to force the sidebar to hide:
drawer_layout.forceNarrow = true;

@lockyt

This comment has been minimized.

Copy link

commented Jan 5, 2019

@brahmafear how did you clear the JS cache?

@Tuncay-Ayhan

This comment has been minimized.

Copy link

commented Jan 8, 2019

@brahmafear how did you clear the JS cache?

Add this part
image

Then go to your Home Assistant website and hit CTRL+SHIFT+R

@blindcoppertop

This comment has been minimized.

Copy link

commented Jan 22, 2019

The kiosk mode looks great, however I was wondering if it was possible to automatically switch tabs every {x} seconds, I have created my own JS file to do this but the page reloads on each interval, and I cannot for the life of me workout how to do it correctly.

@gijbelsy

This comment has been minimized.

Copy link

commented Jan 30, 2019

Is there a possibility to request fullscreen?

@wendan20

This comment has been minimized.

Copy link

commented Jan 31, 2019

Hi, I am trying to get this to work. On my desktop it works fine! Looking very good and exactly what I want. A clean dashboard. On the Ipad however I cannot get it to work. The header from lovelace keeps coming back after a period of time. Looks like it happens on a refresh or something. Does some body have the same experience? Does somebody have some tips? Thanks!

@simpat1zq

This comment has been minimized.

Copy link

commented Jan 31, 2019

Hi, is there any way to add a refresh button in the top right corner? I have a kiosk set up and there's no easy way to refresh it other than turning the pi off and then on.

@wendan20

This comment has been minimized.

Copy link

commented Feb 3, 2019

view.style.minHeight = "100vh";

Hi Jesselenne, did you manage to get it right? I have the same problem with a background image. But when I add your line to the config or use your whole config, I get an empty bar on top. Hope to hear from you.

@krinehart

This comment has been minimized.

Copy link

commented Mar 2, 2019

This is amazing and exactly what I was looking for. Just wanted to say thank you for this!

@Sonic-Y3k

This comment has been minimized.

Copy link

commented Mar 10, 2019

view.style.minHeight = "100vh";

Hi Jesselenne, did you manage to get it right? I have the same problem with a background image. But when I add your line to the config or use your whole config, I get an empty bar on top. Hope to hear from you.

I fixed it by changing the minHeight for huiroot.querySelector('ha-app-layout').querySelector('#view').

if (window.location.href.indexOf('kiosk') > 0)
    setTimeout(function () {
        try {
            const drawer_layout = document
                    .querySelector('home-assistant').shadowRoot
                    .querySelector('home-assistant-main').shadowRoot
                    .querySelector('app-drawer-layout');
            const huiroot = drawer_layout
                    .querySelector('partial-panel-resolver').shadowRoot
                    .querySelector('ha-panel-lovelace').shadowRoot
                    .querySelector('hui-root').shadowRoot;

            const header = huiroot.querySelector('app-header');
            const toolbar = huiroot.querySelector('app-toolbar');
            const button_menu = toolbar.querySelector('ha-menu-button').shadowRoot;
            const app_drawer = drawer_layout.querySelector('app-drawer');

            if (window.location.href.indexOf('show_tabs') > 0) {
                toolbar.style.display = 'none';
            } else {
                header.style.display = 'none';
            }

            if(app_drawer.hasAttribute("opened")){
                button_menu.querySelector('paper-icon-button').click();
            }

            const app_layout = huiroot.querySelector('ha-app-layout').querySelector('#view')
            app_layout.style.minHeight = '100vh';

            window.dispatchEvent(new Event('resize'));
        }
        catch (e) {
            console.log(e);
        }
    }, 500);
@lolouk44

This comment has been minimized.

Copy link

commented Mar 22, 2019

Kiosk is not working for me on 0.90.1 anymore, used to work up until 0.89
Anyone else affected?
Console gives me this:
image

@killabeenl

This comment has been minimized.

Copy link

commented Mar 22, 2019

Kiosk is not working for me on 0.90.1 anymore, used to work up until 0.89
Anyone else affected?

Yes, same here since 0.90.0

@2xdehelft

This comment has been minimized.

Copy link

commented Mar 22, 2019

Yep same problem here on 0.90.0

@RyanRayNeff

This comment has been minimized.

Copy link

commented Mar 23, 2019

Same here, didn't notice until 90.1

@SirRene

This comment has been minimized.

Copy link

commented Mar 23, 2019

Same problem here since 0.90.0 :-(

@lolouk44

This comment has been minimized.

Copy link

commented Mar 23, 2019

Fixed it for the top bar at least. The menu drawer does not automatically hide

if (window.location.href.indexOf('kiosk') > 0)
    setTimeout(function () {
        try {
            const drawer_layout = document
                    .querySelector('home-assistant').shadowRoot
                    .querySelector('home-assistant-main').shadowRoot
                    .querySelector('app-drawer-layout');
            const huiroot = drawer_layout
                    .querySelector('partial-panel-resolver')
                    .querySelector('ha-panel-lovelace').shadowRoot
                    .querySelector('hui-root').shadowRoot;

            const header = huiroot.querySelector('app-header');
            const toolbar = huiroot.querySelector('app-toolbar');
            const button_menu = toolbar.querySelector('ha-menu-button').shadowRoot;
            const app_drawer = drawer_layout.querySelector('app-drawer');

            if (window.location.href.indexOf('show_tabs') > 0) {
                toolbar.style.display = 'none';
            } else {
                header.style.display = 'none';
            }

            if(app_drawer.hasAttribute("opened")){
                button_menu.querySelector('paper-icon-button').click();
            }

            const app_layout = huiroot.querySelector('ha-app-layout').querySelector('#view')
            app_layout.style.minHeight = '100vh';

            window.dispatchEvent(new Event('resize'));
        }
        catch (e) {
            console.log(e);
        }
    }, 500);
@RyanRayNeff

This comment has been minimized.

Copy link

commented Mar 23, 2019

Thanks for that! it's working as you said it would.

@nate922

This comment has been minimized.

Copy link

commented Mar 24, 2019

Hi guys, I can't seem to get this working under 0.90.
When I use "https://url:8123/lovelace/1?kiosk" - the header still shows.
Any pointers would be awesome - Thanks

I'm using lovelace editor:
/.storage/lovelace

{
"data": {
"config": {
"resources": [
{
"type": "js",
"url": "/local/kiosk.js",
"type": "js",
"url": "/local/mini-media-player-bundle.js?v=1.0.3"
}
],
"title": "Home",
"panel": "true",
"id": "kiosk",
"icon": "mdi:heart",
"views": [
(using the updated script - thanks for the update)

root@hassio:/config/www# ls -lt
total 328
-rwxr-xr-x 1 root root 1456 Mar 24 10:15 kiosk.js

cat kiosk.js

if (window.location.href.indexOf('kiosk') > 0)
setTimeout(function () {
try {
const drawer_layout = document
.querySelector('home-assistant').shadowRoot
.querySelector('home-assistant-main').shadowRoot
.querySelector('app-drawer-layout');
const huiroot = drawer_layout
.querySelector('partial-panel-resolver')
.querySelector('ha-panel-lovelace').shadowRoot
.querySelector('hui-root').shadowRoot;

        const header = huiroot.querySelector('app-header');
        const toolbar = huiroot.querySelector('app-toolbar');
        const button_menu = toolbar.querySelector('ha-menu-button').shadowRoot;
        const app_drawer = drawer_layout.querySelector('app-drawer');

        if (window.location.href.indexOf('show_tabs') > 0) {
            toolbar.style.display = 'none';
        } else {
            header.style.display = 'none';
        }

        if(app_drawer.hasAttribute("opened")){
            button_menu.querySelector('paper-icon-button').click();
        }

        const app_layout = huiroot.querySelector('ha-app-layout').querySelector('#view')
        app_layout.style.minHeight = '100vh';

        window.dispatchEvent(new Event('resize'));
    }
    catch (e) {
        console.log(e);
    }
}, 500);
@RyanRayNeff

This comment has been minimized.

Copy link

commented Mar 24, 2019

{
"data": {
"config": {
"resources": [
{
"type": "js",
"url": "/local/kiosk.js",
"type": "js",
"url": "/local/mini-media-player-bundle.js?v=1.0.3"
}
],

Have you tried using the raw config editor instead of editing the /.storage/lovelace file? Using yaml is much easier. To get to the raw config editor, click the three dots in the upper right corner, select "Configure UI" then you can click those three dots again, and you will see the option for "Raw config editor". It's essentially the same as /.storage/lovelace, but in a much more readable format. Editing this way at least rules out syntax errors.

@papperone

This comment has been minimized.

Copy link

commented Apr 13, 2019

I've the same problem, I edit the config via the "raw config editor" all cards/addons works perfectly but this one does nothing...
I tried any option in the URL but the menu is still showing, any clue or real working example to help me understand where's the issue?

@agrigo2s

This comment has been minimized.

Copy link

commented Apr 19, 2019

It didn't worked for me so i changed the Script like this:
I'm using Home Assistant 0.91.4

function removeHeader() {

    const root = document.querySelector('home-assistant').shadowRoot;
    const main = root.querySelector('home-assistant-main').shadowRoot;
    const drawer_layout = main.querySelector('app-drawer-layout');
    /*    const drawer = drawer_layout.querySelector('app-drawer');
        drawer_sidebar = drawer.querySelector('ha-sidebar').shadowRoot;
        const app_toolbar = drawer_sidebar.querySelector('app-toolbar');
        const pages = drawer_layout.querySelector('partial-panel-resolver').shadowRoot;*/
    const lovelace = drawer_layout.querySelector('ha-panel-lovelace').shadowRoot;
    const huiroot = lovelace.querySelector('hui-root').shadowRoot;
    const header = huiroot.querySelector('app-header');
    const toolbar = huiroot.querySelector('app-toolbar');
    if (window.location.href.indexOf('show_tabs') > 0) {
        toolbar.style.display = 'none';
    } else {
        header.style.display = 'none';
    }
    window.dispatchEvent(new Event('resize'));
}
removeHeader();
@fmonday

This comment has been minimized.

Copy link

commented Apr 19, 2019

@agrigo2s, is that code working for you on 0.91.4? Doesn't work for me

@agrigo2s

This comment has been minimized.

Copy link

commented Apr 20, 2019

@fmonday do you get Javascript-errors? Can you check you js -console?

@fmonday

This comment has been minimized.

Copy link

commented Apr 20, 2019

I have some errors in home-assistant.log, but none of them seem relevant. How do I call the JS console on an RPi? I'm running the latest HA virtually. I tried entering "js -console" into a command prompt and bash doesn't know the command.

@agrigo2s

This comment has been minimized.

Copy link

commented Apr 20, 2019

Open your http://hassio.local:8123/ in firefox or chrome and press ctrl+shift+i and then press the "console"-tab.

@fmonday

This comment has been minimized.

Copy link

commented Apr 20, 2019

OK so interestingly, I'd been testing this on Safari on a MacBook Pro, which continues to behave as if kiosk.js isn't installed. However, following your directions I opened Chrome on a MacBook pro, and everything works as intended. Nevertheless the JS console in Chrome give this error:
Uncaught (in promise) DOMException :8123/lovelace/default_view?kiosk?show_tabs:1 Uncaught (in promise) DOMException

I've also now tested it out on both mobile Safari and the HA v 2.0 beta companion app, and both of them go directly into Kiosk mode as soon as you start, and then you're stuck on just the first tab in kiosk mode. There's no URL bar in the app, but in Safari checking the URL confirms that there's no query string. My second view is titled "kiosk", but it defaults to the first view and there's no way to change it.

Thoughts?

@Zemoj

This comment has been minimized.

Copy link

commented Apr 21, 2019

@agrigo2s

This comment has been minimized.

Copy link

commented Apr 21, 2019

@Zemoj nice!
@fmonday do you want to use it with a tablet? I could try to use a swipe-event to change the pages :)

@fmonday

This comment has been minimized.

Copy link

commented Apr 23, 2019

@agrigo2s yes, I'm trying to get it to work on an iPad. Swiping to change pages would be great!

I think I'm realizing that the kiosk mode persists until one clears the cache, which is kind of a bummer on your main browser, and doesn't even seem to be possible in the companion app (including the v2 beta right now). Does that sound right to you guys?

@arretx

This comment has been minimized.

Copy link

commented Apr 25, 2019

Not sure what I'm missing here, but I added the kiosk.js file to the www folder, added the resources section to the ui-lovelace.yaml, restarted, and tried accessing the URL with ?kiosk in it and I don't see anything different happening.

I see this though:

TypeError: Cannot read property 'querySelector' of null
at kiosk.js:11

v 91.4 here.

@agrigo2s

This comment has been minimized.

Copy link

commented Apr 25, 2019

like this : http://hassio.local:8123/lovelace/0?kiosk ? Can you check in the sourcecode if the js file is loaded?

@TheAlphaLaw

This comment has been minimized.

Copy link

commented May 28, 2019

like this : http://hassio.local:8123/lovelace/0?kiosk ? Can you check in the sourcecode if the js file is loaded?

Doesn't work for me either, nothing in my /www is being picked up.

@jmbouffa

This comment has been minimized.

Copy link

commented Jun 7, 2019

view.style.minHeight = "100vh";

Hi Jesselenne, did you manage to get it right? I have the same problem with a background image. But when I add your line to the config or use your whole config, I get an empty bar on top. Hope to hear from you.

I fixed it by changing the minHeight for huiroot.querySelector('ha-app-layout').querySelector('#view').

if (window.location.href.indexOf('kiosk') > 0)
    setTimeout(function () {
        try {
            const drawer_layout = document
                    .querySelector('home-assistant').shadowRoot
                    .querySelector('home-assistant-main').shadowRoot
                    .querySelector('app-drawer-layout');
            const huiroot = drawer_layout
                    .querySelector('partial-panel-resolver').shadowRoot
                    .querySelector('ha-panel-lovelace').shadowRoot
                    .querySelector('hui-root').shadowRoot;

            const header = huiroot.querySelector('app-header');
            const toolbar = huiroot.querySelector('app-toolbar');
            const button_menu = toolbar.querySelector('ha-menu-button').shadowRoot;
            const app_drawer = drawer_layout.querySelector('app-drawer');

            if (window.location.href.indexOf('show_tabs') > 0) {
                toolbar.style.display = 'none';
            } else {
                header.style.display = 'none';
            }

            if(app_drawer.hasAttribute("opened")){
                button_menu.querySelector('paper-icon-button').click();
            }

            const app_layout = huiroot.querySelector('ha-app-layout').querySelector('#view')
            app_layout.style.minHeight = '100vh';

            window.dispatchEvent(new Event('resize'));
        }
        catch (e) {
            console.log(e);
        }
    }, 500);

I still get the white bar, is this still working for you?

@sheminasalam

This comment has been minimized.

Copy link

commented Jun 12, 2019

i have tried this with hassio running in OPi PC2,but it is not working..any advises...the error message in consule is 404 not found. Also none of the custom addon works...any advises..?

@tikkerei

This comment has been minimized.

Copy link

commented Jun 18, 2019

Not sure what I'm missing here, but I added the kiosk.js file to the www folder, added the resources section to the ui-lovelace.yaml, restarted, and tried accessing the URL with ?kiosk in it and I don't see anything different happening.

I see this though:

TypeError: Cannot read property 'querySelector' of null
at kiosk.js:11

v 91.4 here.

Same here:
TypeError: Cannot read property 'querySelector' of null
hassio 0.94.3
chrome latest

@Zemoj

This comment has been minimized.

Copy link

commented Jun 18, 2019

Are you guys using the updated versions from the comments? My link above should work for 91.4 Also just for reference if this is the first item in the www folder HA needs to be restarted. Version 94 might have changed page structure again, I can take a look tonight.

@tikkerei

This comment has been minimized.

Copy link

commented Jun 19, 2019

Are you guys using the updated versions from the comments? My link above should work for 91.4 Also just for reference if this is the first item in the www folder HA needs to be restarted. Version 94 might have changed page structure again, I can take a look tonight.

You are right, your version works correctly with the latest version of ha
Thank you!!!

@JoHaNMcR

This comment has been minimized.

Copy link

commented Aug 2, 2019

I get this error on version 0.96.5"

TypeError: Cannot read property 'querySelector' of null
at kiosk.js:11

@corrafig

This comment has been minimized.

Copy link

commented Aug 18, 2019

I get this error on version 0.96.5"

TypeError: Cannot read property 'querySelector' of null
at kiosk.js:11

I made the following quick fix for myself:
https://gist.github.com/corrafig/c8288df960e7f59e82c12d14de26fde8

@JoHaNMcR

This comment has been minimized.

Copy link

commented Aug 19, 2019

I get this error on version 0.96.5"
TypeError: Cannot read property 'querySelector' of null
at kiosk.js:11

I made the following quick fix for myself:
https://gist.github.com/corrafig/c8288df960e7f59e82c12d14de26fde8

thanks man! it worked! there is anyway to keep the tabs from the top?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.