Advertisement
erocm123

NZW31 w/Scene Z-Wave Replace

Feb 12th, 2018
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.58 KB | None | 0 0
  1. /**
  2. * Inovelli Dimmer NZW31 w/Scene
  3. * Author: Eric Maycock (erocm123)
  4. * Date: 2017-07-15
  5. *
  6. * Copyright 2017 Eric Maycock
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  9. * in compliance with the License. You may obtain a copy of the License at:
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  14. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  15. * for the specific language governing permissions and limitations under the License.
  16. *
  17. */
  18.  
  19. metadata {
  20. definition (name: "Inovelli Dimmer NZW31 w/Scene", namespace: "erocm123", author: "Eric Maycock") {
  21. capability "Switch"
  22. capability "Refresh"
  23. capability "Polling"
  24. capability "Actuator"
  25. capability "Sensor"
  26. //capability "Health Check"
  27. capability "Button"
  28. capability "Holdable Button"
  29. capability "Indicator"
  30. capability "Switch Level"
  31.  
  32. attribute "lastActivity", "String"
  33. attribute "lastEvent", "String"
  34.  
  35. command "pressUpX1"
  36. command "pressDownX1"
  37. command "pressUpX2"
  38. command "pressDownX2"
  39. command "pressUpX3"
  40. command "pressDownX3"
  41. command "pressUpX4"
  42. command "pressDownX4"
  43. command "pressUpX5"
  44. command "pressDownX5"
  45. command "holdUp"
  46. command "holdDown"
  47.  
  48. fingerprint mfr: "015D", prod: "B111", model: "251C", deviceJoinName: "Inovelli Dimmer"
  49. fingerprint mfr: "051D", prod: "B111", model: "251C", deviceJoinName: "Inovelli Dimmer"
  50. fingerprint mfr: "015D", prod: "1F00", model: "1F00", deviceJoinName: "Inovelli Dimmer"
  51. fingerprint mfr: "0312", prod: "1F00", model: "1F00", deviceJoinName: "Inovelli Dimmer"
  52. }
  53.  
  54. simulator {
  55. }
  56.  
  57. preferences {
  58. input "minimumLevel", "number", title: "Minimum Level\n\nMinimum dimming level for attached light\nRange: 1 to 99", description: "Tap to set", required: false, range: "1..99"
  59. input "dimmingStep", "number", title: "Dimming Step Size\n\nPercentage of step when switch is dimming up or down\nRange: 1 to 99", description: "Tap to set", required: false, range: "1..99"
  60. input "autoOff", "number", title: "Auto Off\n\nAutomatically turn switch off after this number of seconds\nRange: 0 to 32767", description: "Tap to set", required: false, range: "0..32767"
  61. input "ledIndicator", "enum", title: "LED Indicator\n\nTurn LED indicator on when light is:\n", description: "Tap to set", required: false, options:[1: "On", 0: "Off", 2: "Disable"], defaultValue: 1
  62. input "invert", "enum", title: "Invert Switch", description: "Tap to set", required: false, options:[0: "No", 1: "Yes"], defaultValue: 0
  63. input description: "1 pushed - Up 1x click\n2 pushed - Up 2x click\n3 pushed - Up 3x click\n4 pushed - Up 4x click\n5 pushed - Up 5x click\n6 pushed - Up held\n\n1 held - Down 1x click\n2 held - Down 2x click\n3 held - Down 3x click\n4 held - Down 4x click\n5 held - Down 5x click\n6 held - Down held", title: "Button Mappings", displayDuringSetup: false, type: "paragraph", element: "paragraph"
  64. }
  65.  
  66. tiles {
  67. multiAttributeTile(name: "switch", type: "lighting", width: 6, height: 4, canChangeIcon: true) {
  68. tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
  69. attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
  70. attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
  71. attributeState "turningOff", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
  72. attributeState "turningOn", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#00a0dc", nextState: "turningOff"
  73. }
  74. tileAttribute ("device.level", key: "SLIDER_CONTROL") {
  75. attributeState "level", action:"switch level.setLevel"
  76. }
  77. tileAttribute("device.lastEvent", key: "SECONDARY_CONTROL") {
  78. attributeState("default", label:'${currentValue}',icon: "st.unknown.zwave.remote-controller")
  79. }
  80. }
  81.  
  82. standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
  83. state "default", label: "", action: "refresh.refresh", icon: "st.secondary.refresh"
  84. }
  85.  
  86. standardTile("pressUpX2", "device.button", width: 2, height: 1, decoration: "flat") {
  87. state "default", label: "Tap ▲▲", backgroundColor: "#ffffff", action: "pressUpX2"
  88. }
  89.  
  90. standardTile("pressUpX3", "device.button", width: 2, height: 1, decoration: "flat") {
  91. state "default", label: "Tap ▲▲▲", backgroundColor: "#ffffff", action: "pressUpX3"
  92. }
  93.  
  94. standardTile("pressDownX2", "device.button", width: 2, height: 1, decoration: "flat") {
  95. state "default", label: "Tap ▼▼", backgroundColor: "#ffffff", action: "pressDownX2"
  96. }
  97.  
  98. standardTile("pressDownX3", "device.button", width: 2, height: 1, decoration: "flat") {
  99. state "default", label: "Tap ▼▼▼", backgroundColor: "#ffffff", action: "pressDownX3"
  100. }
  101.  
  102. valueTile("level", "device.level", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
  103. state "default", label: '${currentValue}%', icon: ""
  104. }
  105.  
  106. standardTile("pressUpX4", "device.button", width: 2, height: 1, decoration: "flat") {
  107. state "default", label: "Tap ▲▲▲▲", backgroundColor: "#ffffff", action: "pressUpX4"
  108. }
  109.  
  110. standardTile("pressUpX5", "device.button", width: 2, height: 1, decoration: "flat") {
  111. state "default", label: "Tap ▲▲▲▲▲", backgroundColor: "#ffffff", action: "pressUpX5"
  112. }
  113.  
  114. standardTile("pressDownX4", "device.button", width: 2, height: 1, decoration: "flat") {
  115. state "default", label: "Tap ▼▼▼▼", backgroundColor: "#ffffff", action: "pressDownX4"
  116. }
  117.  
  118. standardTile("pressDownX5", "device.button", width: 2, height: 1, decoration: "flat") {
  119. state "default", label: "Tap ▼▼▼▼▼", backgroundColor: "#ffffff", action: "pressDownX5"
  120. }
  121.  
  122. valueTile("lastActivity", "device.lastActivity", inactiveLabel: false, decoration: "flat", width: 4, height: 1) {
  123. state "default", label: 'Last Activity: ${currentValue}',icon: "st.Health & Wellness.health9"
  124. }
  125.  
  126. valueTile("blank", "device.blank", inactiveLabel: false, decoration: "flat", width: 2, height: 1) {
  127. state "default", label: '', icon: ""
  128. }
  129.  
  130. valueTile("info", "device.info", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
  131. state "default", label: 'Tap on the buttons above to test scenes (ie: Tap ▲ 1x, ▲▲ 2x, etc depending on the button)'
  132. }
  133.  
  134. valueTile("icon", "device.icon", inactiveLabel: false, decoration: "flat", width: 3, height: 1) {
  135. state "default", label: '', icon: "https://inovelli.com/wp-content/uploads/Device-Handler/Inovelli-Device-Handler-Logo.png"
  136. }
  137. }
  138. }
  139.  
  140. def installed() {
  141. refresh()
  142. }
  143.  
  144. def updated() {
  145. state.sec = 0
  146. sendEvent(name: "checkInterval", value: 3 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID, offlinePingable: "1"])
  147. sendEvent(name: "numberOfButtons", value: 6, displayed: true)
  148. def cmds = []
  149. cmds << zwave.associationV2.associationSet(groupingIdentifier: 1, nodeId: zwaveHubNodeId)
  150. cmds << zwave.associationV2.associationGet(groupingIdentifier: 1)
  151. cmds << zwave.configurationV1.configurationSet(configurationValue: [dimmingStep? dimmingStep.toInteger() : 1], parameterNumber: 1, size: 1)
  152. cmds << zwave.configurationV1.configurationGet(parameterNumber: 1)
  153. cmds << zwave.configurationV1.configurationSet(configurationValue: [minimumLevel? minimumLevel.toInteger() : 1], parameterNumber: 2, size: 1)
  154. cmds << zwave.configurationV1.configurationGet(parameterNumber: 2)
  155. cmds << zwave.configurationV1.configurationSet(configurationValue: [ledIndicator? ledIndicator.toInteger() : 1], parameterNumber: 3, size: 1)
  156. cmds << zwave.configurationV1.configurationGet(parameterNumber: 3)
  157. cmds << zwave.configurationV1.configurationSet(configurationValue: [invert? invert.toInteger() : 0], parameterNumber: 4, size: 1)
  158. cmds << zwave.configurationV1.configurationGet(parameterNumber: 4)
  159. cmds << zwave.configurationV1.configurationSet(scaledConfigurationValue: autoOff? autoOff.toInteger() : 0, parameterNumber: 5, size: 2)
  160. cmds << zwave.configurationV1.configurationGet(parameterNumber: 5)
  161. response(commands(cmds))
  162. }
  163.  
  164. def parse(description) {
  165. def result = null
  166. state.sec = 0
  167. if (description.startsWith("Err 106")) {
  168. state.sec = 0
  169. result = createEvent(descriptionText: description, isStateChange: true)
  170. } else if (description != "updated") {
  171. def cmd = zwave.parse(description, [0x20: 1, 0x25: 1, 0x70: 1, 0x98: 1])
  172. if (cmd) {
  173. result = zwaveEvent(cmd)
  174. log.debug("'$description' parsed to $result")
  175. } else {
  176. log.debug("Couldn't zwave.parse '$description'")
  177. }
  178. }
  179. def now
  180. if(location.timeZone)
  181. now = new Date().format("yyyy MMM dd EEE h:mm:ss a", location.timeZone)
  182. else
  183. now = new Date().format("yyyy MMM dd EEE h:mm:ss a")
  184. sendEvent(name: "lastActivity", value: now, displayed:false)
  185. result
  186. }
  187.  
  188. def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
  189. dimmerEvents(cmd)
  190. }
  191.  
  192. def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
  193. createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "physical")
  194. }
  195.  
  196. def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
  197. createEvent(name: "switch", value: cmd.value ? "on" : "off", type: "digital")
  198. }
  199.  
  200. def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelReport cmd) {
  201. dimmerEvents(cmd)
  202. }
  203.  
  204. def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelReport cmd) {
  205. dimmerEvents(cmd)
  206. }
  207.  
  208. private dimmerEvents(physicalgraph.zwave.Command cmd) {
  209. def value = (cmd.value ? "on" : "off")
  210. def result = [createEvent(name: "switch", value: value, descriptionText: "$device.displayName was turned $value")]
  211. if (cmd.value) {
  212. result << createEvent(name: "level", value: cmd.value, unit: "%")
  213. }
  214. return result
  215. }
  216.  
  217. def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
  218. def encapsulatedCommand = cmd.encapsulatedCommand([0x20: 1, 0x25: 1])
  219. if (encapsulatedCommand) {
  220. state.sec = 1
  221. zwaveEvent(encapsulatedCommand)
  222. }
  223. }
  224.  
  225. def zwaveEvent(physicalgraph.zwave.commands.centralscenev1.CentralSceneNotification cmd) {
  226. switch (cmd.keyAttributes) {
  227. case 0:
  228. createEvent(buttonEvent(cmd.keyAttributes + 1, (cmd.sceneNumber == 2? "pushed" : "held"), "physical"))
  229. break
  230. case 1:
  231. createEvent(buttonEvent(6, (cmd.sceneNumber == 2? "pushed" : "held"), "physical"))
  232. break
  233. case 2:
  234. null
  235. break
  236. default:
  237. createEvent(buttonEvent(cmd.keyAttributes - 1, (cmd.sceneNumber == 2? "pushed" : "held"), "physical"))
  238. break
  239. }
  240. }
  241.  
  242. def buttonEvent(button, value, type = "digital") {
  243. if(button != 6)
  244. sendEvent(name:"lastEvent", value: "${value != 'pushed'?' Tap '.padRight(button+5, '▼'):' Tap '.padRight(button+5, '▲')}", displayed:false)
  245. else
  246. sendEvent(name:"lastEvent", value: "${value != 'pushed'?' Hold ▼':' Hold ▲'}", displayed:false)
  247. [name: "button", value: value, data: [buttonNumber: button], descriptionText: "$device.displayName button $button was $value", isStateChange: true, type: type]
  248. }
  249.  
  250. def zwaveEvent(physicalgraph.zwave.Command cmd) {
  251. log.debug "Unhandled: $cmd"
  252. null
  253. }
  254.  
  255. def on() {
  256. commands([
  257. zwave.basicV1.basicSet(value: 0xFF),
  258. zwave.switchMultilevelV1.switchMultilevelGet()
  259. ])
  260. }
  261.  
  262. def off() {
  263. commands([
  264. zwave.basicV1.basicSet(value: 0x00),
  265. zwave.switchMultilevelV1.switchMultilevelGet()
  266. ])
  267. }
  268.  
  269. def setLevel(value) {
  270. commands([
  271. zwave.basicV1.basicSet(value: value < 100 ? value : 99),
  272. zwave.switchMultilevelV1.switchMultilevelGet()
  273. ])
  274. }
  275.  
  276. def setLevel(value, duration) {
  277. def dimmingDuration = duration < 128 ? duration : 128 + Math.round(duration / 60)
  278. commands([
  279. zwave.switchMultilevelV2.switchMultilevelSet(value: value < 100 ? value : 99, dimmingDuration: dimmingDuration),
  280. zwave.switchMultilevelV1.switchMultilevelGet().format()
  281. ])
  282. }
  283.  
  284. def ping() {
  285. log.debug "ping()"
  286. refresh()
  287. }
  288.  
  289. def poll() {
  290. log.debug "poll()"
  291. refresh()
  292. }
  293.  
  294. def refresh() {
  295. log.debug "refresh()"
  296. commands([zwave.switchBinaryV1.switchBinaryGet(),
  297. zwave.switchMultilevelV1.switchMultilevelGet()
  298. ])
  299. }
  300.  
  301. private command(physicalgraph.zwave.Command cmd) {
  302. if (state.sec) {
  303. zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
  304. } else {
  305. cmd.format()
  306. }
  307. }
  308.  
  309. private commands(commands, delay=500) {
  310. delayBetween(commands.collect{ command(it) }, delay)
  311. }
  312.  
  313. def pressUpX1() {
  314. sendEvent(buttonEvent(1, "pushed"))
  315. }
  316.  
  317. def pressDownX1() {
  318. sendEvent(buttonEvent(1, "held"))
  319. }
  320.  
  321. def pressUpX2() {
  322. sendEvent(buttonEvent(2, "pushed"))
  323. }
  324.  
  325. def pressDownX2() {
  326. sendEvent(buttonEvent(2, "held"))
  327. }
  328.  
  329. def pressUpX3() {
  330. sendEvent(buttonEvent(3, "pushed"))
  331. }
  332.  
  333. def pressDownX3() {
  334. sendEvent(buttonEvent(3, "held"))
  335. }
  336.  
  337. def pressUpX4() {
  338. sendEvent(buttonEvent(4, "pushed"))
  339. }
  340.  
  341. def pressDownX4() {
  342. sendEvent(buttonEvent(4, "held"))
  343. }
  344.  
  345. def pressUpX5() {
  346. sendEvent(buttonEvent(5, "pushed"))
  347. }
  348.  
  349. def pressDownX5() {
  350. sendEvent(buttonEvent(5, "held"))
  351. }
  352.  
  353. def holdUp() {
  354. sendEvent(buttonEvent(6, "pushed"))
  355. }
  356.  
  357. def holdDown() {
  358. sendEvent(buttonEvent(6, "held"))
  359. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement