Notice: This forum has been recovered from an old backup, so some content, links, and dates may be outdated. The forum is currently read-only while we restore sign-in and registration functionality. Details

If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.

Stop processing a different macro

If you have a question or need help, this is the place to be.
Post Reply
cableghost
Posts: 37
Joined: Thu Oct 10, 2013 9:43 pm

Stop processing a different macro

Post by cableghost »

As an Action, is there a way to stop a different macro from processing?

I have a simple macro setup if my computer changes to battery power, I wait 120 seconds, then Hibernate. I then have another macro to watch when back on ACadapter power. What I would like is if the power outage was intermittent, i.e. back on within 120 seconds, I would like the Hibernate macro to stop processing.
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Stop processing a different macro

Post by kgschlosser »

I would need to see the exact actions you have in those macros.

EG can only process one macro and one event at a time. So I do not know how you are waiting the 120 seconds.
If you like the work I have been doing then feel free to Image
cableghost
Posts: 37
Joined: Thu Oct 10, 2013 9:43 pm

Re: Stop processing a different macro

Post by cableghost »

I'm using a Wait Action, so to your point (see attached), I could not execute actions/events in a different macro until this one ended.

Is it possible to add some type of If/then action, i.e. after the Wait period, if power back on ACadapter, stop processing?

I've attempted using scripts, but as I'm not a true programmer, I get lost. Here's what I have as a script...

Code: Select all

from ctypes import windll, byref, Structure, c_ubyte, c_ulong

class SYSTEM_POWER_STATUS(Structure):
    _fields_ = [("ACLineStatus", c_ubyte),
                ("BatteryFlag", c_ubyte),
                ("BatteryLifePercent", c_ubyte),
                ("Reserved1", c_ubyte),
                ("BatteryLifeTime", c_ulong),
                ("BatteryFullLifeTime", c_ulong)]

sps = SYSTEM_POWER_STATUS()
windll.kernel32.GetSystemPowerStatus(byref(sps))
#print 'sps.ACLineStatus =',sps.ACLineStatus
#print 'sps.BatteryFlag =',sps.BatteryFlag
#print 'sps.BatteryLifePercent =',sps.BatteryLifePercent
#print 'sps.BatteryLifeTime =',sps.BatteryLifeTime
#print 'sps.BatteryFullLifeTime =',sps.BatteryFullLifeTime
eg.TriggerEvent('%s.%s' % ("PowerSource",("Battery","ACadapter")[sps.ACLineStatus]), prefix = "System")
Attachments
power_macro.jpg
power_macro.jpg (22.48 KiB) Viewed 2602 times
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Stop processing a different macro

Post by kgschlosser »

ok using the wait for 120 seconds i am surprised that by using the wait for 120 seconds EG doesn't crash.

the use of the wait action is not to delay the execution of a specific task. what you would want to use is the timer plugin to do what you need. this will create a thread that in a pre defined amount of time will generate an event. and from that event you would have it execute the action you want. this also provides a mechanism to cancel the timer if an event gets generated tht would change the state back to it's original.



so as an example. you would want to create 3 macros as follows. The timer plugin will allow for EG to continue about it's way to do whatever it is it needs to. and when the thread that is running the timer countdown expires it will trigger an event and that is the event that you would use to run the hibernate action


Macro - Hibernate Timer
Event - System.PowerSource.Battery
Action - Timer Add Timer 120 seconds generates event Battery.Hibernate

Macro - Hibernate
Event - Battery.Hibernate
Action - Hibernate Computer

Macro - Cancel Hibernate Timer
Event - System.PowerState.ACadapter
Action - Timer Cancel Timer Battery.Hibernate
If you like the work I have been doing then feel free to Image
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Stop processing a different macro

Post by kgschlosser »

cableghost wrote: I've attempted using scripts, but as I'm not a true programmer, I get lost. Here's what I have as a script...

Code: Select all

from ctypes import windll, byref, Structure, c_ubyte, c_ulong

class SYSTEM_POWER_STATUS(Structure):
    _fields_ = [("ACLineStatus", c_ubyte),
                ("BatteryFlag", c_ubyte),
                ("BatteryLifePercent", c_ubyte),
                ("Reserved1", c_ubyte),
                ("BatteryLifeTime", c_ulong),
                ("BatteryFullLifeTime", c_ulong)]

sps = SYSTEM_POWER_STATUS()
windll.kernel32.GetSystemPowerStatus(byref(sps))
#print 'sps.ACLineStatus =',sps.ACLineStatus
#print 'sps.BatteryFlag =',sps.BatteryFlag
#print 'sps.BatteryLifePercent =',sps.BatteryLifePercent
#print 'sps.BatteryLifeTime =',sps.BatteryLifeTime
#print 'sps.BatteryFullLifeTime =',sps.BatteryFullLifeTime
eg.TriggerEvent('%s.%s' % ("PowerSource",("Battery","ACadapter")[sps.ACLineStatus]), prefix = "System")

using a ctypes structure in this manner is not going to do what you need it to. the scructure is just a container to house the data. it does not make a request to get filled, kind of like passing an empty cup to have it filled with
water. the cup it's self doesn't ask the person that wants the water does. so you would have to ask to get the container filled.

that's a pretty good way of explaining it. i will have to remember that

it's a very complex process to get that container filled but it involves creating a dummy window (frame) that is invisible and then asking windows to notify you of power changes and you would pass a pointer or a memory location of that container to the windows notification system at that point. and also you would tell the windows notification system to "call you back" and give you a couple of small clues as to what information is coming in. then you would access that container that has now been filled up with new data to get the information you need. now all of this is done through the use of numbers. so you have to associate specific numbers that come to what the human readable version of it would be.

now that i am looking at that i am not 100% sure if it wouldn't work. i would have to dig into the GetPowerStatus API and see what it says. but I would think it would have to be a 2 part thing. because you never gave it the pointer to the container.
If you like the work I have been doing then feel free to Image
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Stop processing a different macro

Post by kgschlosser »

this script works. so you can see i set the arguments to a pointer of the structure and i also set the return type and then when i pass the initialized structure that is when i will use byref

the c_ulong and things of that nature you had correct i changed them for ease of readability against the Microsoft API documentation for GetSystemPowerStatus
but you can also see where i am checking the variables for specific numbers. these numbers have a meaning and that is what i turn into an event

Code: Select all

from ctypes import windll, Structure, POINTER, byref
from ctypes.wintypes import BYTE, DWORD


class SYSTEM_POWER_STATUS(Structure):
    _fields_ = [
    ("ACLineStatus", BYTE),
    ("BatteryFlag", BYTE),
    ("BatteryLifePercent", BYTE),
    ("Reserved1", BYTE),
    ("BatteryLifeTime", DWORD),
    ("BatteryFullLifeTime", DWORD)
    ]
    
GetSystemPowerStatusAPI = windll.kernel32.GetSystemPowerStatus
GetSystemPowerStatusAPI.argtypes = [POINTER(SYSTEM_POWER_STATUS)]
GetSystemPowerStatusAPI.restype = DWORD


def GetSystemPowerStatus(lpSystemPowerStatus):
    return GetSystemPowerStatusAPI(byref(lpSystemPowerStatus))


sps = SYSTEM_POWER_STATUS()


if GetSystemPowerStatus(sps):
    event = []
    if sps.ACLineStatus:
        event.append('Line')
    else:
        event.append('Battery')
        event.append('Status')
        
        flag = sps.BatteryFlag
        if flag == -128:
            event.append('NoBattery')
        elif flag == -255:
            event.append('Unknown')
        elif flag == 1:
            event.append('ChargeHigh')
        elif flag == 2:
            event.append('ChargeLow')
        elif flag == 4:
            event.append('ChargeCritical')
        elif flag == 8:
            event.append('Charging')
            
        event.append('Life')
        
        flag = sps.BatteryLifePercent
        if flag == -255:
            event.append('Unknown')
        else:
            event.append(str(flag) + '%')
        
        event.append('Saver')
        event.append('On' if sps.SystemStatusFlag else 'Off')
        
    eg.TriggerEvent(prefix='SystemPower', suffix='.'.join(event))
    
*** EDIT incorrect setting of argtypes and restype has now been fixed..
If you like the work I have been doing then feel free to Image
cableghost
Posts: 37
Joined: Thu Oct 10, 2013 9:43 pm

Re: Stop processing a different macro

Post by cableghost »

Thanks @kgschlosser. Let me work through all this and I'll respond back.
User avatar
kgschlosser
Site Admin
Posts: 5190
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Stop processing a different macro

Post by kgschlosser »

yeah hey no worries, if you have any questions feel free to ask away. and if ya get stuck on something let me know i will walk ya through it.
If you like the work I have been doing then feel free to Image
Post Reply