Page 1 of 1

Scripting to respond to changes in Mac display state

PostPosted: Fri May 22, 2020 9:48 am
by SearchCz
When I was on Indigo 6, I used to have a script that checked the status of my display periodically and set an Indigo variable accordingly/]. That way, whenever my computer was idle for a bit and the display went in to screen save or sleep mode, I could trigger a corresponding scene change in my office.

When I switched to Indigo 7, I axed that script entirely. I'm trying to get that capability back, and I'm a bit stumped.

Any ideas on how I can can get some visibility to the Mac display status in Indigo, presumably with a python script?

Re: Scripting to respond to changes in Mac display state

PostPosted: Fri May 22, 2020 1:14 pm
by matt (support)
Do you have the old script? I'm curious how it worked.

Re: Scripting to respond to changes in Mac display state

PostPosted: Sat May 23, 2020 11:51 am
by SearchCz
I had a backup with the old script. it went like this:

Code: Select all
set display_sleep_state to do shell script "ioreg -n IODisplayWrangler |grep -i IOPowerManagement"

if display_sleep_state contains "\"DEVICEPOWERSTATE\"=1" or display_sleep_state contains "\"DEVICEPOWERSTATE\"=0" then
   -- Display is asleep
   tell application "IndigoServer"
      set value of variable "OFFICESTATUS" to 0
   end tell
   
else if display_sleep_state contains "\"DEVICEPOWERSTATE\"=4" then
   -- Display is awake
   tell application "System Events" to set the saveractivated to (exists process "ScreenSaverEngine")
   
   if saveractivated then
      
      tell application "IndigoServer"
         set value of variable "OFFICESTATUS" to 1
      end tell
      
   else
      
      tell application "IndigoServer"
         set value of variable "OFFICESTATUS" to 2
      end tell
      
   end if
   
else
   -- We don't know.
   
   tell application "IndigoServer"
      log "Display State:"
      log display_sleep_state
   end tell
end if

Re: Scripting to respond to changes in Mac display state

PostPosted: Wed May 27, 2020 8:48 am
by SearchCz
matt (support) wrote:
Do you have the old script? I'm curious how it worked.

I wrote a cleaner new bash script to extract the DevicePowerState. Works great from the Terminal command line. It goes like this:

Code: Select all
#!/bin/bash
display_sleep_state=$(ioreg -n IODisplayWrangler |grep -i IOPowerManagement)
sub='"DevicePowerState"='
rest=${display_sleep_state#*$sub}
echo ${rest:0:1}


When I run the script
1) display_sleep_state gets set to:
| | | "IOPowerManagement" = {"DevicePowerState"=4,"CurrentPowerState"=4,"CapabilityFlags"=32832,"MaxPowerState"=4}

2) rest gets set to:
4,"CurrentPowerState"=4,"CapabilityFlags"=32832,"MaxPowerState"=4}

3) I echo the first character of that result.
4

Beautiful! But when I have Indigo 7.4 run that same script (and place the value in a variable) my result is an empty string. I suspect that I may have a scope problem, but don't know how to confirm or overcome it. Any advice?

Re: Scripting to respond to changes in Mac display state

PostPosted: Wed May 27, 2020 11:45 am
by matt (support)
The ioreg call needs the complete path. I'd also recommend doing it all from python like this:

Code: Select all
command = """
display_sleep_state=$(/usr/sbin/ioreg -n IODisplayWrangler |grep -i IOPowerManagement)
sub='"DevicePowerState"='
rest=${display_sleep_state#*$sub}
echo ${rest:0:1}
"""

import subprocess
reply = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
indigo.server.log("result is: " + reply[0])


Note the result is in reply[0]. Also note the result includes a \n character after the 4. You might want to strip that off:

reply[0].strip()

Roughly the rest of your script might look something like (untested):

Code: Select all
officeStatueVarID = 1234567    # Use variable ID from Indigo
powerState = reply[0].strip()
if powerState == "1":
   indigo.variable.updateValue(officeStatueVarID, value="0")
elif powerState == "4":
   # If you want to check for ScreenSaverEngine process running you might need to execute another shell script
   indigo.variable.updateValue(officeStatueVarID, value="1")
else:
   indigo.server.log("unknown power state")

Re: Scripting to respond to changes in Mac display state

PostPosted: Wed May 27, 2020 1:11 pm
by jay (support)
Slightly more Pythonic version (guess we were working on the same post) that can be embedded as a normal Python script action:

Code: Select all
import subprocess, shlex

reply = subprocess.Popen("/usr/sbin/ioreg -n IODisplayWrangler |grep -i IOPowerManagement", shell=True, stdout=subprocess.PIPE).stdout.read()
lexer = shlex.shlex(re.split(r'{|}', reply)[1], posix=True)
lexer.whitespace_split = True
lexer.whitespace = ","
power_management_props = dict(pair.split("=", 1) for pair in lexer)
# At this point, you have a dictionary that contains all the name/value pairs of the IOPowerManagement information
indigo.variable.updateValue(552164998, value=power_management_props["CurrentPowerState"])

Re: Scripting to respond to changes in Mac display state

PostPosted: Wed May 27, 2020 4:25 pm
by SearchCz
Thanks, gentlemen. This hits the spot. Now I know the office lights will turn off whenever the computer goes idle.

Much appreciated!

Re: Scripting to respond to changes in Mac display state

PostPosted: Tue Jul 07, 2020 4:59 pm
by Sierra
Sorry for the beginner question. I was looking for similar funtionality as sometimes my sensor does not detect motion while working.

Question is where I do need to create/save this script? Is there a guide I can use?

Tx

Re: Scripting to respond to changes in Mac display state

PostPosted: Wed Jul 08, 2020 4:44 am
by Turribeach
This is very useful, thanks! I put my movement sensor next to my mouse pad so I don't get any unwanted turning off of my home office light these days but this method is much better I think. There are 3 scripts on this Apple Script, Bash Shell Script y Python script. All of them should be able to do what you want. The easiest one to implement is probably Jay's. Just grab his code and put it on an Action Group and execute it as part of Execute Script => Embedded Python. You need to create a new variable and get the variable ID and replace it on Jay's code. Then you can create a schedule and execute the Action Group every minute or so to update your variable. Finally create a trigger to update your light based on changes of the variable.

Re: Scripting to respond to changes in Mac display state

PostPosted: Wed Jul 08, 2020 2:13 pm
by Sierra
Thanks a lot!! I got it working


Sent from my iPhone using Tapatalk