iTunes + Airplay instead of Sonos?

Yup, @brianlees is right. To use the speaker selection, you need to have the device and smartapps from us. Unfortunately these updates are still not approved by SmartThings :frowning:, so manual install is the only way to make it work.

LOVE OBYCODE!!! Great job guys - have been using for a while now… Anyway to get it to automatically “re-discover” when the Mac IP address changes from DHCP ? Like storing the device network name in the ST app and then doing a discovery by subscribing to the location events?? That would be cool!!! Whenever I take my laptop away and then get a new IP I have to “jiggle” everything and I am just too lazy for that…

That would be great, but unfortunately, I’m not sure that’s possible right now, due to limitations in SmartThings interfaces. There is supposed to be Bonjour support, which we could potentially use to do this, but last time we tried it, it was not working as described and there was very little documentation or help on this. We will definitely keep this on the todo list for the future.

Many Airplay speakers have dlna, you can use RELEASE Generic Media Renderer (DLNA Speakers). Cheap Sonos Alternative (Update V2) to send music and alert to speakers, just verify if your speakers have dlna. it works with any smartapp to sonos. try it

Hey Cooper,
Depending on what kind of router you have, it’s probably possible to “reserve” a DHCP IP address based on your laptop’s MAC address. So you’ll have the equivalent of a static IP address without all of the downsides.

1 Like

You can use your airplay and bluetooth speakers if you use a PC Server, try it [RELEASE] Airplay and Bluetooth Speakers Working from PC server

Hi folks,

Any updates to this? I would like to be able to control iTunes at home from work.

Thank you.

John

Seems to me this is asking for a LOT of work to do a very limited thing. I imagine the same amount of work could be done to give ST a handle into AppleScript, and then a whole new world of possibilities would open up, far beyond just iTunes and AirPlay, for the same amount of work.

Or maybe I’m naive about the work required. But wow, Applescript hooks into and out of ST would be amazing.

Check out HAM Bridge…there’s more info scattered around, but @scottinpollock setup sounds like it works very well for him!

I bought your HAM Bridge, and by combining it with HA Bridge I’ve been able to add an iTunes ‘Hue light’; by adding the HAM Bridge GET url for the iTunesPlay and iTunesPause applescripts into the on and off sections in HA Bridge. I really want to assign HAM Bridge commands into the Smartthings Media controller (HAM Bridge commands for play, pause, skip, rewind, etc) but I’m not a great coder, if it were open (users input the HAM Bridge command for each button on the remote then they could assign separate iTunes and Spotify remotes, maybe even multiple e.g.pause could trigger multiple pause commands (or just one to launch an AppleScript app that tells multiple applications). I currently have iTunes and Spotify pause when the home mode changes to Away, and an iTunes alarm set by time - I did this by combining your smartthings Ham Bridge smart app with Obything (just to get the mode and time sections).

@ijaspley

I am not clear what your question is, but HAM Bridge can run scripts that do multiple things. I have quite a number that manage the whole house. These are AppleScripts that tell the Mac to do things, as well as run shell and python scripts (called from AppleScript’s ‘do shell script’ command) that control Hue, thermostats, and AudioVideo gear directly via local APIs and a Global Caché iTach.

Time and presence triggers are all sent from SmartThings’ SmartApps that do what they do, plus send a command to HAM Bridge. Adding this capability to any SmartApp takes only a half dozen or so lines of code and is described on the Help page.

HTH

Hi, sorry about my confusing, ranting comment. I’m very pleased with HAM Bridge, it’s my new favourite toy! I’ve set up mostly media and safari commands so far. I guess my question is if I have a Smartthings music controller app and currently the play button triggers:
play()
Is there a bit of code to make it talk to HAM Bridge and trigger my iTunes play command instead? I’d like to do this for all the buttons in the app but I’ll start with play if you can help

I don’t see an app named ‘SmartThings music controller’ in the IDE templates. Are you sure that is its name? If so, how did you install it?

But yes… any SmartApp should be modifiable to send HAM Bridge commands using the code in the Help page I linked to previously.

I was going to try and use the documentation (I think), got really busy and forgot what I was doing, I’d prefer to have a real button to press but I’m just going to use the simulated minimise with icons to begin. I need to add HAM Bridge commands to each of the buttons to try out a few things and see how it goes. I only have this so far…

/**

  • Copyright 2015 SmartThings
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.

*/
metadata {
definition (name: “Simulated Minimote”, namespace: “smartthings/testing”, author: “SmartThings”) {
capability "Actuator"
capability "Button"
capability "Holdable Button"
capability "Configuration"
capability “Sensor”

    command "push1"
    command "push2"
    command "push3"
    command "push4"
    command "hold1"
    command "hold2"
    command "hold3"
    command "hold4"
}

simulator {
	status "button 1 pushed":  "command: 2001, payload: 01"
	status "button 1 held":  "command: 2001, payload: 15"
	status "button 2 pushed":  "command: 2001, payload: 29"
	status "button 2 held":  "command: 2001, payload: 3D"
	status "button 3 pushed":  "command: 2001, payload: 51"
	status "button 3 held":  "command: 2001, payload: 65"
	status "button 4 pushed":  "command: 2001, payload: 79"
	status "button 4 held":  "command: 2001, payload: 8D"
	status "wakeup":  "command: 8407, payload: "
}
tiles {
	standardTile("button", "device.button") {
		state "default", label: "", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffffff"
	}
	standardTile("push1", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Play iTunes", icon:"st.sonos.play-btn", backgroundColor: "#ffffff", action: "push1"
	}
	standardTile("push2", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Pause iTunes", icon:"st.sonos.pause-btn", backgroundColor: "#ffffff", action: "push2"
	}
	standardTile("push3", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Prev iTunes", icon:"st.sonos.previous-btn", backgroundColor: "#ffffff", action: "push3"
	}
	standardTile("push4", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Next iTunes", icon:"st.sonos.next-btn", backgroundColor: "#ffffff", action: "push4"
	}
	standardTile("dummy1", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: " ", backgroundColor: "#ffffff", action: "push4"
	}
	standardTile("hold1", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Play Spotify", icon:"st.sonos.play-btn", backgroundColor: "#ffffff", action: "hold1"
	}
	standardTile("hold2", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Pause Spotify", icon:"st.sonos.pause-btn", backgroundColor: "#ffffff", action: "hold2"
	}
	standardTile("dummy2", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: " ", backgroundColor: "#ffffff", action: "push4"
	}
	standardTile("hold3", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Prev Spotify", icon:"st.sonos.previous-btn", backgroundColor: "#ffffff", action: "hold3"
	}
	standardTile("hold4", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Next Spotify", icon:"st.sonos.next-btn", backgroundColor: "#ffffff", action: "hold4"
	}

	main "button"
	details(["push1","push2","button","push3","push4","dummy1","hold1","hold2","dummy2","hold3","hold4"])
}

}

def parse(String description) {

}

def push1() {
push(1)
}

def push2() {
push(2)
}

def push3() {
push(3)
}

def push4() {
push(4)
}

def hold1() {
hold(1)
}

def hold2() {
hold(2)
}

def hold3() {
hold(3)
}

def hold4() {
hold(4)
}

private push(button) {
log.debug "$device.displayName button $button was pushed"
sendEvent(name: “button”, value: “pushed”, data: [buttonNumber: button], descriptionText: “$device.displayName button $button was pushed”, isStateChange: true)
}

private hold(button) {
log.debug "$device.displayName button $button was held"
sendEvent(name: “button”, value: “held”, data: [buttonNumber: button], descriptionText: “$device.displayName button $button was held”, isStateChange: true)
}

def installed() {
initialize()
}

def updated() {
initialize()
}

def initialize() {
sendEvent(name: “numberOfButtons”, value: 4)
}

Is there a way of adding multiple commands? I thought of changing the def doHAMB() to def doHAMB1() def doHAMB2() def doHAMB3() and so on, would that work?

If I understand you correctly there is no need to have multiple doHAMB commands, just stuff the command you want to send in each case into a var and pass the var to doHAMB…

def theCOM = "commandToSendToHAMBridge"
doHAMB(theCOM)
def doHAMB(theCOM) {
	def ip = "${settings.server}:${settings.port}"
	sendHubCommand(new physicalgraph.device.HubAction("""GET /?$theCOM HTTP/1.1\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN))
}

OK, I think I’ve done it…? I can’t test it yet because my baby is sleeping, but here is the Simulated Media Controller

================================================================================================

/**

  • Copyright 2017 ijaspley
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.

*/
metadata {
definition (name: “Simulated Media Controller”, namespace: “ijaspley”, author: “ijaspley”) {
capability "Actuator"
capability "Button"
capability "Holdable Button"
capability "Configuration"
capability “Sensor”

    command "iTunesPlay"
    command "iTunesPause"
    command "iTunesPrev"
    command "iTunesNext"
    command "SpotifyPlay"
    command "SpotifyPause"
    command "SpotifyPrev"
    command "SpotifyNext"
}

simulator {
	status "button 1 pushed":  "command: 2001, payload: 01"
	status "button 1 held":  "command: 2001, payload: 15"
	status "button 2 pushed":  "command: 2001, payload: 29"
	status "button 2 held":  "command: 2001, payload: 3D"
	status "button 3 pushed":  "command: 2001, payload: 51"
	status "button 3 held":  "command: 2001, payload: 65"
	status "button 4 pushed":  "command: 2001, payload: 79"
	status "button 4 held":  "command: 2001, payload: 8D"
	status "wakeup":  "command: 8407, payload: "
}
tiles {
	standardTile("button", "device.button") {
		state "default", label: "", icon: "http://tinyurl.com/mehdpmu", backgroundColor: "#ffffff"
	}
	standardTile("push1", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Play iTunes", icon:"st.sonos.play-btn", backgroundColor: "#ffffff", action: "push1"
	}
	standardTile("push2", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Pause iTunes", icon:"st.sonos.pause-btn", backgroundColor: "#ffffff", action: "push2"
	}
	standardTile("dummy1", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: " ", backgroundColor: "#ffffff"
	}
	standardTile("push3", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Prev iTunes", icon:"st.sonos.previous-btn", backgroundColor: "#ffffff", action: "push3"
	}
	standardTile("push4", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Next iTunes", icon:"st.sonos.next-btn", backgroundColor: "#ffffff", action: "push4"
	}
	standardTile("dummy2", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: " ", icon: "http://tinyurl.com/lcndohy", backgroundColor: "#ffffff", action: "push4"
	}
	standardTile("hold1", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Play Spotify", icon:"st.sonos.play-btn", backgroundColor: "#ffffff", action: "hold1"
	}
	standardTile("hold2", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Pause Spotify", icon:"st.sonos.pause-btn", backgroundColor: "#ffffff", action: "hold2"
	}
	standardTile("dummy3", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: " ", backgroundColor: "#ffffff"
	}
	standardTile("hold3", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Prev Spotify", icon:"st.sonos.previous-btn", backgroundColor: "#ffffff", action: "hold3"
	}
	standardTile("hold4", "device.button", width: 1, height: 1, decoration: "flat") {
		state "default", label: "Next Spotify", icon:"st.sonos.next-btn", backgroundColor: "#ffffff", action: "hold4"
	}

	main "button"
	details(["button","push1","push2","dummy1","push3","push4","dummy2","hold1","hold2","dummy3","hold3","hold4"])
}

}

def parse(String description) {

}

def push1() {
push(1)
}

def push2() {
push(2)
}

def push3() {
push(3)
}

def push4() {
push(4)

}

def hold1() {
hold(1)
}

def hold2() {
hold(2)

}

def hold3() {
hold(3)
}

def hold4() {
hold(4)

}

private push(button) {
log.debug "$device.displayName button $button was pushed"
sendEvent(name: “button”, value: “pushed”, data: [buttonNumber: button], descriptionText: “$device.displayName button $button was pushed”, isStateChange: true)
}

private hold(button) {
log.debug "$device.displayName button $button was held"
sendEvent(name: “button”, value: “held”, data: [buttonNumber: button], descriptionText: “$device.displayName button $button was held”, isStateChange: true)
}

def installed() {
initialize()
}

def updated() {
initialize()
}

def initialize() {
sendEvent(name: “numberOfButtons”, value: 4)
}

================================================================================================

Here is the SmartApp to configure it…

================================================================================================

/**

  • Copyright 2017 ijaspley
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.
  • Button Controller
  • Author: ijaspley
  • Date: 2017-3-30
    */
    definition(
    name: “Media Controller”,
    namespace: “ijaspley”,
    author: “ijaspley”,
    description: “Control iTunes, Spotify and anything via HAM Bridge with Simulated Media Controller”,
    category: “Convenience”,
    iconUrl: “http://tinyurl.com/lmyjsso”,
    )

preferences {
page(name: “selectButton”)
page(name: “configureButton1”)
page(name: “configureButton2”)
page(name: “configureButton3”)
page(name: “configureButton4”)

page(name: "timeIntervalInput", title: "Only during a certain time") {
	section {
		input "starting", "time", title: "Starting", required: false
		input "ending", "time", title: "Ending", required: false
	}
}

}

def selectButton() {
dynamicPage(name: “selectButton”, title: “Select your media remote”, nextPage: “configureButton1”, uninstall: configured()) {
section {
input “buttonDevice”, “capability.button”, title: “Button”, multiple: false, required: true
}

	section(title: "More options", hidden: hideOptionsSection(), hideable: true) {

		def timeLabel = timeIntervalLabel()

		href "timeIntervalInput", title: "Only during a certain time", description: timeLabel ?: "Tap to set", state: timeLabel ? "complete" : null

		input "days", "enum", title: "Only on certain days of the week", multiple: true, required: false,
			options: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

		input "modes", "mode", title: "Only when mode is", multiple: true, required: false
	}
}

}

def configureButton1() {
dynamicPage(name: “configureButton1”, title: “Configure Play Buttons (Button 1: Push for iTunes, Hold for Spotify)”,
nextPage: “configureButton2”, uninstall: configured(), getButtonSections(1))
}
def configureButton2() {
dynamicPage(name: “configureButton2”, title: “Configure Pause Buttons (Button 2: Push for iTunes, Hold for Spotify)”,
nextPage: “configureButton3”, uninstall: configured(), getButtonSections(2))
}

def configureButton3() {
dynamicPage(name: “configureButton3”, title: “Configure Prev Buttons (Button 3: Push for iTunes, Hold for Spotify)”,
nextPage: “configureButton4”, uninstall: configured(), getButtonSections(3))
}
def configureButton4() {
dynamicPage(name: “configureButton4”, title: “Configure Skip Buttons (Button 4: Push for iTunes, Hold for Spotify)”,
install: true, uninstall: true, getButtonSections(4))
}

def getButtonSections(buttonNumber) {
return {
section(“Send this command to HAM Bridge”) {
input “HAMBcommand_${buttonNumber}pushed", “text”, title: “Pushed Command to send”, multiple: false, required: false
input "HAMBcommand
${buttonNumber}held", “text”, title: “Held Command to send”, multiple: false, required: false
input “server”, “text”, title: “Server IP”, description: “Your HAM Bridger Server IP”, required: true
input “port”, “number”, title: “Port”, description: “Port Number”, required: true
}
section(“Lights”) {
input "lights
${buttonNumber}pushed", “capability.switch”, title: “Pushed”, multiple: true, required: false
input "lights
${buttonNumber}held", “capability.switch”, title: “Held”, multiple: true, required: false
}
section(“Locks”) {
input "locks
${buttonNumber}pushed", “capability.lock”, title: “Pushed”, multiple: true, required: false
input "locks
${buttonNumber}held", “capability.lock”, title: “Held”, multiple: true, required: false
}
section(“Sonos”) {
input "sonos
${buttonNumber}pushed", “capability.musicPlayer”, title: “Pushed”, multiple: true, required: false
input "sonos
${buttonNumber}held", “capability.musicPlayer”, title: “Held”, multiple: true, required: false
}
section(“Modes”) {
input "mode
${buttonNumber}pushed", “mode”, title: “Pushed”, required: false
input "mode
${buttonNumber}held", “mode”, title: “Held”, required: false
}
def phrases = location.helloHome?.getPhrases()*.label
if (phrases) {
section(“Hello Home Actions”) {
log.trace phrases
input "phrase
${buttonNumber}pushed", “enum”, title: “Pushed”, required: false, options: phrases
input "phrase
${buttonNumber}held", “enum”, title: “Held”, required: false, options: phrases
}
}
section(“Sirens”) {
input "sirens
${buttonNumber}pushed",“capability.alarm” ,title: “Pushed”, multiple: true, required: false
input "sirens
${buttonNumber}_held”, “capability.alarm”, title: “Held”, multiple: true, required: false
}

	section("Custom Message") {
		input "textMessage_${buttonNumber}", "text", title: "Message", required: false
	}

    section("Push Notifications") {
        input "notifications_${buttonNumber}_pushed","bool" ,title: "Pushed", required: false, defaultValue: false
        input "notifications_${buttonNumber}_held", "bool", title: "Held", required: false, defaultValue: false
    }

    section("Sms Notifications") {
        input "phone_${buttonNumber}_pushed","phone" ,title: "Pushed", required: false
        input "phone_${buttonNumber}_held", "phone", title: "Held", required: false
    }
}

}

def installed() {
initialize()
}

def updated() {
unsubscribe()
initialize()
}

def initialize() {
subscribe(buttonDevice, “button”, buttonEvent)
}

def configured() {
return buttonDevice || buttonConfigured(1) || buttonConfigured(2) || buttonConfigured(3) || buttonConfigured(4)
}

def buttonConfigured(idx) {
return settings[“HAMBcommand_$idx_pushed”] ||
settings[“lights_$idx_pushed”] ||
settings[“locks_$idx_pushed”] ||
settings[“sonos_$idx_pushed”] ||
settings[“mode_$idx_pushed”] ||
settings[“notifications_$idx_pushed”] ||
settings[“sirens_$idx_pushed”] ||
settings[“notifications_$idx_pushed”] ||
settings[“phone_$idx_pushed”]
}

def buttonEvent(evt){
if(allOk) {
def buttonNumber = evt.data // why doesn’t jsonData work? always returning [:]
def value = evt.value
log.debug "buttonEvent: $evt.name = $evt.value ($evt.data)"
log.debug “button: $buttonNumber, value: $value”

	def recentEvents = buttonDevice.eventsSince(new Date(now() - 3000)).findAll{it.value == evt.value && it.data == evt.data}
	log.debug "Found ${recentEvents.size()?:0} events in past 3 seconds"

	if(recentEvents.size <= 1){
		switch(buttonNumber) {
			case ~/.*1.*/:
				executeHandlers(1, value)
				break
			case ~/.*2.*/:
				executeHandlers(2, value)
				break
			case ~/.*3.*/:
				executeHandlers(3, value)
				break
			case ~/.*4.*/:
				executeHandlers(4, value)
				break
		}
	} else {
		log.debug "Found recent button press events for $buttonNumber with value $value"
	}
}

}

def executeHandlers(buttonNumber, value) {
log.debug “executeHandlers: $buttonNumber - $value”

def HAMBcommand = find('HAMBcommand', buttonNumber, value)

def lights = find('lights', buttonNumber, value)
if (lights != null) toggle(lights)

def locks = find('locks', buttonNumber, value)
if (locks != null) toggle(locks)

def sonos = find('sonos', buttonNumber, value)
if (sonos != null) toggle(sonos)

def mode = find('mode', buttonNumber, value)
if (mode != null) changeMode(mode)

def phrase = find('phrase', buttonNumber, value)
if (phrase != null) location.helloHome.execute(phrase)

def textMessage = findMsg('textMessage', buttonNumber)

def notifications = find('notifications', buttonNumber, value)
if (notifications?.toBoolean()) sendPush(textMessage ?: "Button $buttonNumber was pressed" )

def phone = find('phone', buttonNumber, value)
if (phone != null) sendSms(phone, textMessage ?:"Button $buttonNumber was pressed")

def sirens = find('sirens', buttonNumber, value)
if (sirens != null) toggle(sirens)

}

def find(type, buttonNumber, value) {
def preferenceName = type + “" + buttonNumber + "” + value
def pref = settings[preferenceName]
if(pref != null) {
log.debug “Found: $pref for $preferenceName”
}

return pref

}

def findMsg(type, buttonNumber) {
def preferenceName = type + “_” + buttonNumber
def pref = settings[preferenceName]
if(pref != null) {
log.debug “Found: $pref for $preferenceName”
}

return pref

}

def toggle(devices) {
log.debug “toggle: $devices = ${devices*.currentValue(‘switch’)}”

if (devices*.currentValue('switch').contains('on')) {
	devices.off()
}
else if (devices*.currentValue('switch').contains('off')) {
	devices.on()
}
else if (devices*.currentValue('lock').contains('locked')) {
	devices.unlock()
}
else if (devices*.currentValue('lock').contains('unlocked')) {
	devices.lock()
}
else if (devices*.currentValue('alarm').contains('off')) {
    devices.siren()
}
else {
	devices.on()
}

}

def changeMode(mode) {
log.debug “changeMode: $mode, location.mode = $location.mode, location.modes = $location.modes”

if (location.mode != mode && location.modes?.find { it.name == mode }) {
	setLocationMode(mode)
}

}

def doHAMB() {
def ip = “${settings.server}:${settings.port}“sendHubCommand(new physicalgraph.device.HubAction(””“GET /?${settings.HAMBcommand} HTTP/1.1\r\nHOST: $ip\r\n\r\n”"", physicalgraph.device.Protocol.LAN))
}

// execution filter methods
private getAllOk() {
modeOk && daysOk && timeOk
}

private getModeOk() {
def result = !modes || modes.contains(location.mode)
log.trace "modeOk = $result"
result
}

private getDaysOk() {
def result = true
if (days) {
def df = new java.text.SimpleDateFormat(“EEEE”)
if (location.timeZone) {
df.setTimeZone(location.timeZone)
}
else {
df.setTimeZone(TimeZone.getTimeZone(“America/New_York”))
}
def day = df.format(new Date())
result = days.contains(day)
}
log.trace "daysOk = $result"
result
}

private getTimeOk() {
def result = true
if (starting && ending) {
def currTime = now()
def start = timeToday(starting, location.timeZone).time
def stop = timeToday(ending, location.timeZone).time
result = start < stop ? currTime >= start && currTime <= stop : currTime <= stop || currTime >= start
}
log.trace "timeOk = $result"
result
}

private hhmm(time, fmt = “h:mm a”)
{
def t = timeToday(time, location.timeZone)
def f = new java.text.SimpleDateFormat(fmt)
f.setTimeZone(location.timeZone ?: timeZone(time))
f.format(t)
}

private hideOptionsSection() {
(starting || ending || days || modes) ? false : true
}

private timeIntervalLabel() {
(starting && ending) ? hhmm(starting) + “-” + hhmm(ending, “h:mm a z”) : “”
}

================================================================================================

I’ve named my HAM Commands iTunesPlay, SpotifyPlay, iTunesPrev… etc, but that is not important as anyone can configure their own. I haven’t included airplay commands as I’ve used Airfoil for that (that’s where I get separate Play and Pause GETs for Spotify.

Hope it works, if not I’m stuck for ideas.

Thanks for the help and HAM Bridge @scottinpollock

Sorry, it doesn’t work.

As a workaround I’ve decided to use one of Scottin Pollock’s modified Alexa momentary switches for each of play/pause, skip, previous and for iTunes and Spotify. Then used button controller+ to associate each of the media controller buttons with the required command. End result is working media remote which can be used by Alexa, Harmony and Siri via Homebridge so I guess I can live with having separate buttons in my list.

I’ve figured out a workaround which allows control of iTunes and Spotify via HAM Bridge using Amazon Echo, Logitech Harmony and Smartthings (both for automation and with a Simulated Media Remote in the App). I’ve knocked together a quick guide in the readme.md in a repository in my GitHub (https://github.com/ijaspley/HAM-Bridge-Smartthings-Media-Control). Enjoy.

I see you have stated there was a plan on creating a windows version of this. I am highly anticipating this and would be very grateful for such. I have a windows server running iTunes and I would like to use that as my system to stream music from, especially Apple Music service. Looking forward to an update!

1 Like