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

Set the contrast after setting the brightness will raise an error #69

Closed
BruceLee569 opened this issue Apr 20, 2021 · 9 comments
Closed
Labels
bug Something isn't working

Comments

@BruceLee569
Copy link

BruceLee569 commented Apr 20, 2021

Code:

for monitor in get_monitors():
    with monitor:
        monitor.set_luminance(0)
        monitor.set_contrast(5)

Error:

Traceback (most recent call last):
  File "D:/python/Lib/site-packages/MyUtils/RPA/monitor_control.py", line 221, in <module>
    monitor.set_contrast(5)
  File "D:\python\lib\site-packages\monitorcontrol\monitorcontrol.py", line 277, in set_contrast
    self._set_vcp_feature(code, value)
  File "D:\python\lib\site-packages\monitorcontrol\monitorcontrol.py", line 134, in _set_vcp_feature
    f"value of {value} exceeds code maximum of {maximum}"
ValueError: value of 5 exceeds code maximum of 0

Add time.sleep(0.05) between set_luminance and set_contrast method could avoid this error, either if you call set_contrast first.

Please check and try to fix it.

@newAM newAM added the bug Something isn't working label Apr 20, 2021
@newAM
Copy link
Owner

newAM commented Apr 25, 2021

The bus needs a 40ms delay after commands, but the Windows APIs should be adding those delays.

I will try to get to this tomorrow, the PC that I normally use to boot into Windows is preoccupied with a different (Linux) project right now.

Adding my own debug code for future reference:

from monitorcontrol import get_monitors
import sys
import logging

root_logger = logging.getLogger()
handler = logging.StreamHandler(stream=sys.stderr)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("{levelname} {name} {message}", style="{")
handler.setFormatter(formatter)
root_logger.setLevel(logging.DEBUG)
root_logger.addHandler(handler)

for _ in range(0, 1000):
    for monitor in get_monitors():
        with monitor:
            monitor.set_luminance(100)
            monitor.set_contrast(50)

@newAM
Copy link
Owner

newAM commented Apr 28, 2021

I am unable to reproduce this with my monitors on Windows unfortunately.

I think in the case of some monitor needed longer delays on the bus this should be handled outside of the API - to keep this fast where it can be.

@newAM newAM closed this as completed Apr 28, 2021
@BruceLee569
Copy link
Author

BruceLee569 commented Apr 28, 2021

Ok, thank you, I added a TRY statement to the contrast adjustment function:

try:
    self.mo.set_contrast(value)
except Exception:
    #  After waiting for the bus delay: https://github.com/newAM/monitorcontrol/issues/69
    time.sleep(0.05)    
    try:
        self.mo.set_contrast(value)
    except Exception:
        pass

@newAM
Copy link
Owner

newAM commented Apr 28, 2021

Looks good, but you may want to consider changing that bare except: https://stackoverflow.com/a/54948581

@BruceLee569
Copy link
Author

Looks good, but you may want to consider changing that bare except: https://stackoverflow.com/a/54948581

🤣👍🤞

@BruceLee569
Copy link
Author

BruceLee569 commented Apr 30, 2021

A new problem was discovered today, and immediately getting the brightness after setting the brightness returns 0:

from monitorcontrol import get_monitors

with get_monitors()[0] as monitor:
    print('luminance before set luminance 50:\n', monitor.get_luminance())
    monitor.set_luminance(50)
    print('luminance after set luminance 50:\n', monitor.get_luminance())

    print('contrast before set contrast 50:\n', monitor.get_contrast())
    monitor.set_contrast(50)
    print('contrast after set contrast 50:\n', monitor.get_contrast())

Now I think it is necessary to add time.sleep (0.05) after all functions execute or before.

@newAM
Copy link
Owner

newAM commented May 1, 2021

A new problem was discovered today, and immediately getting the brightness after setting the brightness returns 0

I have seen that before when reading in intervals less than 40ms for my own monitor (can only do on Linux because the 40ms is included in the API calls on Windows), likely a symptom of the bus delays not being long enough for the monitor you're using.

Now I think it is necessary to add time.sleep (0.05) after all functions execute or before.

Yes, if it is reproducible in one place for the monitor you're using then you should probably add it to all calls, or maybe utilize a retry loop if it is only reproducible some of the time.

@BruceLee569
Copy link
Author

今天发现了一个新问题,设置亮度返回0后立即获得亮度

我已经看到,在以不到40毫秒的间隔为自己的监视器读取消息之前(只能在Linux上执行,因为Windows的API调用中包含40毫秒),总线延迟的症状可能不足以使监视器适应您正在使用。

现在,我认为有必要在所有功能执行之后或之前添加time.sleep(0.05)。

是的,如果您正在使用的监视器在某个位置可重现,则您可能应该将其添加到所有调用中,或者,如果某些时间仅可重现,则可以使用重试循环。

I am developing an image interface application because the bus latency causes a carton when dragging the brightness bar, so I need to use the thread to execute commands with the physical display interact with the physics display.

But because I have two displays, when I initiate two windows, the thread requests of the two display instances have almost simultaneously, although three retrys are allowed, but the three retrys are almost arrived almost simultaneously, resulting in almost back of all orders, midway I have repeatedly looking for other code bases.

After the investigation, it can only be avoided by adding synchronous delays, and the frequency synchronization between the GUI restriction request frequency, the frequency synchronization between multi-threaded different programs is really hurt! 🤣

@newAM
Copy link
Owner

newAM commented May 2, 2021

After the investigation, it can only be avoided by adding synchronous delays, and the frequency synchronization between the GUI restriction request frequency, the frequency synchronization between multi-threaded different programs is really hurt!

That is something I have not experienced yet! Maybe check for GPU driver updates? I have done control of multiple monitors in independent processes before without issue - but maybe they just never synchronized (or maybe it just never happens on Linux).

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