OK here we go.
First step is to create the device type for your squeeze server:
/**
* squeezeSwitch
*
* Copyright 2014 Mike Maxwell
*
* 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.
*
*/
//player mac adddresses, for each required player
preferences {
input("confp1", "string", title:"Enter Player 1 MAC",defaultValue:"00:00:00:00:00:00", required:true, displayDuringSetup:true)
input("confp2", "string", title:"Enter Player 2 MAC",defaultValue:"00:00:00:00:00:00", required:true, displayDuringSetup:true)
input("confp3", "string", title:"Enter Player 3 MAC",defaultValue:"00:00:00:00:00:00", required:true, displayDuringSetup:true)
}
metadata {
definition (name: "squeezeSwitch", namespace: "mmaxwell", author: "Mike Maxwell") {
capability "Switch"
//custom commands for multiple players
//use the standard (built in on/off) if you only have one player
command "p1On"
command "p1Off"
command "p2On"
command "p2Off"
command "p3On"
command "p3Off"
//enable and use to create the hex version of your squeeze servers CLI interface
//ip address and port, this will need to be assigned to the "Device Network Id" field
//after the device is added to your system
//command "getNid"
}
simulator {
// TODO: define status and reply messages here
}
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
}
main "switch"
details(["switch"])
}
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
}
private String makeNetworkId(ipaddr, port) {
String hexIp = ipaddr.tokenize('.').collect {
String.format('%02X', it.toInteger())
}.join()
String hexPort = String.format('%04X', port())
return "${hexIp}:${hexPort}"
}
def getNID() {
log.debug makeNetworkId("192.168.1.200", 9000) //your squeeze server CLI interface ip address and port
}
// handle commands for multiple players
def p1On() {
//log.debug settings.confp1
def ha = new physicalgraph.device.HubAction("${settings.confp1} play\r\n\r\n",physicalgraph.device.Protocol.LAN, "${device.deviceNetworkId}")
return ha
}
def p1Off() {
//log.debug settings.confp1
def ha = new physicalgraph.device.HubAction("${settings.confp1} power 0\r\n\r\n",physicalgraph.device.Protocol.LAN, "${device.deviceNetworkId}")
return ha
}
def p2On() {
//log.debug settings.confp2
def ha = new physicalgraph.device.HubAction("${settings.confp2} play\r\n\r\n",physicalgraph.device.Protocol.LAN, "${device.deviceNetworkId}")
return ha
}
def p2Off() {
//log.debug settings.confp2
def ha = new physicalgraph.device.HubAction("${settings.confp2} power 0\r\n\r\n",physicalgraph.device.Protocol.LAN, "${device.deviceNetworkId}")
return ha
}
def p3On() {
//log.debug settings.confp3
def ha = new physicalgraph.device.HubAction("${settings.confp3} play\r\n\r\n",physicalgraph.device.Protocol.LAN, "${device.deviceNetworkId}")
return ha
}
def p3Off() {
//log.debug settings.confp3
def ha = new physicalgraph.device.HubAction("${settings.confp3} power 0\r\n\r\n",physicalgraph.device.Protocol.LAN, "${device.deviceNetworkId}")
return ha
}
// command for one player only
def on() {
//log.debug "Executing 'on'"
def ha = new physicalgraph.device.HubAction("${settings.confp1} play\r\n\r\n",physicalgraph.device.Protocol.LAN, "${device.deviceNetworkId}")
return ha
}
def off() {
//log.debug "Executing 'off'"
def ha = new physicalgraph.device.HubAction("${settings.confp1} power 0\r\n\r\n",physicalgraph.device.Protocol.LAN, "${device.deviceNetworkId}")
return ha
}
After creating/publishing and adding this device to your system, you will need to assign the servers ip/port and the individual player MAC addresses to the new device:
Create a new virtual switch type and add an instance to your system for each player, these are not needed if you only have one player as this can be controlled directly from the above device. The input field “squeezeBox” is only used as a note to help you remember which player is connected to these virtual switches.
/**
* sqVS
*
* Copyright 2014 Mike Maxwell
*
* 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: "sqVS", namespace: "mmaxwell", author: "Mike Maxwell") {
capability "Switch"
}
preferences {
input name: "sq", type: "enum", title: "squeezeBox", description: "Squeeze Box to Connect to", required: true
}
simulator {
// TODO: define status and reply messages here
}
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "switch"
details(["switch","refresh"])
}
}
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
// TODO: handle 'switch' attribute
}
// handle commands
def on() {
log.debug "On"
sendEvent (name: "switch", value: "on")
}
def off() {
log.debug "Off"
sendEvent (name: "switch", value: "off")
}
When creating these devices any random/unique ID will do in the device ID field
Next you need a smartApp to function as the controller for all these. This smartapp (derived from @badgermanus 's 8 way relay project) functions as a middle man, subscribing to the on/off events of each virtual switch (representing your palyers), then firing the appropriate custom command against your squeeze device.
/**
* squeezeController
*
* Copyright 2014 Mike Maxwell
*
* 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.
*
*/
definition(
name: "squeezeController",
namespace: "mmaxwell",
author: "Mike Maxwell",
description: "SqueezeBox virtual supervisor.",
category: "My Apps",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
/**
* VirtualSwitchParent
*
* Author: badgermanus@gmail.com
* Date: 2014-03-26
*/
preferences {
section("Connect these virtual switches to the squeeze players") {
input "switch1", title: "family", "capability.switch", required: true
input "switch2", title: "master", "capability.switch", required: true
input "switch3", title: "garage", "capability.switch", required: true
}
section("Which squeeze server?") {
input "squeeze", "capability.switch"
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
subscribe()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
subscribe()
}
def subscribe() {
subscribe(switch1, "switch.on", p1On)
subscribe(switch1, "switch.off", p1Off)
subscribe(switch2, "switch.on", p2On)
subscribe(switch2, "switch.off", p2Off)
subscribe(switch3, "switch.on", p3On)
subscribe(switch3, "switch.off", p3Off)
}
def p1On(evt)
{
log.debug "switchOn1($evt.name: $evt.value: $evt.deviceId)"
squeeze.p1On()
}
def p1Off(evt)
{
log.debug "switchOff1($evt.name: $evt.value: $evt.deviceId)"
squeeze.p1Off()
}
def p2On(evt)
{
log.debug "switchOn2($evt.name: $evt.value: $evt.deviceId)"
squeeze.p2On()
}
def p2Off(evt)
{
log.debug "switchOff2($evt.name: $evt.value: $evt.deviceId)"
squeeze.p2Off()
}
def p3On(evt)
{
log.debug "switchOn3($evt.name: $evt.value: $evt.deviceId)"
squeeze.p3On()
}
def p3Off(evt)
{
log.debug "switchOff3($evt.name: $evt.value: $evt.deviceId)"
squeeze.p3Off()
}
It’s a lot of work just to power up/down each player but it does the job.
It should be noted that your squeeze server needs to have the CLI plugin enabled, I don’t know if this is the default or not.