mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-13 05:11:51 +00:00
Compare commits
1 Commits
MSA-1822-1
...
MSA-1818-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b63f07ab42 |
@@ -0,0 +1,282 @@
|
||||
/**
|
||||
* SmartThings Device Handler: Yamaha Zone
|
||||
*
|
||||
* Author: redloro@gmail.com
|
||||
*
|
||||
* 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: "Yamaha Zone", namespace: "redloro-smartthings", author: "redloro@gmail.com") {
|
||||
|
||||
/**
|
||||
* List our capabilties. Doing so adds predefined command(s) which
|
||||
* belong to the capability.
|
||||
*/
|
||||
capability "Music Player"
|
||||
capability "Switch"
|
||||
capability "Switch Level"
|
||||
capability "Refresh"
|
||||
capability "Polling"
|
||||
|
||||
/**
|
||||
* Define all commands, ie, if you have a custom action not
|
||||
* covered by a capability, you NEED to define it here or
|
||||
* the call will not be made.
|
||||
*
|
||||
* To call a capability function, just prefix it with the name
|
||||
* of the capability, for example, refresh would be "refresh.refresh"
|
||||
*/
|
||||
command "source0"
|
||||
command "source1"
|
||||
command "source2"
|
||||
command "source3"
|
||||
command "source4"
|
||||
command "source5"
|
||||
command "mutedOn"
|
||||
command "mutedOff"
|
||||
command "partyModeOn"
|
||||
command "partyModeOff"
|
||||
command "zone"
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the various tiles and the states that they can be in.
|
||||
* The 2nd parameter defines an event which the tile listens to,
|
||||
* if received, it tries to map it to a state.
|
||||
*
|
||||
* You can also use ${currentValue} for the value of the event
|
||||
* or ${name} for the name of the event. Just make SURE to use
|
||||
* single quotes, otherwise it will only be interpreted at time of
|
||||
* launch, instead of every time the event triggers.
|
||||
*/
|
||||
tiles(scale: 2) {
|
||||
multiAttributeTile(name:"state", type:"lighting", width:6, height:4) {
|
||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||
attributeState "on", label:'On', action:"switch.off", icon:"st.Electronics.electronics16", backgroundColor:"#79b821", nextState:"off"
|
||||
attributeState "off", label:'Off', action:"switch.on", icon:"st.Electronics.electronics16", backgroundColor:"#ffffff", nextState:"on"
|
||||
}
|
||||
tileAttribute ("source", key: "SECONDARY_CONTROL") {
|
||||
attributeState "source", label:'${currentValue}'
|
||||
}
|
||||
}
|
||||
|
||||
// row
|
||||
//controlTile("volume", "device.volume", "slider", height: 1, width: 6, range:"(0..100)") {
|
||||
controlTile("volume", "device.volume", "slider", height: 1, width: 6, range:"(-80..16)") {
|
||||
state "volume", label: "Volume", action:"music Player.setLevel", backgroundColor:"#00a0dc"
|
||||
}
|
||||
|
||||
// row
|
||||
standardTile("0", "device.source0", decoration: "flat", width: 2, height: 2) {
|
||||
state("off", label:"AV1", action:"source0", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-gray.png", backgroundColor:"#ffffff")
|
||||
state("on", label:"AV1", action:"source0", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-green.png", backgroundColor:"#ffffff")
|
||||
}
|
||||
standardTile("1", "device.source1", decoration: "flat", width: 2, height: 2) {
|
||||
state("off", label:"AV2", action:"source1", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-gray.png", backgroundColor:"#ffffff")
|
||||
state("on", label:"AV2", action:"source1", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-green.png", backgroundColor:"#ffffff")
|
||||
}
|
||||
standardTile("2", "device.source2", decoration: "flat", width: 2, height: 2) {
|
||||
state("off", label:"AV3", action:"source2", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-gray.png", backgroundColor:"#ffffff")
|
||||
state("on", label:"AV3", action:"source2", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-green.png", backgroundColor:"#ffffff")
|
||||
}
|
||||
standardTile("3", "device.source3", decoration: "flat", width: 2, height: 2) {
|
||||
state("off", label:"AV4", action:"source3", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-gray.png", backgroundColor:"#ffffff")
|
||||
state("on", label:"AV4", action:"source3", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-green.png", backgroundColor:"#ffffff")
|
||||
}
|
||||
standardTile("4", "device.source4", decoration: "flat", width: 2, height: 2) {
|
||||
state("off", label:"AV5", action:"source4", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-gray.png", backgroundColor:"#ffffff")
|
||||
state("on", label:"AV5", action:"source4", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-green.png", backgroundColor:"#ffffff")
|
||||
}
|
||||
standardTile("5", "device.source5", decoration: "flat", width: 2, height: 2) {
|
||||
state("off", label:"AV6", action:"source5", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-gray.png", backgroundColor:"#ffffff")
|
||||
state("on", label:"AV6", action:"source5", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-green.png", backgroundColor:"#ffffff")
|
||||
}
|
||||
|
||||
// row
|
||||
standardTile("muted", "device.muted", decoration: "flat", width: 2, height: 2) {
|
||||
state("off", label:'Muted', action:"mutedOn", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-gray.png", backgroundColor:"#ffffff", nextState:"on")
|
||||
state("on", label:'Muted', action:"mutedOff", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-mute.png", backgroundColor:"#ffffff", nextState:"off")
|
||||
}
|
||||
standardTile("partyMode", "device.partyMode", decoration: "flat", width: 2, height: 2, inactiveLabel: false) {
|
||||
state("off", label:'Party Mode', action:"partyModeOn", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-gray.png", backgroundColor:"#ffffff", nextState:"on")
|
||||
state("on", label:'Party Mode', action:"partyModeOff", icon:"https://raw.githubusercontent.com/redloro/smartthings/master/images/indicator-dot-party.png", backgroundColor:"#ffffff", nextState:"off")
|
||||
}
|
||||
standardTile("refresh", "device.status", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
|
||||
state "default", label:"Refresh", action:"refresh.refresh", icon:"st.secondary.refresh-icon", backgroundColor:"#ffffff"
|
||||
}
|
||||
|
||||
// Defines which tile to show in the overview
|
||||
main "state"
|
||||
|
||||
// Defines which tile(s) to show when user opens the detailed view
|
||||
details([
|
||||
"state",
|
||||
"volume",
|
||||
"0","1","2","3","4","5",
|
||||
"muted", "partyMode","refresh"
|
||||
])
|
||||
}
|
||||
|
||||
preferences {
|
||||
input name: "source0", type: "text", title: "Source 1", defaultValue: "AV1"
|
||||
input name: "source1", type: "text", title: "Source 2", defaultValue: "AV2"
|
||||
input name: "source2", type: "text", title: "Source 3", defaultValue: "AV3"
|
||||
input name: "source3", type: "text", title: "Source 4", defaultValue: "AV4"
|
||||
input name: "source4", type: "text", title: "Source 5", defaultValue: "AV5"
|
||||
input name: "source5", type: "text", title: "Source 6", defaultValue: "AV6"
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* The following section simply maps the actions as defined in
|
||||
* the metadata into onAction() calls.
|
||||
*
|
||||
* This is preferred since some actions can be dealt with more
|
||||
* efficiently this way. Also keeps all user interaction code in
|
||||
* one place.
|
||||
*
|
||||
*/
|
||||
def on() {
|
||||
sendCommand("<YAMAHA_AV cmd=\"PUT\"><${getZone()}><Power_Control><Power>On</Power></Power_Control></${getZone()}></YAMAHA_AV>")
|
||||
sendEvent(name: "switch", value: "on")
|
||||
}
|
||||
def off() {
|
||||
sendCommand("<YAMAHA_AV cmd=\"PUT\"><${getZone()}><Power_Control><Power>Standby</Power></Power_Control></${getZone()}></YAMAHA_AV>")
|
||||
sendEvent(name: "switch", value: "off")
|
||||
}
|
||||
def setLevel(value) {
|
||||
//sendCommand("<YAMAHA_AV cmd=\"PUT\"><${getZone()}><Volume><Lvl><Val>${(Math.round(value * 9 / 5) * 5 - 800).intValue()}</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></${getZone()}></YAMAHA_AV>")
|
||||
sendCommand("<YAMAHA_AV cmd=\"PUT\"><${getZone()}><Volume><Lvl><Val>${(value * 10).intValue()}</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></${getZone()}></YAMAHA_AV>")
|
||||
sendEvent(name: "volume", value: value)
|
||||
}
|
||||
def source0() {
|
||||
setSource(0)
|
||||
}
|
||||
def source1() {
|
||||
setSource(1)
|
||||
}
|
||||
def source2() {
|
||||
setSource(2)
|
||||
}
|
||||
def source3() {
|
||||
setSource(3)
|
||||
}
|
||||
def source4() {
|
||||
setSource(4)
|
||||
}
|
||||
def source5() {
|
||||
setSource(5)
|
||||
}
|
||||
def mutedOn() {
|
||||
sendCommand("<YAMAHA_AV cmd=\"PUT\"><${getZone()}><Volume><Mute>On</Mute></Volume></${getZone()}></YAMAHA_AV>")
|
||||
sendEvent(name: "muted", value: "on")
|
||||
}
|
||||
def mutedOff() {
|
||||
sendCommand("<YAMAHA_AV cmd=\"PUT\"><${getZone()}><Volume><Mute>Off</Mute></Volume></${getZone()}></YAMAHA_AV>")
|
||||
sendEvent(name: "muted", value: "off")
|
||||
}
|
||||
def partyModeOn() {
|
||||
sendCommand("<YAMAHA_AV cmd=\"PUT\"><System><Party_Mode><Mode>On</Mode></Party_Mode></System></YAMAHA_AV>")
|
||||
sendEvent(name: "partyMode", value: "on")
|
||||
}
|
||||
def partyModeOff() {
|
||||
sendCommand("<YAMAHA_AV cmd=\"PUT\"><System><Party_Mode><Mode>Off</Mode></Party_Mode></System></YAMAHA_AV>")
|
||||
sendEvent(name: "partyMode", value: "off")
|
||||
}
|
||||
def refresh() {
|
||||
sendCommand("<YAMAHA_AV cmd=\"GET\"><${getZone()}><Basic_Status>GetParam</Basic_Status></${getZone()}></YAMAHA_AV>")
|
||||
sendCommand("<YAMAHA_AV cmd=\"GET\"><System><Party_Mode><Mode>GetParam</Mode></Party_Mode></System></YAMAHA_AV>")
|
||||
}
|
||||
/**************************************************************************/
|
||||
|
||||
/**
|
||||
* Called every so often (every 5 minutes actually) to refresh the
|
||||
* tiles so the user gets the correct information.
|
||||
*/
|
||||
def poll() {
|
||||
refresh()
|
||||
}
|
||||
|
||||
def parse(String description) {
|
||||
return
|
||||
}
|
||||
|
||||
def setSource(id) {
|
||||
//log.debug "source: "+getSourceName(id)
|
||||
sendCommand("<YAMAHA_AV cmd=\"PUT\"><${getZone()}><Input><Input_Sel>"+getSourceName(id)+"</Input_Sel></Input></${getZone()}></YAMAHA_AV>")
|
||||
setSourceTile(getSourceName(id))
|
||||
}
|
||||
|
||||
def getSourceName(id) {
|
||||
if (settings) {
|
||||
return settings."source${id}"
|
||||
} else {
|
||||
return ['AV1', 'AV2', 'AV3', 'AV4', 'AV5', 'AV6'].get(id)
|
||||
}
|
||||
}
|
||||
|
||||
def setSourceTile(name) {
|
||||
sendEvent(name: "source", value: "Source: ${name}")
|
||||
for (def i = 0; i < 6; i++) {
|
||||
if (name == getSourceName(i)) {
|
||||
sendEvent(name: "source${i}", value: "on")
|
||||
}
|
||||
else {
|
||||
sendEvent(name: "source${i}", value: "off")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def zone(evt) {
|
||||
/*
|
||||
* Zone On/Off
|
||||
*/
|
||||
if (evt.Basic_Status.Power_Control.Power.text()) {
|
||||
sendEvent(name: "switch", value: (evt.Basic_Status.Power_Control.Power.text() == "On") ? "on" : "off")
|
||||
}
|
||||
|
||||
/*
|
||||
* Zone Volume
|
||||
*/
|
||||
if (evt.Basic_Status.Volume.Lvl.Val.text()) {
|
||||
def int volLevel = evt.Basic_Status.Volume.Lvl.Val.toInteger() ?: -250
|
||||
//sendEvent(name: "volume", value: ((volLevel + 800) / 9).intValue())
|
||||
sendEvent(name: "volume", value: (volLevel / 10).intValue())
|
||||
}
|
||||
|
||||
/*
|
||||
* Zone Muted
|
||||
*/
|
||||
if (evt.Basic_Status.Volume.Mute.text()) {
|
||||
sendEvent(name: "muted", value: (evt.Basic_Status.Volume.Mute.text() == "On") ? "on" : "off")
|
||||
}
|
||||
|
||||
/*
|
||||
* Zone Source
|
||||
*/
|
||||
if (evt.Basic_Status.Input.Input_Sel.text()) {
|
||||
setSourceTile(evt.Basic_Status.Input.Input_Sel.text())
|
||||
}
|
||||
|
||||
/*
|
||||
* Party Mode
|
||||
*/
|
||||
if (evt.Party_Mode.Mode.text()) {
|
||||
sendEvent(name: "partyMode", value: (evt.Party_Mode.Mode.text() == "On") ? "on" : "off")
|
||||
}
|
||||
}
|
||||
|
||||
private sendCommand(body) {
|
||||
parent.sendCommand(body)
|
||||
}
|
||||
|
||||
private getZone() {
|
||||
return new String(device.deviceNetworkId).tokenize('|')[2]
|
||||
}
|
||||
@@ -1,794 +0,0 @@
|
||||
/**
|
||||
* Gideon
|
||||
*
|
||||
* Copyright 2016 Nicola Russo
|
||||
*
|
||||
* 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: "Gideon Smart Home",
|
||||
namespace: "gideon.api",
|
||||
author: "Braindrain Solutions ltd",
|
||||
description: "Gideon Smart Home SmartApp allows you to connect and control all of your SmartThings devices through the Gideon app, making your SmartThings devices even smarter.",
|
||||
category: "Family",
|
||||
iconUrl: "http://s33.postimg.org/t77u7y7v3/logo.png",
|
||||
iconX2Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
|
||||
iconX3Url: "http://s33.postimg.org/t77u7y7v3/logo.png",
|
||||
oauth: [displayName: "Gideon Smart Home API app", displayLink: "gideon.ai"])
|
||||
|
||||
preferences {
|
||||
section("Control these contact sensors...") {
|
||||
input "contact", "capability.contactSensor", multiple:true, required:false
|
||||
}
|
||||
section("Control these switch levels...") {
|
||||
input "switchlevels", "capability.switchLevel", multiple:true, required:false
|
||||
}
|
||||
/* section("Control these thermostats...") {
|
||||
input "thermostats", "capability.thermostat", multiple:true, required:false
|
||||
}*/
|
||||
section("Control the color for these devices...") {
|
||||
input "colors", "capability.colorControl", multiple:true, required:false
|
||||
}
|
||||
section("Control the color temperature for these devices...") {
|
||||
input "kelvin", "capability.colorTemperature", multiple:true, required:false
|
||||
}
|
||||
section("Control these switches...") {
|
||||
input "switches", "capability.switch", multiple:true, required:false
|
||||
}
|
||||
section("Control these smoke alarms...") {
|
||||
input "smoke_alarms", "capability.smokeDetector", multiple:true, required:false
|
||||
}
|
||||
section("Control these window shades...") {
|
||||
input "shades", "capability.windowShade", multiple:true, required:false
|
||||
}
|
||||
section("Control these garage doors...") {
|
||||
input "garage", "capability.garageDoorControl", multiple:true, required:false
|
||||
}
|
||||
section("Control these water sensors...") {
|
||||
input "water_sensors", "capability.waterSensor", multiple:true, required:false
|
||||
}
|
||||
section("Control these motion sensors...") {
|
||||
input "motions", "capability.motionSensor", multiple:true, required:false
|
||||
}
|
||||
section("Control these presence sensors...") {
|
||||
input "presence_sensors", "capability.presenceSensor", multiple:true, required:false
|
||||
}
|
||||
section("Control these outlets...") {
|
||||
input "outlets", "capability.outlet", multiple:true, required:false
|
||||
}
|
||||
section("Control these power meters...") {
|
||||
input "meters", "capability.powerMeter", multiple:true, required:false
|
||||
}
|
||||
section("Control these locks...") {
|
||||
input "locks", "capability.lock", multiple:true, required:false
|
||||
}
|
||||
section("Control these temperature sensors...") {
|
||||
input "temperature_sensors", "capability.temperatureMeasurement", multiple:true, required:false
|
||||
}
|
||||
section("Control these batteries...") {
|
||||
input "batteries", "capability.battery", multiple:true, required:false
|
||||
}
|
||||
}
|
||||
|
||||
def installed() {
|
||||
log.debug "Installed with settings: ${settings}"
|
||||
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "Updated with settings: ${settings}"
|
||||
|
||||
unsubscribe()
|
||||
initialize()
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
}
|
||||
|
||||
private device(it, type) {
|
||||
it ? [id: it.id, label: it.label, type: type] : null
|
||||
}
|
||||
|
||||
//API Mapping
|
||||
mappings {
|
||||
path("/getalldevices") {
|
||||
action: [
|
||||
GET: "getAllDevices"
|
||||
]
|
||||
}
|
||||
/*
|
||||
path("/thermostat/setcool/:id/:temp") {
|
||||
action: [
|
||||
GET: "setCoolTemp"
|
||||
]
|
||||
}
|
||||
path("/thermostat/setheat/:id/:temp") {
|
||||
action: [
|
||||
GET: "setHeatTemp"
|
||||
]
|
||||
}
|
||||
path("/thermostat/setfanmode/:id/:mode") {
|
||||
action: [
|
||||
GET: "setFanMode"
|
||||
]
|
||||
}
|
||||
path("/thermostat/setmode/:id/:mode") {
|
||||
action: [
|
||||
GET: "setThermostatMode"
|
||||
]
|
||||
}
|
||||
path("/thermostat/:id") {
|
||||
action: [
|
||||
GET: "getThermostatStatus"
|
||||
]
|
||||
}
|
||||
*/
|
||||
path("/light/dim/:id/:dim") {
|
||||
action: [
|
||||
GET: "setLevelStatus"
|
||||
]
|
||||
}
|
||||
path("/light/kelvin/:id/:kelvin") {
|
||||
action: [
|
||||
GET: "setKelvin"
|
||||
]
|
||||
}
|
||||
path("/colorlight/:id/:hue/:sat") {
|
||||
action: [
|
||||
GET: "setColor"
|
||||
]
|
||||
}
|
||||
path("/light/status/:id") {
|
||||
action: [
|
||||
GET: "getLightStatus"
|
||||
]
|
||||
}
|
||||
path("/light/on/:id") {
|
||||
action: [
|
||||
GET: "turnOnLight"
|
||||
]
|
||||
}
|
||||
path("/light/off/:id") {
|
||||
action: [
|
||||
GET: "turnOffLight"
|
||||
]
|
||||
}
|
||||
path("/doorlocks/lock/:id") {
|
||||
action: [
|
||||
GET: "lockDoorLock"
|
||||
]
|
||||
}
|
||||
path("/doorlocks/unlock/:id") {
|
||||
action: [
|
||||
GET: "unlockDoorLock"
|
||||
]
|
||||
}
|
||||
path("/doorlocks/:id") {
|
||||
action: [
|
||||
GET: "getDoorLockStatus"
|
||||
]
|
||||
}
|
||||
path("/contacts/:id") {
|
||||
action: [
|
||||
GET: "getContactStatus"
|
||||
]
|
||||
}
|
||||
path("/smoke/:id") {
|
||||
action: [
|
||||
GET: "getSmokeStatus"
|
||||
]
|
||||
}
|
||||
path("/shades/open/:id") {
|
||||
action: [
|
||||
GET: "openShade"
|
||||
]
|
||||
}
|
||||
path("/shades/preset/:id") {
|
||||
action: [
|
||||
GET: "presetShade"
|
||||
]
|
||||
}
|
||||
path("/shades/close/:id") {
|
||||
action: [
|
||||
GET: "closeShade"
|
||||
]
|
||||
}
|
||||
path("/shades/:id") {
|
||||
action: [
|
||||
GET: "getShadeStatus"
|
||||
]
|
||||
}
|
||||
path("/garage/open/:id") {
|
||||
action: [
|
||||
GET: "openGarage"
|
||||
]
|
||||
}
|
||||
path("/garage/close/:id") {
|
||||
action: [
|
||||
GET: "closeGarage"
|
||||
]
|
||||
}
|
||||
path("/garage/:id") {
|
||||
action: [
|
||||
GET: "getGarageStatus"
|
||||
]
|
||||
}
|
||||
path("/watersensors/:id") {
|
||||
action: [
|
||||
GET: "getWaterSensorStatus"
|
||||
]
|
||||
}
|
||||
path("/tempsensors/:id") {
|
||||
action: [
|
||||
GET: "getTempSensorsStatus"
|
||||
]
|
||||
}
|
||||
path("/meters/:id") {
|
||||
action: [
|
||||
GET: "getMeterStatus"
|
||||
]
|
||||
}
|
||||
path("/batteries/:id") {
|
||||
action: [
|
||||
GET: "getBatteryStatus"
|
||||
]
|
||||
}
|
||||
path("/presences/:id") {
|
||||
action: [
|
||||
GET: "getPresenceStatus"
|
||||
]
|
||||
}
|
||||
path("/motions/:id") {
|
||||
action: [
|
||||
GET: "getMotionStatus"
|
||||
]
|
||||
}
|
||||
path("/outlets/:id") {
|
||||
action: [
|
||||
GET: "getOutletStatus"
|
||||
]
|
||||
}
|
||||
path("/outlets/turnon/:id") {
|
||||
action: [
|
||||
GET: "turnOnOutlet"
|
||||
]
|
||||
}
|
||||
path("/outlets/turnoff/:id") {
|
||||
action: [
|
||||
GET: "turnOffOutlet"
|
||||
]
|
||||
}
|
||||
path("/switches/turnon/:id") {
|
||||
action: [
|
||||
GET: "turnOnSwitch"
|
||||
]
|
||||
}
|
||||
path("/switches/turnoff/:id") {
|
||||
action: [
|
||||
GET: "turnOffSwitch"
|
||||
]
|
||||
}
|
||||
path("/switches/:id") {
|
||||
action: [
|
||||
GET: "getSwitchStatus"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
//API Methods
|
||||
def getAllDevices() {
|
||||
def locks_list = locks.collect{device(it,"Lock")}
|
||||
/*def thermo_list = thermostats.collect{device(it,"Thermostat")}*/
|
||||
def colors_list = colors.collect{device(it,"Color")}
|
||||
def kelvin_list = kelvin.collect{device(it,"Kelvin")}
|
||||
def contact_list = contact.collect{device(it,"Contact Sensor")}
|
||||
def smokes_list = smoke_alarms.collect{device(it,"Smoke Alarm")}
|
||||
def shades_list = shades.collect{device(it,"Window Shade")}
|
||||
def garage_list = garage.collect{device(it,"Garage Door")}
|
||||
def water_sensors_list = water_sensors.collect{device(it,"Water Sensor")}
|
||||
def presences_list = presence_sensors.collect{device(it,"Presence")}
|
||||
def motions_list = motions.collect{device(it,"Motion")}
|
||||
def outlets_list = outlets.collect{device(it,"Outlet")}
|
||||
def switches_list = switches.collect{device(it,"Switch")}
|
||||
def switchlevels_list = switchlevels.collect{device(it,"Switch Level")}
|
||||
def temp_list = temperature_sensors.collect{device(it,"Temperature")}
|
||||
def meters_list = meters.collect{device(it,"Power Meters")}
|
||||
def battery_list = batteries.collect{device(it,"Batteries")}
|
||||
return outlets_list + kelvin_list + colors_list + switchlevels_list + smokes_list + contact_list + water_sensors_list + shades_list + garage_list + locks_list + presences_list + motions_list + switches_list + temp_list + meters_list + battery_list
|
||||
}
|
||||
|
||||
//thermostat
|
||||
/*
|
||||
def setCoolTemp() {
|
||||
def device = thermostats.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
if(device.hasCommand("setCoolingSetpoint")) {
|
||||
device.setCoolingSetpoint(params.temp.toInteger());
|
||||
return [result_action: "200"]
|
||||
}
|
||||
else {
|
||||
httpError(510, "Not supported!")
|
||||
}
|
||||
}
|
||||
}
|
||||
def setHeatTemp() {
|
||||
def device = thermostats.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
if(device.hasCommand("setHeatingSetpoint")) {
|
||||
device.setHeatingSetpoint(params.temp.toInteger());
|
||||
return [result_action: "200"]
|
||||
}
|
||||
else {
|
||||
httpError(510, "Not supported!")
|
||||
}
|
||||
}
|
||||
}
|
||||
def setFanMode() {
|
||||
def device = thermostats.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
if(device.hasCommand("setThermostatFanMode")) {
|
||||
device.setThermostatFanMode(params.mode);
|
||||
return [result_action: "200"]
|
||||
}
|
||||
else {
|
||||
httpError(510, "Not supported!")
|
||||
}
|
||||
}
|
||||
}
|
||||
def setThermostatMode() {
|
||||
def device = thermostats.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
if(device.hasCommand("setThermostatMode")) {
|
||||
device.setThermostatMode(params.mode);
|
||||
return [result_action: "200"]
|
||||
}
|
||||
else {
|
||||
httpError(510, "Not supported!")
|
||||
}
|
||||
}
|
||||
}
|
||||
def getThermostatStatus() {
|
||||
def device = thermostats.find{ it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
return [ThermostatOperatingState: device.currentValue('thermostatOperatingState'), ThermostatSetpoint: device.currentValue('thermostatSetpoint'),
|
||||
ThermostatFanMode: device.currentValue('thermostatFanMode'), ThermostatMode: device.currentValue('thermostatMode')]
|
||||
}
|
||||
}
|
||||
*/
|
||||
//light
|
||||
def turnOnLight() {
|
||||
def device = switches.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
device.on();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
def turnOffLight() {
|
||||
def device = switches.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
device.off();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
def getLightStatus() {
|
||||
def device = switches.find{ it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
return [Status: device.currentValue('switch'), Dim: getLevelStatus(params.id), Color: getColorStatus(params.id), Kelvin: getKelvinStatus(params.id)]
|
||||
}
|
||||
}
|
||||
|
||||
//color control
|
||||
def setColor() {
|
||||
def device = colors.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
def map = [hue:params.hue.toInteger(), saturation:params.sat.toInteger()]
|
||||
|
||||
device.setColor(map);
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
def getColorStatus(id) {
|
||||
def device = colors.find { it.id == id }
|
||||
if (!device) {
|
||||
return [Color: "none"]
|
||||
} else {
|
||||
return [hue: device.currentValue('hue'), saturation: device.currentValue('saturation')]
|
||||
}
|
||||
}
|
||||
|
||||
//kelvin control
|
||||
def setKelvin() {
|
||||
def device = kelvin.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.setColorTemperature(params.kelvin.toInteger());
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
def getKelvinStatus(id) {
|
||||
def device = kelvin.find { it.id == id }
|
||||
if (!device) {
|
||||
return [kelvin: "none"]
|
||||
} else {
|
||||
return [kelvin: device.currentValue('colorTemperature')]
|
||||
}
|
||||
}
|
||||
|
||||
//switch level
|
||||
def getLevelStatus() {
|
||||
def device = switchlevels.find { it.id == params.id }
|
||||
if (!device) {
|
||||
[Level: "No dimmer"]
|
||||
} else {
|
||||
return [Level: device.currentValue('level')]
|
||||
}
|
||||
}
|
||||
|
||||
def getLevelStatus(id) {
|
||||
def device = switchlevels.find { it.id == id }
|
||||
if (!device) {
|
||||
[Level: "No dimmer"]
|
||||
} else {
|
||||
return [Level: device.currentValue('level')]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def setLevelStatus() {
|
||||
def device = switchlevels.find { it.id == params.id }
|
||||
def level = params.dim
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
device.setLevel(level.toInteger())
|
||||
return [result_action: "200", Level: device.currentValue('level')]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//contact sensors
|
||||
def getContactStatus() {
|
||||
def device = contact.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
def args = getTempSensorsStatus(device.id)
|
||||
return [Device_state: device.currentValue('contact')] + args
|
||||
}
|
||||
}
|
||||
|
||||
//smoke detectors
|
||||
def getSmokeStatus() {
|
||||
def device = smoke_alarms.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
def bat = getBatteryStatus(device.id)
|
||||
return [Device_state: device.currentValue('smoke')] + bat
|
||||
}
|
||||
}
|
||||
|
||||
//garage
|
||||
def getGarageStatus() {
|
||||
def device = garage.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
return [Device_state: device.currentValue('door')]
|
||||
}
|
||||
}
|
||||
|
||||
def openGarage() {
|
||||
def device = garage.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.open();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
def closeGarage() {
|
||||
def device = garage.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.close();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
//shades
|
||||
def getShadeStatus() {
|
||||
def device = shades.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
return [Device_state: device.currentValue('windowShade')]
|
||||
}
|
||||
}
|
||||
|
||||
def openShade() {
|
||||
def device = shades.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.open();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
def presetShade() {
|
||||
def device = shades.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.presetPosition();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
def closeShade() {
|
||||
def device = shades.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.close();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
//water sensor
|
||||
def getWaterSensorStatus() {
|
||||
def device = water_sensors.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
def bat = getBatteryStatus(device.id)
|
||||
return [Device_state: device.currentValue('water')] + bat
|
||||
}
|
||||
}
|
||||
//batteries
|
||||
def getBatteryStatus() {
|
||||
def device = batteries.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
return [Device_state: device.latestValue("battery")]
|
||||
}
|
||||
}
|
||||
|
||||
def getBatteryStatus(id) {
|
||||
def device = batteries.find { it.id == id }
|
||||
if (!device) {
|
||||
return []
|
||||
} else {
|
||||
return [battery_state: device.latestValue("battery")]
|
||||
}
|
||||
}
|
||||
|
||||
//LOCKS
|
||||
def getDoorLockStatus() {
|
||||
def device = locks.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
def bat = getBatteryStatus(device.id)
|
||||
return [Device_state: device.currentValue('lock')] + bat
|
||||
}
|
||||
}
|
||||
|
||||
def lockDoorLock() {
|
||||
def device = locks.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.lock();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
def unlockDoorLock() {
|
||||
def device = locks.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.unlock();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
//PRESENCE
|
||||
def getPresenceStatus() {
|
||||
|
||||
def device = presence_sensors.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
def bat = getBatteryStatus(device.id)
|
||||
return [Device_state: device.currentValue('presence')] + bat
|
||||
}
|
||||
}
|
||||
|
||||
//MOTION
|
||||
def getMotionStatus() {
|
||||
|
||||
def device = motions.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
def args = getTempSensorsStatus(device.id)
|
||||
return [Device_state: device.currentValue('motion')] + args
|
||||
}
|
||||
}
|
||||
|
||||
//OUTLET
|
||||
def getOutletStatus() {
|
||||
|
||||
def device = outlets.find { it.id == params.id }
|
||||
if (!device) {
|
||||
device = switches.find { it.id == params.id }
|
||||
if(!device) {
|
||||
httpError(404, "Device not found")
|
||||
}
|
||||
}
|
||||
def watt = getMeterStatus(device.id)
|
||||
|
||||
return [Device_state: device.currentValue('switch')] + watt
|
||||
}
|
||||
|
||||
def getMeterStatus() {
|
||||
|
||||
def device = meters.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
return [Device_id: device.id, Device_type: device.type, Current_watt: device.currentValue("power")]
|
||||
}
|
||||
}
|
||||
|
||||
def getMeterStatus(id) {
|
||||
|
||||
def device = meters.find { it.id == id }
|
||||
if (!device) {
|
||||
return []
|
||||
} else {
|
||||
return [Current_watt: device.currentValue("power")]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def turnOnOutlet() {
|
||||
def device = outlets.find { it.id == params.id }
|
||||
if (!device) {
|
||||
device = switches.find { it.id == params.id }
|
||||
if(!device) {
|
||||
httpError(404, "Device not found")
|
||||
}
|
||||
}
|
||||
|
||||
device.on();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
|
||||
def turnOffOutlet() {
|
||||
def device = outlets.find { it.id == params.id }
|
||||
if (!device) {
|
||||
device = switches.find { it.id == params.id }
|
||||
if(!device) {
|
||||
httpError(404, "Device not found")
|
||||
}
|
||||
}
|
||||
|
||||
device.off();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
|
||||
//SWITCH
|
||||
def getSwitchStatus() {
|
||||
def device = switches.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
return [Device_state: device.currentValue('switch'), Dim: getLevelStatus(params.id)]
|
||||
}
|
||||
}
|
||||
|
||||
def turnOnSwitch() {
|
||||
def device = switches.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.on();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
def turnOffSwitch() {
|
||||
def device = switches.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
|
||||
device.off();
|
||||
|
||||
return [Device_id: params.id, result_action: "200"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TEMPERATURE
|
||||
def getTempSensorsStatus() {
|
||||
def device = temperature_sensors.find { it.id == params.id }
|
||||
if (!device) {
|
||||
httpError(404, "Device not found")
|
||||
} else {
|
||||
def bat = getBatteryStatus(device.id)
|
||||
def scale = [Scale: location.temperatureScale]
|
||||
return [Device_state: device.currentValue('temperature')] + scale + bat
|
||||
}
|
||||
}
|
||||
|
||||
def getTempSensorsStatus(id) {
|
||||
def device = temperature_sensors.find { it.id == id }
|
||||
if (!device) {
|
||||
return []
|
||||
} else {
|
||||
def bat = getBatteryStatus(device.id)
|
||||
return [temperature: device.currentValue('temperature')] + bat
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* SmartThings SmartApp: Yamaha Network Receiver
|
||||
*
|
||||
* Author: redloro@gmail.com
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* https://github.com/PSeitz/yamaha-nodejs
|
||||
* http://<RECEIVER_IP_ADDRESS>/YamahaRemoteControl/desc.xml
|
||||
*/
|
||||
import groovy.util.XmlSlurper
|
||||
|
||||
definition(
|
||||
name: "Yamaha Receiver",
|
||||
namespace: "redloro-smartthings",
|
||||
author: "redloro@gmail.com",
|
||||
description: "Yamaha SmartApp",
|
||||
category: "My Apps",
|
||||
iconUrl: "https://raw.githubusercontent.com/redloro/smartthings/master/images/yamaha-receiver.png",
|
||||
iconX2Url: "https://raw.githubusercontent.com/redloro/smartthings/master/images/yamaha-receiver.png",
|
||||
iconX3Url: "https://raw.githubusercontent.com/redloro/smartthings/master/images/yamaha-receiver.png"
|
||||
)
|
||||
|
||||
preferences {
|
||||
section("SmartThings Hub") {
|
||||
input "hostHub", "hub", title: "Select Hub", multiple: false, required: true
|
||||
}
|
||||
section("Yamaha Receiver") {
|
||||
input name: "receiverName", type: "text", title: "Name", required: true, defaultValue: "Yamaha"
|
||||
input name: "receiverIp", type: "text", title: "IP", required: true
|
||||
input name: "receiverZones", type: "enum", title: "Zones", required: true, multiple: true, options: ["Main_Zone","Zone_B","Zone_2","Zone_3","Zone_4"]
|
||||
}
|
||||
}
|
||||
|
||||
def installed() {
|
||||
subscribeToEvents()
|
||||
}
|
||||
|
||||
def subscribeToEvents() {
|
||||
subscribe(location, null, lanResponseHandler, [filterEvents:false])
|
||||
}
|
||||
|
||||
def updated() {
|
||||
addChildDevices()
|
||||
}
|
||||
|
||||
def uninstalled() {
|
||||
removeChildDevices()
|
||||
}
|
||||
|
||||
def lanResponseHandler(evt) {
|
||||
def map = stringToMap(evt.stringValue)
|
||||
|
||||
//verify that this message is from Yamaha Receiver IP
|
||||
if (!map.ip || map.ip != convertIPtoHex(settings.receiverIp)) {
|
||||
return
|
||||
}
|
||||
|
||||
def headers = getHttpHeaders(map.headers);
|
||||
def body = getHttpBody(map.body);
|
||||
//log.trace "Headers: ${headers}"
|
||||
//log.trace "Body: ${body}"
|
||||
|
||||
updateZoneDevices(body.children()[0])
|
||||
}
|
||||
|
||||
private updateZoneDevices(evt) {
|
||||
//log.debug "updateZoneDevices: ${evt.toString()}"
|
||||
if (evt.name() == "System") {
|
||||
//log.debug "Update all zones"
|
||||
childDevices*.zone(evt)
|
||||
return
|
||||
}
|
||||
|
||||
def zonedevice = getChildDevice(getDeviceId(evt.name()))
|
||||
if (zonedevice) {
|
||||
zonedevice.zone(evt)
|
||||
}
|
||||
|
||||
//check for Zone_B
|
||||
zonedevice = getChildDevice(getDeviceId("Zone_B"))
|
||||
if (zonedevice && evt.name() == "Main_Zone") {
|
||||
zonedevice.zone(evt)
|
||||
}
|
||||
}
|
||||
|
||||
private addChildDevices() {
|
||||
// add yamaha device
|
||||
settings.receiverZones.each {
|
||||
def deviceId = getDeviceId(it)
|
||||
if (!getChildDevice(deviceId)) {
|
||||
addChildDevice("redloro-smartthings", "Yamaha Zone", deviceId, hostHub.id, ["name": it, label: "${settings.receiverName}: ${it}", completedSetup: true])
|
||||
log.debug "Added Yamaha zone: ${deviceId}"
|
||||
}
|
||||
}
|
||||
|
||||
childDevices*.refresh()
|
||||
}
|
||||
|
||||
private removeChildDevices() {
|
||||
getAllChildDevices().each { deleteChildDevice(it.deviceNetworkId) }
|
||||
}
|
||||
|
||||
private sendCommand(body) {
|
||||
//log.debug "Yamaha Network Receiver send command: ${body}"
|
||||
|
||||
def hubAction = new physicalgraph.device.HubAction(
|
||||
headers: [HOST: getReceiverAddress()],
|
||||
method: "POST",
|
||||
path: "/YamahaRemoteControl/ctrl",
|
||||
body: body
|
||||
)
|
||||
sendHubCommand(hubAction)
|
||||
}
|
||||
|
||||
private getHttpHeaders(headers) {
|
||||
def obj = [:]
|
||||
new String(headers.decodeBase64()).split("\r\n").each {param ->
|
||||
def nameAndValue = param.split(":")
|
||||
obj[nameAndValue[0]] = (nameAndValue.length == 1) ? "" : nameAndValue[1].trim()
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
private getHttpBody(body) {
|
||||
def obj = null;
|
||||
if (body) {
|
||||
obj = new XmlSlurper().parseText(new String(body.decodeBase64()))
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
private getDeviceId(zone) {
|
||||
return "yamaha|${settings.receiverIp}|${zone}"
|
||||
}
|
||||
|
||||
private getReceiverAddress() {
|
||||
return settings.receiverIp + ":80"
|
||||
}
|
||||
|
||||
private String convertIPtoHex(ipAddress) {
|
||||
return ipAddress.tokenize( '.' ).collect { String.format( '%02x', it.toInteger() ) }.join().toUpperCase()
|
||||
}
|
||||
|
||||
private String convertPortToHex(port) {
|
||||
return port.toString().format( '%04x', port.toInteger() ).toUpperCase()
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Monitors a switch for ON condition and switches OFF after time delay.
|
||||
*
|
||||
* Author: SmartThings modified by TC Hayes
|
||||
*
|
||||
* This app detects the ON status of a switch, waits X seconds, then switches off.
|
||||
* May be used anywhere a short on/off condition of a few seconds is needed, for example:
|
||||
* --- An automatic doorbell where a motion sensor switches ON a buzzer. This app terminates the buzz after X seconds.
|
||||
* --- An automated pet/fish feeder where a separate timer app turns on the feed switch. This app turns off the flow after X seconds. Use along
|
||||
* with a delay timer between feeds eg (Home Monitor / Custom / New Monitoring Rule ...).
|
||||
* --- A garage door opener actuator where an on/off pulse of X seconds is needed to either open or close. Any other app can trigger
|
||||
* the ON condition by detecting motion, button operation of a button, or elapsed time. This app will teminate the pulse with an OFF signal. Use
|
||||
* ST Smart Home Monitor (Custom / New Monitoring Rule ... ) with this app to close a door left open.
|
||||
* --- Use with app 'Switch ON After Delay' to create a continuing on/off flashing sequence. (Lighthouse.)
|
||||
**/
|
||||
definition(
|
||||
name: "Switch OFF After Delay",
|
||||
namespace: "tchayes57",
|
||||
author: "tchayes57",
|
||||
description: "Monitor switch and respond to an ON condition with OFF after X seconds.",
|
||||
category: "Convenience",
|
||||
)
|
||||
|
||||
preferences {
|
||||
section("Switch to be monitored ...") {
|
||||
input "switch1", "capability.switch", required: true
|
||||
}
|
||||
|
||||
section("Set Delay") {
|
||||
input "openTimer", "number", title: "Number of seconds delay", required: true
|
||||
}
|
||||
}
|
||||
|
||||
def installed() {
|
||||
subscribe(app, appTouchHandler)
|
||||
subscribeToCommand(switch1, "on", onCommand)
|
||||
}
|
||||
|
||||
def updated() {
|
||||
unsubscribe()
|
||||
subscribe(app, appTouchHandler)
|
||||
subscribeToCommand(switch1, "on", onCommand)
|
||||
}
|
||||
// identify transition to ON
|
||||
def appTouch(evt) {
|
||||
log.debug "appTouch: $evt.value, $evt"
|
||||
switch1?.on()
|
||||
}
|
||||
|
||||
// initiate OFF after delay
|
||||
def onCommand(evt) {
|
||||
log.debug "onCommand: $evt.value, $evt"
|
||||
switch1?.off(delay: openTimer * 1000)
|
||||
}
|
||||
Reference in New Issue
Block a user