# Screensavers After a period of inactivity the kiosk can become a clock, a photo frame, a camera wall, a web page, or simply a black panel, and come back the moment someone touches it, says the wake word, or walks up to it. One design decision runs through everything here: the screensaver never turns the display off. Even the Black mode is the backlight at zero behind a black overlay, with the app alive underneath, so motion wake, wake word detection, MQTT and the remote admin (including its live view) all keep working through the night. Real display power is a separate thing, the Screen light entity in the [MQTT integration](mqtt.md). ## Setup Settings, then **Screensaver** (the same tab exists in the remote admin): | Setting | Default | Notes | | --- | --- | --- | | Screensaver | off | The master switch. Turning it off also dismisses a screensaver that is showing. | | Idle timeout (seconds) | 300 | Inactivity period before the screensaver starts. | | Screensaver brightness | off | A separate brightness while the screensaver shows. See below. | | Brightness level | 20% | Applies to every mode except Dim and Black. | | Turn screen off after | 0 (never) | Truly power the panel off once the screensaver has run this long. See below. | | Pixel shift | off | Nudge the image every minute to protect OLED panels. Not for Black, whose pixels are already off. | | Screensaver mode | Black | What the screensaver shows. Only the selected mode's settings appear below the picker. | Below the mode's own settings sits the **Widgets** group, small corner overlays that ride over the modes. See [Widgets](#widgets). ## The modes ### Dim Lowers the backlight to the configured **Dim level** and leaves the dashboard on screen. Because the dashboard stays visible, the **Pause dashboard during screensaver** optimization cannot apply in this mode, so the page keeps using CPU, GPU and battery; the settings page says so next to the slider. ### Black A fully dark panel that still answers. **Hide all extras** keeps it truly black: no widgets, no At a Glance row, no overlays of any kind, and the At a Glance connection is not even opened. ### Clock A full-screen clock in one of three faces, picked with **Style**: **Digital Clock**, **Flip Clock** (split-flap cards) or **Roller Clock** (oversized rolling digits, modeled on the Lenovo Smart Clock 2). Dates follow the device language. | Setting | Notes | | --- | --- | | 24-hour clock | All faces. | | Show seconds | Digital only. | | Show date | Digital only, on by default. | | Clock size | 50 to 300 percent. | | Clock color | Digital only; Flip and Roller have their own digit and card or background colors. | | Background color | Digital only; the solid color behind the clock, black by default. White here with a black clock color gives the inverted face e-ink panels read best (issue #173). | | Background photo | A photo behind the clock instead of the solid color, any face. | The **Background photo** is picked on the device (the picker copies it into app storage), or set remotely: the remote admin and the MQTT **Clock background** text entity write a device file path into the same setting, applied live even while the clock is on screen, and an empty value clears it (issue #150). The photo gets the same fill treatment as the photo modes, with a scrim so the clock stays readable. ### Home Assistant Media Anything Home Assistant's media browser can serve: an image, a folder of them, a video, or a `camera.*` entity, which streams over WebRTC with an MJPEG fallback. **Media source** opens the browser to pick one; a folder gets the usual playlist controls (**Seconds per image**, **Shuffle**, **Include subfolders**, **Transition**), and videos play in full. ### Local Media A folder on the device itself, cycled as a slideshow: **Local folder** (picked on the device, or the path typed in the remote admin), **Seconds per photo**, **Shuffle**, **Include subfolders**, **Transition**, and **Fill the screen**. ### Photo Gallery Like Local Media, but the selection comes from the system gallery picker instead of a folder, so no storage permission is involved: **Photos** (picking again replaces the selection; the chosen items are copied into app storage so they survive reboots), **Seconds per photo**, **Shuffle**, **Transition**, and **Fill the screen**. ### Immich Media An [Immich](https://immich.app/) server as a photo frame, with a local cache and an optional metadata overlay. It has its own page: [Immich](immich.md). ### Website Any web page, full screen. The page loads as a top-level page in its own view, not embedded in a frame, and shares the app's cookie jar, so private URLs that rely on session cookies (a DAKboard private URL, say) work (issue #118). Tap-to-dismiss and pixel shift are injected into the page, so it behaves like every other mode. A page that fails to load, or whose server answers with an error, is retried every ten seconds instead of parking an error page for the night. A page from your own Home Assistant gets two things extra. It signs in with the session the dashboard already holds, since the login form it would otherwise show cannot be answered here (the first touch dismisses the screensaver). And it follows **HA kiosk mode**, so a dashboard put here shows as the whole screen instead of carrying Home Assistant's header and sidebar. Both are held to your own Home Assistant: a page anywhere else is shown exactly as its owner built it. Voice Satellite does not start on it either. It runs on every Home Assistant page that loads it, so a dashboard shown here would open a second microphone and answer as the same satellite the dashboard behind it is already answering as. The dashboard stays the satellite, and the screensaver is just a display. ### WebRTC Camera A configured [camera view](cameras.md) as the screensaver, picked with **Camera view**. The grid is scenery: any touch dismisses the screensaver rather than focusing a camera, and the small clock stays off so nothing sits over the video. ## Slideshow behavior The photo modes (Local Media, Photo Gallery, Immich Media) share one machinery: - **Transitions**: None, Crossfade, Slide, Zoom, Ken Burns, or Random. Ken Burns applies to stills only (videos crossfade), and Random rolls one of the real transitions on every change. - **Fill the screen** (on by default): a photo shaped close enough to the panel (within about a 25 percent crop along one axis) is enlarged edge to edge; portrait and square photos keep their full frame over an enlarged, blurred and dimmed copy of themselves instead of black bars. - **Videos** play muted and in full, ignoring the per-image interval; a video the device cannot decode is skipped, not looped. - The playlist is read once per activation, so new photos appear the next time the screensaver starts, not mid-session. - Photos are decoded at panel resolution and shown slides are released, so a folder of huge originals does not exhaust a low-RAM tablet. ## Widgets Small overlays in the corners of the screensaver, added from the **Widgets** group under the mode's settings. Each widget takes one of the four corners (one widget per corner) and carries its own settings, picked when adding or editing it. Widgets ride over every mode their type allows, but never over Black with Hide all extras. The group's **Widget scaling** slider (50 to 150 percent) sizes every widget for the screen, and moving it while the screensaver shows previews live. Widgets own their corners: the Immich metadata overlay steps to the first free corner when a widget claims its spot, and hides only when every corner is taken. ### Small clock A corner clock over any mode except Clock (already a clock) and WebRTC Camera (kept clear so nothing sits over the video): | Setting | Default | Notes | | --- | --- | --- | | Corner | first free corner | The Immich metadata overlay steps out of any corner a widget claims. | | Color | white | | | 24-hour clock | off | Its own switch, independent of the Clock mode's. | | Show date | off | A short date under the time, in the device language. | It sits on a soft vignette so it stays readable on bright photos, and it honors pixel shift. A small clock configured before the Widgets group existed becomes a clock widget automatically, keeping its corner and settings. ### Weather Live weather from a Home Assistant `weather` entity, over any mode except WebRTC Camera — a clock face with a weather corner is exactly what the Clock mode wants. The block reads, top to bottom: the location name, the temperature in a large font with its unit (always shown, "28°C"), the forecast text with a matching icon, then humidity, wind speed and visibility, each with its icon. Units come from the entity, and the icons are monochrome and take the widget's color, like the text. | Setting | Default | Notes | | --- | --- | --- | | Weather entity | none | Picked from Home Assistant. The widget shows nothing until one is set. | | Location name | empty | The place shown over the temperature. Weather entities carry no city attribute, so it is named by hand; left empty, the line stays off. | | Corner | first free corner | | | Color | white | Text and icons alike. | | Location, Forecast, Humidity, Wind speed, Visibility | on | One toggle per line. A line also needs the entity to actually carry that reading; whatever the entity lacks is simply left out. | Readings arrive over a live Home Assistant subscription while the screensaver shows, so they stay current without polling, and the last known values survive a short Home Assistant outage. ## Brightness **Screensaver brightness** gives the screensaver its own panel brightness, applied when it starts and restored when it ends. Dim and Black ignore it (they have their own levels), and a [schedule](#schedule) entry's brightness overrides it while that entry is active. Moving the slider while the screensaver shows applies immediately, so it can be tuned by eye. The pre-screensaver brightness is saved persistently, so even an app restart mid-screensaver cannot make the night level the new normal. ## Turning the screen off The screensaver holds the panel awake while it shows, so the OS idle timeout never fires under it. **Turn screen off after** is the sanctioned way out: once the screensaver has been up that long, the panel truly powers off (up to 60 minutes, in 5-minute steps; 0, the default, never does). Powering the panel off is device-admin territory on Android, so the setting needs the **Device admin** permission (Settings, Device, Permissions); without it the timer logs a warning and leaves the panel on. The screensaver session stays active behind the dark panel, which is what makes waking symmetrical: every dismiss source powers the panel back on. That covers motion (with [background listening](microphone.md) on, the camera keeps watching through a real screen-off; see [Camera](camera.md)), the wake word, the MQTT **Dismiss screensaver** button, and a Home Assistant automation calling `stopScreensaver`. All of them land on the dashboard, not on the screensaver. The power button and double-tap-to-wake count as activity like a touch, so they land on the dashboard too (under Lockdown Mode the screensaver stays, as it does for motion). The one wake that keeps the screensaver is the app switching its own panel on, the MQTT **Screen** switch: an automation turning a photo frame on in the morning gets its photos back, with a fresh screen-off countdown, and can call the dismiss button when it wants the dashboard instead. A day-to-day example: photos during the day, Black in the evening via the [schedule](#schedule), and Turn screen off after set to 10 minutes. The display goes fully dark overnight once the room empties, and the first person walking past in the morning (or "okay nabu") brings the dashboard straight back. ## Schedule **Scheduled screensavers** switches to a different screensaver at set times of day. Each entry under **Times** carries a time, a mode, a brightness and three overrides — motion, widgets and At a glance — edited by tapping the entry; it applies from its time until the next entry, and the last entry of the day carries over past midnight. There is no day-of-week dimension, deliberately: the schedule describes a day, every day. The typical shape is two entries: photos at a comfortable brightness from the morning, Black (or Clock, dimmed) from the evening. The motion override sets **Dismiss on motion** per entry, in either direction, so an overnight entry can keep the camera off entirely, or a daytime entry can enable approach wake even though the global switch is off. The widgets and At a glance overrides do the same for the [widgets](#widgets) and the [At a Glance](#at-a-glance) row: leave them on Default to follow their own settings, or set them to Off on the night entry for a screen with nothing on it but the mode itself. On shows what those settings configure, so an override cannot conjure a widget that was never added. Editing the schedule while the screensaver is showing applies live. ## Motion detection With the [device camera](camera.md) enabled, two switches under Motion Detection put it to work for the screensaver: - **Dismiss on motion**: watch the camera while the screensaver is up and wake the screen when someone approaches. The camera runs only during the screensaver. - **Postpone screensaver on motion**: also watch between screensavers, so movement in the room keeps resetting the idle timer and the screensaver waits for the room to empty. This keeps the camera running permanently, and it requires Dismiss on motion. Detection works in the dark, ignores whole-room lighting changes (a TV, a lamp), and stands down for a couple of seconds around the app's own light changes, including slide transitions, so a bright photo cannot wake the screensaver it belongs to. Sensitivity, frame rate and the camera pick are tuned in the Camera settings; the details are in the [Device Camera doc](camera.md). Under [Lockdown Mode](kiosk.md), motion neither dismisses nor postpones, even when the screensaver itself is allowed to run. ## Starting and dismissing The idle timeout is the normal path in. On demand, the screensaver can be started by the kiosk menu's **Start Screensaver** entry (its presence in restricted kiosk mode is an Allowed Action), a [gesture](gestures.md) bound to **Start the screensaver**, the MQTT **Screensaver active** switch, or the `startScreensaver` command on the [remote](remote-api.md) and [JavaScript](js-api.md) APIs. Any touch dismisses it and resets the timer. Beyond touch: - **The wake word** dismisses it immediately, and the idle countdown holds for the whole voice interaction, so the screen cannot go dark between question and answer. - **Motion**, with Dismiss on motion (above). - **Opening a camera view** dismisses it, and the idle timer stays off while the view is open. - **Navigation from Home Assistant** (the Dashboard view select, or `haNavigate`) dismisses it so the requested page is actually seen. - **DLNA media pushed to the kiosk** dismisses it and holds it off while playing; DLNA audio kept in the background deliberately does not. - **Music on the Sendspin player** holds it off, unless the player's **"Now Playing" instead of the screensaver** mode is on, in which case the screensaver becomes a full-screen now-playing view while music plays (see [Sendspin](sendspin.md)). - The MQTT **Screensaver** switch (the master enable) takes a showing screensaver down when turned off; **Screensaver active** turned off and the **Postpone screensaver** button dismiss one and re-arm the timeout. ## Around the dashboard While the screensaver covers the page, the **Pause dashboard during screensaver** optimization (on by default) stops the dashboard from rendering at all, which is where most of the screensaver's power savings come from; the numbers are in [Optimizations](optimizations.md). Dim is the exception, since the dashboard stays visible. Dashboard rotation freezes in place while the screensaver is up and resumes where it left off, so the kiosk does not page through views nobody sees. **Return to home dashboard view**, on the other hand, works quietly behind a showing screensaver, so the morning starts on the home view without the screen having lit up at 3 AM to navigate. With the Voice Satellite integration on the dashboard, **Turn off the Voice Satellite screensaver** (on by default, Voice Satellite settings) makes the integration's own screensaver stand down while this app's screensaver is enabled, so the two never fight. ## At a Glance **At a glance** puts a row of up to four Home Assistant entity states on the Black and Clock screensavers, kept live over its own Home Assistant subscription while the screensaver is up. It has its own page: [At a Glance](at-a-glance.md). ## Home Assistant With [MQTT publishing](mqtt.md) enabled, the screensaver is fully remote-controllable: the **Screensaver** master switch, the **Screensaver active** switch (start and dismiss), the **Postpone screensaver** button for automations that keep the display awake from an external sensor, the **Screensaver mode** and **Clock style** selects, the **Clock background** text entity, the **Screensaver brightness** switch and level, and the **Screensaver motion detection** switch. The full list, with topics, is in the [MQTT doc](mqtt.md).