Control AirPlay with AppleScript and Domoticz
Posted: Monday 30 November 2015 20:55
Hi,
Here's a project I'm working on for a while now.
I have a couple of airplay locations in house (for example: bathroom, kitchen, garage).
At 6:30 radio starts playing in the bathroom, at 7:00 in the kitchen etcetera.
But I also wanted to control it manually on location with a hardware button.
The KlikaanKlikuit AWST-8802 switches trigger a switch in Domoticz (on Raspberry Pi) which does a webcall to my Mac which triggers the AppleScript.
The on-button has three functions:
(if music is not playing) start playing a specific radio station from specific playlist or
(if music is playing but not on this speaker) add this airport to itunes selected devices or
(if music is playing on this speaker) play next song.
The off-button has two functions:
(if music is playing on this speaker) remove this airport from selected itunes devices or
(if music is not playing on this speaker) let itunes stop playing over all speakers and remove all speakers as selected device.
The On-Action of the device looks like this:
The Off-Action of the device looks like this:
The webcall is a simple php script (with basic authentication) that looks like this:
The AppleScript looks like this: (I couldn't upload a scpt-extension file, edit with Script Editor app)
Please feel free to modify the code, it's absolutely not optimal. This is the first time I'm coding AppleScript.
Here's a project I'm working on for a while now.
I have a couple of airplay locations in house (for example: bathroom, kitchen, garage).
At 6:30 radio starts playing in the bathroom, at 7:00 in the kitchen etcetera.
But I also wanted to control it manually on location with a hardware button.
The KlikaanKlikuit AWST-8802 switches trigger a switch in Domoticz (on Raspberry Pi) which does a webcall to my Mac which triggers the AppleScript.
The on-button has three functions:
(if music is not playing) start playing a specific radio station from specific playlist or
(if music is playing but not on this speaker) add this airport to itunes selected devices or
(if music is playing on this speaker) play next song.
The off-button has two functions:
(if music is playing on this speaker) remove this airport from selected itunes devices or
(if music is not playing on this speaker) let itunes stop playing over all speakers and remove all speakers as selected device.
The On-Action of the device looks like this:
Code: Select all
http://admin:[email protected]/radio_control.php?state=on&speaker=AE_Kitchen&volume=50
Code: Select all
http://admin:[email protected]/radio_control.php?state=off&speaker=AE_Kitchen
Code: Select all
<?php
if (count($_GET) >= 2) {
$speaker = str_replace('_', ' ', $_GET['speaker']);
$cmd = 'sudo su "kevin" -c "/usr/bin/osascript /path/to/script/radio_airplay.scpt ' .
$_GET['state'] . ' ' .
'\'' . $speaker . '\' ' .
(@$_GET['volume'] ?: '') . '"';
$result = exec($cmd);
var_dump($cmd);
var_dump($result);
}
?>
Code: Select all
on run argv
try
set onOff to item 1 of argv
set inpDevicename to item 2 of argv
set inpVolume to 0
if (onOff is "on") then
set inpVolume to item 3 of argv
end if
on error
error number -128
return
end try
if onOff is "on" then
speakerOn(inpDevicename, inpVolume)
else if onOff is "off" then
speakerOff(inpDevicename)
end if
end run
on stopItunes()
tell application "iTunes"
pause
end tell
end stopItunes
on speakerOn(speakername, vol)
tell application "iTunes"
# check if speaker exists in home network
if not my is_speaker(speakername) then
log ("Airplay device '" & speakername & "' not found")
error number -128
return
end if
# check if speaker is already active
if not my is_current_speaker(speakername) then
log ("setting device " & speakername)
my set_speaker(speakername, vol)
# else play next track (speaker is active)
else if player state is playing then
next track
end if
# if itunes is not playing yet, start with 3FM
if player state is not playing then
play playlist "Stream (radio)"
play track "3FM" of playlist "Stream (radio)"
end if
end tell
end speakerOn
on speakerOff(speakername)
tell application "iTunes"
# check if speaker exists in home network
if not my is_speaker(speakername) then
log ("Airplay device '" & speakername & "' not found")
error number -128
return
end if
# check if speaker is already active
if my is_current_speaker(speakername) then
log ("unsetting device " & speakername)
my unset_speaker(speakername)
else
my unset_all_speakers()
end if
end tell
end speakerOff
on set_speaker(speakername, vol)
tell application "iTunes"
set apDevices to (get AirPlay devices where selected is true)
set speaker to (first AirPlay device whose name = speakername)
set sound volume of speaker to vol
# add speaker to speakerlist
copy speaker to the end of apDevices
set current AirPlay devices to apDevices
end tell
end set_speaker
on unset_speaker(speakername)
tell application "iTunes"
set apDevices to (get AirPlay devices where selected is true)
set speaker to (first AirPlay device whose name = speakername)
# remove speaker from speakerlist
set apDevicesNew to {}
repeat with aDevice in apDevices
if (aDevice's name as string is not speakername) then
copy aDevice to the end of apDevicesNew
end if
end repeat
set current AirPlay devices to apDevicesNew
if (count apDevicesNew) is 1 then
my stopItunes()
end if
end tell
end unset_speaker
on unset_all_speakers()
tell application "iTunes"
set speaker to (first AirPlay device whose name = "Computer")
set current AirPlay devices to speaker
my stopItunes()
end tell
end unset_all_speakers
on is_speaker(speakername)
tell application "iTunes"
set apDevices to (get name of every AirPlay device)
set deviceFound to false
repeat with aDevice in apDevices
if (aDevice as string is speakername) then
set deviceFound to true
end if
end repeat
return deviceFound
end tell
end is_speaker
on is_current_speaker(speakername)
tell application "iTunes"
set apDevices to (get name of AirPlay devices where selected is true)
set deviceFound to false
repeat with aDevice in apDevices
if (aDevice as string is speakername) then
set deviceFound to true
end if
end repeat
return deviceFound
end tell
end is_current_speaker