MQTT Client

Questions and comments specific to a particular plugin should go here.
Snowbird
Experienced User
Posts: 360
Joined: Fri Jul 03, 2009 10:04 am

Re: MQTT Client

Post by Snowbird » Fri Jul 13, 2018 5:12 pm

this is something missing in EG for such a long time ;) the only way I've found to do this is with WMI, but the WMI lib needs to be loaded.

you can download the wmi zip file here : https://pypi.org/project/WMI/#files

then open the zip file and place the wmi.py file here : %programfiles(x86)%\EventGhost\lib27\site-packages

for example to get the current brightness you can run this code :

Code: Select all

import wmi
c = wmi.WMI(namespace='wmi')
GetBrightness = c.WmiMonitorBrightness()[0]
print "Brightness " + str(GetBrightness.CurrentBrightness) +"%"
Here's an example to set the brightness to 60% :

Code: Select all

import wmi
BrightLevel = 60
c = wmi.WMI(namespace='wmi')
methods = c.WmiMonitorBrightnessMethods()[0]
methods.WmiSetBrightness(BrightLevel, 0)
I always thought that WMI should be embedded to Evenghost, since you can do so much with WMI, but there must be a valid reason why it has never been done.

User avatar
kgschlosser
Site Admin
Posts: 4652
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MQTT Client

Post by kgschlosser » Sat Jul 14, 2018 4:04 am

you don't have to worry about adding the wmi module.

read HERE


@Snowbird
I have not forgotten the XMPP Plus plugin, My eyes were going cross eyed looking at that disaster called sleekxmpp. I really do hate voodoo magic code. i needed a break from it.
If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 4652
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MQTT Client

Post by kgschlosser » Sat Jul 14, 2018 4:50 am

Snowbird wrote:
Fri Jul 13, 2018 5:12 pm
I always thought that WMI should be embedded to Evenghost, since you can do so much with WMI, but there must be a valid reason why it has never been done.

The reason why is because i do not believe the WMI module is being supported anymore. Plus WMI is horrendously slow, woven all about in a really screwed up manner, and everything that you can do with it can be done without the need for using COM. (which is what the wmi library uses)

as an example. to get all drive letters using WMI

Code: Select all

import pythoncom
import win32com.client

pythoncom.CoInitialize()
wmi = win32com.client.GetObject("winmgmts:\\root\\cimv2")
drive_letters = []


logical_disks = wmi.ExecQuery("Select * from Win32_LogicalDisk")

for disk in logical_disks:
    drive_types = (
        None,
        None,
        'DiskDrive',
        'DiskDrive',
        'MappedLogicalDisk',
        'CDROMDrive',
        'DiskDrive',
    )

    drive_type = drive_types[disk.DriveType]
    if drive_type is not None:
        drives =wmi.ExecQuery(
            'Select * from Win32_' + drive_type
        )
        for drive in drives:
            if drive_type == 'CDROMDrive':
                drive_letters += [drive.Drive[:-1]]
            elif drive_type == 'MappedLogicalDisk':
                drive_letters += [drive.Name[:-1]]
            else:
                partitionQuery = (
                    'ASSOCIATORS OF {Win32_DiskDrive.DeviceID="%s"} '
                    'WHERE AssocClass=Win32_DiskDriveToDiskPartition' %
                    drive.DeviceID.replace('\\', '\\\\')
                )
                for partition in wmi.ExecQuery(partitionQuery):
                    diskQuery = (
                        'ASSOCIATORS OF {Win32_DiskPartition.DeviceID="%s"} '
                        'WHERE AssocClass=Win32_LogicalDiskToPartition' %
                        partition.DeviceID
                    )
                    for logical_disc in wmi.ExecQuery(diskQuery):
                        drive_letters += [logical_disc.DeviceID[:-1]]

print drive_letters

and to do the same using ctypes and a single API function call.

Code: Select all


import ctypes
from ctypes.wintypes import DWORD

GetLogicalDrives = ctypes.windll.kernel32.GetLogicalDrives
GetLogicalDrives.restype = DWORD

drive_letters = []
uDriveMask = GetLogicalDrives()

for i in range(27):
    if uDriveMask & 1:
        drive_letters += [chr(i + 65)]

    uDriveMask >>= 1

    if not uDriveMask:
        break

print drive_letters
so as you can see based on sheer amount of code. WMI loses
the nested layers of SQL database access just to obtain the drive letters is BONKERS with WMI. so as far as the code complexity WMI loses
The readability of the code WMI loses
and using WMI is horribly slow. SQL queries take time and having to do 3 or 4 of them just to get a drive letter is COO COO


so goes the reason for not using WMI in the core. It can be added to EG if a user wants and that i think is good enough :-D if you disagree the complaint department is HERE :D JK
If you like the work I have been doing then feel free to Image

Terr
Posts: 14
Joined: Wed Jul 11, 2018 8:42 am

Re: MQTT Client

Post by Terr » Sat Jul 14, 2018 6:56 am

Snowbird wrote:
Fri Jul 13, 2018 5:12 pm

Code: Select all

import wmi
c = wmi.WMI(namespace='wmi')
GetBrightness = c.WmiMonitorBrightness()[0]
print "Brightness " + str(GetBrightness.CurrentBrightness) +"%"
eventghost 0.5
try add code to python script
log errors

Code: Select all

Python Script
   Traceback (most recent call last):
     Python script "24", line 3, in <module>
       GetBrightness = c.WmiMonitorBrightness()[0]
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\wmi.py", line 819, in query
       handle_com_error ()
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\wmi.py", line 241, in handle_com_error
       raise klass (com_error=err)
   x_wmi: <x_wmi: Unexpected COM Error (-2147217396, 'OLE error 0x8004100c', None, None)>
the complaint department is HERE
lol )

Snowbird
Experienced User
Posts: 360
Joined: Fri Jul 03, 2009 10:04 am

Re: MQTT Client

Post by Snowbird » Sat Jul 14, 2018 7:04 am

thanks Kevin for this complete explanation, I knew there was a good reason behind it, now I know what it is ! ;) the only drawback for me is that WMI has been around for so many years, and seems "easier" to use, I'm not very familiar with ctypes and API function calls, but that's something I can learn. If the same things can be achieved with less code and faster, then it's a good reason not to use WMI anymore :)
Last edited by Snowbird on Sat Jul 14, 2018 7:28 am, edited 1 time in total.

Snowbird
Experienced User
Posts: 360
Joined: Fri Jul 03, 2009 10:04 am

Re: MQTT Client

Post by Snowbird » Sat Jul 14, 2018 7:11 am

kgschlosser wrote:
Sat Jul 14, 2018 4:04 am
you don't have to worry about adding the wmi module.

read HERE
Seems to be promising ! :) Can't wait to see it n action ! thanks for all your efforts, really appreciated !

kgschlosser wrote:
Sat Jul 14, 2018 4:04 am
@Snowbird
I have not forgotten the XMPP Plus plugin, My eyes were going cross eyed looking at that disaster called sleekxmpp. I really do hate voodoo magic code. i needed a break from it.
I want you to be a Voodoo specialist ! :D you'll thank me later :) all kidding aside, I'm struggling everyday with this, so the sooner you'll fix this and the more chances you'll get to continue talking to a sane person : me ! :) you are warned LOL

Snowbird
Experienced User
Posts: 360
Joined: Fri Jul 03, 2009 10:04 am

Re: MQTT Client

Post by Snowbird » Sat Jul 14, 2018 7:24 am

Code: Select all

Python Script
   Traceback (most recent call last):
     Python script "24", line 3, in <module>
       GetBrightness = c.WmiMonitorBrightness()[0]
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\wmi.py", line 819, in query
       handle_com_error ()
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\wmi.py", line 241, in handle_com_error
       raise klass (com_error=err)
   x_wmi: <x_wmi: Unexpected COM Error (-2147217396, 'OLE error 0x8004100c', None, None)>
that's strange...

try to change this line :
c = wmi.WMI(namespace='wmi')
with this one :
c = wmi.WMI(namespace='cimv2')

Terr
Posts: 14
Joined: Wed Jul 11, 2018 8:42 am

Re: MQTT Client

Post by Terr » Sat Jul 14, 2018 7:41 am

Snowbird wrote:
Sat Jul 14, 2018 7:24 am
try to change this line :
c = wmi.WMI(namespace='wmi')
with this one :
c = wmi.WMI(namespace='cimv2')

Code: Select all

   Traceback (most recent call last):
     Python script "52", line 3, in <module>
       GetBrightness = c.WmiMonitorBrightness()[0]
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\wmi.py", line 1147, in __getattr__
       return getattr (self._namespace, attribute)
     File "win32com\client\dynamic.pyc", line 527, in __getattr__
   AttributeError: winmgmts:root/cimv2.WmiMonitorBrightness

User avatar
kgschlosser
Site Admin
Posts: 4652
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MQTT Client

Post by kgschlosser » Sat Jul 14, 2018 9:01 am

woooo

Follow the instructions at the top of the script

Code: Select all

# Set the 2 values below, 
# the monitor number is the number you see in Display Properties
# Brightness is from 0 - 100

MONITOR_NUMBER = 1
BRIGHTNESS = 100

import ctypes
from ctypes.wintypes import HMONITOR, BOOL, DWORD, HDC, RECT, LPARAM, WCHAR

NULL = None
PHYSICAL_MONITOR_DESCRIPTION_SIZE = 128

dxva2 = ctypes.windll.dxva2
user32 = ctypes.windll.user32

MONITORENUMPROC = ctypes.WINFUNCTYPE(
    BOOL,
    HMONITOR,
    HDC,
    ctypes.POINTER(RECT),
    LPARAM
)


class _PHYSICAL_MONITOR(ctypes.Structure):
    _fields_ = [
        ('hPhysicalMonitor', HMONITOR),
        (
            'szPhysicalMonitorDescription',
            WCHAR * PHYSICAL_MONITOR_DESCRIPTION_SIZE
        )
    ]


PHYSICAL_MONITOR = _PHYSICAL_MONITOR

GetNumberOfPhysicalMonitorsFromHMONITOR = (
    dxva2.GetNumberOfPhysicalMonitorsFromHMONITOR
)
GetNumberOfPhysicalMonitorsFromHMONITOR.restype = BOOL

SetMonitorBrightness = dxva2.SetMonitorBrightness
SetMonitorBrightness.restype = BOOL

GetPhysicalMonitorsFromHMONITOR = (
    dxva2.GetPhysicalMonitorsFromHMONITOR
)
GetPhysicalMonitorsFromHMONITOR.restype = BOOL

EnumDisplayMonitors = user32.EnumDisplayMonitors
EnumDisplayMonitors.restype = BOOL


def get_displays():
    """Get a list of the available displays"""

    def MonitorEnumProc(hMonitor, *_):
        hMonitors.append(hMonitor)
        return True

    hMonitors = []
    pPhysicalMonitors = []

    # get display monitors
    if not EnumDisplayMonitors(
        NULL,
        NULL,
        MONITORENUMPROC(MonitorEnumProc),
        NULL
    ):
        raise ctypes.WinError()

    # get physical monitors for each display monitor
    for hMonitor in hMonitors:
        pdwNumberOfPhysicalMonitors = DWORD()
        if not GetNumberOfPhysicalMonitorsFromHMONITOR(
            hMonitor,
            ctypes.byref(pdwNumberOfPhysicalMonitors)
        ):
            raise ctypes.WinError()

        pPhysicalMonitorArray = (
            PHYSICAL_MONITOR * pdwNumberOfPhysicalMonitors.value
        )()

        if not GetPhysicalMonitorsFromHMONITOR(
            hMonitor,
            pdwNumberOfPhysicalMonitors,
            pPhysicalMonitorArray
        ):
            raise ctypes.WinError()

        for pPhysicalMonitor in pPhysicalMonitorArray:
            pPhysicalMonitors.append(pPhysicalMonitor.hPhysicalMonitor)

    return pPhysicalMonitors


SetMonitorBrightness(get_displays()[MONITOR_NUMBER - 1], DWORD(BRIGHTNESS))

If you like the work I have been doing then feel free to Image

Snowbird
Experienced User
Posts: 360
Joined: Fri Jul 03, 2009 10:04 am

Re: MQTT Client

Post by Snowbird » Sat Jul 14, 2018 9:14 am

no errors but nothing happens LOL tried different values, is there anything special to to on a laptop ?

User avatar
kgschlosser
Site Admin
Posts: 4652
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MQTT Client

Post by kgschlosser » Sat Jul 14, 2018 5:20 pm

give this a try

Code: Select all


BRIGHTNESS = 100


import ctypes
from ctypes.wintypes import HMONITOR, BOOL, DWORD, HDC, RECT, LPARAM, WCHAR

NULL = None
PHYSICAL_MONITOR_DESCRIPTION_SIZE = 128

dxva2 = ctypes.windll.dxva2
user32 = ctypes.windll.user32

MONITORENUMPROC = ctypes.WINFUNCTYPE(
    BOOL,
    HMONITOR,
    HDC,
    ctypes.POINTER(RECT),
    LPARAM
)


class _PHYSICAL_MONITOR(ctypes.Structure):
    _fields_ = [
        ('hPhysicalMonitor', HMONITOR),
        (
            'szPhysicalMonitorDescription',
            WCHAR * PHYSICAL_MONITOR_DESCRIPTION_SIZE
        )
    ]


PHYSICAL_MONITOR = _PHYSICAL_MONITOR


CapabilitiesRequestAndCapabilitiesReply = (
    dxva2.CapabilitiesRequestAndCapabilitiesReply
)
CapabilitiesRequestAndCapabilitiesReply.restype = BOOL

GetCapabilitiesStringLength = dxva2.GetCapabilitiesStringLength
GetCapabilitiesStringLength.restype = BOOL

GetNumberOfPhysicalMonitorsFromHMONITOR = (
    dxva2.GetNumberOfPhysicalMonitorsFromHMONITOR
)
GetNumberOfPhysicalMonitorsFromHMONITOR.restype = BOOL

SetMonitorBrightness = dxva2.SetMonitorBrightness
SetMonitorBrightness.restype = BOOL


GetPhysicalMonitorsFromHMONITOR = (
    dxva2.GetPhysicalMonitorsFromHMONITOR
)
GetPhysicalMonitorsFromHMONITOR.restype = BOOL

EnumDisplayMonitors = user32.EnumDisplayMonitors
EnumDisplayMonitors.restype = BOOL


def get_displays():
    """Get a list of the available displays"""

    def MonitorEnumProc(hMonitor, *_):
        pdwNumberOfPhysicalMonitors = DWORD()
        
        if not GetNumberOfPhysicalMonitorsFromHMONITOR(
            hMonitor,
            ctypes.byref(pdwNumberOfPhysicalMonitors)
        ):
            raise ctypes.WinError()

        pPhysicalMonitorArray = (
            PHYSICAL_MONITOR * pdwNumberOfPhysicalMonitors.value
        )()
        
        if not GetPhysicalMonitorsFromHMONITOR(
            hMonitor,
            pdwNumberOfPhysicalMonitors,
            pPhysicalMonitorArray
        ):
            raise ctypes.WinError()
        
        for pPhysicalMonitor in pPhysicalMonitorArray:
            pPhysicalMonitors.append(pPhysicalMonitor.hPhysicalMonitor)
            
        return True

    pPhysicalMonitors = []

    # get display monitors
    if not EnumDisplayMonitors(
        NULL,
        NULL,
        MONITORENUMPROC(MonitorEnumProc),
        NULL
    ):
        raise ctypes.WinError()

    return pPhysicalMonitors

for hMonitor in get_displays():
    SetMonitorBrightness(hMonitor, DWORD(BRIGHTNESS))
    

Now this may or may not work This is all dependant on the monitor it's self.
If you like the work I have been doing then feel free to Image

Snowbird
Experienced User
Posts: 360
Joined: Fri Jul 03, 2009 10:04 am

Re: MQTT Client

Post by Snowbird » Sat Jul 14, 2018 5:37 pm

same result :) no errors, but nothing happens no matter what value I set.

User avatar
kgschlosser
Site Admin
Posts: 4652
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MQTT Client

Post by kgschlosser » Sat Jul 14, 2018 6:31 pm

could be that the brightness cannot be set.

let me add some error reporting on the last function call

Code: Select all

BRIGHTNESS = 100


import ctypes
from ctypes.wintypes import HMONITOR, BOOL, DWORD, HDC, RECT, LPARAM, WCHAR

NULL = None
PHYSICAL_MONITOR_DESCRIPTION_SIZE = 128

dxva2 = ctypes.windll.dxva2
user32 = ctypes.windll.user32

MONITORENUMPROC = ctypes.WINFUNCTYPE(
    BOOL,
    HMONITOR,
    HDC,
    ctypes.POINTER(RECT),
    LPARAM
)


class _PHYSICAL_MONITOR(ctypes.Structure):
    _fields_ = [
        ('hPhysicalMonitor', HMONITOR),
        (
            'szPhysicalMonitorDescription',
            WCHAR * PHYSICAL_MONITOR_DESCRIPTION_SIZE
        )
    ]


PHYSICAL_MONITOR = _PHYSICAL_MONITOR


CapabilitiesRequestAndCapabilitiesReply = (
    dxva2.CapabilitiesRequestAndCapabilitiesReply
)
CapabilitiesRequestAndCapabilitiesReply.restype = BOOL

GetCapabilitiesStringLength = dxva2.GetCapabilitiesStringLength
GetCapabilitiesStringLength.restype = BOOL

GetNumberOfPhysicalMonitorsFromHMONITOR = (
    dxva2.GetNumberOfPhysicalMonitorsFromHMONITOR
)
GetNumberOfPhysicalMonitorsFromHMONITOR.restype = BOOL

SetMonitorBrightness = dxva2.SetMonitorBrightness
SetMonitorBrightness.restype = BOOL


GetPhysicalMonitorsFromHMONITOR = (
    dxva2.GetPhysicalMonitorsFromHMONITOR
)
GetPhysicalMonitorsFromHMONITOR.restype = BOOL

EnumDisplayMonitors = user32.EnumDisplayMonitors
EnumDisplayMonitors.restype = BOOL


def get_displays():
    """Get a list of the available displays"""

    def MonitorEnumProc(hMonitor, *_):
        pdwNumberOfPhysicalMonitors = DWORD()
        
        if not GetNumberOfPhysicalMonitorsFromHMONITOR(
            hMonitor,
            ctypes.byref(pdwNumberOfPhysicalMonitors)
        ):
            raise ctypes.WinError()

        pPhysicalMonitorArray = (
            PHYSICAL_MONITOR * pdwNumberOfPhysicalMonitors.value
        )()
        
        if not GetPhysicalMonitorsFromHMONITOR(
            hMonitor,
            pdwNumberOfPhysicalMonitors,
            pPhysicalMonitorArray
        ):
            raise ctypes.WinError()
        
        for pPhysicalMonitor in pPhysicalMonitorArray:
            pPhysicalMonitors.append(pPhysicalMonitor.hPhysicalMonitor)
            
        return True

    pPhysicalMonitors = []

    # get display monitors
    if not EnumDisplayMonitors(
        NULL,
        NULL,
        MONITORENUMPROC(MonitorEnumProc),
        NULL
    ):
        raise ctypes.WinError()

    return pPhysicalMonitors

for hMonitor in get_displays():
    if not SetMonitorBrightness(hMonitor, DWORD(BRIGHTNESS)):
        raise ctypes.WinError()

Oh one other thing. This is ging to be a nice thing. This whole thing I am working on with the VESA MCCS coms there is the ability to blank the screen. I am hoping this is also going to turn off the back light.

The other cool thing is if it works is the ability to turn off a single display. the windows API only has monitor off and monitor on which is for all monitors. this is a nice thing for those of us who have dual monitors one for the PC and the other is a TV for watching movies. now we will be able to turn off the monitor and leave the TV on or possibly even black out the monitor if powering it off does something funky with the desktop.
If you like the work I have been doing then feel free to Image

Snowbird
Experienced User
Posts: 360
Joined: Fri Jul 03, 2009 10:04 am

Re: MQTT Client

Post by Snowbird » Sat Jul 14, 2018 6:48 pm

here's the error I get now :

Code: Select all

14/07  20:47:31      Traceback (most recent call last):
14/07  20:47:31        Python script "175", line 104, in <module>
14/07  20:47:31          raise ctypes.WinError()
14/07  20:47:31      WindowsError: [Error -1071241854] An error occurred while transmitting data to the device on the I2C bus.

User avatar
kgschlosser
Site Admin
Posts: 4652
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: MQTT Client

Post by kgschlosser » Sat Jul 14, 2018 9:40 pm

OK so it is working. I am thinking that your screen does not support it directly.

Are you using a Laptop?
If it is a laptop it could be something the laptop designer made in a way that the brightness is not controlled by the screen but instead by some other mechanism.

You have to remember that these controls need to be implemented by the screen manufacturer if it is not then it will not work. we can test another thing if you want to see if your screen even supports the VESA MCCS control standard.

But lets jump that conversation on over to the thread I made for the plugin instead of here. it is going off topic from this thread.
If you like the work I have been doing then feel free to Image

Post Reply