Advertisement
erocm123

Untitled

Aug 17th, 2018
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.28 KB | None | 0 0
  1. /**
  2. * Note: This handler requires the "Metering Switch Child Device" to be installed.
  3. *
  4. * Copyright 2016 Eric Maycock
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at:
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  12. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing permissions and limitations under the License.
  14. *
  15. * Fibaro FGS-223 Dual Relay
  16. *
  17. * Author: Eric Maycock (erocm123)
  18. *
  19. * 04/25/2017 - Fix for combined energy & power reports & switch endpoints showing correct info.
  20. * 04/18/2017 - This handler requires the Metering Switch Child device to create the multiple switch endpoints.
  21. */
  22.  
  23. metadata {
  24. definition (name: "Fibaro Double Switch 2 FGS-223", namespace: "erocm123", author: "Eric Maycock") {
  25. capability "Sensor"
  26. capability "Actuator"
  27. capability "Switch"
  28. capability "Polling"
  29. capability "Configuration"
  30. capability "Refresh"
  31. capability "Zw Multichannel"
  32. capability "Energy Meter"
  33. capability "Power Meter"
  34. capability "Health Check"
  35. capability "Button"
  36. capability "Holdable Button"
  37.  
  38. command "reset"
  39.  
  40. fingerprint mfr: "010F", prod: "0203", model: "2000", deviceJoinName: "Fibaro Double Switch 2"
  41. fingerprint mfr: "010F", prod: "0203", model: "1000", deviceJoinName: "Fibaro Double Switch 2"
  42.  
  43. fingerprint deviceId: "0x1001", inClusters:"0x5E,0x86,0x72,0x59,0x73,0x22,0x56,0x32,0x71,0x98,0x7A,0x25,0x5A,0x85,0x70,0x8E,0x60,0x75,0x5B"
  44. }
  45.  
  46. simulator {
  47. }
  48.  
  49. tiles(scale: 2){
  50.  
  51. multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
  52. tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
  53. attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
  54. attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00a0dc", nextState:"turningOff"
  55. attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
  56. attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#00a0dc", nextState:"turningOff"
  57. }
  58. tileAttribute ("statusText", key: "SECONDARY_CONTROL") {
  59. attributeState "statusText", label:'${currentValue}'
  60. }
  61. }
  62. valueTile("power", "device.power", decoration: "flat", width: 2, height: 2) {
  63. state "default", label:'${currentValue} W'
  64. }
  65. valueTile("energy", "device.energy", decoration: "flat", width: 2, height: 2) {
  66. state "default", label:'${currentValue} kWh'
  67. }
  68. standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
  69. state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
  70. }
  71. standardTile("configure", "device.needUpdate", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
  72. state "NO" , label:'', action:"configuration.configure", icon:"st.secondary.configure"
  73. state "YES", label:'', action:"configuration.configure", icon:"https://github.com/erocm123/SmartThingsPublic/raw/master/devicetypes/erocm123/qubino-flush-1d-relay.src/configure@2x.png"
  74. }
  75. standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
  76. state "default", label:'reset kWh', action:"reset"
  77. }
  78.  
  79. main(["switch"])
  80. details(["switch", childDeviceTiles("all"),
  81. "refresh","reset","configure"])
  82.  
  83. }
  84. preferences {
  85. input description: "Once you change values on this page, the corner of the \"configuration\" icon will change orange until all configuration parameters are updated.", title: "Settings", displayDuringSetup: false, type: "paragraph", element: "paragraph"
  86. generate_preferences(configuration_model())
  87. }
  88. }
  89.  
  90. def parse(String description) {
  91. def result = []
  92. if (description.startsWith("Err 106")) {
  93. state.sec = 0
  94. result = createEvent(descriptionText: description, isStateChange: true)
  95. } else {
  96. def cmd = zwave.parse(description)
  97. if (cmd) {
  98. result += zwaveEvent(cmd)
  99. //log.debug "Parsed ${cmd} to ${result.inspect()}"
  100. } else {
  101. log.debug "Non-parsed event: ${description}"
  102. }
  103. }
  104.  
  105. def statusTextmsg = ""
  106.  
  107. result.each {
  108. if ((it instanceof Map) == true && it.find{ it.key == "name" }?.value == "power") {
  109. statusTextmsg = "${it.value} W ${device.currentValue('energy')? device.currentValue('energy') : "0"} kWh"
  110. }
  111. if ((it instanceof Map) == true && it.find{ it.key == "name" }?.value == "energy") {
  112. statusTextmsg = "${device.currentValue('power')? device.currentValue('power') : "0"} W ${it.value} kWh"
  113. }
  114. }
  115. if (statusTextmsg != "") sendEvent(name:"statusText", value:statusTextmsg, displayed:false)
  116.  
  117. return result
  118. }
  119.  
  120. def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
  121. {
  122. log.debug "BasicReport $cmd"
  123. }
  124.  
  125. def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd, ep=null) {
  126. logging("BasicSet: $cmd : Endpoint: $ep")
  127. if (ep) {
  128. def event
  129. childDevices.each { childDevice ->
  130. if (childDevice.deviceNetworkId == "$device.deviceNetworkId-ep$ep") {
  131. childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
  132. }
  133. }
  134. if (cmd.value) {
  135. event = [createEvent([name: "switch", value: "on"])]
  136. } else {
  137. def allOff = true
  138. childDevices.each { n ->
  139. if (n.currentState("switch").value != "off") allOff = false
  140. }
  141. if (allOff) {
  142. event = [createEvent([name: "switch", value: "off"])]
  143. } else {
  144. event = [createEvent([name: "switch", value: "on"])]
  145. }
  146. }
  147. return event
  148. }
  149. }
  150.  
  151. def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd, ep=null)
  152. {
  153. logging("SwitchBinaryReport: $cmd : Endpoint: $ep")
  154. if (ep) {
  155. def event
  156. childDevices.each { childDevice ->
  157. if (childDevice.deviceNetworkId == "$device.deviceNetworkId-ep$ep") {
  158. childDevice.sendEvent(name: "switch", value: cmd.value ? "on" : "off")
  159. }
  160. }
  161. if (cmd.value) {
  162. event = [createEvent([name: "switch", value: "on"])]
  163. } else {
  164. def allOff = true
  165. childDevices.each { n ->
  166. if (n.currentState("switch").value != "off") allOff = false
  167. }
  168. if (allOff) {
  169. event = [createEvent([name: "switch", value: "off"])]
  170. } else {
  171. event = [createEvent([name: "switch", value: "on"])]
  172. }
  173. }
  174. return event
  175. } else {
  176. def cmds = []
  177. cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 1)
  178. cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
  179. return response(commands(cmds)) // returns the result of reponse()
  180. }
  181. }
  182.  
  183. def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd, ep=null) {
  184. logging("MeterReport: $cmd : Endpoint: $ep")
  185. def result
  186. def cmds = []
  187. if (cmd.scale == 0) {
  188. result = [name: "energy", value: cmd.scaledMeterValue, unit: "kWh"]
  189. } else if (cmd.scale == 1) {
  190. result = [name: "energy", value: cmd.scaledMeterValue, unit: "kVAh"]
  191. } else {
  192. result = [name: "power", value: cmd.scaledMeterValue, unit: "W"]
  193. }
  194. if (ep) {
  195. def childDevice = childDevices.find{it.deviceNetworkId == "$device.deviceNetworkId-ep$ep"}
  196. if (childDevice)
  197. childDevice.sendEvent(result)
  198. def combinedValue = 0.00
  199. childDevices.each {
  200. if(it.currentValue(result.name)) combinedValue += it.currentValue(result.name)
  201. }
  202. return createEvent([name: result.name, value: combinedValue])
  203. } else {
  204. (1..2).each { endpoint ->
  205. cmds << encap(zwave.meterV2.meterGet(scale: 0), endpoint)
  206. cmds << encap(zwave.meterV2.meterGet(scale: 2), endpoint)
  207. }
  208. return response(commands(cmds))
  209. }
  210. }
  211.  
  212. def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCapabilityReport cmd)
  213. {
  214. //log.debug "multichannelv3.MultiChannelCapabilityReport $cmd"
  215. if (cmd.endPoint == 2 ) {
  216. def currstate = device.currentState("switch2").getValue()
  217. if (currstate == "on")
  218. sendEvent(name: "switch2", value: "off", isStateChange: true, display: false)
  219. else if (currstate == "off")
  220. sendEvent(name: "switch2", value: "on", isStateChange: true, display: false)
  221. }
  222. else if (cmd.endPoint == 1 ) {
  223. def currstate = device.currentState("switch1").getValue()
  224. if (currstate == "on")
  225. sendEvent(name: "switch1", value: "off", isStateChange: true, display: false)
  226. else if (currstate == "off")
  227. sendEvent(name: "switch1", value: "on", isStateChange: true, display: false)
  228. }
  229. }
  230.  
  231. def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
  232. //logging("MultiChannelCmdEncap ${cmd}")
  233. def encapsulatedCommand = cmd.encapsulatedCommand([0x32: 3, 0x25: 1, 0x20: 1])
  234. if (encapsulatedCommand) {
  235. zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
  236. }
  237. }
  238.  
  239. def zwaveEvent(physicalgraph.zwave.commands.associationv2.AssociationReport cmd) {
  240. log.debug "AssociationReport $cmd"
  241. if (zwaveHubNodeId in cmd.nodeId) state."association${cmd.groupingIdentifier}" = true
  242. else state."association${cmd.groupingIdentifier}" = false
  243. }
  244.  
  245. def zwaveEvent(physicalgraph.zwave.commands.multichannelassociationv2.MultiChannelAssociationReport cmd) {
  246. log.debug "MultiChannelAssociationReport $cmd"
  247. if (cmd.groupingIdentifier == 1) {
  248. if ([0,zwaveHubNodeId,1] == cmd.nodeId) state."associationMC${cmd.groupingIdentifier}" = true
  249. else state."associationMC${cmd.groupingIdentifier}" = false
  250. }
  251. }
  252.  
  253. def zwaveEvent(physicalgraph.zwave.Command cmd) {
  254. log.debug "Unhandled event $cmd"
  255. // This will capture any commands not handled by other instances of zwaveEvent
  256. // and is recommended for development so you can see every command the device sends
  257. return createEvent(descriptionText: "${device.displayName}: ${cmd}")
  258. }
  259.  
  260. def zwaveEvent(physicalgraph.zwave.commands.switchallv1.SwitchAllReport cmd) {
  261. log.debug "SwitchAllReport $cmd"
  262. }
  263.  
  264. def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
  265. update_current_properties(cmd)
  266. logging("${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd2Integer(cmd.configurationValue)}'")
  267. }
  268.  
  269. def refresh() {
  270. def cmds = []
  271. (1..2).each { endpoint ->
  272. cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), endpoint)
  273. cmds << encap(zwave.meterV2.meterGet(scale: 0), endpoint)
  274. cmds << encap(zwave.meterV2.meterGet(scale: 2), endpoint)
  275. }
  276. commands(cmds, 1000)
  277. }
  278.  
  279. def reset() {
  280. logging("reset()")
  281. def cmds = []
  282. (1..2).each { endpoint ->
  283. cmds << encap(zwave.meterV2.meterReset(), endpoint)
  284. cmds << encap(zwave.meterV2.meterGet(scale: 0), endpoint)
  285. cmds << encap(zwave.meterV2.meterGet(scale: 2), endpoint)
  286. }
  287. commands(cmds, 1000)
  288. }
  289.  
  290. def ping() {
  291. def cmds = []
  292. cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 1)
  293. cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
  294. commands(cmds, 1000)
  295. }
  296.  
  297. def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
  298. def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
  299. log.debug "msr: $msr"
  300. updateDataValue("MSR", msr)
  301. }
  302.  
  303. def poll() {
  304. def cmds = []
  305. cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 1)
  306. cmds << encap(zwave.switchBinaryV1.switchBinaryGet(), 2)
  307. commands(cmds, 1000)
  308. }
  309.  
  310. def configure() {
  311. state.enableDebugging = settings.enableDebugging
  312. logging("Configuring Device For SmartThings Use")
  313. def cmds = []
  314.  
  315. cmds = update_needed_settings()
  316.  
  317. if (cmds != []) commands(cmds)
  318. }
  319.  
  320. def zwaveEvent(physicalgraph.zwave.commands.centralscenev1.CentralSceneNotification cmd) {
  321. logging("CentralSceneNotification: $cmd")
  322. logging("sceneNumber: $cmd.sceneNumber")
  323. logging("sequenceNumber: $cmd.sequenceNumber")
  324. logging("keyAttributes: $cmd.keyAttributes")
  325.  
  326. buttonEvent(cmd.keyAttributes + 1, (cmd.sceneNumber == 1? "pushed" : "held"))
  327.  
  328. }
  329.  
  330. def buttonEvent(button, value) {
  331. logging("buttonEvent() Button:$button, Value:$value")
  332. createEvent(name: "button", value: value, data: [buttonNumber: button], descriptionText: "$device.displayName button $button was $value", isStateChange: true)
  333. }
  334.  
  335. /**
  336. * Triggered when Done button is pushed on Preference Pane
  337. */
  338. def updated()
  339. {
  340. state.enableDebugging = settings.enableDebugging
  341. logging("updated() is being called")
  342. if (!childDevices) {
  343. createChildDevices()
  344. }
  345. else if (device.label != state.oldLabel) {
  346. childDevices.each {
  347. if (it.label == "${state.oldLabel} (S${channelNumber(it.deviceNetworkId)})") {
  348. def newLabel = "${device.displayName} (S${channelNumber(it.deviceNetworkId)})"
  349. it.setLabel(newLabel)
  350. }
  351. }
  352. state.oldLabel = device.label
  353. }
  354. sendEvent(name: "checkInterval", value: 2 * 30 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
  355. def cmds = update_needed_settings()
  356.  
  357. sendEvent(name:"needUpdate", value: device.currentValue("needUpdate"), displayed:false, isStateChange: true)
  358.  
  359. if (cmds != []) response(commands(cmds))
  360. }
  361.  
  362. def on() {
  363. commands([
  364. encap(zwave.basicV1.basicSet(value: 0xFF), 1),
  365. encap(zwave.basicV1.basicSet(value: 0xFF), 2)
  366. ])
  367. }
  368. def off() {
  369. commands([
  370. encap(zwave.basicV1.basicSet(value: 0x00), 1),
  371. encap(zwave.basicV1.basicSet(value: 0x00), 2)
  372. ])
  373. }
  374.  
  375. void childOn(String dni) {
  376. logging("childOn($dni)")
  377. def cmds = []
  378. cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0xFF), channelNumber(dni))))
  379. sendHubCommand(cmds, 1000)
  380. }
  381.  
  382. void childOff(String dni) {
  383. logging("childOff($dni)")
  384. def cmds = []
  385. cmds << new physicalgraph.device.HubAction(command(encap(zwave.basicV1.basicSet(value: 0x00), channelNumber(dni))))
  386. sendHubCommand(cmds, 1000)
  387. }
  388.  
  389. void childRefresh(String dni) {
  390. logging("childRefresh($dni)")
  391. def cmds = []
  392. cmds << new physicalgraph.device.HubAction(command(encap(zwave.switchBinaryV1.switchBinaryGet(), channelNumber(dni))))
  393. cmds << new physicalgraph.device.HubAction(command(encap(zwave.meterV2.meterGet(scale: 0), channelNumber(dni))))
  394. cmds << new physicalgraph.device.HubAction(command(encap(zwave.meterV2.meterGet(scale: 2), channelNumber(dni))))
  395. sendHubCommand(cmds, 1000)
  396. }
  397.  
  398. void childReset(String dni) {
  399. logging("childReset($dni)")
  400. def cmds = []
  401. cmds << new physicalgraph.device.HubAction(command(encap(zwave.meterV2.meterReset(), channelNumber(dni))))
  402. cmds << new physicalgraph.device.HubAction(command(encap(zwave.meterV2.meterGet(scale: 0), channelNumber(dni))))
  403. cmds << new physicalgraph.device.HubAction(command(encap(zwave.meterV2.meterGet(scale: 2), channelNumber(dni))))
  404. sendHubCommand(cmds, 1000)
  405. }
  406.  
  407. private encap(cmd, endpoint) {
  408. if (endpoint) {
  409. zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint:endpoint).encapsulate(cmd)
  410. } else {
  411. cmd
  412. }
  413. }
  414.  
  415. def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
  416. state.sec = 1
  417. def encapsulatedCommand = cmd.encapsulatedCommand([0x20: 1, 0x32: 3, 0x25: 1, 0x98: 1, 0x70: 2, 0x85: 2, 0x9B: 1, 0x90: 1, 0x73: 1, 0x30: 1, 0x28: 1, 0x2B: 1]) // can specify command class versions here like in zwave.parse
  418. if (encapsulatedCommand) {
  419. return zwaveEvent(encapsulatedCommand)
  420. } else {
  421. log.warn "Unable to extract encapsulated cmd from $cmd"
  422. createEvent(descriptionText: cmd.toString())
  423. }
  424. }
  425.  
  426. def generate_preferences(configuration_model)
  427. {
  428. def configuration = parseXml(configuration_model)
  429.  
  430. configuration.Value.each
  431. {
  432. switch(it.@type)
  433. {
  434. case ["byte","short","four"]:
  435. input "${it.@index}", "number",
  436. title:"${it.@label}\n" + "${it.Help}",
  437. range: "${it.@min}..${it.@max}",
  438. defaultValue: "${it.@value}",
  439. displayDuringSetup: "${it.@displayDuringSetup}"
  440. break
  441. case "list":
  442. def items = []
  443. it.Item.each { items << ["${it.@value}":"${it.@label}"] }
  444. input "${it.@index}", "enum",
  445. title:"${it.@label}\n" + "${it.Help}",
  446. defaultValue: "${it.@value}",
  447. displayDuringSetup: "${it.@displayDuringSetup}",
  448. options: items
  449. break
  450. case "decimal":
  451. input "${it.@index}", "decimal",
  452. title:"${it.@label}\n" + "${it.Help}",
  453. range: "${it.@min}..${it.@max}",
  454. defaultValue: "${it.@value}",
  455. displayDuringSetup: "${it.@displayDuringSetup}"
  456. break
  457. case "boolean":
  458. input "${it.@index}", "boolean",
  459. title: it.@label != "" ? "${it.@label}\n" + "${it.Help}" : "" + "${it.Help}",
  460. defaultValue: "${it.@value}",
  461. displayDuringSetup: "${it.@displayDuringSetup}"
  462. break
  463. case "paragraph":
  464. input title: "${it.@label}",
  465. description: "${it.Help}",
  466. type: "paragraph",
  467. element: "paragraph"
  468. break
  469. }
  470. }
  471. }
  472.  
  473. def update_current_properties(cmd)
  474. {
  475. def currentProperties = state.currentProperties ?: [:]
  476.  
  477. currentProperties."${cmd.parameterNumber}" = cmd.configurationValue
  478.  
  479. if (settings."${cmd.parameterNumber}" != null)
  480. {
  481. if (convertParam(cmd.parameterNumber, settings."${cmd.parameterNumber}") == cmd2Integer(cmd.configurationValue))
  482. {
  483. sendEvent(name:"needUpdate", value:"NO", displayed:false, isStateChange: true)
  484. }
  485. else
  486. {
  487. sendEvent(name:"needUpdate", value:"YES", displayed:false, isStateChange: true)
  488. }
  489. }
  490.  
  491. state.currentProperties = currentProperties
  492. }
  493.  
  494. def update_needed_settings()
  495. {
  496. def cmds = []
  497. def currentProperties = state.currentProperties ?: [:]
  498.  
  499. def configuration = parseXml(configuration_model())
  500. def isUpdateNeeded = "NO"
  501.  
  502. sendEvent(name:"numberOfButtons", value:"5")
  503.  
  504. if(!state.associationMC1) {
  505. logging("Adding MultiChannel association group 1")
  506. cmds << zwave.associationV2.associationRemove(groupingIdentifier: 1, nodeId: [])
  507. cmds << zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier: 1, nodeId: [0,zwaveHubNodeId,1])
  508. cmds << zwave.multiChannelAssociationV2.multiChannelAssociationGet(groupingIdentifier: 1)
  509. }
  510. if(state.association2){
  511. logging("Removing association group 2")
  512. cmds << zwave.associationV2.associationRemove(groupingIdentifier:2, nodeId:zwaveHubNodeId)
  513. cmds << zwave.associationV2.associationGet(groupingIdentifier:2)
  514. }
  515. if(state.association4){
  516. logging("Removing association group 4")
  517. cmds << zwave.associationV2.associationRemove(groupingIdentifier:4, nodeId:zwaveHubNodeId)
  518. cmds << zwave.associationV2.associationGet(groupingIdentifier:4)
  519. }
  520.  
  521. configuration.Value.each
  522. {
  523. if ("${it.@setting_type}" == "zwave"){
  524. if (currentProperties."${it.@index}" == null)
  525. {
  526. isUpdateNeeded = "YES"
  527. logging("Current value of parameter ${it.@index} is unknown")
  528. cmds << zwave.configurationV1.configurationGet(parameterNumber: it.@index.toInteger())
  529. }
  530. else if (settings."${it.@index}" != null && cmd2Integer(currentProperties."${it.@index}") != convertParam(it.@index.toInteger(), settings."${it.@index}"))
  531. {
  532. isUpdateNeeded = "YES"
  533.  
  534. logging("Parameter ${it.@index} will be updated to " + convertParam(it.@index.toInteger(), settings."${it.@index}"))
  535. def convertedConfigurationValue = convertParam(it.@index.toInteger(), settings."${it.@index}")
  536. cmds << zwave.configurationV1.configurationSet(configurationValue: integer2Cmd(convertedConfigurationValue, it.@byteSize.toInteger()), parameterNumber: it.@index.toInteger(), size: it.@byteSize.toInteger())
  537. cmds << zwave.configurationV1.configurationGet(parameterNumber: it.@index.toInteger())
  538. }
  539. }
  540. }
  541.  
  542. sendEvent(name:"needUpdate", value: isUpdateNeeded, displayed:false, isStateChange: true)
  543. return cmds
  544. }
  545.  
  546. def convertParam(number, value) {
  547. def parValue
  548. switch (number){
  549. case 28:
  550. parValue = (value == "true" ? 1 : 0)
  551. parValue += (settings."fc_2" == "true" ? 2 : 0)
  552. parValue += (settings."fc_3" == "true" ? 4 : 0)
  553. parValue += (settings."fc_4" == "true" ? 8 : 0)
  554. break
  555. case 29:
  556. parValue = (value == "true" ? 1 : 0)
  557. parValue += (settings."sc_2" == "true" ? 2 : 0)
  558. parValue += (settings."sc_3" == "true" ? 4 : 0)
  559. parValue += (settings."sc_4" == "true" ? 8 : 0)
  560. break
  561. default:
  562. parValue = value
  563. break
  564. }
  565. return parValue.toInteger()
  566. }
  567.  
  568. private def logging(message) {
  569. if (state.enableDebugging == null || state.enableDebugging == "true") log.debug "$message"
  570. }
  571.  
  572. /**
  573. * Convert 1 and 2 bytes values to integer
  574. */
  575. def cmd2Integer(array) {
  576.  
  577. switch(array.size()) {
  578. case 1:
  579. array[0]
  580. break
  581. case 2:
  582. ((array[0] & 0xFF) << 8) | (array[1] & 0xFF)
  583. break
  584. case 3:
  585. ((array[0] & 0xFF) << 16) | ((array[1] & 0xFF) << 8) | (array[2] & 0xFF)
  586. break
  587. case 4:
  588. ((array[0] & 0xFF) << 24) | ((array[1] & 0xFF) << 16) | ((array[2] & 0xFF) << 8) | (array[3] & 0xFF)
  589. break
  590. }
  591. }
  592.  
  593. def integer2Cmd(value, size) {
  594. switch(size) {
  595. case 1:
  596. [value]
  597. break
  598. case 2:
  599. def short value1 = value & 0xFF
  600. def short value2 = (value >> 8) & 0xFF
  601. [value2, value1]
  602. break
  603. case 3:
  604. def short value1 = value & 0xFF
  605. def short value2 = (value >> 8) & 0xFF
  606. def short value3 = (value >> 16) & 0xFF
  607. [value3, value2, value1]
  608. break
  609. case 4:
  610. def short value1 = value & 0xFF
  611. def short value2 = (value >> 8) & 0xFF
  612. def short value3 = (value >> 16) & 0xFF
  613. def short value4 = (value >> 24) & 0xFF
  614. [value4, value3, value2, value1]
  615. break
  616. }
  617. }
  618.  
  619. private command(physicalgraph.zwave.Command cmd) {
  620. if (state.sec) {
  621. zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
  622. } else {
  623. cmd.format()
  624. }
  625. }
  626.  
  627. private commands(commands, delay=1000) {
  628. delayBetween(commands.collect{ command(it) }, delay)
  629. }
  630.  
  631. def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd) {
  632. def versions = [0x31: 5, 0x30: 1, 0x9C: 1, 0x70: 2, 0x85: 2]
  633. def version = versions[cmd.commandClass as Integer]
  634. def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
  635. def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
  636. if (encapsulatedCommand) {
  637. zwaveEvent(encapsulatedCommand)
  638. }
  639. }
  640.  
  641. private channelNumber(String dni) {
  642. dni.split("-ep")[-1] as Integer
  643. }
  644.  
  645. private void createChildDevices() {
  646. state.oldLabel = device.label
  647. try {
  648. for (i in 1..2) {
  649. addChildDevice("Metering Switch Child Device", "${device.deviceNetworkId}-ep${i}", null,
  650. [completedSetup: true, label: "${device.displayName} (S${i})",
  651. isComponent: false, componentName: "ep$i", componentLabel: "Switch $i"])
  652. }
  653. } catch (e) {
  654. runIn(2, "sendAlert")
  655. }
  656. }
  657.  
  658. private sendAlert() {
  659. sendEvent(
  660. descriptionText: "Child device creation failed. Please make sure that the \"Metering Switch Child Device\" is installed and published.",
  661. eventType: "ALERT",
  662. name: "childDeviceCreation",
  663. value: "failed",
  664. displayed: true,
  665. )
  666. }
  667.  
  668. def configuration_model()
  669. {
  670. '''
  671. <configuration>
  672. <Value type="list" byteSize="1" index="9" label="State of the device after a power failure" min="0" max="1" value="1" setting_type="zwave" fw="">
  673. <Help>
  674. The device will return to the last state before power failure.
  675. 0 - the Dimmer 2 does not save the state before a power failure, it returns to the "off" position
  676. 1 - the Dimmer 2 restores its state before power failure
  677. Range: 0~1
  678. Default: 1 (Previous State)
  679. </Help>
  680. <Item label="Off" value="0" />
  681. <Item label="Previous State" value="1" />
  682. </Value>
  683. <Value type="list" byteSize="1" index="10" label="First Channel - Operating Mode" min="0" max="5" value="0" setting_type="zwave" fw="">
  684. <Help>
  685. This parameter allows you to choose the operating mode for the 1st channel controlled by the S1 switch.
  686. Range: 0~5
  687. Default: 0 (Standard)
  688. </Help>
  689. <Item label="Standard" value="0" />
  690. <Item label="Delay On" value="1" />
  691. <Item label="Delay Off" value="2" />
  692. <Item label="Auto On" value="3" />
  693. <Item label="Auto Off" value="4" />
  694. <Item label="Flashing" value="5" />
  695. </Value>
  696. <Value type="list" byteSize="1" index="11" label="First Channel - Reaction For Delay/Auto" min="0" max="2" value="0" setting_type="zwave" fw="">
  697. <Help>
  698. This parameter determines how the device in timed mode reacts to pushing the switch connected to the S1 terminal.
  699. Range: 0~2
  700. Default: 0 (Cancel)
  701. </Help>
  702. <Item label="Cancel" value="0" />
  703. <Item label="No Reaction" value="1" />
  704. <Item label="Reset" value="2" />
  705. </Value>
  706. <Value type="byte" byteSize="2" index="12" label="First Channel - Time Parameter for Delay/Auto" min="0" max="32000" value="50" setting_type="zwave" fw="">
  707. <Help>
  708. This parameter allows to set time parameter used in timed modes.
  709. Range: 0~32000 (0.1s, 1-32000s)
  710. Default: 50
  711. </Help>
  712. </Value>
  713. <Value type="byte" byteSize="2" index="13" label="First Channel - Pulse Time For Flashing" min="1" max="32000" value="5" setting_type="zwave" fw="">
  714. <Help>
  715. This parameter allows to set time of switching to opposite state in flashing mode.
  716. Range: 1~32000 (0.1s-3200.0s)
  717. Default: 5 (0.5s)
  718. </Help>
  719. </Value>
  720. <Value type="list" byteSize="1" index="15" label="Second Channel - Operating Mode" min="0" max="5" value="0" setting_type="zwave" fw="">
  721. <Help>
  722. This parameter allows you to choose the operating mode for the 2nd channel controlled by the S2 switch.
  723. Range: 0~5
  724. Default: 0 (Standard)
  725. </Help>
  726. <Item label="Standard" value="0" />
  727. <Item label="Delay On" value="1" />
  728. <Item label="Delay Off" value="2" />
  729. <Item label="Auto On" value="3" />
  730. <Item label="Auto Off" value="4" />
  731. <Item label="Flashing" value="5" />
  732. </Value>
  733. <Value type="list" byteSize="1" index="16" label="Second Channel - Reaction For Delay/Auto" min="0" max="2" value="0" setting_type="zwave" fw="">
  734. <Help>
  735. This parameter determines how the device in timed mode reacts to pushing the switch connected to the S2 terminal.
  736. Range: 0~2
  737. Default: 0 (Cancel)
  738. </Help>
  739. <Item label="Cancel" value="0" />
  740. <Item label="No Reaction" value="1" />
  741. <Item label="Reset" value="2" />
  742. </Value>
  743. <Value type="byte" byteSize="2" index="17" label="Second Channel - Time Parameter for Delay/Auto" min="0" max="32000" value="50" setting_type="zwave" fw="">
  744. <Help>
  745. This parameter allows to set time parameter used in timed modes.
  746. Range: 0~32000 (0.1s, 1-32000s)
  747. Default: 50
  748. </Help>
  749. </Value>
  750. <Value type="byte" byteSize="2" index="18" label="Second Channel - Pulse Time For Flashing" min="1" max="32000" value="5" setting_type="zwave" fw="">
  751. <Help>
  752. This parameter allows to set time of switching to opposite state in flashing mode.
  753. Range: 1~32000 (0.1s-3200.0s)
  754. Default: 5 (0.5s)
  755. </Help>
  756. </Value>
  757. <Value type="list" byteSize="1" index="20" label="Switch type" min="0" max="2" value="2" setting_type="zwave" fw="">
  758. <Help>
  759. Choose between momentary and toggle switch.
  760. Range: 0~2
  761. Default: 2 (Toggle)
  762. </Help>
  763. <Item label="Momentary" value="0" />
  764. <Item label="Toggle (Open=On, Closed=Off)" value="1" />
  765. <Item label="Toggle (On Switch Change)" value="2" />
  766. </Value>
  767. <Value type="list" byteSize="1" index="40" label="Reaction to General Alarm" min="0" max="3" value="3" setting_type="zwave" fw="">
  768. <Help>
  769. This parameter determines how the device will react to General Alarm frame.
  770. Range: 0~3
  771. Default: 3 (Flash)
  772. </Help>
  773. <Item label="Alarm frame is ignored" value="0" />
  774. <Item label="Turn ON after receiving the alarm frame" value="1" />
  775. <Item label="Turn OFF after receiving the alarm frame" value="2" />
  776. <Item label="Flash after receiving the alarm frame" value="3" />
  777. </Value>
  778. <Value type="list" byteSize="1" index="41" label="Reaction to Flood Alarm" min="0" max="3" value="2" setting_type="zwave" fw="">
  779. <Help>
  780. This parameter determines how the device will react to Flood Alarm frame.
  781. Range: 0~3
  782. Default: 2 (OFF)
  783. </Help>
  784. <Item label="Alarm frame is ignored" value="0" />
  785. <Item label="Turn ON after receiving the alarm frame" value="1" />
  786. <Item label="Turn OFF after receiving the alarm frame" value="2" />
  787. <Item label="Flash after receiving the alarm frame" value="3" />
  788. </Value>
  789. <Value type="list" byteSize="1" index="42" label="Reaction to CO/CO2/Smoke Alarm" min="0" max="3" value="3" setting_type="zwave" fw="">
  790. <Help>
  791. This parameter determines how the device will react to CO, CO2 or Smoke frame.
  792. Range: 0~3
  793. Default: 3 (Flash)
  794. </Help>
  795. <Item label="Alarm frame is ignored" value="0" />
  796. <Item label="Turn ON after receiving the alarm frame" value="1" />
  797. <Item label="Turn OFF after receiving the alarm frame" value="2" />
  798. <Item label="Flash after receiving the alarm frame" value="3" />
  799. </Value>
  800. <Value type="list" byteSize="1" index="43" label="Reaction to Heat Alarm" min="0" max="3" value="1" setting_type="zwave" fw="">
  801. <Help>
  802. This parameter determines how the device will react to Heat Alarm frame.
  803. Range: 0~3
  804. Default: 1 (ON)
  805. </Help>
  806. <Item label="Alarm frame is ignored" value="0" />
  807. <Item label="Turn ON after receiving the alarm frame" value="1" />
  808. <Item label="Turn OFF after receiving the alarm frame" value="2" />
  809. <Item label="Flash after receiving the alarm frame" value="3" />
  810. </Value>
  811. <Value type="byte" byteSize="2" index="44" label="Flashing alarm duration" min="1" max="32000" value="600" setting_type="zwave" fw="">
  812. <Help>
  813. This parameter allows to set duration of flashing alarm mode.
  814. Range: 1~32000 (1s-32000s)
  815. Default: 600 (10 min)
  816. </Help>
  817. </Value>
  818. <Value type="byte" byteSize="1" index="50" label="First Channel - Active power reports" min="0" max="100" value="10" setting_type="zwave" fw="">
  819. <Help>
  820. The parameter defines the power level change that will result in a new power report being sent. The value is a percentage of the previous report.
  821. Range: 0~100 (1-100%)
  822. Default: 10
  823. </Help>
  824. </Value>
  825. <Value type="byte" byteSize="1" index="51" label="First Channel - Periodic active power and energy reports" min="0" max="120" value="10" setting_type="zwave" fw="">
  826. <Help>
  827. Parameter 51 defines a time period between consecutive reports. Timer is reset and counted from zero after each report.
  828. Range: 0~120 (1-120s)
  829. Default: 10
  830. </Help>
  831. </Value>
  832. <Value type="short" byteSize="2" index="53" label="First Channel - Energy reports" min="0" max="32000" value="100" setting_type="zwave" fw="">
  833. <Help>
  834. Energy level change which will result in sending a new energy report.
  835. Range: 0~32000 (0.01-320 kWh)
  836. Default: 100
  837. </Help>
  838. </Value>
  839. <Value type="byte" byteSize="1" index="54" label="Second Channel - Active power reports" min="0" max="100" value="10" setting_type="zwave" fw="">
  840. <Help>
  841. The parameter defines the power level change that will result in a new power report being sent. The value is a percentage of the previous report.
  842. Range: 0~100 (1-100%)
  843. Default: 10
  844. </Help>
  845. </Value>
  846. <Value type="byte" byteSize="1" index="55" label="Second Channel - Periodic active power and energy reports" min="0" max="120" value="10" setting_type="zwave" fw="">
  847. <Help>
  848. Parameter 55 defines a time period between consecutive reports. Timer is reset and counted from zero after each report.
  849. Range: 0~120 (1-120s)
  850. Default: 10
  851. </Help>
  852. </Value>
  853. <Value type="short" byteSize="2" index="57" label="Second Channel - Energy reports" min="0" max="32000" value="100" setting_type="zwave" fw="">
  854. <Help>
  855. Energy level change which will result in sending a new energy report.
  856. Range: 0~32000 (0.01-320 kWh)
  857. Default: 100
  858. </Help>
  859. </Value>
  860. <Value type="byte" byteSize="2" index="58" label="Periodic power reports" min="0" max="32000" value="3600" setting_type="zwave" fw="">
  861. <Help>
  862. This parameter determines in what time interval the periodic power reports are sent to the main controller.
  863. Range: 0~32000 (1-32000s)
  864. Default: 3600
  865. </Help>
  866. </Value>
  867. <Value type="byte" byteSize="2" index="59" label="Periodic energy reports" min="0" max="32000" value="3600" setting_type="zwave" fw="">
  868. <Help>
  869. This parameter determines in what time interval the periodic energy reports are sent to the main controller.
  870. Range: 0~32000 (1-32000s)
  871. Default: 3600
  872. </Help>
  873. </Value>
  874. <Value type="boolean" byteSize="1" index="28" label="First Channel" value="false" setting_type="zwave" fw="">
  875. <Help>
  876. Send scene ID on single press
  877. </Help>
  878. </Value>
  879. <Value type="boolean" byteSize="1" index="fc_2" label="" value="false" setting_type="" fw="">
  880. <Help>
  881. Send scene ID on double press
  882. </Help>
  883. </Value>
  884. <Value type="boolean" byteSize="1" index="fc_3" label="" value="false" setting_type="" fw="">
  885. <Help>
  886. Send scene ID on tripple press
  887. </Help>
  888. </Value>
  889. <Value type="boolean" byteSize="1" index="fc_4" label="" value="false" setting_type="" fw="">
  890. <Help>
  891. Send scene ID on hold and release
  892. </Help>
  893. </Value>
  894. <Value type="boolean" byteSize="1" index="29" label="Second Channel" value="false" setting_type="zwave" fw="">
  895. <Help>
  896. Send scene ID on single press
  897. </Help>
  898. </Value>
  899. <Value type="boolean" byteSize="1" index="sc_2" label="" value="false" setting_type="" fw="">
  900. <Help>
  901. Send scene ID on double press
  902. </Help>
  903. </Value>
  904. <Value type="boolean" byteSize="1" index="sc_3" label="" value="false" setting_type="" fw="">
  905. <Help>
  906. Send scene ID on tripple press
  907. </Help>
  908. </Value>
  909. <Value type="boolean" byteSize="1" index="sc_4" label="" value="false" setting_type="" fw="">
  910. <Help>
  911. Send scene ID on hold and release
  912. </Help>
  913. </Value>
  914. <Value type="paragraph" byteSize="1" index="mappings" label="Button Mappings" value="false" setting_type="" fw="">
  915. <Help>
  916. Toggle Mode
  917. 1 pushed - S1 1x toggle
  918. 4 pushed - S1 2x toggle
  919. 5 pushed - S1 3x toggle
  920.  
  921. 1 held - S2 1x toggle
  922. 4 held - S2 2x toggle
  923. 5 held - S2 3x toggle
  924.  
  925. Momentary Mode
  926. 1 pushed - S1 1x click
  927. 2 pushed - S1 release
  928. 3 pushed - S1 hold
  929. 4 pushed - S1 2x click
  930. 5 pushed - S1 3x click
  931.  
  932. 1 held - S2 1x click
  933. 2 held - S2 release
  934. 3 held - S2 hold
  935. 4 held - S2 2x click
  936. 5 held - S2 3x click
  937. </Help>
  938. </Value>
  939. <Value type="boolean" index="enableDebugging" label="Enable Debug Logging?" value="true" setting_type="preference" fw="">
  940. <Help>
  941. </Help>
  942. </Value>
  943. </configuration>
  944. '''
  945. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement