Add per-device night sleep schedule (quiet hours)#25
Open
mochlast wants to merge 4 commits into
Open
Conversation
Devices can now be configured with a nightly quiet-hours window. During the window the display endpoint returns refresh_rate = seconds-until-wake, so the device deep-sleeps the whole night in one cycle (battery saving, no nighttime e-ink refreshes) and wakes at the configured time. Two per-device modes (showSleepScreen): - false (default): keep the current screen frozen until morning - true: show a dedicated sleep screen (crescent moon + "Sleeping until HH:MM"), generated as a 1-bit e-ink PNG via Sharp (new SleepScreenService) The window is evaluated in the global DEFAULT_TIMEZONE and supports ranges that cross midnight. The sleepStartAt/sleepStopAt columns already existed in the schema; adds showSleepScreen (applied via prisma db push, no migration). Wires the fields through the device update DTO/service and the device edit form (toggle + time inputs). Unit tests cover the quiet-hours logic. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The preview path (getCurrentScreenImage) rendered the playlist screen regardless of quiet hours, so the admin UI showed the normal screen even while the device was displaying the sleep screen. Render the sleep screen in the preview too when the device is within its sleep window and showSleepScreen is enabled (freeze mode already shows the current screen). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
25bba7a to
73e776e
Compare
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an optional per-device quiet-hours / night sleep schedule, like other self-hosted TRMNL servers: during the configured window the device deep-sleeps for the whole night in a single cycle instead of polling, saving battery and avoiding nighttime e-ink refreshes.
Screenshots
How it works
During the device poll (
GET /api/display), if the device is inside its sleep window the response returnsrefresh_rate = seconds-until-wake, so the firmware sleeps until the wake time and polls once. The window is evaluated in the existingDEFAULT_TIMEZONE(same timezone used by the clock/date widgets) and supports ranges that cross midnight (e.g.22:00–07:00).Two per-device modes (
showSleepScreen):SleepScreenService, mirroringDefaultScreenService).The admin "Current Screen" preview reflects the sleep screen during quiet hours too, so it matches what the device shows.
Changes
display.service.ts:getQuietHoursSeconds()helper + wiring ingetDisplayContent()(sleep-screen short-circuit / freeze-mode refresh override) andgetCurrentScreenImage()(preview).sleep-screen.service.ts(new): generates/caches the sleep screen per resolution + wake time, served from/assets.Device.showSleepScreenadded to the Prisma schema. ThesleepStartAt/sleepStopAtcolumns already existed; everything is applied viaprisma db push(no migration file needed).Testing
402 backend unit tests pass. Verified end-to-end on a real TRMNL device (firmware 1.7.8): inside the window the device fetches the sleep screen and sleeps until the configured wake time; outside the window it behaves normally.
🤖 Generated with Claude Code