Skip to content

feat(windows): enable Night Light on a sunset-to-sunrise schedule - #738

Merged
DevSecNinja merged 1 commit into
mainfrom
feat/windows-night-light
Aug 16, 2026
Merged

feat(windows): enable Night Light on a sunset-to-sunrise schedule#738
DevSecNinja merged 1 commit into
mainfrom
feat/windows-night-light

Conversation

@DevSecNinja

Copy link
Copy Markdown
Owner

What

Adds home/.chezmoiscripts/windows/run_onchange_41-set-night-light.ps1, which enables Windows Night Light on a sunset-to-sunrise schedule at strength 50 (3850 K). Pass -Strength 0..100 for a different intensity.

Why it needs a binary codec

Night Light has no supported configuration API. Windows persists it as two REG_BINARY CloudStore values under HKEY_CURRENT_USER:

Value Contents
default$windows.data.bluelightreduction.settings\... Schedule mode, colour temperature, schedule times, cached sunset/sunrise
default$windows.data.bluelightreduction.bluelightreductionstate\... Whether Night Light is currently on

Both are Microsoft Bond CompactBinary v1 payloads inside a CloudStore envelope. Rather than hardcoding a blob (which would clobber the sunset/sunrise times Windows computes from your location), the script implements just enough of the codec to decode, mutate only the fields it owns, and re-encode.

Format reference: kvnxiao/win-nightlight-cli registry format docs (evidence grade 3 — reverse-engineered, not a Microsoft contract).

Design notes

  • Schedule mode is presence-encoded: field 0 (schedule_enabled) is set to true, and field 10 (set_hours_mode) is omitted — that is how Windows represents "Sunset to sunrise".
  • Strength maps linearly onto colour temperature: 0 -> 6500 K (no effect), 100 -> 1200 K, so 50 stores 3850 K.
  • State is derived, not forced: Night Light is switched on only when the current time falls inside the cached sunset-to-sunrise window, matching what Windows itself would do. Forcing the flag on would leave it on all day.
  • BT_INT8 is a raw byte, not a zigzag varint (unlike BT_INT16/BT_INT32). Getting this wrong silently corrupts the hour/minute time blocks.
  • All writes stay in HKEY_CURRENT_USER, the script honours -WhatIf, and it is idempotent (second run reports 0 changes).

Verification

  • Both blobs captured from a live Windows 11 install round-trip byte for byte through the codec.
  • Live apply test: -Strength 60 -> 3320 K, -Strength 50 -> 3850 K, third run -> 0 setting(s) changed.
  • tests/powershell/NightLight.Tests.ps1: 62 new tests covering the Bond primitives, CloudStore wrapper, both payload schemas, strength conversion, night-window detection, and Set-NightLightConfiguration against a fake registry.
  • Full Pester suite: 853 passed, 0 failed.
  • PSScriptAnalyzer: clean.
  • No non-ASCII characters in the .ps1 (enforced by a test).

Docs

docs/customization.md gains a "Windows Night Light" section documenting the registry layout, encoding rules, evidence grade, and reversal steps.

Adds run_onchange_41-set-night-light.ps1, which turns Night Light on with a
sunset-to-sunrise schedule at strength 50 (3850 K).

Night Light has no supported API; Windows persists it as two REG_BINARY
CloudStore values holding Microsoft Bond CompactBinary v1 payloads. The script
implements enough of that codec to decode the existing blobs, change only the
fields it owns, and re-encode them, so the sunset/sunrise times Windows derives
from the machine location are preserved byte for byte.

Schedule mode is encoded by field presence: field 0 (schedule_enabled) is set
and field 10 (set_hours_mode) is omitted. The on/off state is derived from the
cached sunset/sunrise window rather than force-toggled, so Windows keeps
managing the transitions. All writes stay in HKEY_CURRENT_USER and the script
is idempotent.

Verified against a live Windows 11 install: both captured blobs round-trip
byte for byte through the codec.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@DevSecNinja
DevSecNinja merged commit f0df02e into main Aug 16, 2026
19 checks passed
@DevSecNinja
DevSecNinja deleted the feat/windows-night-light branch August 16, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant