mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-16 21:03:28 +00:00
Compare commits
10 Commits
DVCSMP-180
...
PROD_2016.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1a910f11f | ||
|
|
9f09a4b0b2 | ||
|
|
3c47fe7b60 | ||
|
|
45a0822e9b | ||
|
|
bbba20288e | ||
|
|
ff9dd3f6e2 | ||
|
|
a94a62d34c | ||
|
|
e861d3c256 | ||
|
|
7adff88d0f | ||
|
|
8d8b039dda |
@@ -29,6 +29,7 @@ metadata {
|
|||||||
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,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
|
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x72,0x5A,0x80,0x73,0x86,0x84,0x85,0x59,0x71,0x70,0x7A,0x98" // Vision door/window
|
||||||
|
fingerprint deviceId: "0x0701", inClusters: "0x5E,0x98,0x86,0x72,0x5A,0x85,0x59,0x73,0x80,0x71,0x31,0x70,0x84,0x7A" // Vision Motion
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulator metadata
|
// simulator metadata
|
||||||
@@ -263,5 +264,9 @@ def retypeBasedOnMSR() {
|
|||||||
log.debug "Changing device type to Door / Window Sensor Plus (SG)"
|
log.debug "Changing device type to Door / Window Sensor Plus (SG)"
|
||||||
setDeviceType("Door / Window Sensor Plus (SG)")
|
setDeviceType("Door / Window Sensor Plus (SG)")
|
||||||
break
|
break
|
||||||
|
case "0109-2002-0205": // Vision Motion
|
||||||
|
log.debug "Changing device type to Vision Motion Sensor Plus (SG)"
|
||||||
|
setDeviceType("Vision Motion Sensor Plus (SG)")
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,244 +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: "Z-Wave Plus Window Shade", namespace: "smartthings", author: "SmartThings") {
|
|
||||||
capability "Window Shade"
|
|
||||||
capability "Battery"
|
|
||||||
capability "Refresh"
|
|
||||||
capability "Health Check"
|
|
||||||
capability "Actuator"
|
|
||||||
capability "Sensor"
|
|
||||||
|
|
||||||
command "stop"
|
|
||||||
|
|
||||||
capability "Switch Level" // until we get a Window Shade Level capability
|
|
||||||
capability "Switch" // temporary for use with Routines
|
|
||||||
|
|
||||||
// This device handler is specifically for position-aware window coverings
|
|
||||||
//
|
|
||||||
fingerprint type: "0x1107", cc: "0x5E,0x26", deviceJoinName: "Window Shade"
|
|
||||||
fingerprint type: "0x9A00", cc: "0x5E,0x26", deviceJoinName: "Window Shade"
|
|
||||||
fingerprint mfr:"026E", prod:"4353", model:"5A31", deviceJoinName: "Window Blinds"
|
|
||||||
fingerprint mfr:"026E", prod:"5253", model:"5A31", deviceJoinName: "Roller Shade"
|
|
||||||
}
|
|
||||||
|
|
||||||
simulator {
|
|
||||||
status "open": "command: 2603, payload: FF"
|
|
||||||
status "closed": "command: 2603, payload: 00"
|
|
||||||
status "10%": "command: 2603, payload: 0A"
|
|
||||||
status "66%": "command: 2603, payload: 42"
|
|
||||||
status "99%": "command: 2603, payload: 63"
|
|
||||||
status "battery 100%": "command: 8003, payload: 64"
|
|
||||||
status "battery low": "command: 8003, payload: FF"
|
|
||||||
|
|
||||||
// reply messages
|
|
||||||
reply "2001FF,delay 1000,2602": "command: 2603, payload: 10 FF FE"
|
|
||||||
reply "200100,delay 1000,2602": "command: 2603, payload: 60 00 FE"
|
|
||||||
reply "200142,delay 1000,2602": "command: 2603, payload: 10 42 FE"
|
|
||||||
reply "200163,delay 1000,2602": "command: 2603, payload: 10 63 FE"
|
|
||||||
}
|
|
||||||
|
|
||||||
tiles(scale: 2) {
|
|
||||||
multiAttributeTile(name:"windowShade", type: "lighting", width: 6, height: 4, canChangeIcon: true){
|
|
||||||
tileAttribute ("device.windowShade", key: "PRIMARY_CONTROL") {
|
|
||||||
attributeState "open", label:'${name}', action:"close", icon:"st.doors.garage.garage-open", backgroundColor:"#79b821", nextState:"closing"
|
|
||||||
attributeState "closed", label:'${name}', action:"open", icon:"st.doors.garage.garage-closed", backgroundColor:"#ffffff", nextState:"opening"
|
|
||||||
attributeState "partiallyOpen", label:'Open', action:"close", icon:"st.doors.garage.garage-open", backgroundColor:"#79b821", nextState:"closing"
|
|
||||||
attributeState "opening", label:'${name}', action:"stop", icon:"st.doors.garage.garage-opening", backgroundColor:"#79b821", nextState:"partiallyOpen"
|
|
||||||
attributeState "closing", label:'${name}', action:"stop", icon:"st.doors.garage.garage-closing", backgroundColor:"#ffffff", nextState:"partiallyOpen"
|
|
||||||
}
|
|
||||||
tileAttribute ("device.level", key: "SLIDER_CONTROL") {
|
|
||||||
attributeState "level", action:"setLevel"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
standardTile("refresh", "device.refresh", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
|
|
||||||
state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh", nextState: "disabled"
|
|
||||||
state "disabled", label:'', action:"", icon:"st.secondary.refresh"
|
|
||||||
}
|
|
||||||
|
|
||||||
valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
|
|
||||||
state "battery", label:'${currentValue}% battery', unit:""
|
|
||||||
}
|
|
||||||
|
|
||||||
preferences {
|
|
||||||
input "preset", "number", title: "Default half-open position (1-100)", defaultValue: 50, required: false, displayDuringSetup: false
|
|
||||||
}
|
|
||||||
|
|
||||||
main(["windowShade"])
|
|
||||||
details(["windowShade", "refresh", "battery"])
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def parse(String description) {
|
|
||||||
def result = null
|
|
||||||
//if (description =~ /command: 2603, payload: ([0-9A-Fa-f]{6})/)
|
|
||||||
// TODO: Workaround manual parsing of v4 multilevel report
|
|
||||||
def cmd = zwave.parse(description, [0x20: 1, 0x26: 3]) // TODO: switch to SwitchMultilevel v4 and use target value
|
|
||||||
if (cmd) {
|
|
||||||
result = zwaveEvent(cmd)
|
|
||||||
}
|
|
||||||
log.debug "Parsed '$description' to ${result.inspect()}"
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
def getCheckInterval() {
|
|
||||||
// These are battery-powered devices, and it's not very critical
|
|
||||||
// to know whether they're online or not – 12 hrs
|
|
||||||
12 * 60 * 60
|
|
||||||
}
|
|
||||||
|
|
||||||
def installed() {
|
|
||||||
sendEvent(name: "checkInterval", value: checkInterval, displayed: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
def updated() {
|
|
||||||
if (device.latestValue("checkInterval") != checkInterval) {
|
|
||||||
sendEvent(name: "checkInterval", value: checkInterval, displayed: false)
|
|
||||||
}
|
|
||||||
if (!device.latestState("battery")) {
|
|
||||||
response(zwave.batteryV1.batteryGet())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
|
|
||||||
handleLevelReport(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
|
|
||||||
handleLevelReport(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelReport cmd) {
|
|
||||||
handleLevelReport(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
private handleLevelReport(physicalgraph.zwave.Command cmd) {
|
|
||||||
def descriptionText = null
|
|
||||||
def shadeValue = null
|
|
||||||
|
|
||||||
def level = cmd.value as Integer
|
|
||||||
if (level >= 99) {
|
|
||||||
level = 99
|
|
||||||
shadeValue = "open"
|
|
||||||
} else if (level <= 0) {
|
|
||||||
level = 0 // unlike dimmer switches, the level isn't saved when closed
|
|
||||||
shadeValue = "closed"
|
|
||||||
} else {
|
|
||||||
shadeValue = "partiallyOpen"
|
|
||||||
descriptionText = "${device.displayName} shade is ${level}% open"
|
|
||||||
}
|
|
||||||
def levelEvent = createEvent(name: "level", value: level, unit: "%", displayed: false)
|
|
||||||
def stateEvent = createEvent(name: "windowShade", value: shadeValue, descriptionText: descriptionText, isStateChange: levelEvent.isStateChange)
|
|
||||||
|
|
||||||
def result = [stateEvent, levelEvent]
|
|
||||||
if (!state.lastbatt || now() - state.lastbatt > 24 * 60 * 60 * 1000) {
|
|
||||||
log.debug "requesting battery"
|
|
||||||
state.lastbatt = (now() - 23 * 60 * 60 * 1000) // don't queue up multiple battery reqs in a row
|
|
||||||
result << response(["delay 15000", zwave.batteryV1.batteryGet().format()])
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelStopLevelChange cmd) {
|
|
||||||
[ createEvent(name: "windowShade", value: "partiallyOpen", displayed: false, descriptionText: "$device.displayName shade stopped"),
|
|
||||||
response(zwave.switchMultilevelV1.switchMultilevelGet().format()) ]
|
|
||||||
}
|
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
|
|
||||||
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
|
|
||||||
updateDataValue("MSR", msr)
|
|
||||||
if (cmd.manufacturerName) {
|
|
||||||
updateDataValue("manufacturer", cmd.manufacturerName)
|
|
||||||
}
|
|
||||||
createEvent([descriptionText: "$device.displayName MSR: $msr", isStateChange: false])
|
|
||||||
}
|
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
|
|
||||||
def map = [ name: "battery", unit: "%" ]
|
|
||||||
if (cmd.batteryLevel == 0xFF) {
|
|
||||||
map.value = 1
|
|
||||||
map.descriptionText = "${device.displayName} has a low battery"
|
|
||||||
map.isStateChange = true
|
|
||||||
} else {
|
|
||||||
map.value = cmd.batteryLevel
|
|
||||||
}
|
|
||||||
state.lastbatt = now()
|
|
||||||
createEvent(map)
|
|
||||||
}
|
|
||||||
|
|
||||||
def zwaveEvent(physicalgraph.zwave.Command cmd) {
|
|
||||||
log.debug "unhandled $cmd"
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
def open() {
|
|
||||||
log.debug "open()"
|
|
||||||
/*delayBetween([
|
|
||||||
zwave.basicV1.basicSet(value: 0xFF).format(),
|
|
||||||
zwave.switchMultilevelV1.switchMultilevelGet().format()
|
|
||||||
], 1000)*/
|
|
||||||
zwave.basicV1.basicSet(value: 0xFF).format()
|
|
||||||
}
|
|
||||||
|
|
||||||
def close() {
|
|
||||||
log.debug "close()"
|
|
||||||
/*delayBetween([
|
|
||||||
zwave.basicV1.basicSet(value: 0x00).format(),
|
|
||||||
zwave.switchMultilevelV1.switchMultilevelGet().format()
|
|
||||||
], 1000)*/
|
|
||||||
zwave.basicV1.basicSet(value: 0).format()
|
|
||||||
}
|
|
||||||
|
|
||||||
def on() {
|
|
||||||
open()
|
|
||||||
}
|
|
||||||
|
|
||||||
def off() {
|
|
||||||
close()
|
|
||||||
}
|
|
||||||
|
|
||||||
def setLevel(value, duration = null) {
|
|
||||||
log.debug "setLevel(${value.inspect()})"
|
|
||||||
Integer level = value as Integer
|
|
||||||
if (level < 0) level = 0
|
|
||||||
if (level > 99) level = 99
|
|
||||||
if (!preset && level > 0 && level < 95) state.preset = level
|
|
||||||
delayBetween([
|
|
||||||
zwave.basicV1.basicSet(value: level).format(),
|
|
||||||
zwave.switchMultilevelV1.switchMultilevelGet().format()
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
def presetPosition() {
|
|
||||||
setLevel(preset ?: state.preset ?: 50)
|
|
||||||
}
|
|
||||||
|
|
||||||
def stop() {
|
|
||||||
log.debug "stop()"
|
|
||||||
zwave.switchMultilevelV3.switchMultilevelStopLevelChange().format()
|
|
||||||
}
|
|
||||||
|
|
||||||
def ping() {
|
|
||||||
zwave.switchMultilevelV1.switchMultilevelGet().format()
|
|
||||||
}
|
|
||||||
|
|
||||||
def refresh() {
|
|
||||||
log.debug "refresh()"
|
|
||||||
delayBetween([
|
|
||||||
zwave.switchMultilevelV1.switchMultilevelGet().format(),
|
|
||||||
zwave.batteryV1.batteryGet().format()
|
|
||||||
], 1500)
|
|
||||||
}
|
|
||||||
@@ -337,10 +337,10 @@ def initialize() {
|
|||||||
|
|
||||||
settings.devices.each {
|
settings.devices.each {
|
||||||
def deviceId = it
|
def deviceId = it
|
||||||
def detail = state.deviceDetail[deviceId]
|
def detail = state?.deviceDetail[deviceId]
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch(detail.type) {
|
switch(detail?.type) {
|
||||||
case 'NAMain':
|
case 'NAMain':
|
||||||
log.debug "Base station"
|
log.debug "Base station"
|
||||||
createChildDevice("Netatmo Basestation", deviceId, "${detail.type}.${deviceId}", detail.module_name)
|
createChildDevice("Netatmo Basestation", deviceId, "${detail.type}.${deviceId}", detail.module_name)
|
||||||
@@ -487,12 +487,12 @@ def poll() {
|
|||||||
log.debug "State: ${state.deviceState}"
|
log.debug "State: ${state.deviceState}"
|
||||||
|
|
||||||
settings.devices.each { deviceId ->
|
settings.devices.each { deviceId ->
|
||||||
def detail = state.deviceDetail[deviceId]
|
def detail = state?.deviceDetail[deviceId]
|
||||||
def data = state.deviceState[deviceId]
|
def data = state?.deviceState[deviceId]
|
||||||
def child = children.find { it.deviceNetworkId == deviceId }
|
def child = children?.find { it.deviceNetworkId == deviceId }
|
||||||
|
|
||||||
log.debug "Update: $child";
|
log.debug "Update: $child";
|
||||||
switch(detail.type) {
|
switch(detail?.type) {
|
||||||
case 'NAMain':
|
case 'NAMain':
|
||||||
log.debug "Updating NAMain $data"
|
log.debug "Updating NAMain $data"
|
||||||
child?.sendEvent(name: 'temperature', value: cToPref(data['Temperature']) as float, unit: getTemperatureScale())
|
child?.sendEvent(name: 'temperature', value: cToPref(data['Temperature']) as float, unit: getTemperatureScale())
|
||||||
|
|||||||
Reference in New Issue
Block a user