Scripting to respond to changes in Mac display state

Posted on
Fri May 22, 2020 9:48 am
SearchCz offline
Posts: 44
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: 20568
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: 44
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: 44
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: 20568
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: 16815
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: 44
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!

Posted on
Tue Jul 07, 2020 4:59 pm
Sierra offline
Posts: 21
Joined: Jul 07, 2020

Re: Scripting to respond to changes in Mac display state

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

Posted on
Wed Jul 08, 2020 4:44 am
Turribeach offline
Posts: 323
Joined: Feb 06, 2015
Location: London, UK

Re: Scripting to respond to changes in Mac display state

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.

Posted on
Wed Jul 08, 2020 2:13 pm
Sierra offline
Posts: 21
Joined: Jul 07, 2020

Re: Scripting to respond to changes in Mac display state

Thanks a lot!! I got it working


Sent from my iPhone using Tapatalk

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 1 guest