Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_*()-commands return absurdly high values for luminance and contrast while monitor OSD is open #294

Closed
XDA-Bam opened this issue Oct 15, 2023 · 9 comments
Labels
bug Something isn't working

Comments

@XDA-Bam
Copy link

XDA-Bam commented Oct 15, 2023

  • Monitor manufacturer and model number:
    HP Omen 27u
  • Input source (HDMI, VGA, display port, ect.):
    DP
  • Output device (video card, discrete graphics, ect.):
    Discrete Radeon 6800
  • Operating system:
    Win 10 Pro 64 bit
  • Python version:
    3.12.0
  • monitorcontrol version (monitorcontrol --version):
    3.1.0

Steps to Reproduce

Create a very basic Python script, which asks for monitor brightness and contrast:

import time
from monitorcontrol import get_monitors

# Check monitors
while True:
    for monitor in get_monitors():
        with monitor:
            try:
                brightness = monitor.get_luminance()
                contrast   = monitor.get_contrast()
                print(f'Brightness: {brightness}') 
                print(f'Contrast:   {contrast}')
            except:
                print('Error occured during get-command')

    time.sleep(0.25)

As discussed in #288, many get_*()-commands fail with an error, but that is not relevant for this bug. I kept the errors in the log, but they can be ignored. What is more interesting is the behaviour while interacting with the monitor OSD. Log looks like this:

= RESTART: C:\Users\MyName\Downloads\Monitor brightness\Test_Set brightness_monitorcontrol.py
Error occured during get-command

Error occured during get-command

Brightness: 0
Contrast:   80

Brightness: 0
Contrast:   80

Error occured during get-command

Error occured during get-command	<--- Around here I opened the OSD by pressing the control dial on the screen

Brightness: 43690
Contrast:   43690

Error occured during get-command

Error occured during get-command

Error occured during get-command	<--- OSD closed around here

Error occured during get-command

Error occured during get-command

Brightness: 0
Contrast:   80

The behaviour is repeatable and the value is always 43690 for both, get_luminance() and get_contrast(). I am not sure, where this problem originates - it might be specific to my display, but that's difficult for me to check right now.

That being said, those values should be far outside of the allowed value ranges for these parameters, right? If so, I feel like this should trigger an error regardless of the origin of the problem.

@newAM
Copy link
Owner

newAM commented Oct 16, 2023

Can you modify the script to print the code maximums as it iterates?

When getting a VCP feature value the monitor returns a tuple of the current code and the maximum value. I'm curious what the maximum values will show.

import time
from monitorcontrol import get_monitors

# Check monitors
while True:
    for monitor in get_monitors():
        with monitor:
            try:
                brightness = monitor.get_luminance()
                contrast   = monitor.get_contrast()
                print(f'Brightness: {brightness}') 
                print(f'Contrast:   {contrast}')
                print(f'Max: {monitor.code_maximum}')
            except:
                print('Error occured during get-command')

    time.sleep(0.25)

@newAM newAM added the bug Something isn't working label Oct 16, 2023
@XDA-Bam
Copy link
Author

XDA-Bam commented Oct 16, 2023

Sure thing. The output looks like this:

Error occured during get-command

Brightness: 22
Contrast:   80
Max: {}

Brightness: 22
Contrast:   80
Max: {}
					<--- Opened OSD
Brightness: 43690
Contrast:   43690
Max: {}

Error occured during get-command

Brightness: 43690
Contrast:   43690
Max: {}

Error occured during get-command

Error occured during get-command

Brightness: 43690
Contrast:   43690
Max: {}

Error occured during get-command
					<--- Closed OSD
Brightness: 22
Contrast:   80
Max: {}

Error occured during get-command

Brightness: 22
Contrast:   80
Max: {}

EDIT: I just realized, that 43690 is 1010101010101010 in binary. Thought that may be relevant.

@newAM
Copy link
Owner

newAM commented Oct 19, 2023

🤦 sorry, I forgot the max value structure doesn't get updated on get_vcp_feature even though the data is available. This was my first python library and it sometimes shows 😅


I'll add some logging for this in a couple weeks. I need to add more visibility around the Windows API calls.

EDIT: I just realized, that 43690 is 1010101010101010 in binary. Thought that may be relevant.

That is definitely interesting.

I'll poke around with my monitor when I'm back home. I've never tried using commands with the OSD open.

@newAM
Copy link
Owner

newAM commented Nov 25, 2023

Sorry for the late reply, this issue got buried under a mountain of other issues.

I tried running commands with the OSD open on the acer monitors I have - no change in behavior.

I've opened #305 to add logging - if you're still interested in this issue are you able to give that a go with the previous script?

@XDA-Bam
Copy link
Author

XDA-Bam commented Nov 26, 2023

Yes, thanks. I updated the package to e0ae184 and ran the script from your last suggestion (with an added line break for clarity). That gave no additional output on the shell. Needed to change monitorcontrol/vcp/vcp_windows.py as follows:

logging.basicConfig()
self.logger = logging.getLogger(__name__)
self.logger.setLevel(logging.DEBUG)
self.hmonitor = hmonitor

Now the output on the shell looks like this:

DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
Error occured during get-command
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (1, 100)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (80, 100)

Brightness: 1
Contrast:   80
Max: {}
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (1, 100)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (80, 100)

Brightness: 1
Contrast:   80
Max: {}
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
Error occured during get-command
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)

Brightness: 43690
Contrast:   43690
Max: {}
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)

Brightness: 43690
Contrast:   43690
Max: {}
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)

Brightness: 43690
Contrast:   43690
Max: {}
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)

Brightness: 43690
Contrast:   43690
Max: {}
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
Error occured during get-command
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
Error occured during get-command
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
Error occured during get-command
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)

Brightness: 43690
Contrast:   43690
Max: {}
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)

Brightness: 43690
Contrast:   43690
Max: {}
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (43690, 43690)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
Error occured during get-command
DEBUG:monitorcontrol.vcp.vcp_windows:DestroyPhysicalMonitor
DEBUG:monitorcontrol.vcp.vcp_windows:GetNumberOfPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetPhysicalMonitorsFromHMONITOR
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=16, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (1, 100)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply(_, code=18, None, _, _)
DEBUG:monitorcontrol.vcp.vcp_windows:GetVCPFeatureAndVCPFeatureReply -> (80, 100)

Brightness: 1
Contrast:   80
Max: {}

Hope this helps. Didn't mark where I opened the OSD - should be pretty clear from the log 😉

@newAM
Copy link
Owner

newAM commented Nov 29, 2023

That does help narrow it down, but sadly it narrows it down to a location that's hard to debug :(

The Windows API is returning a value it shouldn't - which either means the monitor firmware is returning a value it shouldn't, or the underlying Windows API call is misinterpreting data sent by the monitor. This could be further narrowed down to firmware or Windows by running the same thing on Linux, but I suspect it is the hardware based on the symptoms.

@XDA-Bam
Copy link
Author

XDA-Bam commented Dec 1, 2023

Not ideal, but also not surprising. At least this one is easy to work around (for my case) by rejecting anything outside of the valid range [0,100] for brightness & contrast and just repeating the request.

Coming back to my initial post: Do you think it would be useful to check that range in monitorcontrol and throw an error if the Win API returns incorrect values, instead of forwarding them?

@newAM
Copy link
Owner

newAM commented Dec 1, 2023

The maximum legal value for a given code is defined by the monitor. I checked the MCCS, but did not find anything that would indicate the values you are seeing would be illegal for all monitors. There are other options for detecting this behavior, but I think the most elegant is probably checking it in application code.

@XDA-Bam
Copy link
Author

XDA-Bam commented Dec 5, 2023

OK. In that case, I'll close this since there is nothing to fix in monitorcontrol itself.

@XDA-Bam XDA-Bam closed this as completed Dec 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants