-
Notifications
You must be signed in to change notification settings - Fork 6
/
Monoprice-Door-Window-Sensor-as-Smoke-Detector-v2
211 lines (183 loc) · 6.89 KB
/
Monoprice-Door-Window-Sensor-as-Smoke-Detector-v2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/**
* Z-Wave Door/Window Sensor
*
* Author: SmartThings
* Date: 2013-11-3
*/
// for the UI
metadata {
// Automatically generated. Make future change here.
definition (name: "Monoprice Door/Window Sensor as Smoke Detector v2", namespace: "trostc", author: "trostc") {
//capability "Contact Sensor"
capability "Smoke Detector"
capability "Sensor"
capability "Battery"
//0 0 0x2001 0 0 0 7 0x71 0x85 0x80 0x72 0x30 0x86 0x84
fingerprint deviceId: "0x2001", inClusters: "0x71, 0x85, 0x80, 0x72, 0x30, 0x86, 0x84"
}
// simulator metadata
simulator {
// status messages
status "clear": "command: 2001, payload: FF"
status "detected": "command: 2001, payload: 00"
}
// UI tile definitions
tiles(scale: 2) {
multiAttributeTile(name:"smoke", type: "lighting", width: 6, height: 4){
tileAttribute ("device.smoke", key: "PRIMARY_CONTROL") {
attributeState "clear", label:'${name}', icon:"st.alarm.smoke.clear", backgroundColor:"#79b821"
attributeState "detected", label:'${name}', icon:"st.particulate.particulate.particulate", backgroundColor:"#ff1f1f"
}
}
valueTile("battery", "device.battery", inactiveLabel: false, width: 2, height: 2) {
state "battery", label:'${currentValue}% battery', unit:""
}
standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
state "default", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "smoke"
details(["smoke","battery","refresh"])
}
}
def parse(String description) {
log.debug "parse:${description}"
def result = null
if (description.startsWith("Err")) {
result = createEvent(descriptionText:description)
} else if (description == "updated") {
if (!state.MSR) {
result = [
response(zwave.wakeUpV1.wakeUpIntervalSet(seconds:4*3600, nodeid:zwaveHubNodeId)),
response(zwave.manufacturerSpecificV2.manufacturerSpecificGet()),
]
}
} else {
def cmd = zwave.parse(description, [0x20: 1, 0x25: 1, 0x30: 1, 0x31: 5, 0x80: 1, 0x84: 1, 0x71: 3, 0x9C: 1])
log.debug "parse:cmd = ${cmd}"
if (cmd) {
result = zwaveEvent(cmd)
}
}
return result
}
def sensorValueEvent(value) {
log.debug "sensorValueEvent:value = ${value}"
def result = null
if (value) {
result = createEvent(name: "smoke", value: "clear", descriptionText: "$device.displayName smoke is clear")
} else {
result = createEvent(name: "smoke", value: "detected", descriptionText: "$device.displayName detected smoke")
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv1.SensorBinaryReport cmd)
{
sensorValueEvent(cmd.sensorValue)
}
def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd)
{
sensorValueEvent(cmd.sensorState)
}
def zwaveEvent(physicalgraph.zwave.commands.notificationv3.NotificationReport cmd)
{
def result = []
if (cmd.notificationType == 0x06 && cmd.event == 0x16) {
result << sensorValueEvent(1)
} else if (cmd.notificationType == 0x06 && cmd.event == 0x17) {
result << sensorValueEvent(0)
} else if (cmd.notificationType == 0x07) {
if (cmd.v1AlarmType == 0x07) { // special case for nonstandard messages from Monoprice door/window sensors
result << sensorValueEvent(cmd.v1AlarmLevel)
} else if (cmd.event == 0x01 || cmd.event == 0x02) {
result << sensorValueEvent(1)
} else if (cmd.event == 0x03) {
result << createEvent(descriptionText: "$device.displayName covering was removed", isStateChange: true)
result << response(zwave.wakeUpV1.wakeUpIntervalSet(seconds:4*3600, nodeid:zwaveHubNodeId))
if(!state.MSR) result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
} else if (cmd.event == 0x05 || cmd.event == 0x06) {
result << createEvent(descriptionText: "$device.displayName detected glass breakage", isStateChange: true)
} else if (cmd.event == 0x07) {
if(!state.MSR) result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
result << createEvent(name: "motion", value: "active", descriptionText:"$device.displayName detected motion")
}
} else if (cmd.notificationType) {
def text = "Notification $cmd.notificationType: event ${([cmd.event] + cmd.eventParameter).join(", ")}"
result << createEvent(name: "notification$cmd.notificationType", value: "$cmd.event", descriptionText: text, displayed: false)
} else {
def value = cmd.v1AlarmLevel == 255 ? "active" : cmd.v1AlarmLevel ?: "inactive"
result << createEvent(name: "alarm $cmd.v1AlarmType", value: value, displayed: false)
}
result
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
if (!state.lastbat || (new Date().time) - state.lastbat > 53*60*60*1000) {
result << response(zwave.batteryV1.batteryGet())
result << response("delay 1200")
}
if (!state.MSR) {
result << response(zwave.wakeUpV1.wakeUpIntervalSet(seconds:4*3600, nodeid:zwaveHubNodeId))
result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet())
result << response("delay 1200")
}
result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
result
}
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.lastbat = new Date().time
[createEvent(map), response(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
def result = []
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
log.debug "msr: $msr"
updateDataValue("MSR", msr)
retypeBasedOnMSR()
result << createEvent(descriptionText: "$device.displayName MSR: $msr", isStateChange: false)
if (msr == "011A-0601-0901") { // Enerwave motion doesn't always get the associationSet that the hub sends on join
result << response(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId))
} else if (!device.currentState("battery")) {
result << response(zwave.batteryV1.batteryGet())
}
result
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
createEvent(descriptionText: "$device.displayName: $cmd", displayed: false)
}
def retypeBasedOnMSR() {
switch (state.MSR) {
case "0086-0002-002D":
log.debug("Changing device type to Z-Wave Water Sensor")
setDeviceType("Z-Wave Water Sensor")
break
case "011F-0001-0001": // Schlage motion
case "014A-0001-0001": // Ecolink motion
case "0060-0001-0002": // Everspring SP814
case "0060-0001-0003": // Everspring HSP02
case "011A-0601-0901": // Enerwave ZWN-BPC
log.debug("Changing device type to Z-Wave Motion Sensor")
setDeviceType("Z-Wave Motion Sensor")
break
}
}