Scripting to respond to changes in Mac display state

Posted on
Fri May 22, 2020 9:48 am
SearchCz offline
Posts: 10
Joined: Sep 18, 2019

Scripting to respond to changes in Mac display state

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?

Posted on
Fri May 22, 2020 1:14 pm
matt (support) offline
Site Admin
User avatar
Posts: 19964
Joined: Jan 27, 2003
Location: Texas

Re: Scripting to respond to changes in Mac display state

Do you have the old script? I'm curious how it worked.

Image

Posted on
Sat May 23, 2020 11:51 am
SearchCz offline
Posts: 10
Joined: Sep 18, 2019

Re: Scripting to respond to changes in Mac display state

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

Posted on
Wed May 27, 2020 8:48 am
SearchCz offline
Posts: 10
Joined: Sep 18, 2019

Re: Scripting to respond to changes in Mac display state

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?

Posted on
Wed May 27, 2020 11:45 am
matt (support) offline
Site Admin
User avatar
Posts: 19964
Joined: Jan 27, 2003
Location: Texas

Re: Scripting to respond to changes in Mac display state

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")

Image

Posted on
Wed May 27, 2020 1:11 pm
jay (support) offline
Site Admin
User avatar
Posts: 16212
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Scripting to respond to changes in Mac display state

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"])

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Wed May 27, 2020 4:25 pm
SearchCz offline
Posts: 10
Joined: Sep 18, 2019

Re: Scripting to respond to changes in Mac display state

Thanks, gentlemen. This hits the spot. Now I know the office lights will turn off whenever the computer goes idle.

Much appreciated!

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 1 guest