Page 1 of 1

Airfoil python script to count connected speakers

PostPosted: Sat Mar 16, 2019 10:49 am
by ginganinja
Hi All,

I know that there is another post that has a script to count connected airfoil speakers but I could not get it to work, so I wrote my own. Basically the script will update a variable with the total count of connected speakers, then you can trigger on the variable being 0 and tell iTunes to stop playing. I don't count the local speakers on the mac, because i don't have any, but it's pretty clear in the script where i exclude that, so it matters to you, you can always remove those lines.

Code: Select all
# this script will go through a folder and check each device to see if it's
# a speaker and it connected
# I am using this with airfoil, to determine if anyone is listening to music
# After the script has run a variable will contain the number of speakers connected
# you can then create a trigger to stop the music from playing if the speaker count is 0
devConnectCount = 0

# Get a list of all devices
devs = indigo.devices

# Scroll through devices looking for ones that are in a specific folder, for me that is
# my airfoil folder
for dev in devs:
   if (dev.folderId == 1196330473): # airfoil
      # Now check if the device is a speaker and is currently connected
      if(dev.deviceTypeId == 'speaker' and dev.displayStateValUi == 'connected'):
         # Grab the states and make sure this is not the locally connected speaker
         # i.e. the mac default speaker, this speaker will typically alway be connected
         # although that is not a requirement, I just don't have speakers connected to
         # to my mac, so it's not important to me
         states = dev.states
         if(states['type'] != 'local'):
            devConnectCount = devConnectCount + 1
# Update the variable to the number of connected speakers, for me this 'ConnectedSpeakers'
indigo.variable.updateValue(1954203491, value=unicode(devConnectCount))

Re: Airfoil python script to count connected speakers

PostPosted: Sat Mar 16, 2019 11:35 am
by jay (support)
Very nice, thanks for the contribution.

Here are a few optimizations that will make the script more efficient and future proof:

Code: Select all
# this script will go through a folder and check each device to see if it's
# a speaker and it connected
# I am using this with airfoil, to determine if anyone is listening to music
# After the script has run a variable will contain the number of speakers connected
# you can then create a trigger to stop the music from playing if the speaker count is 0
devConnectCount = 0

# Iterate through all speaker devices
for dev in indigo.devices.iter("com.perceptiveautomation.indigoplugin.airfoilpro.speaker"):
   # If the speaker is in the correct folder and it's connected
   if (dev.folderId == 1196330473 and dev.displayStateValRaw == 'connected'):
      # Grab the states and make sure this is not the locally connected speaker
      # i.e. the mac default speaker, this speaker will typically alway be connected
      # although that is not a requirement, I just don't have speakers connected to
      # to my mac, so it's not important to me
      if(dev.states['type'] != 'local'):
         devConnectCount += 1
# Update the variable to the number of connected speakers, for me this 'ConnectedSpeakers'
indigo.variable.updateValue(1954203491, value=unicode(devConnectCount))


The changes I made:

  1. I only iterate through airfoil speaker devices. Using this iterator is significantly more efficient because it's executed on the server - so the only devices that get passed to the script are speaker devices, which is likely a much smaller number of device objects.
  2. I combined checking the folder ID with the state into a single if statement
  3. I changed dev.displayStateValUi to dev.displayStateValRaw because we could change what's displayed to the user (if for instance we wanted to localize it), but the raw value will never change

Note, however, there are some other things that I didn't do/address:

  • Not sure if you want this or not, but you could end up counting some devices twice because it's possible that the type of the speaker is "group" since Airfoil supports groups of speakers
  • If you happen to have 2 Airfoil "server" instances (you have Airfoil running on 2 different computers), then the current implementation would count all regardless. So you could also check dev.states["parentInstanceId"] against the ID of the instance device.

Re: Airfoil python script to count connected speakers

PostPosted: Tue Jul 02, 2019 7:05 am
by CBowles
Hi Jay,

I'm looking to implement the revised script you suggested in this post in my Indigo 7.3 system but it is failing with the following error:
Script Error embedded script: invalid syntax
Script Error around line 9 - "for dev in indigo.devices.iter("com.perceptiveautomation.indigoplugin.airfoilpro.speakar")"

I've updated it with my own folder and variable IDs and double checked the quotes but it is still failing.
I've had a good google but can't determine where the line is wrong. I'm using Indigo 7.3

Interestingly, the original poster's script works OK.

Any tips or pointers?

Re: Airfoil python script to count connected speakers

PostPosted: Tue Jul 02, 2019 7:17 am
by CliveS
CBowles wrote:
Script Error around line 9 - "for dev in indigo.devices.iter("com.perceptiveautomation.indigoplugin.airfoilpro.speakar")"

Any tips or pointers?


You have typed speakar instead of speaker on that line

Re: Airfoil python script to count connected speakers

PostPosted: Tue Jul 02, 2019 7:19 am
by forestfield
... and there should be a colon at the end of that line, i.e.

Code: Select all
for dev in indigo.devices.iter('com.perceptiveautomation.indigoplugin.airfoilpro.speaker'):

Re: Airfoil python script to count connected speakers

PostPosted: Tue Jul 02, 2019 8:37 am
by CBowles
Hi Chaps,

Many thanks for spotting the deliberate mistake (typo)! :) That was not there in the active script!
It seems the missing colon was the culprit so perhaps Jay could update the code so other don't fall into his well laid trap :wink:
All working fine now.

Thanks again,

Chris
--

Re: Airfoil python script to count connected speakers

PostPosted: Tue Jul 02, 2019 9:39 am
by jay (support)
CBowles wrote:
It seems the missing colon was the culprit so perhaps Jay could update the code so other don't fall into his well laid trap :wink:


Fixed, though I will say that it's important to understand Python syntax if you're going to use it!! ;)