2

How to check if Night Light is enabled on Windows 10 using a batch file? I think it can be accessed from Windows Registry, but I'm unsure about how to do it.

I'm trying to get and set/change the value of the Blue Light Reduction setting.

I found this and many others, but I'm not sure how to only get the value and not change the settings (nor do I know which command is for getting and which is for setting or what file I should put it in).

It would be better if I could do this using BAT files and even better using Python.

If there's no API/library for doing this, I'd go for getting the key's value to check if Night Light is enabled and changing its value to enable/disable Night Light.

If Windows Registry is involved, please specify what language it is and what file the code should be in (.bat if it's Batch code and .py if Python, for example).

1 Answers1

5

This is a straight copy/paste from another superuser answer (by Ben N) that I found by following your link. Is there a reason this doesn't work for you? To be honest I shouldn't get an upvote considering I copy/pasted this. However I MAYBE deserve the upvote/bounty to help you implement it. To be honest I tried to close your question as a duplicate, however it won't let me because it has a bounty. I'm guessing you want help understanding things even though your question just wants code. You need to specify EXACT code or EXACT answers you tried & WHY they didn't work.

---------------------------------------------------------------------

With a bunch of experimentation, I managed to more or less work out the format of that Registry value and wrote a PowerShell script to set it.

Tested on 21H2

And possibly appropriate for versions as early as the 2019 updates.

Function Set-BlueLightReductionSettings {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true)] [ValidateRange(0, 23)] [int]$StartHour,
        [Parameter(Mandatory=$true)] [ValidateSet(0, 15, 30, 45)] [int]$StartMinutes,
        [Parameter(Mandatory=$true)] [ValidateRange(0, 23)] [int]$EndHour,
        [Parameter(Mandatory=$true)] [ValidateSet(0, 15, 30, 45)] [int]$EndMinutes,
        [Parameter(Mandatory=$true)] [bool]$Enabled,
        [Parameter(Mandatory=$true)] [ValidateRange(1200, 6500)] [int]$NightColorTemperature
    )
    $data = (0x43, 0x42, 0x01, 0x00, 0x0A, 0x02, 0x01, 0x00, 0x2A, 0x06)
    $epochTime = [System.DateTimeOffset]::new((date)).ToUnixTimeSeconds()
    $data += $epochTime -band 0x7F -bor 0x80
    $data += ($epochTime -shr 7) -band 0x7F -bor 0x80
    $data += ($epochTime -shr 14) -band 0x7F -bor 0x80
    $data += ($epochTime -shr 21) -band 0x7F -bor 0x80
    $data += $epochTime -shr 28
    $data += (0x2A, 0x2B, 0x0E, 0x1D, 0x43, 0x42, 0x01, 0x00)
    If ($Enabled) {$data += (0x02, 0x01)}
    $data += (0xCA, 0x14, 0x0E)
    $data += $StartHour
    $data += 0x2E
    $data += $StartMinutes
    $data += (0x00, 0xCA, 0x1E, 0x0E)
    $data += $EndHour
    $data += 0x2E
    $data += $EndMinutes
    $data += (0x00, 0xCF, 0x28)
    $data += ($NightColorTemperature -band 0x3F) * 2 + 0x80
    $data += ($NightColorTemperature -shr 6)
    $data += (0xCA, 0x32, 0x00, 0xCA, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00)
    Set-ItemProperty -Path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\CloudStore\Store\DefaultAccount\Current\default$windows.data.bluelightreduction.settings\windows.data.bluelightreduction.settings' -Name 'Data' -Value ([byte[]]$data) -Type Binary
}

The format (or more properly a working format, since the Settings app can create multiple slightly different layouts):

  • 10 constant bytes
  • The last-modified Unix timestamp in seconds, mangled and spread across 5 bytes in what is probably a variable-length encoding:
    • One byte whose bits 0-6 are the timestamp's bits 0-6 but whose top bit 7 is always set
    • One byte whose bits 0-6 are the timestamps' 7-13 but whose top bit is always set
    • Likewise for two more sets of 7 bits
    • One final byte for timestamp bits 28-31, top bit not set
  • 8 constant bytes
  • Only if the schedule is enabled: constant bytes 0x02, 0x01
  • 3 constant bytes
  • The start hour
  • The constant byte 0x2E (presumably a field delimiter or type)
  • The start minute
  • 4 constant bytes
  • The end hour
  • The constant byte 0x2E again
  • 3 constant bytes
  • The night color temperature in Kelvin, two mangled bytes:
    • One byte whose low bit 0 is always unset, bits 1-6 are the temperature's bits 0-5, and top bit 7 is always set
    • One byte for the temperature's bit 6 and above, top bit not set
  • 10 constant bytes

Tested on 1703/1709

And possibly working as late as the 2018 updates.

Function Set-BlueLightReductionSettings {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true)] [ValidateRange(0, 23)] [int]$StartHour,
        [Parameter(Mandatory=$true)] [ValidateSet(0, 15, 30, 45)] [int]$StartMinutes,
        [Parameter(Mandatory=$true)] [ValidateRange(0, 23)] [int]$EndHour,
        [Parameter(Mandatory=$true)] [ValidateSet(0, 15, 30, 45)] [int]$EndMinutes,
        [Parameter(Mandatory=$true)] [bool]$Enabled,
        [Parameter(Mandatory=$true)] [ValidateRange(1200, 6500)] [int]$NightColorTemperature
    )
    $data = (2, 0, 0, 0)
    $data += [BitConverter]::GetBytes((Get-Date).ToFileTime())
    $data += (0, 0, 0, 0, 0x43, 0x42, 1, 0)
    If ($Enabled) {$data += (2, 1)}
    $data += (0xC2, 0x0A, 0x00) # Some users have reported this line necessary on 1709, was not needed originally
    $data += (0xCA, 0x14, 0x0E)
    $data += $StartHour
    $data += 0x2E
    $data += $StartMinutes
    $data += (0, 0xCA, 0x1E, 0x0E)
    $data += $EndHour
    $data += 0x2E
    $data += $EndMinutes
    $data += (0, 0xCF, 0x28)
    $tempHi = [Math]::Floor($NightColorTemperature / 64)
    $tempLo = (($NightColorTemperature - ($tempHi * 64)) * 2) + 128
    # Alternate proposed version (see edit history), possibly version-specific?: $tempLo = ($NightColorTemperature - ($tempHi * 64)) * 4
    $data += ($tempLo, $tempHi)
    $data += (0xCA, 0x32, 0, 0xCA, 0x3C, 0, 0)
    Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\$$windows.data.bluelightreduction.settings\Current' -Name 'Data' -Value ([byte[]]$data) -Type Binary
}

Using it

Save the script as a .ps1 file and follow the instructions in the Enabling Scripts section of the PowerShell tag wiki. You can then import the script's contents by dot-sourcing:

. ./bluelightmanagement.ps1

And then use the cmdlet-like function that it supplies:

Set-BlueLightReductionSettings -StartHour 7 -StartMinutes 0 -EndHour 21 -EndMinutes 15 -Enabled $true -NightColorTemperature 6000

the results

The Settings app even updates everything (except the strength/color slider) immediately if you have the blue light reduction page open when you run the command. For the slider to see the changes, you'll need to reopen the Settings app.

gregg
  • 6,307