mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-19 13:20:53 +00:00
Compare commits
1 Commits
PROD_2016.
...
MSA-1189-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a27ca03edd |
@@ -9,7 +9,7 @@ apply plugin: 'smartthings-slack'
|
|||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.8"
|
classpath "com.smartthings.deployment:executable-deployment-scripts:1.0.7"
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
|
|||||||
@@ -1,795 +0,0 @@
|
|||||||
/**
|
|
||||||
* CoopBoss H3Vx
|
|
||||||
* 02/29/16 Fixed app crash with Android by changing the syntax of default state in tile definition.
|
|
||||||
* Fixed null value errors during join process. Added 3 new commands to refresh data.
|
|
||||||
*
|
|
||||||
* 01/18/16 Masked invalid temperature reporting when TempProbe1 is below 0C
|
|
||||||
* Added setBaseCurrentNE, readBaseCurrentNE, commands as well as baseCurrentNE attribute.
|
|
||||||
*
|
|
||||||
* Copyright 2016 John Rucker
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
* Icon location = http://scripts.3dgo.net/smartthings/icons/
|
|
||||||
*/
|
|
||||||
metadata {
|
|
||||||
definition (name: "CoopBoss H3Vx", namespace: "JohnRucker", author: "John.Rucker@Solar-Current.com") {
|
|
||||||
capability "Refresh"
|
|
||||||
capability "Polling"
|
|
||||||
capability "Sensor"
|
|
||||||
capability "Actuator"
|
|
||||||
capability "Configuration"
|
|
||||||
capability "Temperature Measurement"
|
|
||||||
capability "Door Control"
|
|
||||||
capability "Switch"
|
|
||||||
|
|
||||||
command "closeDoor"
|
|
||||||
command "closeDoorHiI"
|
|
||||||
command "openDoor"
|
|
||||||
command "autoCloseOn"
|
|
||||||
command "autoCloseOff"
|
|
||||||
command "autoOpenOn"
|
|
||||||
command "autoOpenOff"
|
|
||||||
command "setCloseLevelTo"
|
|
||||||
command "setOpenLevelTo"
|
|
||||||
command "setSensitivityLevel"
|
|
||||||
command "Aux1On"
|
|
||||||
command "Aux1Off"
|
|
||||||
command "Aux2On"
|
|
||||||
command "Aux2Off"
|
|
||||||
command "updateTemp1"
|
|
||||||
command "updateTemp2"
|
|
||||||
command "updateSun"
|
|
||||||
command "setNewBaseCurrent"
|
|
||||||
command "setNewPhotoCalibration"
|
|
||||||
command "readNewPhotoCalibration"
|
|
||||||
command "readBaseCurrentNE"
|
|
||||||
command "setBaseCurrentNE"
|
|
||||||
command "updateSensitivity"
|
|
||||||
command "updateCloseLightLevel"
|
|
||||||
command "updateOpenLightLevel"
|
|
||||||
|
|
||||||
attribute "doorState","string"
|
|
||||||
attribute "currentLightLevel","number"
|
|
||||||
attribute "closeLightLevel","number"
|
|
||||||
attribute "openLightLevel","number"
|
|
||||||
attribute "autoCloseEnable","string"
|
|
||||||
attribute "autoOpenEnable","string"
|
|
||||||
attribute "TempProb1","number"
|
|
||||||
attribute "TempProb2","number"
|
|
||||||
attribute "dayOrNight","string"
|
|
||||||
attribute "doorSensitivity","number"
|
|
||||||
attribute "doorCurrent","number"
|
|
||||||
attribute "doorVoltage","number"
|
|
||||||
attribute "Aux1","string"
|
|
||||||
attribute "Aux2","string"
|
|
||||||
attribute "coopStatus","string"
|
|
||||||
attribute "baseDoorCurrent","number"
|
|
||||||
attribute "photoCalibration","number"
|
|
||||||
attribute "baseCurrentNE","string"
|
|
||||||
|
|
||||||
fingerprint profileId: "0104", inClusters: "0000,0101,0402", manufacturer: "Solar-Current", model: "Coop Boss"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// simulator metadata
|
|
||||||
simulator {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
preferences {
|
|
||||||
input description: "This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter \"-5\". If 3 degrees too cold, enter \"+3\".", displayDuringSetup: false, type: "paragraph", element: "paragraph"
|
|
||||||
input "tempOffsetCoop", "number", title: "Coop Temperature Offset", description: "Adjust temperature by this many degrees", range: "*..*", displayDuringSetup: false
|
|
||||||
input "tempOffsetOutside", "number", title: "Outside Temperature Offset", description: "Adjust temperature by this many degrees", range: "*..*", displayDuringSetup: false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// UI tile definitions
|
|
||||||
tiles(scale: 2){
|
|
||||||
multiAttributeTile(name:"doorCtrl", type:"generic", width:6, height:4) {tileAttribute("device.doorState", key: "PRIMARY_CONTROL")
|
|
||||||
{
|
|
||||||
attributeState "unknown", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", nextState:"Sent"
|
|
||||||
attributeState "open", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#0000ff" , nextState:"Sent"
|
|
||||||
attributeState "opening", label: '${name}', action:"closeDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffa81e"
|
|
||||||
attributeState "closed", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#79b821", nextState:"Sent"
|
|
||||||
attributeState "closing", label: '${name}', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ffa81e"
|
|
||||||
attributeState "jammed", label: '${name}', action:"closeDoorHiI", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff0000", nextState:"Sent"
|
|
||||||
attributeState "forced close", label: 'forced\rclose', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff8000", nextState:"Sent"
|
|
||||||
attributeState "fault", label: 'FAULT', action:"openDoor", icon: "st.Outdoor.outdoor20", backgroundColor: "#ff0000", nextState:"Sent"
|
|
||||||
attributeState "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
|
||||||
}
|
|
||||||
tileAttribute ("device.coopStatus", key: "SECONDARY_CONTROL") {
|
|
||||||
attributeState "device.coopStatus", label:'${currentValue}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
multiAttributeTile(name:"dtlsDoorCtrl", type:"generic", width:6, height:4) {tileAttribute("device.doorState", key: "PRIMARY_CONTROL")
|
|
||||||
{
|
|
||||||
attributeState "unknown", label: '${name}', action:"openDoor", icon: "st.secondary.tools", nextState:"Sent"
|
|
||||||
attributeState "open", label: '${name}', action:"closeDoor", icon: "st.doors.garage.garage-open", backgroundColor: "#0000ff", nextState:"Sent"
|
|
||||||
attributeState "opening", label: '${name}', action:"closeDoor", icon: "st.doors.garage.garage-opening", backgroundColor: "#ffa81e"
|
|
||||||
attributeState "closed", label: '${name}', action:"openDoor", icon: "st.doors.garage.garage-closed", backgroundColor: "#79b821", nextState:"Sent"
|
|
||||||
attributeState "closing", label: '${name}', action:"openDoor", icon: "st.doors.garage.garage-closing", backgroundColor: "#ffa81e"
|
|
||||||
attributeState "jammed", label: '${name}', action:"closeDoorHiI", icon: "st.doors.garage.garage-open", backgroundColor: "#ff0000", nextState:"Sent"
|
|
||||||
attributeState "forced close", label: "forced", action:"openDoor", icon: "st.doors.garage.garage-closed", backgroundColor: "#ff8000", nextState:"Sent"
|
|
||||||
attributeState "fault", label: 'FAULT', action:"openDoor", icon: "st.secondary.tools", backgroundColor: "#ff0000", nextState:"Sent"
|
|
||||||
attributeState "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
|
||||||
}
|
|
||||||
tileAttribute ("device.doorState", key: "SECONDARY_CONTROL") {
|
|
||||||
attributeState "unknown", label: 'Door is in unknown state. Push to open.'
|
|
||||||
attributeState "open", label: 'Coop door is open. Push to close.'
|
|
||||||
attributeState "opening", label: 'Caution, door is opening!'
|
|
||||||
attributeState "closed", label: 'Coop door is closed. Push to open.'
|
|
||||||
attributeState "closing", label: 'Caution, door is closing!'
|
|
||||||
attributeState "jammed", label: 'Door open! Push for high-force close'
|
|
||||||
attributeState "forced close", label: "Door is closed. Push to open."
|
|
||||||
attributeState "fault", label: 'Door fault check electrical connection.'
|
|
||||||
attributeState "Sent", label: 'Command sent to CoopBoss...'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("autoClose", "device.autoCloseEnable", width: 2, height: 2){
|
|
||||||
state "on", label: 'Auto', action:"autoCloseOff", icon: "st.doors.garage.garage-closing", backgroundColor: "#79b821", nextState:"Sent"
|
|
||||||
state "off", label: 'Auto', action:"autoCloseOn", icon: "st.doors.garage.garage-closing", nextState:"Sent"
|
|
||||||
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("autoOpen", "device.autoOpenEnable", width: 2, height: 2){
|
|
||||||
state "on", label: 'Auto', action:"autoOpenOff", icon: "st.doors.garage.garage-opening", backgroundColor: "#79b821", nextState:"Sent"
|
|
||||||
state "off", label: 'Auto', action:"autoOpenOn", icon: "st.doors.garage.garage-opening", nextState:"Sent"
|
|
||||||
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
|
||||||
}
|
|
||||||
|
|
||||||
valueTile("TempProb1", "device.TempProb1", width: 2, height: 2, decoration: "flat"){
|
|
||||||
state "default", label:'Coop\r${currentValue}°', unit:"F", action:"updateTemp1"}
|
|
||||||
|
|
||||||
valueTile("TempProb2", "device.TempProb2", width: 2, height: 2, decoration: "flat"){
|
|
||||||
state "default", label:'Outside\r${currentValue}°', unit:"F", action:"updateTemp2"}
|
|
||||||
|
|
||||||
valueTile("currentLevel", "device.currentLightLevel", width: 2, height: 2, decoration: "flat") {
|
|
||||||
state "default", label:'Sun\r${currentValue}', action:"updateSun"}
|
|
||||||
|
|
||||||
valueTile("dayOrNight", "device.dayOrNight", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
|
|
||||||
state "default", label:'${currentValue}.'
|
|
||||||
}
|
|
||||||
|
|
||||||
controlTile("SetClSlider", "device.closeLightLevel", "slider", height: 2, width: 4, inactiveLabel: false, range:"(1..100)") {
|
|
||||||
state "closeLightLevel", action:"setCloseLevelTo", backgroundColor:"#d04e00"
|
|
||||||
}
|
|
||||||
|
|
||||||
valueTile("SetClValue", "device.closeLightLevel", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
|
|
||||||
state "default", label:'Close\nSunlight\n${currentValue}', action:'updateCloseLightLevel'
|
|
||||||
}
|
|
||||||
|
|
||||||
controlTile("SetOpSlider", "device.openLightLevel", "slider", height: 2, width: 4, inactiveLabel: false, range:"(1..100)") {
|
|
||||||
state "openLightLevel", action:"setOpenLevelTo", backgroundColor:"#d04e00"
|
|
||||||
}
|
|
||||||
|
|
||||||
valueTile("SetOpValue", "device.openLightLevel", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
|
|
||||||
state "default", label:'Open\nSunlight\n${currentValue}', action:'updateOpenLightLevel'
|
|
||||||
}
|
|
||||||
|
|
||||||
controlTile("SetSensitivitySlider", "device.doorSensitivity", "slider", height: 2, width: 4, inactiveLabel: false, range:"(1..100)") {
|
|
||||||
state "openLightLevel", action:"setSensitivityLevel", backgroundColor:"#d04e00"
|
|
||||||
}
|
|
||||||
|
|
||||||
valueTile("SetSensitivityValue", "device.doorSensitivity", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
|
|
||||||
state "default", label:'Door\nSensitivity\n${currentValue}', action:'updateSensitivity'
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("refresh", "device.refresh", width: 2, height: 2, decoration: "flat", inactiveLabel: false) {
|
|
||||||
state "default", label:'All', action:"refresh.refresh", icon:"st.secondary.refresh-icon"
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("aux1", "device.Aux1", width: 2, height: 2, canChangeIcon: true) {
|
|
||||||
state "off", label:'Aux 1', action:"Aux1On", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"Sent"
|
|
||||||
state "on", label:'Aux 1', action:"Aux1Off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"Sent"
|
|
||||||
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("aux2", "device.Aux2", width: 2, height: 2, canChangeIcon: true) {
|
|
||||||
state "off", label:'Aux 2', action:"Aux2On", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"Sent"
|
|
||||||
state "on", label:'Aux 2', action:"Aux2Off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"Sent"
|
|
||||||
state "Sent", label: 'wait', icon: "st.motion.motion.active", backgroundColor: "#ffa81e"
|
|
||||||
}
|
|
||||||
|
|
||||||
main "doorCtrl"
|
|
||||||
details (["dtlsDoorCtrl", "TempProb1", "TempProb2", "currentLevel", "autoClose", "autoOpen", "dayOrNight",
|
|
||||||
"SetClSlider", "SetClValue", "SetOpSlider", "SetOpValue", "SetSensitivitySlider", "SetSensitivityValue",
|
|
||||||
"aux1", "aux2", "refresh"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse incoming device messages to generate events def parse(String description) {
|
|
||||||
def parse(String description) {
|
|
||||||
log.debug "description: $description"
|
|
||||||
Map map = [:]
|
|
||||||
if (description?.startsWith('catchall:')) {
|
|
||||||
map = parseCatchAllMessage(description)
|
|
||||||
}
|
|
||||||
else if (description?.startsWith('read attr -')) {
|
|
||||||
map = parseReportAttributeMessage(description)
|
|
||||||
}
|
|
||||||
else if (description?.startsWith('temperature: ') || description?.startsWith('humidity: ')) {
|
|
||||||
map = parseCustomMessage(description)
|
|
||||||
}
|
|
||||||
log.debug map
|
|
||||||
//return map ? createEvent(map) : null
|
|
||||||
sendEvent(map)
|
|
||||||
callUpdateStatusTxt()
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map parseCatchAllMessage(String description) {
|
|
||||||
Map resultMap = [:]
|
|
||||||
def cluster = zigbee.parse(description)
|
|
||||||
log.debug cluster
|
|
||||||
if (cluster.clusterId == 0x0402) {
|
|
||||||
switch(cluster.sourceEndpoint) {
|
|
||||||
|
|
||||||
case 0x39: // Endpoint 0x39 is the temperature of probe 1
|
|
||||||
String temp = cluster.data[-2..-1].reverse().collect { cluster.hex1(it) }.join()
|
|
||||||
resultMap.name = "TempProb1"
|
|
||||||
def celsius = Integer.valueOf(temp,16).shortValue()
|
|
||||||
if (celsius == -32768){ // This number is used to indicate an error in the temperature reading
|
|
||||||
resultMap.value = "---"
|
|
||||||
}else{
|
|
||||||
celsius = celsius / 100 // Temperature value is sent X 100.
|
|
||||||
resultMap.value = celsiusToFahrenheit(celsius)
|
|
||||||
if (tempOffsetOutside) {
|
|
||||||
def offset = tempOffsetOutside as int
|
|
||||||
resultMap.value = resultMap.value + offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sendEvent(name: "temperature", value: resultMap.value, displayed: false) // set the temperatureMeasurment capability to temperature
|
|
||||||
break
|
|
||||||
|
|
||||||
case 0x40: // Endpoint 0x40 is the temperature of probe 2
|
|
||||||
String temp = cluster.data[-2..-1].reverse().collect { cluster.hex1(it) }.join()
|
|
||||||
resultMap.name = "TempProb2"
|
|
||||||
def celsius = Integer.valueOf(temp,16).shortValue()
|
|
||||||
//resultMap.descriptionText = "Prob2 celsius value = ${celsius}"
|
|
||||||
if (celsius == -32768){ // This number is used to indicate an error in the temperature reading
|
|
||||||
resultMap.value = "---"
|
|
||||||
}else{
|
|
||||||
celsius = celsius / 100 // Temperature value is sent X 100.
|
|
||||||
resultMap.value = celsiusToFahrenheit(celsius)
|
|
||||||
if (tempOffsetCoop) {
|
|
||||||
def offset = tempOffsetCoop as int
|
|
||||||
resultMap.value = resultMap.value + offset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cluster.clusterId == 0x0101 && cluster.command == 0x0b) { // This is a default response to a command sent to cluster 0x0101 door control
|
|
||||||
//log.debug "Default Response Data = $cluster.data"
|
|
||||||
switch(cluster.data) {
|
|
||||||
|
|
||||||
case "[10, 0]": // 0x0a turn auto close on command verified
|
|
||||||
resultMap.name = "autoCloseEnable"
|
|
||||||
resultMap.value = "on"
|
|
||||||
break
|
|
||||||
|
|
||||||
case "[11, 0]": // 0x0b turn auto close off command verified
|
|
||||||
resultMap.name = "autoCloseEnable"
|
|
||||||
resultMap.value = "off"
|
|
||||||
break
|
|
||||||
|
|
||||||
case "[12, 0]": // 0x0C turn auto open on command verified
|
|
||||||
resultMap.name = "autoOpenEnable"
|
|
||||||
resultMap.value = "on"
|
|
||||||
break
|
|
||||||
|
|
||||||
case "[13, 0]": // 0x0d turn auto open off command verified
|
|
||||||
resultMap.name = "autoOpenEnable"
|
|
||||||
resultMap.value = "off"
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
case "[20, 0]": // 0x14 Aux1 On command verified
|
|
||||||
log.info "verified Aux1 On"
|
|
||||||
sendEvent(name: "switch", value: "on", displayed: false)
|
|
||||||
resultMap.name = "Aux1"
|
|
||||||
resultMap.value = "on"
|
|
||||||
break
|
|
||||||
|
|
||||||
case "[21, 0]": // 0x15 Aux1 Off command verified
|
|
||||||
log.info "verified Aux1 Off"
|
|
||||||
sendEvent(name: "switch", value: "off", displayed: false)
|
|
||||||
resultMap.name = "Aux1"
|
|
||||||
resultMap.value = "off"
|
|
||||||
break
|
|
||||||
|
|
||||||
case "[22, 0]": // 0x16 Aux2 On command verified
|
|
||||||
log.info "verified Aux2 On"
|
|
||||||
resultMap.name = "Aux2"
|
|
||||||
resultMap.value = "on"
|
|
||||||
break
|
|
||||||
|
|
||||||
case "[23, 0]": // 0x17 Aux2 Off command verified
|
|
||||||
log.info "verified Aux2 Off"
|
|
||||||
resultMap.name = "Aux2"
|
|
||||||
resultMap.value = "off"
|
|
||||||
break
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resultMap
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map parseReportAttributeMessage(String description) {
|
|
||||||
Map resultMap = [:]
|
|
||||||
def descMap = parseDescriptionAsMap(description)
|
|
||||||
//log.debug "read attr descMap --> $descMap"
|
|
||||||
if (descMap.cluster == "0101" && descMap.attrId == "0003") {
|
|
||||||
resultMap.name = "doorState"
|
|
||||||
if (descMap.value == "00"){
|
|
||||||
resultMap.value = "unknown"
|
|
||||||
sendEvent(name: "door", value: "unknown", displayed: false)
|
|
||||||
}else if(descMap.value == "01"){
|
|
||||||
resultMap.value = "closed"
|
|
||||||
sendEvent(name: "door", value: "closed", displayed: false)
|
|
||||||
}else if(descMap.value == "02"){
|
|
||||||
resultMap.value = "open"
|
|
||||||
sendEvent(name: "door", value: "open", displayed: false)
|
|
||||||
}else if(descMap.value == "03"){
|
|
||||||
resultMap.value = "jammed"
|
|
||||||
}else if(descMap.value == "04"){
|
|
||||||
resultMap.value = "forced close"
|
|
||||||
}else if(descMap.value == "05"){
|
|
||||||
resultMap.value = "forced close"
|
|
||||||
}else if(descMap.value == "06"){
|
|
||||||
resultMap.value = "closing"
|
|
||||||
sendEvent(name: "door", value: "closing", displayed: false)
|
|
||||||
}else if(descMap.value == "07"){
|
|
||||||
resultMap.value = "opening"
|
|
||||||
sendEvent(name: "door", value: "opening", displayed: false)
|
|
||||||
}else if(descMap.value == "08"){
|
|
||||||
resultMap.value = "fault"
|
|
||||||
}else {
|
|
||||||
resultMap.value = "unknown"
|
|
||||||
}
|
|
||||||
resultMap.descriptionText = "Door State Changed to ${resultMap.value}"
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "0400") {
|
|
||||||
resultMap.name = "currentLightLevel"
|
|
||||||
resultMap.value = (Integer.parseInt(descMap.value, 16))
|
|
||||||
resultMap.displayed = false
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "0401") {
|
|
||||||
resultMap.name = "closeLightLevel"
|
|
||||||
resultMap.value = (Integer.parseInt(descMap.value, 16))
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "0402") {
|
|
||||||
resultMap.name = "openLightLevel"
|
|
||||||
resultMap.value = (Integer.parseInt(descMap.value, 16))
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "0403") {
|
|
||||||
resultMap.name = "autoCloseEnable"
|
|
||||||
if (descMap.value == "01"){resultMap.value = "on"}
|
|
||||||
else{resultMap.value = "off"}
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "0404") {
|
|
||||||
resultMap.name = "autoOpenEnable"
|
|
||||||
if (descMap.value == "01"){resultMap.value = "on"}
|
|
||||||
else{resultMap.value = "off"}
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "0405") {
|
|
||||||
resultMap.name = "doorCurrent"
|
|
||||||
resultMap.value = (Integer.parseInt(descMap.value, 16))
|
|
||||||
resultMap.value = resultMap.value * 0.001
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "0408") {
|
|
||||||
resultMap.name = "doorSensitivity"
|
|
||||||
resultMap.value = (100 - Integer.parseInt(descMap.value, 16))
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "0409") {
|
|
||||||
resultMap.name = "baseDoorCurrent"
|
|
||||||
resultMap.value = (Integer.parseInt(descMap.value, 16))
|
|
||||||
resultMap.value = resultMap.value * 0.001
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "040a") {
|
|
||||||
resultMap.name = "doorVoltage"
|
|
||||||
resultMap.value = (Integer.parseInt(descMap.value, 16))
|
|
||||||
resultMap.value = resultMap.value * 0.001
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "040b") {
|
|
||||||
resultMap.name = "Aux1"
|
|
||||||
if(descMap.value == "01"){
|
|
||||||
resultMap.value = "on"
|
|
||||||
sendEvent(name: "switch", value: "on", displayed: false)
|
|
||||||
}else{
|
|
||||||
resultMap.value = "off"
|
|
||||||
sendEvent(name: "switch", value: "off", displayed: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "040c") {
|
|
||||||
resultMap.name = "Aux2"
|
|
||||||
if(descMap.value == "01"){
|
|
||||||
resultMap.value = "on"
|
|
||||||
}else{
|
|
||||||
resultMap.value = "off"
|
|
||||||
}
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "040d") {
|
|
||||||
resultMap.name = "photoCalibration"
|
|
||||||
resultMap.value = (Integer.parseInt(descMap.value, 16))
|
|
||||||
} else if (descMap.cluster == "0101" && descMap.attrId == "040e") {
|
|
||||||
resultMap.name = "baseCurrentNE"
|
|
||||||
resultMap.value = (Integer.parseInt(descMap.value, 16))
|
|
||||||
}
|
|
||||||
return resultMap
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map parseCustomMessage(String description) {
|
|
||||||
//log.info "ParseCustomMessage called with ${description}"
|
|
||||||
Map resultMap = [:]
|
|
||||||
if (description?.startsWith('temperature: ')) {
|
|
||||||
resultMap.name = "temperature"
|
|
||||||
def rawT = (description - "temperature: ").trim()
|
|
||||||
resultMap.descriptionText = "Temperature celsius value = ${rawT}"
|
|
||||||
def rawTint = Float.parseFloat(rawT)
|
|
||||||
if (rawTint > 65){
|
|
||||||
resultMap.name = null
|
|
||||||
resultMap.value = null
|
|
||||||
resultMap.descriptionText = "Temperature celsius value = ${rawT} is invalid not updating"
|
|
||||||
log.warn "Invalid temperature value detected! rawT = ${rawT}, description = ${description}"
|
|
||||||
}else if (rawT == -32768){ // This number is used to indicate an error in the temperature reading
|
|
||||||
resultMap.value = "ERR"
|
|
||||||
}else{
|
|
||||||
resultMap.value = celsiusToFahrenheit(rawT.toFloat()) as Float
|
|
||||||
sendEvent(name: "TempProb1", value: resultMap.value, displayed: false) // Workaround for lack of access to endpoint information for Temperature report
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resultMap.displayed = false
|
|
||||||
log.info "Temperature reported = ${resultMap.value}"
|
|
||||||
return resultMap
|
|
||||||
}
|
|
||||||
|
|
||||||
def parseDescriptionAsMap(description) {
|
|
||||||
(description - "read attr - ").split(",").inject([:]) { map, param ->
|
|
||||||
def nameAndValue = param.split(":")
|
|
||||||
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Added for Temeperature parse
|
|
||||||
def getFahrenheit(value) {
|
|
||||||
def celsius = Integer.parseInt(value, 16)
|
|
||||||
return celsiusToFahrenheit(celsius) as Integer
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private methods
|
|
||||||
def callUpdateStatusTxt(){
|
|
||||||
def cTemp = device.currentState("TempProb1")?.value
|
|
||||||
def cLight = 0
|
|
||||||
def testNull = device.currentState("currentLightLevel")?.value
|
|
||||||
if (testNull != null){
|
|
||||||
cLight = device.currentState("currentLightLevel")?.value as int
|
|
||||||
}
|
|
||||||
updateStatusTxt(cTemp, cLight)
|
|
||||||
}
|
|
||||||
|
|
||||||
def updateStatusTxt(currentTemp, currentLight){
|
|
||||||
//log.info "called updateStatusTxt with ${currentTemp}, ${currentLight}"
|
|
||||||
def cTmp = currentTemp
|
|
||||||
def cLL = 10
|
|
||||||
def oLL = 10
|
|
||||||
|
|
||||||
def testNull = device.currentState("closeLightLevel")?.value
|
|
||||||
if (testNull != null){
|
|
||||||
cLL = device.currentState("closeLightLevel")?.value as int
|
|
||||||
}
|
|
||||||
|
|
||||||
testNull = device.currentState("openLightLevel")?.value
|
|
||||||
if (testNull != null){
|
|
||||||
oLL = device.currentState("openLightLevel")?.value as int
|
|
||||||
}
|
|
||||||
|
|
||||||
def aOpnEn = device.currentState("autoOpenEnable")?.value
|
|
||||||
def aClsEn = device.currentState("autoCloseEnable")?.value
|
|
||||||
|
|
||||||
if (currentLight < cLL){
|
|
||||||
if (aOpnEn == "on"){
|
|
||||||
sendEvent(name: "dayOrNight", value: "Sun must be > ${oLL} to auto open", displayed: false)
|
|
||||||
sendEvent(name: "coopStatus", value: "Sunlight ${currentLight} open at ${oLL}. Coop ${cTmp}°", displayed: false)
|
|
||||||
}else{
|
|
||||||
sendEvent(name: "dayOrNight", value: "Auto Open is turned off.", displayed: false)
|
|
||||||
sendEvent(name: "coopStatus", value: "Sunlight ${currentLight} auto open off. Coop ${cTmp}°", displayed: false)
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
if (aClsEn == "on"){
|
|
||||||
sendEvent(name: "dayOrNight", value: "Sun must be < ${cLL} to auto close", displayed: false)
|
|
||||||
sendEvent(name: "coopStatus", value: "Sunlight ${currentLight} close at ${cLL}. Coop ${cTmp}°", displayed: false)
|
|
||||||
}else{
|
|
||||||
sendEvent(name: "dayOrNight", value: "Auto Close is turned off.", displayed: false)
|
|
||||||
sendEvent(name: "coopStatus", value: "Sunlight ${currentLight} auto close off. Coop ${cTmp}°", displayed: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commands to device
|
|
||||||
def on() {
|
|
||||||
log.debug "on calling Aux1On"
|
|
||||||
Aux1On()
|
|
||||||
}
|
|
||||||
|
|
||||||
def off() {
|
|
||||||
log.debug "off calling Aux1Off"
|
|
||||||
Aux1Off()
|
|
||||||
}
|
|
||||||
|
|
||||||
def close() {
|
|
||||||
log.debug "close calling closeDoor"
|
|
||||||
closeDoor()
|
|
||||||
}
|
|
||||||
|
|
||||||
def open() {
|
|
||||||
log.debug "open calling openDoor"
|
|
||||||
openDoor()
|
|
||||||
}
|
|
||||||
|
|
||||||
def Aux1On(){
|
|
||||||
log.debug "Sending Aux1 = on command"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x14 {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def Aux1Off(){
|
|
||||||
log.debug "Sending Aux1 = off command"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x15 {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def Aux2On(){
|
|
||||||
log.debug "Sending Aux2 = on command"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x16 {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def Aux2Off(){
|
|
||||||
log.debug "Sending Aux2 = off command"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x17 {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def openDoor() {
|
|
||||||
log.debug "Sending Open command"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x1 {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def closeDoor() {
|
|
||||||
log.debug "Sending Close command"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x0 {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def closeDoorHiI() {
|
|
||||||
log.debug "Sending High Current Close command"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x4 {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def autoOpenOn() {
|
|
||||||
log.debug "Setting Auto Open On"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x0C {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def autoOpenOff() {
|
|
||||||
log.debug "Setting Auto Open Off"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x0D {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def autoCloseOn() {
|
|
||||||
log.debug "Setting Auto Close On"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x0A {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def autoCloseOff() {
|
|
||||||
log.debug "Setting Auto Close Off"
|
|
||||||
"st cmd 0x${device.deviceNetworkId} 0x38 0x0101 0x0B {}"
|
|
||||||
}
|
|
||||||
|
|
||||||
def setOpenLevelTo(cValue) {
|
|
||||||
def cX = cValue
|
|
||||||
log.debug "Setting Open Light Level to ${cX} Hex = 0x${Integer.toHexString(cX)}"
|
|
||||||
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st wattr 0x${device.deviceNetworkId} 0x38 0x0101 0x402 0x23 {${Integer.toHexString(cX)}}"
|
|
||||||
cmd << "delay 150"
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x402" // Read light value
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def setCloseLevelTo(cValue) {
|
|
||||||
def cX = cValue
|
|
||||||
log.debug "Setting Close Light Level to ${cX} Hex = 0x${Integer.toHexString(cX)}"
|
|
||||||
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st wattr 0x${device.deviceNetworkId} 0x38 0x0101 0x401 0x23 {${Integer.toHexString(cX)}}"
|
|
||||||
cmd << "delay 150"
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x401" // Read light value
|
|
||||||
cmd
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
def setSensitivityLevel(cValue) {
|
|
||||||
def cX = 100 - cValue
|
|
||||||
log.debug "Setting Door sensitivity level to ${cX} Hex = 0x${Integer.toHexString(cX)}"
|
|
||||||
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st wattr 0x${device.deviceNetworkId} 0x38 0x0101 0x408 0x23 {${Integer.toHexString(cX)}}" // Write attribute. 0x23 is a 32 bit integer value.
|
|
||||||
cmd << "delay 150"
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x408" // Read attribute
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def setNewBaseCurrent(cValue) {
|
|
||||||
def cX = cValue as int
|
|
||||||
log.info "Setting new BaseCurrent to ${cX} Hex = 0x${Integer.toHexString(cX)}"
|
|
||||||
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st wattr 0x${device.deviceNetworkId} 0x38 0x0101 0x409 0x23 {${Integer.toHexString(cX)}}" // Write attribute. 0x23 is a 32 bit integer value.
|
|
||||||
cmd << "delay 150"
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x409" // Read attribute
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def setNewPhotoCalibration(cValue) {
|
|
||||||
def cX = cValue as int
|
|
||||||
log.info "Setting new Photoresister calibration to ${cX} Hex = 0x${Integer.toHexString(cX)}"
|
|
||||||
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st wattr 0x${device.deviceNetworkId} 0x38 0x0101 0x40D 0x2B {${Integer.toHexString(cX)}}" // Write attribute. 0x2B is a 32 bit signed integer value.
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x40D" // Read attribute
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def readNewPhotoCalibration() {
|
|
||||||
log.info "Requesting current Photoresister calibration "
|
|
||||||
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x40D" // Read attribute
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def readBaseCurrentNE() {
|
|
||||||
log.info "Requesting base current never exceed setting "
|
|
||||||
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x40E" // Read attribute
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def setBaseCurrentNE(cValue) {
|
|
||||||
def cX = cValue as int
|
|
||||||
log.info "Setting new base Current Never Exceed to ${cX} Hex = 0x${Integer.toHexString(cX)}"
|
|
||||||
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st wattr 0x${device.deviceNetworkId} 0x38 0x0101 0x40E 0x23 {${Integer.toHexString(cX)}}" // Write attribute. 0x23 is a 32 bit unsigned integer value.
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x40E" // Read attribute
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def poll(){
|
|
||||||
log.debug "Polling Device"
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0003" // Read Door State
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0400" // Read Current Light Level
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x39 0x0402 0x0000" // Read probe 1 Temperature
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x40 0x0402 0x0000" // Read probe 2 Temperature
|
|
||||||
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def updateTemp1() {
|
|
||||||
log.debug "Sending attribute read request for Temperature Probe1"
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x39 0x0402 0x0000" // Read Current Temperature from Coop Probe 1
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def updateTemp2() {
|
|
||||||
log.debug "Sending attribute read request for Temperature Probe2"
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x40 0x0402 0x0000" // Read Current Temperature from Coop Probe 2
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def updateSun() {
|
|
||||||
log.debug "Sending attribute read request for Sun Light Level"
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0400" // Read Current Light Level
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def updateSensitivity() {
|
|
||||||
log.debug "Sending attribute read request for door sensitivity"
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0408" // Read Door sensitivity
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def updateCloseLightLevel() {
|
|
||||||
log.debug "Sending attribute read close light level"
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0401"
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def updateOpenLightLevel() {
|
|
||||||
log.debug "Sending attribute read open light level"
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0402"
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def refresh() {
|
|
||||||
log.debug "sending refresh command"
|
|
||||||
def cmd = []
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0003" // Read Door State
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0400" // Read Current Light Level
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0401" // Read Door Close Light Level
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0402" // Read Door Open Light Level
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0403" // Read Auto Door Close Settings
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0404" // Read Auto Door Open Settings
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x39 0x0402 0x0000" // Read Current Temperature from Coop Probe 1
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0408" // Object detection sensitivity
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x40 0x0402 0x0000" // Read Current Temperature from Coop Probe 2
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x0405" // Current required to close door
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x040B" // Aux1 Status
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x040C" // Aux2 Status
|
|
||||||
cmd << "delay 150"
|
|
||||||
|
|
||||||
cmd << "st rattr 0x${device.deviceNetworkId} 0x38 0x0101 0x409" // Read Base current
|
|
||||||
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
def configure() {
|
|
||||||
log.debug "Binding SEP 0x38 DEP 0x01 Cluster 0x0101 Lock cluster to hub"
|
|
||||||
log.debug "Binding SEP 0x39 DEP 0x01 Cluster 0x0402 Temperature cluster to hub"
|
|
||||||
log.debug "Binding SEP 0x40 DEP 0x01 Cluster 0x0402 Temperature cluster to hub"
|
|
||||||
|
|
||||||
def cmd = []
|
|
||||||
cmd << "zdo bind 0x${device.deviceNetworkId} 0x38 0x01 0x0101 {${device.zigbeeId}} {}" // Bind to end point 0x38 and the lock cluster
|
|
||||||
cmd << "delay 150"
|
|
||||||
cmd << "zdo bind 0x${device.deviceNetworkId} 0x39 0x01 0x0402 {${device.zigbeeId}} {}" // Bind to end point 0x39 and the temperature cluster
|
|
||||||
cmd << "delay 150"
|
|
||||||
cmd << "zdo bind 0x${device.deviceNetworkId} 0x40 0x01 0x0402 {${device.zigbeeId}} {}" // Bind to end point 0x40 and the temperature cluster
|
|
||||||
cmd << "delay 1500"
|
|
||||||
|
|
||||||
log.info "Sending ZigBee Configuration Commands to Coop Control"
|
|
||||||
return cmd + refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -12,6 +12,16 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Purpose: Arrival Sensor HA DTH File
|
||||||
|
*
|
||||||
|
* Filename: Arrival-Sensor-HA.src/Arrival-Sensor-HA.groovy
|
||||||
|
*
|
||||||
|
* Change History:
|
||||||
|
* 1. 20160115 TW - Update/Edit to support i18n translations
|
||||||
|
* 2. 20160121 TW - Update to V4 battery calcs, added pref's page title translations
|
||||||
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
definition (name: "Arrival Sensor HA", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "Arrival Sensor HA", namespace: "smartthings", author: "SmartThings") {
|
||||||
capability "Tone"
|
capability "Tone"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#==============================================================================
|
||||||
# Copyright 2016 SmartThings
|
# Copyright 2016 SmartThings
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -11,6 +12,15 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
#==============================================================================
|
||||||
|
# Purpose: Arrival Sensor HA i18n Translation File
|
||||||
|
#
|
||||||
|
# Filename: Arrival-Sensor-HA.src/i18n/messages.properties
|
||||||
|
#
|
||||||
|
# Change History:
|
||||||
|
# 1. 20160115 TW Initial release with informal Korean translation.
|
||||||
|
# 2. 20160121 TW Added def preference section titles.
|
||||||
|
#==============================================================================
|
||||||
# Korean (ko)
|
# Korean (ko)
|
||||||
# Device Preferences
|
# Device Preferences
|
||||||
'''Give your device a name'''.ko=기기 이름 설정
|
'''Give your device a name'''.ko=기기 이름 설정
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ metadata {
|
|||||||
|
|
||||||
capability "Actuator"
|
capability "Actuator"
|
||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Polling"
|
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Switch"
|
capability "Switch"
|
||||||
capability "Switch Level"
|
capability "Switch Level"
|
||||||
@@ -89,10 +88,6 @@ def refresh() {
|
|||||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig() + zigbee.levelConfig()
|
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.onOffConfig() + zigbee.levelConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
def poll() {
|
|
||||||
zigbee.onOffRefresh() + zigbee.levelRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
log.debug "Configuring Reporting and Bindings."
|
log.debug "Configuring Reporting and Bindings."
|
||||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
|
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerS
|
|||||||
log.debug "productTypeId: ${cmd.productTypeId}"
|
log.debug "productTypeId: ${cmd.productTypeId}"
|
||||||
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
|
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
|
||||||
updateDataValue("MSR", msr)
|
updateDataValue("MSR", msr)
|
||||||
updateDataValue("manufacturer", cmd.manufacturerName)
|
|
||||||
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
|
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* GE Link Bulb
|
* GE Link Bulb
|
||||||
*
|
*
|
||||||
* Copyright 2016 SmartThings
|
* Copyright 2014 SmartThings
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
* 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:
|
* in compliance with the License. You may obtain a copy of the License at:
|
||||||
@@ -53,8 +53,6 @@ metadata {
|
|||||||
capability "Polling"
|
capability "Polling"
|
||||||
|
|
||||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE_Appliances", model: "ZLL Light", deviceJoinName: "GE Link Bulb"
|
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE_Appliances", model: "ZLL Light", deviceJoinName: "GE Link Bulb"
|
||||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE", model: "SoftWhite", deviceJoinName: "GE Link Soft White Bulb"
|
|
||||||
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019", manufacturer: "GE", model: "Daylight", deviceJoinName: "GE Link Daylight Bulb"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI tile definitions
|
// UI tile definitions
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ metadata {
|
|||||||
tiles (scale: 2){
|
tiles (scale: 2){
|
||||||
multiAttributeTile(name:"rich-control", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
multiAttributeTile(name:"rich-control", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
||||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#C6C7CC", nextState:"turningOn"
|
||||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#C6C7CC", nextState:"turningOn"
|
||||||
}
|
}
|
||||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
||||||
attributeState "level", action:"switch level.setLevel", range:"(0..100)"
|
attributeState "level", action:"switch level.setLevel", range:"(0..100)"
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ metadata {
|
|||||||
tiles(scale: 2) {
|
tiles(scale: 2) {
|
||||||
multiAttributeTile(name:"rich-control", type: "lighting", canChangeIcon: true){
|
multiAttributeTile(name:"rich-control", type: "lighting", canChangeIcon: true){
|
||||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
||||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#C6C7CC", nextState:"turningOn"
|
||||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#00A0DC", nextState:"turningOff"
|
||||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#C6C7CC", nextState:"turningOn"
|
||||||
}
|
}
|
||||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
||||||
attributeState "level", action:"switch level.setLevel", range:"(0..100)"
|
attributeState "level", action:"switch level.setLevel", range:"(0..100)"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#==============================================================================
|
||||||
# Copyright 2016 SmartThings
|
# Copyright 2016 SmartThings
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -11,6 +12,15 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
#==============================================================================
|
||||||
|
# Purpose: Mobile Presence i18n Translation File
|
||||||
|
#
|
||||||
|
# Filename: mobile-presence.src/i18n/messages.properties
|
||||||
|
#
|
||||||
|
# Change History:
|
||||||
|
# 1. 20160205 TW Initial release with informal Korean translation.
|
||||||
|
# 2. 20160224 TW Updated with formal Korean translation.
|
||||||
|
#==============================================================================
|
||||||
# Korean (ko)
|
# Korean (ko)
|
||||||
# Device Preferences
|
# Device Preferences
|
||||||
'''Give your device a name'''.ko=기기 이름 설정
|
'''Give your device a name'''.ko=기기 이름 설정
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
===============================================================================
|
||||||
* Copyright 2016 SmartThings
|
* Copyright 2016 SmartThings
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -12,6 +13,14 @@
|
|||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
* License for the specific language governing permissions and limitations
|
* License for the specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
|
===============================================================================
|
||||||
|
* Purpose: Mobile Presence DTH File
|
||||||
|
*
|
||||||
|
* Filename: mobile-presence.src/mobile-presence.groovy
|
||||||
|
*
|
||||||
|
* Change History:
|
||||||
|
* 1. 20160205 TW - Update/Edit to support i18n translations
|
||||||
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ metadata {
|
|||||||
command "enrollResponse"
|
command "enrollResponse"
|
||||||
|
|
||||||
|
|
||||||
fingerprint inClusters: "0000,0001,0003,0500,0020", manufacturer: "NYCE", model: "3010", deviceJoinName: "NYCE Door Hinge Sensor"
|
|
||||||
fingerprint inClusters: "0000,0001,0003,0406,0500,0020", manufacturer: "NYCE", model: "3011", deviceJoinName: "NYCE Door/Window Sensor"
|
fingerprint inClusters: "0000,0001,0003,0406,0500,0020", manufacturer: "NYCE", model: "3011", deviceJoinName: "NYCE Door/Window Sensor"
|
||||||
fingerprint inClusters: "0000,0001,0003,0500,0020", manufacturer: "NYCE", model: "3011", deviceJoinName: "NYCE Door/Window Sensor"
|
fingerprint inClusters: "0000,0001,0003,0500,0020", manufacturer: "NYCE", model: "3011", deviceJoinName: "NYCE Door/Window Sensor"
|
||||||
fingerprint inClusters: "0000,0001,0003,0406,0500,0020", manufacturer: "NYCE", model: "3014", deviceJoinName: "NYCE Tilt Sensor"
|
fingerprint inClusters: "0000,0001,0003,0406,0500,0020", manufacturer: "NYCE", model: "3014", deviceJoinName: "NYCE Tilt Sensor"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#==============================================================================
|
||||||
# Copyright 2016 SmartThings
|
# Copyright 2016 SmartThings
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -11,6 +12,14 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
#==============================================================================
|
||||||
|
# Purpose: SmartPower Outlet i18n Translation File
|
||||||
|
#
|
||||||
|
# Filename: SmartPower-Outlet.src/i18n/messages.properties
|
||||||
|
#
|
||||||
|
# Change History:
|
||||||
|
# 1. 20160116 TW Initial release with informal Korean translation.
|
||||||
|
#==============================================================================
|
||||||
# Korean (ko)
|
# Korean (ko)
|
||||||
# Device Preferences
|
# Device Preferences
|
||||||
'''Give your device a name'''.ko=기기 이름 설정
|
'''Give your device a name'''.ko=기기 이름 설정
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
===============================================================================
|
||||||
* Copyright 2016 SmartThings
|
* Copyright 2016 SmartThings
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -12,8 +13,15 @@
|
|||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
* License for the specific language governing permissions and limitations
|
* License for the specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
|
===============================================================================
|
||||||
|
* Purpose: SmartPower Outlet DTH File
|
||||||
|
*
|
||||||
|
* Filename: SmartPower-Outlet.src/SmartPower-Outlet.groovy
|
||||||
|
*
|
||||||
|
* Change History:
|
||||||
|
* 1. 20160117 TW - Update/Edit to support i18n translations
|
||||||
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
// Automatically generated. Make future change here.
|
// Automatically generated. Make future change here.
|
||||||
definition (name: "SmartPower Outlet", namespace: "smartthings", author: "SmartThings") {
|
definition (name: "SmartPower Outlet", namespace: "smartthings", author: "SmartThings") {
|
||||||
@@ -23,7 +31,6 @@ metadata {
|
|||||||
capability "Configuration"
|
capability "Configuration"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Sensor"
|
capability "Sensor"
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
// indicates that device keeps track of heartbeat (in state.heartbeat)
|
// indicates that device keeps track of heartbeat (in state.heartbeat)
|
||||||
attribute "heartbeat", "string"
|
attribute "heartbeat", "string"
|
||||||
@@ -129,7 +136,6 @@ def refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 1200, displayed: false)
|
|
||||||
zigbee.onOffConfig() + powerConfig() + refresh()
|
zigbee.onOffConfig() + powerConfig() + refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#==============================================================================
|
||||||
# Copyright 2016 SmartThings
|
# Copyright 2016 SmartThings
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -11,6 +12,14 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
#==============================================================================
|
||||||
|
# Purpose: SmartSense Moisture Sensor i18n Translation File
|
||||||
|
#
|
||||||
|
# Filename: SmartSense-Moisture-Sensor.src/i18n/messages.properties
|
||||||
|
#
|
||||||
|
# Change History:
|
||||||
|
# 1. 20160116 TW Initial release with formal Korean translation.
|
||||||
|
#==============================================================================
|
||||||
# Korean (ko)
|
# Korean (ko)
|
||||||
# Device Preferences
|
# Device Preferences
|
||||||
'''Dry'''.ko=건조
|
'''Dry'''.ko=건조
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
===============================================================================
|
||||||
* Copyright 2016 SmartThings
|
* Copyright 2016 SmartThings
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -12,6 +13,15 @@
|
|||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
* License for the specific language governing permissions and limitations
|
* License for the specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
|
===============================================================================
|
||||||
|
* Purpose: SmartSense Moisture Sensor DTH File
|
||||||
|
*
|
||||||
|
* Filename: SmartSense-Moisture-Sensor.src/SmartSense-Moisture-Sensor.groovy
|
||||||
|
*
|
||||||
|
* Change History:
|
||||||
|
* 1. 20160116 TW - Update/Edit to support i18n translations
|
||||||
|
* 2. 20160125 TW = Incorporated new battery mapping from TM
|
||||||
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
@@ -21,7 +31,6 @@ metadata {
|
|||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Water Sensor"
|
capability "Water Sensor"
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
command "enrollResponse"
|
command "enrollResponse"
|
||||||
|
|
||||||
@@ -311,8 +320,6 @@ def refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false)
|
|
||||||
|
|
||||||
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
||||||
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
||||||
def configCmds = [
|
def configCmds = [
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#==============================================================================
|
||||||
# Copyright 2016 SmartThings
|
# Copyright 2016 SmartThings
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -11,6 +12,15 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
#==============================================================================
|
||||||
|
# Purpose: SmartSense Motion Sensor i18n Translation File
|
||||||
|
#
|
||||||
|
# Filename: SmartSense-Motion-Sensor.src/i18n/messages.properties
|
||||||
|
#
|
||||||
|
# Change History:
|
||||||
|
# 1. 20160116 TW Initial release with formal Korean translation.
|
||||||
|
# 2. 20160224 TW Updated formal Korean translations from Mike Stoller.
|
||||||
|
#==============================================================================
|
||||||
# Korean (ko)
|
# Korean (ko)
|
||||||
# Device Preferences
|
# Device Preferences
|
||||||
'''battery'''.ko=배터리
|
'''battery'''.ko=배터리
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
===============================================================================
|
||||||
* Copyright 2016 SmartThings
|
* Copyright 2016 SmartThings
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -12,6 +13,15 @@
|
|||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
* License for the specific language governing permissions and limitations
|
* License for the specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
|
===============================================================================
|
||||||
|
* Purpose: SmartSense Motion Sensor DTH File
|
||||||
|
*
|
||||||
|
* Filename: SmartSense-Motion-Sensor.src/SmartSense-Motion-Sensor.groovy
|
||||||
|
*
|
||||||
|
* Change History:
|
||||||
|
* 1. 20160116 TW - Update/Edit to support i18n translations
|
||||||
|
* 2. 20160125 TW = Incorporated new battery mapping from TM
|
||||||
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
@@ -21,7 +31,6 @@ metadata {
|
|||||||
capability "Battery"
|
capability "Battery"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
command "enrollResponse"
|
command "enrollResponse"
|
||||||
|
|
||||||
@@ -323,8 +332,6 @@ def refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false)
|
|
||||||
|
|
||||||
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
||||||
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#==============================================================================
|
||||||
# Copyright 2016 SmartThings
|
# Copyright 2016 SmartThings
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -11,6 +12,14 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
#==============================================================================
|
||||||
|
# Purpose: SmartSense Multi Sensor i18n Translation File
|
||||||
|
#
|
||||||
|
# Filename: SmartSense-Multi-Sensor.src/i18n/messages.properties
|
||||||
|
#
|
||||||
|
# Change History:
|
||||||
|
# 1. 20160117 TW Initial release with informal Korean translation.
|
||||||
|
#==============================================================================
|
||||||
# Korean (ko)
|
# Korean (ko)
|
||||||
# Device Preferences
|
# Device Preferences
|
||||||
'''Yes'''.ko=예
|
'''Yes'''.ko=예
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
===============================================================================
|
||||||
* Copyright 2016 SmartThings
|
* Copyright 2016 SmartThings
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
@@ -12,6 +13,15 @@
|
|||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
* License for the specific language governing permissions and limitations
|
* License for the specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
|
===============================================================================
|
||||||
|
* Purpose: SmartSense Multi Sensor DTH File
|
||||||
|
*
|
||||||
|
* Filename: SmartSense-Multi-Sensor.src/SmartSense-Multi-Sensor.groovy
|
||||||
|
*
|
||||||
|
* Change History:
|
||||||
|
* 1. 20160117 TW - Update/Edit to support i18n translations
|
||||||
|
* 2. 20160125 TW = Incorporated new battery mapping from TM
|
||||||
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
metadata {
|
metadata {
|
||||||
@@ -25,7 +35,6 @@ metadata {
|
|||||||
capability "Acceleration Sensor"
|
capability "Acceleration Sensor"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
command "enrollResponse"
|
command "enrollResponse"
|
||||||
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3320"
|
fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3320"
|
||||||
@@ -441,8 +450,6 @@ def refresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false)
|
|
||||||
|
|
||||||
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
||||||
log.debug "Configuring Reporting"
|
log.debug "Configuring Reporting"
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,8 @@
|
|||||||
capability "Acceleration Sensor"
|
capability "Acceleration Sensor"
|
||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Health Check"
|
command "enrollResponse"
|
||||||
|
|
||||||
command "enrollResponse"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
simulator {
|
simulator {
|
||||||
@@ -300,7 +299,6 @@ def getTemperature(value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false)
|
|
||||||
|
|
||||||
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
|
||||||
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
log.debug "Configuring Reporting, IAS CIE, and Bindings."
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ metadata {
|
|||||||
capability "Refresh"
|
capability "Refresh"
|
||||||
capability "Temperature Measurement"
|
capability "Temperature Measurement"
|
||||||
capability "Relative Humidity Measurement"
|
capability "Relative Humidity Measurement"
|
||||||
capability "Health Check"
|
|
||||||
|
|
||||||
fingerprint endpointId: "01", inClusters: "0001,0003,0020,0402,0B05,FC45", outClusters: "0019,0003"
|
fingerprint endpointId: "01", inClusters: "0001,0003,0020,0402,0B05,FC45", outClusters: "0019,0003"
|
||||||
}
|
}
|
||||||
@@ -252,7 +251,6 @@ def refresh()
|
|||||||
}
|
}
|
||||||
|
|
||||||
def configure() {
|
def configure() {
|
||||||
sendEvent(name: "checkInterval", value: 7200, displayed: false)
|
|
||||||
|
|
||||||
log.debug "Configuring Reporting and Bindings."
|
log.debug "Configuring Reporting and Bindings."
|
||||||
def configCmds = [
|
def configCmds = [
|
||||||
|
|||||||
@@ -80,31 +80,19 @@ metadata {
|
|||||||
state "default", label:''
|
state "default", label:''
|
||||||
}
|
}
|
||||||
|
|
||||||
// multi-line text (explicit newlines)
|
main("standard1")
|
||||||
standardTile("multiLine", "device.multiLine", width: 2, height: 2) {
|
|
||||||
state "default", label: '${currentValue}'
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("multiLineWithIcon", "device.multiLine", width: 2, height: 2) {
|
|
||||||
state "default", label: '${currentValue}', icon: "st.switches.switch.off"
|
|
||||||
}
|
|
||||||
|
|
||||||
main("actionRings")
|
|
||||||
details([
|
details([
|
||||||
"actionRings", "actionFlat", "noActionFlat",
|
"actionRings", "actionFlat", "noActionFlat",
|
||||||
|
|
||||||
"flatLabel", "flatIconLabel", "flatIcon",
|
"flatLabel", "flatIconLabel", "flatIcon",
|
||||||
|
|
||||||
"flatDefaultState", "flatImplicitDefaultState1", "flatImplicitDefaultState2",
|
"flatDefaultState", "flatImplicitDefaultState1", "flatImplicitDefaultState2",
|
||||||
|
|
||||||
"multiLine", "multiLineWithIcon"
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def installed() {
|
def installed() {
|
||||||
sendEvent(name: "switch", value: "off")
|
sendEvent(name: "switch", value: "off")
|
||||||
sendEvent(name: "multiLine", value: "Line 1\nLine 2\nLine 3")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def parse(String description) {
|
def parse(String description) {
|
||||||
|
|||||||
@@ -69,25 +69,16 @@ metadata {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
valueTile("noValue", "device.nada", width: 4, height: 2) {
|
valueTile("noValue", "device.nada", width: 2, height: 2) {
|
||||||
state "default", label:'${currentValue}'
|
state "default", label:'${currentValue}'
|
||||||
}
|
}
|
||||||
|
|
||||||
valueTile("multiLine", "device.multiLine", width: 3, height: 2) {
|
|
||||||
state "default", label: '${currentValue}'
|
|
||||||
}
|
|
||||||
|
|
||||||
valueTile("multiLineWithIcon", "device.multiLine", width: 3, height: 2) {
|
|
||||||
state "default", label: '${currentValue}', icon: "st.switches.switch.off"
|
|
||||||
}
|
|
||||||
|
|
||||||
main("text")
|
main("text")
|
||||||
details([
|
details([
|
||||||
"text", "longText", "integer",
|
"text", "longText", "integer",
|
||||||
"integerFloat", "pi", "floatAsText",
|
"integerFloat", "pi", "floatAsText",
|
||||||
"bgColor", "bgColorRange", "bgColorRangeSingleItem",
|
"bgColor", "bgColorRange", "bgColorRangeSingleItem",
|
||||||
"bgColorRangeConflict", "noValue",
|
"bgColorRangeConflict", "noValue"
|
||||||
"multiLine", "multiLineWithIcon"
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +90,6 @@ def installed() {
|
|||||||
sendEvent(name: "integerFloat", value: 47.0)
|
sendEvent(name: "integerFloat", value: 47.0)
|
||||||
sendEvent(name: "pi", value: 3.14159)
|
sendEvent(name: "pi", value: 3.14159)
|
||||||
sendEvent(name: "floatAsText", value: "3.14159")
|
sendEvent(name: "floatAsText", value: "3.14159")
|
||||||
sendEvent(name: "multiLine", value: "Line 1\nLine 2\nLine 3")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def parse(String description) {
|
def parse(String description) {
|
||||||
|
|||||||
@@ -67,50 +67,17 @@ metadata {
|
|||||||
attributeState "VALUE_DOWN", action: "levelDown"
|
attributeState "VALUE_DOWN", action: "levelDown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
multiAttributeTile(name:"lengthyTile", type:"generic", width:6, height:4) {
|
|
||||||
tileAttribute("device.lengthyText", key: "PRIMARY_CONTROL") {
|
|
||||||
attributeState "default", label:'The value of this tile is long and should wrap to two lines', backgroundColor:"#79b821"
|
|
||||||
}
|
|
||||||
tileAttribute("device.lengthyText", key: "SECONDARY_CONTROL") {
|
|
||||||
attributeState "default", label:'The value of this tile is long and should wrap to two lines', backgroundColor:"#79b821"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
multiAttributeTile(name:"multilineTile", type:"generic", width:6, height:4) {
|
|
||||||
tileAttribute("device.multilineText", key: "PRIMARY_CONTROL") {
|
|
||||||
attributeState "default", label:'Line 1 YES\nLine 2 YES\nLine 3 NO', backgroundColor:"#79b821"
|
|
||||||
}
|
|
||||||
tileAttribute("device.multilineText", key: "SECONDARY_CONTROL") {
|
|
||||||
attributeState "default", label:'Line 1 YES\nLine 2 YES\nLine 3 NO', backgroundColor:"#79b821"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
multiAttributeTile(name:"lengthyTileWithIcon", type:"generic", width:6, height:4) {
|
|
||||||
tileAttribute("device.lengthyText", key: "PRIMARY_CONTROL") {
|
|
||||||
attributeState "default", label:'The value of this tile is long and should wrap to two lines', backgroundColor:"#79b821", icon: "st.switches.switch.on"
|
|
||||||
}
|
|
||||||
tileAttribute("device.lengthyText", key: "SECONDARY_CONTROL") {
|
|
||||||
attributeState "default", label:'The value of this tile is long and should wrap to two lines', backgroundColor:"#79b821", icon: "st.switches.switch.on"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
multiAttributeTile(name:"multilineTileWithIcon", type:"generic", width:6, height:4) {
|
|
||||||
tileAttribute("device.multilineText", key: "PRIMARY_CONTROL") {
|
|
||||||
attributeState "default", label:'Line 1 YES\nLine 2 YES\nLine 3 NO', backgroundColor:"#79b821", icon: "st.switches.switch.on"
|
|
||||||
}
|
|
||||||
tileAttribute("device.multilineText", key: "SECONDARY_CONTROL") {
|
|
||||||
attributeState "default", label:'Line 1 YES\nLine 2 YES\nLine 3 NO', backgroundColor:"#79b821", icon: "st.switches.switch.on"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main(["basicTile"])
|
main(["basicTile"])
|
||||||
details(["basicTile", "sliderTile", "valueTile", "lengthyTile", "multilineTile", "lengthyTileWithIcon", "multilineTileWithIcon"])
|
details(["basicTile", "sliderTile", "valueTile"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def installed() {
|
def installed() {
|
||||||
sendEvent(name: "lengthyText", value: "The value of this tile is long and should wrap to two lines")
|
|
||||||
sendEvent(name: "multilineText", value: "Line 1 YES\nLine 2 YES\nLine 3 NO")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def parse(String description) {
|
def parse() {
|
||||||
// This is a simulated device. No incoming data to parse.
|
// This is a simulated device. No incoming data to parse.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,6 @@
|
|||||||
* for the specific language governing permissions and limitations under the License.
|
* for the specific language governing permissions and limitations under the License.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//@Deprecated - Moved to zll-rgbw-bulb
|
|
||||||
|
|
||||||
/* Philips Hue (via Zigbee)
|
/* Philips Hue (via Zigbee)
|
||||||
|
|
||||||
Capabilities:
|
Capabilities:
|
||||||
@@ -44,7 +41,7 @@ metadata {
|
|||||||
|
|
||||||
command "setAdjustedColor"
|
command "setAdjustedColor"
|
||||||
|
|
||||||
//fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,0300,1000", outClusters: "0019"
|
fingerprint profileId: "C05E", inClusters: "0000,0003,0004,0005,0006,0008,0300,1000", outClusters: "0019"
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulator metadata
|
// simulator metadata
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2016 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: "ZLL Dimmer Bulb", namespace: "smartthings", author: "SmartThings") {
|
|
||||||
|
|
||||||
capability "Actuator"
|
|
||||||
capability "Configuration"
|
|
||||||
capability "Polling"
|
|
||||||
capability "Refresh"
|
|
||||||
capability "Switch"
|
|
||||||
capability "Switch Level"
|
|
||||||
|
|
||||||
//fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0000,0019"
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0019"
|
|
||||||
//fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0000,0019", manufacturer: "CREE", model: "Connected A-19 60W Equivalent", deviceJoinName: "Cree Connected Bulb"
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 W clear", deviceJoinName: "OSRAM LIGHTIFY LED Smart Connected Light"
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000, 0B04, FC0F", outClusters: "0019", manufacturer: "OSRAM", model: "Classic A60 W clear - LIGHTIFY", deviceJoinName: "OSRAM LIGHTIFY LED Smart Connected Light"
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 1000", outClusters: "0019", manufacturer: "Philips", model: "LWB006", deviceJoinName: "Philips Hue White"
|
|
||||||
}
|
|
||||||
|
|
||||||
// simulator metadata
|
|
||||||
simulator {
|
|
||||||
// status messages
|
|
||||||
status "on": "on/off: 1"
|
|
||||||
status "off": "on/off: 0"
|
|
||||||
|
|
||||||
// reply messages
|
|
||||||
reply "zcl on-off on": "on/off: 1"
|
|
||||||
reply "zcl on-off off": "on/off: 0"
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI tile definitions
|
|
||||||
tiles(scale: 2) {
|
|
||||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
|
||||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
|
||||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
|
||||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
|
||||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
|
||||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
|
||||||
}
|
|
||||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
|
||||||
attributeState "level", action:"switch level.setLevel"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
|
||||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
|
||||||
}
|
|
||||||
main "switch"
|
|
||||||
details(["switch", "refresh"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse incoming device messages to generate events
|
|
||||||
def parse(String description) {
|
|
||||||
log.debug "description is $description"
|
|
||||||
|
|
||||||
def resultMap = zigbee.getEvent(description)
|
|
||||||
if (resultMap) {
|
|
||||||
sendEvent(resultMap)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.debug "DID NOT PARSE MESSAGE for description : $description"
|
|
||||||
log.debug zigbee.parseDescriptionAsMap(description)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def off() {
|
|
||||||
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def on() {
|
|
||||||
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def setLevel(value) {
|
|
||||||
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
|
|
||||||
}
|
|
||||||
|
|
||||||
def refresh() {
|
|
||||||
zigbee.onOffRefresh() + zigbee.levelRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def poll() {
|
|
||||||
refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def configure() {
|
|
||||||
log.debug "Configuring Reporting and Bindings."
|
|
||||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh()
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2016 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: "ZLL RGBW Bulb", namespace: "smartthings", author: "SmartThings") {
|
|
||||||
|
|
||||||
capability "Actuator"
|
|
||||||
capability "Color Control"
|
|
||||||
capability "Color Temperature"
|
|
||||||
capability "Configuration"
|
|
||||||
capability "Polling"
|
|
||||||
capability "Refresh"
|
|
||||||
capability "Switch"
|
|
||||||
capability "Switch Level"
|
|
||||||
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300", outClusters: "0019"
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019"
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000", outClusters: "0019", "manufacturer":"OSRAM", "model":"Classic A60 RGBW", deviceJoinName: "OSRAM LIGHTIFY LED Classic A60 RGBW"
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI tile definitions
|
|
||||||
tiles(scale: 2) {
|
|
||||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
|
||||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
|
||||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
|
||||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
|
||||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.lights.philips.hue-single", backgroundColor:"#79b821", nextState:"turningOff"
|
|
||||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.lights.philips.hue-single", backgroundColor:"#ffffff", nextState:"turningOn"
|
|
||||||
}
|
|
||||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
|
||||||
attributeState "level", action:"switch level.setLevel"
|
|
||||||
}
|
|
||||||
tileAttribute ("device.color", key: "COLOR_CONTROL") {
|
|
||||||
attributeState "color", action:"color control.setColor"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..6500)") {
|
|
||||||
state "colorTemperature", action:"color temperature.setColorTemperature"
|
|
||||||
}
|
|
||||||
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
|
||||||
state "colorTemperature", label: '${currentValue} K'
|
|
||||||
}
|
|
||||||
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
|
||||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
|
||||||
}
|
|
||||||
|
|
||||||
main(["switch"])
|
|
||||||
details(["switch", "colorTempSliderControl", "colorTemp", "refresh"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Globals
|
|
||||||
private getATTRIBUTE_HUE() { 0x0000 }
|
|
||||||
private getATTRIBUTE_SATURATION() { 0x0001 }
|
|
||||||
private getHUE_COMMAND() { 0x00 }
|
|
||||||
private getSATURATION_COMMAND() { 0x03 }
|
|
||||||
private getCOLOR_CONTROL_CLUSTER() { 0x0300 }
|
|
||||||
private getATTRIBUTE_COLOR_TEMPERATURE() { 0x0007 }
|
|
||||||
|
|
||||||
// Parse incoming device messages to generate events
|
|
||||||
def parse(String description) {
|
|
||||||
log.debug "description is $description"
|
|
||||||
|
|
||||||
def finalResult = zigbee.getEvent(description)
|
|
||||||
if (finalResult) {
|
|
||||||
log.debug finalResult
|
|
||||||
sendEvent(finalResult)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
def zigbeeMap = zigbee.parseDescriptionAsMap(description)
|
|
||||||
log.trace "zigbeeMap : $zigbeeMap"
|
|
||||||
|
|
||||||
if (zigbeeMap?.clusterInt == COLOR_CONTROL_CLUSTER) {
|
|
||||||
if(zigbeeMap.attrInt == ATTRIBUTE_HUE){ //Hue Attribute
|
|
||||||
def hueValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 360)
|
|
||||||
sendEvent(name: "hue", value: hueValue, displayed:false)
|
|
||||||
}
|
|
||||||
else if(zigbeeMap.attrInt == ATTRIBUTE_SATURATION){ //Saturation Attribute
|
|
||||||
def saturationValue = Math.round(zigbee.convertHexToInt(zigbeeMap.value) / 255 * 100)
|
|
||||||
sendEvent(name: "saturation", value: saturationValue, displayed:false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.info "DID NOT PARSE MESSAGE for description : $description"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def on() {
|
|
||||||
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def off() {
|
|
||||||
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def refresh() {
|
|
||||||
refreshAttributes() + configureAttributes()
|
|
||||||
}
|
|
||||||
|
|
||||||
def poll() {
|
|
||||||
refreshAttributes()
|
|
||||||
}
|
|
||||||
|
|
||||||
def configure() {
|
|
||||||
log.debug "Configuring Reporting and Bindings."
|
|
||||||
configureAttributes() + refreshAttributes()
|
|
||||||
}
|
|
||||||
|
|
||||||
def configureAttributes() {
|
|
||||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_HUE, 0x20, 1, 3600, 0x01) + zigbee.configureReporting(COLOR_CONTROL_CLUSTER, ATTRIBUTE_SATURATION, 0x20, 1, 3600, 0x01)
|
|
||||||
}
|
|
||||||
|
|
||||||
def refreshAttributes() {
|
|
||||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.readAttribute(0x0300, 0x00) + zigbee.readAttribute(0x0300, ATTRIBUTE_HUE) + zigbee.readAttribute(0x0300, ATTRIBUTE_SATURATION)
|
|
||||||
}
|
|
||||||
|
|
||||||
def setColorTemperature(value) {
|
|
||||||
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def setLevel(value) {
|
|
||||||
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh() //adding refresh because of ZLL bulb not conforming to send-me-a-report
|
|
||||||
}
|
|
||||||
|
|
||||||
def setColor(value){
|
|
||||||
log.trace "setColor($value)"
|
|
||||||
zigbee.on() + setHue(value.hue) + ["delay 300"] + setSaturation(value.saturation) + ["delay 2000"] + refreshAttributes()
|
|
||||||
}
|
|
||||||
|
|
||||||
def setHue(value) {
|
|
||||||
def scaledHueValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
|
||||||
zigbee.command(COLOR_CONTROL_CLUSTER, HUE_COMMAND, scaledHueValue, "00", "0500") //payload-> hue value, direction (00-> shortest distance), transition time (1/10th second) (0500 in U16 reads 5)
|
|
||||||
}
|
|
||||||
|
|
||||||
def setSaturation(value) {
|
|
||||||
def scaledSatValue = zigbee.convertToHexString(Math.round(value * 0xfe / 100.0), 2)
|
|
||||||
zigbee.command(COLOR_CONTROL_CLUSTER, SATURATION_COMMAND, scaledSatValue, "0500") //payload-> sat value, transition time
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2016 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: "ZLL White Color Temperature Bulb", namespace: "smartthings", author: "SmartThings") {
|
|
||||||
|
|
||||||
capability "Actuator"
|
|
||||||
capability "Color Temperature"
|
|
||||||
capability "Configuration"
|
|
||||||
capability "Polling"
|
|
||||||
capability "Refresh"
|
|
||||||
capability "Switch"
|
|
||||||
capability "Switch Level"
|
|
||||||
|
|
||||||
attribute "colorName", "string"
|
|
||||||
command "setGenericName"
|
|
||||||
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000, 0B04, FC0F", outClusters: "0019", "manufacturer":"OSRAM", "model":"Classic A60 TW", deviceJoinName: "OSRAM LIGHTIFY LED Classic A60 Tunable White"
|
|
||||||
fingerprint profileId: "C05E", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0300, 1000, FC0F", outClusters: "0019", "manufacturer":"OSRAM", "model":"PAR16 50 TW", deviceJoinName: "OSRAM LIGHTIFY LED PAR16 50 Tunable White"
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI tile definitions
|
|
||||||
tiles(scale: 2) {
|
|
||||||
multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
|
||||||
tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
|
|
||||||
attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
|
||||||
attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
|
||||||
attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#79b821", nextState:"turningOff"
|
|
||||||
attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
|
|
||||||
}
|
|
||||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
|
||||||
attributeState "level", action:"switch level.setLevel"
|
|
||||||
}
|
|
||||||
tileAttribute ("colorName", key: "SECONDARY_CONTROL") {
|
|
||||||
attributeState "colorName", label:'${currentValue}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
|
||||||
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
|
|
||||||
}
|
|
||||||
|
|
||||||
controlTile("colorTempSliderControl", "device.colorTemperature", "slider", width: 4, height: 2, inactiveLabel: false, range:"(2700..6500)") {
|
|
||||||
state "colorTemperature", action:"color temperature.setColorTemperature"
|
|
||||||
}
|
|
||||||
valueTile("colorTemp", "device.colorTemperature", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
|
|
||||||
state "colorTemperature", label: '${currentValue} K'
|
|
||||||
}
|
|
||||||
|
|
||||||
main(["switch"])
|
|
||||||
details(["switch", "colorTempSliderControl", "colorTemp", "refresh"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse incoming device messages to generate events
|
|
||||||
def parse(String description) {
|
|
||||||
log.debug "description is $description"
|
|
||||||
def event = zigbee.getEvent(description)
|
|
||||||
if (event) {
|
|
||||||
sendEvent(event)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.warn "DID NOT PARSE MESSAGE for description : $description"
|
|
||||||
log.debug zigbee.parseDescriptionAsMap(description)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def off() {
|
|
||||||
zigbee.off() + ["delay 1500"] + zigbee.onOffRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def on() {
|
|
||||||
zigbee.on() + ["delay 1500"] + zigbee.onOffRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def setLevel(value) {
|
|
||||||
zigbee.setLevel(value) + ["delay 1500"] + zigbee.levelRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def refresh() {
|
|
||||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
def poll() {
|
|
||||||
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def configure() {
|
|
||||||
log.debug "Configuring Reporting and Bindings."
|
|
||||||
zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.colorTemperatureConfig() + zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.colorTemperatureRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
def setColorTemperature(value) {
|
|
||||||
setGenericName(value)
|
|
||||||
zigbee.setColorTemperature(value) + ["delay 1500"] + zigbee.colorTemperatureRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
//Naming based on the wiki article here: http://en.wikipedia.org/wiki/Color_temperature
|
|
||||||
def setGenericName(value){
|
|
||||||
if (value != null) {
|
|
||||||
def genericName = ""
|
|
||||||
if (value < 3300) {
|
|
||||||
genericName = "Soft White"
|
|
||||||
} else if (value < 4150) {
|
|
||||||
genericName = "Moonlight"
|
|
||||||
} else if (value <= 5000) {
|
|
||||||
genericName = "Cool White"
|
|
||||||
} else {
|
|
||||||
genericName = "Daylight"
|
|
||||||
}
|
|
||||||
sendEvent(name: "colorName", value: genericName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,10 +25,7 @@ metadata {
|
|||||||
|
|
||||||
fingerprint deviceId: "0x2001", inClusters: "0x30,0x80,0x84,0x85,0x86,0x72"
|
fingerprint deviceId: "0x2001", inClusters: "0x30,0x80,0x84,0x85,0x86,0x72"
|
||||||
fingerprint deviceId: "0x07", inClusters: "0x30"
|
fingerprint deviceId: "0x07", inClusters: "0x30"
|
||||||
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x98"
|
|
||||||
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x98", outClusters: "0x5A,0x82"
|
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x86,0x72,0x98", outClusters: "0x5A,0x82"
|
||||||
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x80,0x71,0x85,0x70,0x72,0x86,0x30,0x31,0x84,0x59,0x73,0x5A,0x8F,0x98,0x7A", outClusters:"0x20" // Philio multi+
|
|
||||||
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x72,0x5A,0x80,0x73,0x86,0x84,0x85,0x59,0x71,0x70,0x7A,0x98" // Vision door/window
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulator metadata
|
// simulator metadata
|
||||||
@@ -243,7 +240,7 @@ def batteryGetCommand() {
|
|||||||
def retypeBasedOnMSR() {
|
def retypeBasedOnMSR() {
|
||||||
switch (state.MSR) {
|
switch (state.MSR) {
|
||||||
case "0086-0002-002D":
|
case "0086-0002-002D":
|
||||||
log.debug "Changing device type to Z-Wave Water Sensor"
|
log.debug("Changing device type to Z-Wave Water Sensor")
|
||||||
setDeviceType("Z-Wave Water Sensor")
|
setDeviceType("Z-Wave Water Sensor")
|
||||||
break
|
break
|
||||||
case "011F-0001-0001": // Schlage motion
|
case "011F-0001-0001": // Schlage motion
|
||||||
@@ -252,16 +249,9 @@ def retypeBasedOnMSR() {
|
|||||||
case "0060-0001-0002": // Everspring SP814
|
case "0060-0001-0002": // Everspring SP814
|
||||||
case "0060-0001-0003": // Everspring HSP02
|
case "0060-0001-0003": // Everspring HSP02
|
||||||
case "011A-0601-0901": // Enerwave ZWN-BPC
|
case "011A-0601-0901": // Enerwave ZWN-BPC
|
||||||
log.debug "Changing device type to Z-Wave Motion Sensor"
|
log.debug("Changing device type to Z-Wave Motion Sensor")
|
||||||
setDeviceType("Z-Wave Motion Sensor")
|
setDeviceType("Z-Wave Motion Sensor")
|
||||||
break
|
break
|
||||||
case "013C-0002-000D": // Philio multi +
|
|
||||||
log.debug "Changing device type to 3-in-1 Multisensor Plus (SG)"
|
|
||||||
setDeviceType("3-in-1 Multisensor Plus (SG)")
|
|
||||||
break
|
|
||||||
case "0109-2001-0106": // Vision door/window
|
|
||||||
log.debug "Changing device type to Door / Window Sensor Plus (SG)"
|
|
||||||
setDeviceType("Door / Window Sensor Plus (SG)")
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,17 +95,11 @@ def zwaveEvent(physicalgraph.zwave.commands.hailv1.Hail cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
||||||
log.debug "manufacturerId: ${cmd.manufacturerId}"
|
if (state.manufacturer != cmd.manufacturerName) {
|
||||||
log.debug "manufacturerName: ${cmd.manufacturerName}"
|
updateDataValue("manufacturer", cmd.manufacturerName)
|
||||||
log.debug "productId: ${cmd.productId}"
|
}
|
||||||
log.debug "productTypeId: ${cmd.productTypeId}"
|
|
||||||
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
|
|
||||||
updateDataValue("MSR", msr)
|
|
||||||
updateDataValue("manufacturer", cmd.manufacturerName)
|
|
||||||
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
||||||
// Handles all Z-Wave commands we aren't interested in
|
// Handles all Z-Wave commands we aren't interested in
|
||||||
[:]
|
[:]
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* Door Jammed Notification
|
|
||||||
*
|
|
||||||
* Copyright 2015 John Rucker
|
|
||||||
*
|
|
||||||
* 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: "Door Jammed Notification",
|
|
||||||
namespace: "JohnRucker",
|
|
||||||
author: "John.Rucker@Solar-current.com",
|
|
||||||
description: "Sends a SmartThings notification and text messages when your CoopBoss detects a door jam.",
|
|
||||||
category: "My Apps",
|
|
||||||
iconUrl: "http://coopboss.com/images/SmartThingsIcons/coopbossLogo.png",
|
|
||||||
iconX2Url: "http://coopboss.com/images/SmartThingsIcons/coopbossLogo2x.png",
|
|
||||||
iconX3Url: "http://coopboss.com/images/SmartThingsIcons/coopbossLogo3x.png")
|
|
||||||
|
|
||||||
preferences {
|
|
||||||
section("When the door state changes") {
|
|
||||||
paragraph "Send a SmartThings notification when the coop's door jammed and did not close."
|
|
||||||
input "doorSensor", "capability.doorControl", title: "Select CoopBoss", required: true, multiple: false
|
|
||||||
input("recipients", "contact", title: "Recipients", description: "Send notifications to") {
|
|
||||||
input "phone", "phone", title: "Phone number?", required: true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def installed() {
|
|
||||||
log.debug "Installed with settings: ${settings}"
|
|
||||||
initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
def updated() {
|
|
||||||
log.debug "Updated with settings: ${settings}"
|
|
||||||
unsubscribe()
|
|
||||||
initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
def initialize() {
|
|
||||||
subscribe(doorSensor, "doorState", coopDoorStateHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
def coopDoorStateHandler(evt) {
|
|
||||||
if (evt.value == "jammed"){
|
|
||||||
def msg = "WARNING ${doorSensor.displayName} door is jammed and did not close!"
|
|
||||||
log.debug "WARNING ${doorSensor.displayName} door is jammed and did not close, texting $phone"
|
|
||||||
|
|
||||||
if (location.contactBookEnabled) {
|
|
||||||
sendNotificationToContacts(msg, recipients)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sendPush(msg)
|
|
||||||
if (phone) {
|
|
||||||
sendSms(phone, msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
/**
|
|
||||||
* CoopBoss Door Status to color
|
|
||||||
*
|
|
||||||
* Copyright 2015 John Rucker
|
|
||||||
*
|
|
||||||
* 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: "Door State to Color Light (Hue Bulb)",
|
|
||||||
namespace: "JohnRucker",
|
|
||||||
author: "John Rucker",
|
|
||||||
description: "Change the color of your Hue bulbs based on your coop's door status.",
|
|
||||||
category: "My Apps",
|
|
||||||
iconUrl: "http://coopboss.com/images/SmartThingsIcons/coopbossLogo.png",
|
|
||||||
iconX2Url: "http://coopboss.com/images/SmartThingsIcons/coopbossLogo2x.png",
|
|
||||||
iconX3Url: "http://coopboss.com/images/SmartThingsIcons/coopbossLogo3x.png")
|
|
||||||
|
|
||||||
|
|
||||||
preferences {
|
|
||||||
section("When the door opens/closese...") {
|
|
||||||
paragraph "Sets a Hue bulb or bulbs to a color based on your coop's door status:\r unknown = white\r open = blue\r opening = purple\r closed = green\r closing = pink\r jammed = red\r forced close = orange."
|
|
||||||
input "doorSensor", "capability.doorControl", title: "Select CoopBoss", required: true, multiple: false
|
|
||||||
input "bulbs", "capability.colorControl", title: "pick a bulb", required: true, multiple: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def installed() {
|
|
||||||
log.debug "Installed with settings: ${settings}"
|
|
||||||
initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
def updated() {
|
|
||||||
log.debug "Updated with settings: ${settings}"
|
|
||||||
unsubscribe()
|
|
||||||
initialize()
|
|
||||||
}
|
|
||||||
|
|
||||||
def initialize() {
|
|
||||||
subscribe(doorSensor, "doorState", coopDoorStateHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
def coopDoorStateHandler(evt) {
|
|
||||||
log.debug "${evt.descriptionText}, $evt.value"
|
|
||||||
def color = "White"
|
|
||||||
def hueColor = 100
|
|
||||||
def saturation = 100
|
|
||||||
Map hClr = [:]
|
|
||||||
hClr.hex = "#FFFFFF"
|
|
||||||
|
|
||||||
switch(evt.value) {
|
|
||||||
case "open":
|
|
||||||
color = "Blue"
|
|
||||||
break;
|
|
||||||
case "opening":
|
|
||||||
color = "Purple"
|
|
||||||
break;
|
|
||||||
case "closed":
|
|
||||||
color = "Green"
|
|
||||||
break;
|
|
||||||
case "closing":
|
|
||||||
color = "Pink"
|
|
||||||
break;
|
|
||||||
case "jammed":
|
|
||||||
color = "Red"
|
|
||||||
break;
|
|
||||||
case "forced close":
|
|
||||||
color = "Orange"
|
|
||||||
break;
|
|
||||||
case "unknown":
|
|
||||||
color = "White"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(color) {
|
|
||||||
case "White":
|
|
||||||
hueColor = 52
|
|
||||||
saturation = 19
|
|
||||||
break;
|
|
||||||
case "Daylight":
|
|
||||||
hueColor = 53
|
|
||||||
saturation = 91
|
|
||||||
break;
|
|
||||||
case "Soft White":
|
|
||||||
hueColor = 23
|
|
||||||
saturation = 56
|
|
||||||
break;
|
|
||||||
case "Warm White":
|
|
||||||
hueColor = 20
|
|
||||||
saturation = 80 //83
|
|
||||||
break;
|
|
||||||
case "Blue":
|
|
||||||
hueColor = 70
|
|
||||||
hClr.hex = "#0000FF"
|
|
||||||
break;
|
|
||||||
case "Green":
|
|
||||||
hueColor = 39
|
|
||||||
hClr.hex = "#00FF00"
|
|
||||||
break;
|
|
||||||
case "Yellow":
|
|
||||||
hueColor = 25
|
|
||||||
hClr.hex = "#FFFF00"
|
|
||||||
break;
|
|
||||||
case "Orange":
|
|
||||||
hueColor = 10
|
|
||||||
hClr.hex = "#FF6000"
|
|
||||||
break;
|
|
||||||
case "Purple":
|
|
||||||
hueColor = 75
|
|
||||||
hClr.hex = "#BF7FBF"
|
|
||||||
break;
|
|
||||||
case "Pink":
|
|
||||||
hueColor = 83
|
|
||||||
hClr.hex = "#FF5F5F"
|
|
||||||
break;
|
|
||||||
case "Red":
|
|
||||||
hueColor = 100
|
|
||||||
hClr.hex = "#FF0000"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//bulbs*.on()
|
|
||||||
bulbs*.setHue(hueColor)
|
|
||||||
bulbs*.setSaturation(saturation)
|
|
||||||
bulbs*.setColor(hClr)
|
|
||||||
|
|
||||||
//bulbs.each{
|
|
||||||
//it.on() // Turn the bulb on when open (this method does not come directly from the colorControl capability)
|
|
||||||
//it.setLevel(100) // Make sure the light brightness is 100%
|
|
||||||
//it.setHue(hueColor)
|
|
||||||
//it.setSaturation(saturation)
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
@@ -332,7 +332,8 @@ private addChildBulb(dni, hueType, name, hub, update=false, device = null) {
|
|||||||
|
|
||||||
if (deviceType) {
|
if (deviceType) {
|
||||||
return addChildDevice("smartthings", deviceType, dni, hub, ["label": name])
|
return addChildDevice("smartthings", deviceType, dni, hub, ["label": name])
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log.warn "Device type $hueType not supported"
|
log.warn "Device type $hueType not supported"
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -348,10 +349,8 @@ def addBulbs() {
|
|||||||
newHueBulb = bulbs.find { (app.id + "/" + it.value.id) == dni }
|
newHueBulb = bulbs.find { (app.id + "/" + it.value.id) == dni }
|
||||||
if (newHueBulb != null) {
|
if (newHueBulb != null) {
|
||||||
d = addChildBulb(dni, newHueBulb?.value?.type, newHueBulb?.value?.name, newHueBulb?.value?.hub)
|
d = addChildBulb(dni, newHueBulb?.value?.type, newHueBulb?.value?.name, newHueBulb?.value?.hub)
|
||||||
if (d) {
|
log.debug "created ${d.displayName} with id $dni"
|
||||||
log.debug "created ${d.displayName} with id $dni"
|
d.refresh()
|
||||||
d.refresh()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.debug "$dni in not longer paired to the Hue Bridge or ID changed"
|
log.debug "$dni in not longer paired to the Hue Bridge or ID changed"
|
||||||
}
|
}
|
||||||
@@ -359,7 +358,7 @@ def addBulbs() {
|
|||||||
//backwards compatable
|
//backwards compatable
|
||||||
newHueBulb = bulbs.find { (app.id + "/" + it.id) == dni }
|
newHueBulb = bulbs.find { (app.id + "/" + it.id) == dni }
|
||||||
d = addChildBulb(dni, "Extended Color Light", newHueBulb?.value?.name, newHueBulb?.value?.hub)
|
d = addChildBulb(dni, "Extended Color Light", newHueBulb?.value?.name, newHueBulb?.value?.hub)
|
||||||
d?.refresh()
|
d.refresh()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug "found ${d.displayName} with id $dni already exists, type: '$d.typeName'"
|
log.debug "found ${d.displayName} with id $dni already exists, type: '$d.typeName'"
|
||||||
@@ -825,7 +824,7 @@ def setColor(childDevice, huesettings) {
|
|||||||
value.bri = Math.min(Math.round(huesettings.level * 255 / 100), 255)
|
value.bri = Math.min(Math.round(huesettings.level * 255 / 100), 255)
|
||||||
}
|
}
|
||||||
value.alert = huesettings.alert ? huesettings.alert : "none"
|
value.alert = huesettings.alert ? huesettings.alert : "none"
|
||||||
value.transitiontime = huesettings.transitiontime ? huesettings.transitiontime : 4
|
value.transition = huesettings.transition ? huesettings.transition : 4
|
||||||
|
|
||||||
// Make sure to turn off light if requested
|
// Make sure to turn off light if requested
|
||||||
if (huesettings.switch == "off")
|
if (huesettings.switch == "off")
|
||||||
|
|||||||
@@ -131,69 +131,19 @@ def update() {
|
|||||||
def type = params.deviceType
|
def type = params.deviceType
|
||||||
def data = request.JSON
|
def data = request.JSON
|
||||||
def devices = settings[type]
|
def devices = settings[type]
|
||||||
def device = settings[type]?.find { it.id == params.id }
|
|
||||||
def command = data.command
|
def command = data.command
|
||||||
|
|
||||||
log.debug "[PROD] update, params: ${params}, request: ${data}, devices: ${devices*.id}"
|
log.debug "[PROD] update, params: ${params}, request: ${data}, devices: ${devices*.id}"
|
||||||
|
if (command) {
|
||||||
if (!device) {
|
def device = devices?.find { it.id == params.id }
|
||||||
httpError(404, "Device not found")
|
if (!device) {
|
||||||
}
|
httpError(404, "Device not found")
|
||||||
|
} else {
|
||||||
if (validateCommand(device, type, command)) {
|
device."$command"()
|
||||||
device."$command"()
|
}
|
||||||
} else {
|
|
||||||
httpError(403, "Access denied. This command is not supported by current capability.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validating the command passed by the user based on capability.
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
def validateCommand(device, deviceType, command) {
|
|
||||||
def capabilityCommands = getDeviceCapabilityCommands(device.capabilities)
|
|
||||||
def currentDeviceCapability = getCapabilityName(deviceType)
|
|
||||||
if (capabilityCommands[currentDeviceCapability]) {
|
|
||||||
return command in capabilityCommands[currentDeviceCapability] ? true : false
|
|
||||||
} else {
|
|
||||||
// Handling other device types here, which don't accept commands
|
|
||||||
httpError(400, "Bad request.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Need to get the attribute name to do the lookup. Only
|
|
||||||
* doing it for the device types which accept commands
|
|
||||||
* @return attribute name of the device type
|
|
||||||
*/
|
|
||||||
def getCapabilityName(type) {
|
|
||||||
switch(type) {
|
|
||||||
case "switches":
|
|
||||||
return "Switch"
|
|
||||||
case "alarms":
|
|
||||||
return "Alarm"
|
|
||||||
case "locks":
|
|
||||||
return "Lock"
|
|
||||||
default:
|
|
||||||
return type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructing the map over here of
|
|
||||||
* supported commands by device capability
|
|
||||||
* @return a map of device capability -> supported commands
|
|
||||||
*/
|
|
||||||
def getDeviceCapabilityCommands(deviceCapabilities) {
|
|
||||||
def map = [:]
|
|
||||||
deviceCapabilities.collect {
|
|
||||||
map[it.name] = it.commands.collect{ it.name.toString() }
|
|
||||||
}
|
|
||||||
return map
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def show() {
|
def show() {
|
||||||
def type = params.deviceType
|
def type = params.deviceType
|
||||||
def devices = settings[type]
|
def devices = settings[type]
|
||||||
|
|||||||
@@ -147,4 +147,3 @@ private flashLights() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -236,22 +236,23 @@ def addSwitches() {
|
|||||||
d = getChildDevices()?.find {
|
d = getChildDevices()?.find {
|
||||||
it.deviceNetworkId == selectedSwitch.value.mac || it.device.getDataValue("mac") == selectedSwitch.value.mac
|
it.deviceNetworkId == selectedSwitch.value.mac || it.device.getDataValue("mac") == selectedSwitch.value.mac
|
||||||
}
|
}
|
||||||
if (!d) {
|
}
|
||||||
log.debug "Creating WeMo Switch with dni: ${selectedSwitch.value.mac}"
|
|
||||||
d = addChildDevice("smartthings", "Wemo Switch", selectedSwitch.value.mac, selectedSwitch?.value.hub, [
|
if (!d) {
|
||||||
"label": selectedSwitch?.value?.name ?: "Wemo Switch",
|
log.debug "Creating WeMo Switch with dni: ${selectedSwitch.value.mac}"
|
||||||
"data": [
|
d = addChildDevice("smartthings", "Wemo Switch", selectedSwitch.value.mac, selectedSwitch?.value.hub, [
|
||||||
"mac": selectedSwitch.value.mac,
|
"label": selectedSwitch?.value?.name ?: "Wemo Switch",
|
||||||
"ip": selectedSwitch.value.ip,
|
"data": [
|
||||||
"port": selectedSwitch.value.port
|
"mac": selectedSwitch.value.mac,
|
||||||
]
|
"ip": selectedSwitch.value.ip,
|
||||||
])
|
"port": selectedSwitch.value.port
|
||||||
def ipvalue = convertHexToIP(selectedSwitch.value.ip)
|
]
|
||||||
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
])
|
||||||
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
|
def ipvalue = convertHexToIP(selectedSwitch.value.ip)
|
||||||
} else {
|
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
||||||
log.debug "found ${d.displayName} with id $dni already exists"
|
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
|
||||||
}
|
} else {
|
||||||
|
log.debug "found ${d.displayName} with id $dni already exists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,22 +267,23 @@ def addMotions() {
|
|||||||
d = getChildDevices()?.find {
|
d = getChildDevices()?.find {
|
||||||
it.deviceNetworkId == selectedMotion.value.mac || it.device.getDataValue("mac") == selectedMotion.value.mac
|
it.deviceNetworkId == selectedMotion.value.mac || it.device.getDataValue("mac") == selectedMotion.value.mac
|
||||||
}
|
}
|
||||||
if (!d) {
|
}
|
||||||
log.debug "Creating WeMo Motion with dni: ${selectedMotion.value.mac}"
|
|
||||||
d = addChildDevice("smartthings", "Wemo Motion", selectedMotion.value.mac, selectedMotion?.value.hub, [
|
if (!d) {
|
||||||
"label": selectedMotion?.value?.name ?: "Wemo Motion",
|
log.debug "Creating WeMo Motion with dni: ${selectedMotion.value.mac}"
|
||||||
"data": [
|
d = addChildDevice("smartthings", "Wemo Motion", selectedMotion.value.mac, selectedMotion?.value.hub, [
|
||||||
"mac": selectedMotion.value.mac,
|
"label": selectedMotion?.value?.name ?: "Wemo Motion",
|
||||||
"ip": selectedMotion.value.ip,
|
"data": [
|
||||||
"port": selectedMotion.value.port
|
"mac": selectedMotion.value.mac,
|
||||||
]
|
"ip": selectedMotion.value.ip,
|
||||||
])
|
"port": selectedMotion.value.port
|
||||||
def ipvalue = convertHexToIP(selectedMotion.value.ip)
|
]
|
||||||
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
])
|
||||||
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
|
def ipvalue = convertHexToIP(selectedMotion.value.ip)
|
||||||
} else {
|
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
||||||
log.debug "found ${d.displayName} with id $dni already exists"
|
log.debug "Created ${d.displayName} with id: ${d.id}, dni: ${d.deviceNetworkId}"
|
||||||
}
|
} else {
|
||||||
|
log.debug "found ${d.displayName} with id $dni already exists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -296,22 +298,23 @@ def addLightSwitches() {
|
|||||||
d = getChildDevices()?.find {
|
d = getChildDevices()?.find {
|
||||||
it.deviceNetworkId == selectedLightSwitch.value.mac || it.device.getDataValue("mac") == selectedLightSwitch.value.mac
|
it.deviceNetworkId == selectedLightSwitch.value.mac || it.device.getDataValue("mac") == selectedLightSwitch.value.mac
|
||||||
}
|
}
|
||||||
if (!d) {
|
}
|
||||||
log.debug "Creating WeMo Light Switch with dni: ${selectedLightSwitch.value.mac}"
|
|
||||||
d = addChildDevice("smartthings", "Wemo Light Switch", selectedLightSwitch.value.mac, selectedLightSwitch?.value.hub, [
|
if (!d) {
|
||||||
"label": selectedLightSwitch?.value?.name ?: "Wemo Light Switch",
|
log.debug "Creating WeMo Light Switch with dni: ${selectedLightSwitch.value.mac}"
|
||||||
"data": [
|
d = addChildDevice("smartthings", "Wemo Light Switch", selectedLightSwitch.value.mac, selectedLightSwitch?.value.hub, [
|
||||||
"mac": selectedLightSwitch.value.mac,
|
"label": selectedLightSwitch?.value?.name ?: "Wemo Light Switch",
|
||||||
"ip": selectedLightSwitch.value.ip,
|
"data": [
|
||||||
"port": selectedLightSwitch.value.port
|
"mac": selectedLightSwitch.value.mac,
|
||||||
]
|
"ip": selectedLightSwitch.value.ip,
|
||||||
])
|
"port": selectedLightSwitch.value.port
|
||||||
def ipvalue = convertHexToIP(selectedLightSwitch.value.ip)
|
]
|
||||||
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
])
|
||||||
log.debug "created ${d.displayName} with id $dni"
|
def ipvalue = convertHexToIP(selectedLightSwitch.value.ip)
|
||||||
} else {
|
d.sendEvent(name: "currentIP", value: ipvalue, descriptionText: "IP is ${ipvalue}")
|
||||||
log.debug "found ${d.displayName} with id $dni already exists"
|
log.debug "created ${d.displayName} with id $dni"
|
||||||
}
|
} else {
|
||||||
|
log.debug "found ${d.displayName} with id $dni already exists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ def scheduleCheck(evt) {
|
|||||||
else {
|
else {
|
||||||
if(people){
|
if(people){
|
||||||
//don't turn off lights if anyone is home
|
//don't turn off lights if anyone is home
|
||||||
if(someoneIsHome){
|
if(someoneIsHome()){
|
||||||
log.debug("Stopping Check for Light")
|
log.debug("Stopping Check for Light")
|
||||||
unschedule()
|
unschedule()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user