Closed civanahmetyasin closed 3 years ago
Could you try running the following code and send me the output
import screen_brightness_control as sbc
sbc.set_brightness('+10', display='Philips 246E7', verbose_error=True)
Hi Crozzers,
Thank you for return my message,
I tried the code but failed.
Traceback (most recent call last):
File "c:\Users\civan\Desktop\display.py", line 2, in <module>
sbc.set_brightness('+10', display='Philips 246E7', verbose_error=True)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 114, in set_brightness
value += get_brightness(display=Monitor.get_identifier(monitors[0])[1])
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 43, in get_brightness
return __brightness(display=display, method=method, meta_method='get', verbose_error=verbose_error)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 996, in __brightness
raise ScreenBrightnessError(msg)
screen_brightness_control.ScreenBrightnessError:
no valid output was received from brightness methods
The reason for that error is that sbc.windows.VCP.get_brightness
is not returning a brightness value for that monitor but I do not know why that is.
Could you try the following snippets:
import screen_brightness_control as sbc
print(sbc.windows.VCP.get_brightness())
and
import screen_brightness_control as sbc
print(sbc.windows.VCP.get_brightness(display=1))
and
import screen_brightness_control as sbc
sbc.__cache__.enabled = False
sbc.set_brightness('+10', display='Philips 246E7')
Hi Crozzers okay, I could try it.
When I was run this code,
import screen_brightness_control as sbc
print(sbc.windows.VCP.get_brightness())
This return;
[1]
When I was run this code,
import screen_brightness_control as sbc
print(sbc.windows.VCP.get_brightness(display=1))
This return,
[1]
When I was run this code,
import screen_brightness_control as sbc
sbc.__cache__.enabled = False
sbc.set_brightness('+10', display='Philips 246E7')
this return,
Traceback (most recent call last):
File "c:\Users\civan\Desktop\display.py", line 3, in <module>
sbc.set_brightness('+10', display='Philips 246E7')
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 114, in set_brightness
value += get_brightness(display=Monitor.get_identifier(monitors[0])[1])
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 43, in get_brightness
return __brightness(display=display, method=method, meta_method='get', verbose_error=verbose_error)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 996, in __brightness
raise ScreenBrightnessError(msg)
screen_brightness_control.ScreenBrightnessError:
no valid output was received from brightness methods
That is rather interesting and very confusing. The fact that the 'Philips 246E7' has an index of 0 but is returned as the second item in sbc.list_monitors()
is especially interesting.
I'm interested in what kind of display the Lg Display
is. Could you upload the full result of sbc.list_monitors_info()
?
Hi Crozzers,
OK, I think it's interesting too,
This result, for sbc.list_monitors_info()
[{'name': 'Lg Display', 'model': 'Display', 'serial': '', 'manufacturer': 'Lg', 'manufacturer_id': None, 'edid': '00ffffffffffff0030e4b90500000000001b0104952615780a0bb5a35955a0270c5054000000010101010101010101010101010101012e3680a070381f40302035007ed71000001a000000000000000000000000000000000000000000fe004c4720446973706c61790a2020000000fe004c503137335746342d535046360078', 'index': 0, 'method': <class 'screen_brightness_control.windows.WMI'>}, {'name': 'Philips 246E7', 'model': '246E7', 'serial': 'AU01633001285', 'manufacturer': 'Philips', 'manufacturer_id': 'PHL', 'edid': '00ffffffffffff00410c07c105050000211a010380341d782aefb5a95048a327105054bd4b00d1c09500950fb30081c0818081400101023a801871382d40582c450009252100001e000000ff0041553031363333303031323835000000fc0050484c2032343645370a202020000000fd00384c1e5311000a2020202020200116', 'method': <class 'screen_brightness_control.windows.VCP'>, 'index': 0}]
I'm afraid I do not understand what has gone wrong here.
When I was run this code,
import screen_brightness_control as sbc print(sbc.windows.VCP.get_brightness())
This return;
[1]
This means that the brightness method does return something but the errors you are getting suggest that it does not return anything. My only other guess as to what has gone wrong is that the section of code that decides whether the output was valid has a logic error.
I have pushed a commit to a temporary branch called tmp/issue13. All it adds is a debug print statement before the section of code that I think is broken. If you could install that branch and run the following code I would be most grateful.
import screen_brightness_control as s
s.set_brightness('+10', display='Philips 246E7')
Hi Crozzers, I could install that branch. I ran the code.
This is the return;
63333303031323835000000fc0050484c2032343645370a202020000000fd00384c1e5311000a2020202020200116', 'method': None, 'meta_method': 'get', 'no_return': False, 'args': (), 'kwargs': 63333303031323835000000fc0050484c2032343645370a202020000000fd00384c1
{}, 'format_exc': <function __brightness.<locals>.format_exc at 0x0000014222C0F0D0>, 'output': [], 'monitors': [{'name': 'Philips 246E7', 'model': '246E7', 'serial': 'AU016330000014222C0F0D0>, 'output': [], 'monitors': [{'name': 'Philips 246E7'1285', 'manufacturer': 'Philips', 'manufacturer_id': 'PHL', 'edid': '00ffffffffffff00410c07c105050000211a010380341d782aefb5a95048a327105054bd4b00d1c09500950fb30081c081808140010054bd4b00d1c09500950fb30081c0818081400101023a801871382d40582c45000921023a801871382d40582c450009252100001e000000ff0041553031363333303031323835000000fc0050484c2032343645370a202020000000fd00384c1e5311000a2020202020200116', 'method': <class 'screenVCP'>, 'index': 0}], 'monitor': {'name': 'Philips 246E7', 'model': '_brightness_control.windows.VCP'>, 'index': 0}], 'monitor': {'name': 'Philips 246E7', 'model': '246E7', 'serial': 'AU01633001285', 'manufacturer': 'Philips', 'manufacturer_id':09500950fb30081c0818081400101023a801871382d40582c450009252100001e000 'PHL', 'edid': '00ffffffffffff00410c07c105050000211a010380341d782aefb5a95048a327105054bd4b00d1c09500950fb30081c0818081400101023a801871382d40582c450009252100001e000000ff0041553x': 0}, 'errors': [], 'verbose_error': False}031363333303031323835000000fc0050484c2032343645370a202020000000fd00384c1e5311000a2020202020200116', 'method': <class 'screen_brightness_control.windows.VCP'>, 'index': 0}, 'errors': [], 'verbose_error': False}
Traceback (most recent call last):
File "c:\Users\civan\Desktop\display.py", line 2, in <module>
s.set_brightness('+10', display='Philips 246E7')
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 114, in set_brightness
value += get_brightness(display=Monitor.get_identifier(monitors[0])[1])
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 43, in get_brightness
return __brightness(display=display, method=method, meta_method='get', verbose_error=verbose_error)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 998, in __brightness
raise ScreenBrightnessError(msg)
screen_brightness_control.ScreenBrightnessError:
no valid output was received from brightness methods
The output appears to have some formatting errors. For example:
'method': <class 'screenVCP'>, 'index': 0}], 'monitor': {'name': 'Philips 246E7', 'model': '_brightness_control.windows.VCP'>
There is no class screenVCP
and it looks like the middle section VCP'>, 'index': 0}], 'monitor': {'name': 'Philips 246E7', 'model': '
was inserted into the middle of what should have been 'method': <class 'screen_brightness_control.windows.VCP'>
Are you sure this is how the data was printed and that there are no formatting errors?
Yes, Im sure.
Thank you for checking. In any case, from the data it is clear to see this:
'output': []
The output is empty which causes the "no valid output was received from brightness methods" error. What is interesting is that the list is completely empty. If there was an error while the function was running I would expect the output to look more like this:
'output': [None]
The fact that there is nothing in the list is odd. I would expect that at some point in the code that something, anything, would have been appended to the list.
I have pushed a commit to the tmp/issue13 which adds loads of print statements to the function in the hope of finding out what is going on. Could you run that branch and send back the output?
Many thanks
Hi Crozzers, thank you for again return.
Okay, I understand. I pulled tmp/issue13 and I was installed.
I ran this code;
import screen_brightness_control as s
s.set_brightness('+10', display='Philips 246E7')
Output;
[else clause] []
[pre-get_brightness call] []
[post-get_brightness call] [[]]
[pre-flatten_list call] [[]]
[post-flatten_list call] []
Traceback (most recent call last):
File "c:\Users\civan\Desktop\display.py", line 2, in <module>
s.set_brightness('+10', display='Philips 246E7')
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 114, in set_brightness
value += get_brightness(display=Monitor.get_identifier(monitors[0])[1])
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 43, in get_brightness
return __brightness(display=display, method=method, meta_method='get', verbose_error=verbose_error)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 1003, in __brightness
raise ScreenBrightnessError(msg)
screen_brightness_control.ScreenBrightnessError:
no valid output was received from brightness methods
I ran this code;
import screen_brightness_control as sbc
sbc.__cache__.enabled = False
sbc.set_brightness('+10', display='Philips 246E7')
output,
[else clause] []
[pre-get_brightness call] []
[post-get_brightness call] [[]]
[pre-flatten_list call] [[]]
[post-flatten_list call] []
Traceback (most recent call last):
File "c:\Users\civan\Desktop\display.py", line 3, in <module>
sbc.set_brightness('+10', display='Philips 246E7')
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 114, in set_brightness
value += get_brightness(display=Monitor.get_identifier(monitors[0])[1])
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 43, in get_brightness
return __brightness(display=display, method=method, meta_method='get', verbose_error=verbose_error)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 1003, in __brightness
raise ScreenBrightnessError(msg)
screen_brightness_control.ScreenBrightnessError:
no valid output was received from brightness methods
That's useful! The section
[pre-get_brightness call] []
[post-get_brightness call] [[]]
shows us that the call to screen_brightness_control.windows.VCP.get_brightness
is definitely not returning anything from that monitor. This somewhat contradicts the earlier information of:
When I was run this code,
import screen_brightness_control as sbc print(sbc.windows.VCP.get_brightness())
This return;
[1]
But I'm not sure why and for now I will ignore it.
In the screen_brightness_control.windows.VCP.get_brightness
method it will try up to 10 times to read the VCP value from the monitor. I wonder if, for your display, this is too few tries.
I have pushed another commit to tmp/issue13 for you to try out that does a few things:
Thank you for your patience
I pulled tmp/issue13 and I was installed.
import screen_brightness_control as sbc
print(sbc.windows.VCP.get_brightness())
GetVCPFeatureAndVCPFeatureReply failed after 50 attempts
GetVCPFeatureAndVCPFeatureReply succeed after 1 attempts
[1]
import screen_brightness_control as sbc
sbc.__cache__.enabled = False
sbc.set_brightness('+10', display='Philips 246E7')
[else clause] []
[pre-get_brightness call] []
[post-get_brightness call] [[]]
[pre-flatten_list call] [[]]
[post-flatten_list call] []
Traceback (most recent call last):
File "c:\Users\civan\Desktop\display.py", line 3, in <module>
sbc.set_brightness('+10', display='Philips 246E7')
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 114, in set_brightness
value += get_brightness(display=Monitor.get_identifier(monitors[0])[1])
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 43, in get_brightness
return __brightness(display=display, method=method, meta_method='get', verbose_error=verbose_error)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 1003, in __brightness
raise ScreenBrightnessError(msg)
[else clause] []
[pre-get_brightness call] []
GetVCPFeatureAndVCPFeatureReply failed after 50 attempts
[post-get_brightness call] [[]]
[pre-flatten_list call] [[]]
[post-flatten_list call] []
Traceback (most recent call last):
File "c:\Users\civan\Desktop\display.py", line 3, in <module>
sbc.set_brightness('+10', display='Philips 246E7')
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 114, in set_brightness
value += get_brightness(display=Monitor.get_identifier(monitors[0])[1])
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 43, in get_brightness
return __brightness(display=display, method=method, meta_method='get', verbose_error=verbose_error)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 1003, in __brightness
raise ScreenBrightnessError(msg)
screen_brightness_control.ScreenBrightnessError:
no valid output was received from brightness methods
import screen_brightness_control as sbc print(sbc.windows.VCP.get_brightness())
GetVCPFeatureAndVCPFeatureReply failed after 50 attempts GetVCPFeatureAndVCPFeatureReply succeed after 1 attempts [1]
This is interesting. The function is iterating through two detected physical monitors even though there should only be one VCP addressable monitor. As I recall, the "Lg Display" is a laptop display and the "Philips 246E7" is a desktop monitor, as shown in:
[{'name': 'Lg Display', 'model': 'Display', 'serial': '', 'manufacturer': 'Lg', 'manufacturer_id': None, 'edid': '00ffffffffffff0030e4b90500000000001b0104952615780a0bb5a35955a0270c5054000000010101010101010101010101010101012e3680a070381f40302035007ed71000001a000000000000000000000000000000000000000000fe004c4720446973706c61790a2020000000fe004c503137335746342d535046360078', 'index': 0, 'method': <class 'screen_brightness_control.windows.WMI'>}, {'name': 'Philips 246E7', 'model': '246E7', 'serial': 'AU01633001285', 'manufacturer': 'Philips', 'manufacturer_id': 'PHL', 'edid': '00ffffffffffff00410c07c105050000211a010380341d782aefb5a95048a327105054bd4b00d1c09500950fb30081c0818081400101023a801871382d40582c450009252100001e000000ff0041553031363333303031323835000000fc0050484c2032343645370a202020000000fd00384c1e5311000a2020202020200116', 'method': <class 'screen_brightness_control.windows.VCP'>, 'index': 0}]
So either windows.VCP.iter_physical_monitors
is producing duplicate handles or the "Lg Display" also shows up as a desktop monitor.
Could you run the following code:
import screen_brightness_control as sbc
import ctypes
from ctypes import windll
from ctypes.wintypes import DWORD, HANDLE
for handle in sbc.windows.VCP.iter_physical_monitors():
monitor = HANDLE(handle)
caps_string_length = DWORD()
if not windll.dxva2.GetCapabilitiesStringLength(monitor, ctypes.byref(caps_string_length)):
print('empty caps string')
caps_string = (ctypes.c_char * caps_string_length.value)()
if not windll.dxva2.CapabilitiesRequestAndCapabilitiesReply(monitor, caps_string, caps_string_length):
print('no reply')
print(caps_string.value.decode('ASCII'))
This should tell us the name of each monitor that iter_physical_monitor
is generating
I ran code output,
empty caps string
no reply
(prot(monitor)type(LCD)model(246E7QDA)cmds(01 02 03 07 0C E3 F3)vcp(02 04 05 08 0B 0C 10 12 14(01 05 08 0B) 16 18 1A 52 54(00 01) 60(01 03 11) 62 6C 6E 70 72(05 78 FB 50 64 78 8C A0) 86(02 08) 8D(01 02) AC AE B6 C0 C6 C8 C9 CA(01 02) CC(02 03 04 05 07 08 09 0A 0C 0D 01 06 0B 0E 12 14 16 17 1A 1E 24) D6(01 04 05) DC(00 02 05) DF E9(00 02) EB(00 01 02 03) F0(00 01) FF)mswhql(1)asset_eep(40)mccs_ver(2.2))
This somewhat confirms my suspicions that either the Lg Display is showing up as a desktop monitor or that iter_physical_monitors
is generating ghost handles. Either way, the first handle being generated is clearly invalid and that is why we cannot get a VCP reading out of it.
This issue can probably be fixed by checking if each handle has a valid return for windll.dxva2.GetCapabilitiesStringLength(monitor, ctypes.byref(caps_string_length))
, however, this function call is incredibly slow.
In my testing, running windows.VCP.iter_physical_monitors
normally takes (on my system) around 5 milliseconds whereas running it with the check in place takes 2.8 seconds.
An alternative solution could be to ignore any monitor handles that fail after a certain number of tries. This approach does not work if a connected monitor is currently displaying the feed of a different machine, however.
I will do some research into this
Thank youI, I will wait for the solution.
I think I may have a solution.
According to the Microsoft documentation on EnumDisplayMonitors:
The EnumDisplayMonitors function enumerates display monitors (including invisible pseudo-monitors associated with the mirroring drivers) ...
This could explain the invalid "ghost" monitor handle that was being generated by windows.VCP.iter_physical_monitors
as that function calls upon ctypes.windll.user32.EnumDisplayMonitors
to get monitor handles.
According to this StackOverflow answer:
You can enumerate devices with
EnumDisplayMonitors()
and check if it is pseudo monitor withEnumDisplayDevices()
... Then usingEnumDisplayDevices()
you can getDISPLAY_DEVICE
which containsStateFlags
with info if current monitor is a pseudo monitor (or as in case bellow attached to desktop)
So my solution is to check the StateFlags
for each display for the DISPLAY_DEVICE_MIRRORING_DRIVER
flag.
I've pushed a first draft of this change to tmp/issue13. If you could try it out that would be great.
When I ran this code;
import screen_brightness_control as s
s.set_brightness('+10', display='Philips 246E7')
Output
[else clause] []
[pre-get_brightness call] []
GetVCPFeatureAndVCPFeatureReply failed after 50 attempts
[post-get_brightness call] [[]]
[pre-flatten_list call] [[]]
[post-flatten_list call] []
Traceback (most recent call last):
File "c:\Users\civan\Desktop\display.py", line 2, in <module>
s.set_brightness('+10', display='Philips 246E7')
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 114, in set_brightness
value += get_brightness(display=Monitor.get_identifier(monitors[0])[1])
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 43, in get_brightness
return __brightness(display=display, method=method, meta_method='get', verbose_error=verbose_error)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 1003, in __brightness
raise ScreenBrightnessError(msg)
screen_brightness_control.ScreenBrightnessError:
no valid output was received from brightness methods
This code may is not successful.
I have changed the StateFlags
check to check the win32con.DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
flag instead of the win32con.DISPLAY_DEVICE_MIRRORING_DRIVER
flag.
I hope this works!
Im update this commit https://github.com/Crozzers/screen_brightness_control/commit/7f8ec129f5ceba4dbd1e32015fc9e50e5d7b5019 , and I have installed. But I have fail.
My test code;
import screen_brightness_control as s
s.set_brightness('+10', display='Philips 246E7')
Output;
[else clause] []
[pre-get_brightness call] []
GetVCPFeatureAndVCPFeatureReply failed after 50 attempts
[post-get_brightness call] [[]]
[pre-flatten_list call] [[]]
[post-flatten_list call] []
Traceback (most recent call last):
File "c:\Users\civan\Desktop\display.py", line 2, in <module>
s.set_brightness('+10', display='Philips 246E7')
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 114, in set_brightness
value += get_brightness(display=Monitor.get_identifier(monitors[0])[1])
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 43, in get_brightness
return __brightness(display=display, method=method, meta_method='get', verbose_error=verbose_error)
File "D:\Python\Python39\lib\site-packages\screen_brightness_control\__init__.py", line 1003, in __brightness
raise ScreenBrightnessError(msg)
screen_brightness_control.ScreenBrightnessError:
no valid output was received from brightness methods
I think that means that the StateFlag
check is managing to identify the wrong monitor.
Could you send the output of:
import screen_brightness_control as s
for i in s.windows.enum_display_devices():
print({k: getattr(i, k) for k in dir(i) if not k.startswith('_')})
Okay,
Output,
{'Clear': <built-in method Clear of PyDISPLAY_DEVICE object at 0x00000211EAA5FA40>, 'DeviceID': '\\\\?\\DISPLAY#LGD05B9#4&8b59a2d&0&UID265988#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}', 'DeviceKey': '\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0002', 'DeviceName': '\\\\.\\DISPLAY1\\Monitor0', 'DeviceString': 'Generic PnP Monitor', 'Size': 840, 'StateFlags': 3}
{'Clear': <built-in method Clear of PyDISPLAY_DEVICE object at 0x00000211EAA60120>, 'DeviceID': '\\\\?\\DISPLAY#PHLC107#5&5e6cf88&0&UID4354#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}', 'DeviceKey': '\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4d36e96e-e325-11ce-bfc1-08002be10318}\\0001', 'DeviceName': '\\\\.\\DISPLAY4\\Monitor0', 'DeviceString': 'Generic PnP Monitor', 'Size': 840, 'StateFlags': 3}
'DeviceID': '\\\\?\\DISPLAY#LGD05B9#4...'
It would appear that the issue is not pseudo monitors but that the laptop display shows up as a desktop display occasionally. This should be simple enough to patch
windows.VCP.iter_physical_monitors
will now check if each device is actually a laptop display before returning a handle (via wmi.WmiMonitorBrightness
)
If you could try out that change I would be most grateful
It have worked, perfect! Thank you. You could merge to master.
Congratulations.
Ahmet Yasin CİVAN, TURKEY!
I'll get this merged, tested and deployed today. Thank you for all your help
v0.11.3 released with the fixes
This code works correctly on the first monitor but failed on the second monitor.
System; Windows 10
My code;
But only correctly
sbc.windows.VCP.set_brightness(10)
methot.Log;
My monitor info;