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).

  • Please note that https://superuser.com is not a free script/code writing service. If you tell us what you have tried so far (include the scripts/code you are already using) and where you are stuck then we can try to help with specific problems. You should also read [ask]. – DavidPostill Jun 01 '22 at 17:38
  • Python questions are off topic and should be asked on [so]. – DavidPostill Jun 01 '22 at 17:38
  • @DavidPostill, I know that; I'm trying to find the key and the value it should be changed to. Or a *library/API* to access these easily. It's not about programming but this specific Windows setting. I've not found any, though, except `winreg`, which is used for accessing the Registry. I don't think telling the value it should be changed to for the cases would be considered a *script/code writing service*. I've tried almost everything on the internet and SE/SO, but nothing that works or is clear. – The Amateur Coder Jun 02 '22 at 06:21
  • @DavidPostill, as this is like asking where the Night Light setting is, I think a new (not saying updated, the proper method, *any* way, again, not Python specifically) answer would be the best. Also, I searched for this about a year ago too, but couldn't find a working answer. – The Amateur Coder Jun 02 '22 at 06:29

1 Answers1

4

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
  • 5,598
  • 2
  • 21
  • 36
  • Thanks for the answer, but I tried this too; it didn't work. Also, I find PowerShell a bit hard, so prefer Python or Batch. I tried copy-pasting the code in a PS terminal and running it using the command by calling the function, but it didn't enable/disable/have any effect. I tried almost everything I could find, but they just didn't work; I don't know why. – The Amateur Coder Jun 03 '22 at 14:56
  • 1
    Programming & computers can be complex so to get the best help you NEED to tell us EXACTLY what error you have & preferably EXACTLY what you tried. To confirm you copied this code into PowerShell ISE, ran it, then tried a command like `Set-BlueLightReductionSettings -StartHour 7 -StartMinutes 0 -EndHour 21 -EndMinutes 15 -Enabled $true -NightColorTemperature 6000` and it failed? – gregg Jun 03 '22 at 20:09
  • 1
    Watching this registry key below while turning 'Night light' on and off within Settings the value keeps changing & I personally can't figure out the scheme. I also couldn't figure out how to simply enable & disable 'Night light' through that PowerShell code, it appears you have to specify all variables/schedule. `HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\CloudStore\Store\DefaultAccount\Cloud\default$windows.data.bluelightreduction.bluelightreductionstate\windows.data.bluelightreduction.bluelightreductionstate` – gregg Jun 03 '22 at 20:12
  • Yes, I tried a command like that, and yes, you have to specify all the variables, and only then can you run it, or it'll show an error. I'm completely new to PowerShell, and I don't want to meddle with a language that looks like C and .htaccess; that's why I'm looking for something in Python. And, I guess it converts the inputs (the variables' values) into some byte `data` based on them. I also tried watching the change in the Registry key, but it never changes when I turn Night Light on/off manually. Also, I don't get any error when I run the PS code; it just goes to the next line like in CMD – The Amateur Coder Jun 03 '22 at 21:04
  • 1
    I sadly cannot help with other programming languages. StackOverflow is the proper site for that, however the issue with superuser OR them is that no one really knows how to access this night light programtically. I am 99% sure Microsoft hasn't built an API or anything to access it so we're going on no mans road here. If you're watching the registry you have to refresh it (View, Refresh or F5 key) to see the changes. Good luck deciphering it though, after you do you can then build your own coding around it – gregg Jun 06 '22 at 14:15
  • 1
    'No news is good news' is the norm for lots of programs, they don't always give feedback. The code snippet just loads the cmdlet & variables into memory/session so its actually not changing anything on your system. In plain speak: running the code allows you to use the cmdlet `Set-BlueLightReductionSettings` – gregg Jun 06 '22 at 14:17
  • Oh, ok, and yes, I refreshed to check, but it's the same. It's fine; I was trying to make a small utility for myself to turn Night Light off every time my PC boots, as sometimes, it takes some time to (probably load the registry or some well-hidden logs and) turn it off. – The Amateur Coder Jun 07 '22 at 17:02
  • I don't usually meddle with Windows 10 settings because almost half the settings are accessible via the Control Panel too, and some *only* through it; clicking "Schedule night light" under "Night light settings" KEEPS IT ON (probably, by default, Night Light is scheduled to be turned on from a set time to another), but not scheduling Night Light: Night Light is on ALL THE TIME. – The Amateur Coder Jun 07 '22 at 17:14