diff --git a/devicetypes/smartthings/fibaro-dimmer-1.src/fibaro-dimmer-1.groovy b/devicetypes/smartthings/fibaro-dimmer-1.src/fibaro-dimmer-1.groovy new file mode 100644 index 0000000..e028885 --- /dev/null +++ b/devicetypes/smartthings/fibaro-dimmer-1.src/fibaro-dimmer-1.groovy @@ -0,0 +1,456 @@ +/** + * Device Type Definition File + * + * Device Type: Fibaro Dimmer + * File Name: fibaro-dimmer.groovy + * Initial Release: 2015-06-00 + * Author: SmartThings + * + * Copyright 2015 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 { + // Automatically generated. Make future change here. + definition (name: "Fibaro Dimmer 1", namespace: "smartthings", author: "SmartThings, Elnar Hajiyev") { + capability "Switch Level" + capability "Actuator" + capability "Switch" + capability "Polling" + capability "Refresh" + capability "Sensor" + capability "Configuration" + + //Extending Fibaro Dimmer 1 devices with scene attribute + attribute "scene", "number" + + command "configureParams" + + fingerprint deviceId: "0x1101", inClusters: "0x72,0x86,0x70,0x85,0x8E,0x26,0x7A,0x27,0x73,0xEF,0x26,0x2B" + } + + simulator { + status "on": "command: 2003, payload: FF" + status "off": "command: 2003, payload: 00" + status "09%": "command: 2003, payload: 09" + status "10%": "command: 2003, payload: 0A" + status "33%": "command: 2003, payload: 21" + status "66%": "command: 2003, payload: 42" + status "99%": "command: 2003, payload: 63" + + // reply messages + reply "2001FF,delay 5000,2602": "command: 2603, payload: FF" + reply "200100,delay 5000,2602": "command: 2603, payload: 00" + reply "200119,delay 5000,2602": "command: 2603, payload: 19" + reply "200132,delay 5000,2602": "command: 2603, payload: 32" + reply "20014B,delay 5000,2602": "command: 2603, payload: 4B" + reply "200163,delay 5000,2602": "command: 2603, payload: 63" + } + + tiles { + 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.switch.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn" + attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.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" + } + standardTile("configureParams", "device.configure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "configure", label:'', action:"configureParams", icon:"st.secondary.configure" + } + + main(["switch"]) + details(["switch", "refresh", + "levelSliderControl", + "configureParams" + ]) + } + + preferences { + input name: "param1", type: "enum", defaultValue: "255", required: true, + options: ["0" : "0", + "1" : "1", + "2" : "2", + "255" : "255"], + title: "1. Activate / deactivate functions ALL ON / ALL OFF.\n" + + "Available settings:\n" + + "0 = All ON not active, All OFF not active,\n" + + "1 = All ON not active, All OFF active,\n" + + "2 = All ON active, All OFF not active,\n" + + "255 = All ON active, All OFF active.\n" + + "Default value: 255." + + input name: "param6", type: "number", range: "0..2", defaultValue: "0", required: true, + title: "6. Sending commands to control devices assigned to 1st association group (key no. 1).\n" + + "Available settings:\n" + + "0 = commands are sent when device is turned on and off.\n" + + "1 = commands are sent when device is turned off. Enabling device does not send control commands. Double-clicking key sends 'turn on' command, dimmers memorize the last saved state (e.g. 50% brightness).\n" + + "2 = commands are sent when device is turned off. Enabling device does not send control commands. Double-clicking key sends 'turn on' command and dimmers are set to 100% brightness.\n" + + "Default value: 1.\n\n" + + "NOTE: Parameter 15 value must be set to 1 to work properly. This activates the double-click functionality - dimmer/roller shutter control." + + input name: "param7", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "7. Checking the device status before sending a control frame from the key no. 2.\n" + + "Available settings:\n" + + "0 = Device status is not checked.\n" + + "1 = Device status is checked.\n" + + "Default value: 1.\n\n" + + "Info: Key no. 2 is not represented by any physical device expect of devices on association list. " + + "This functionality prevents of lack of reaction on pressing key no. 2 through polling devices from list one by one and checking thier actual states.\n" + + "It is not possible to check the device status before sending a control frame from the key no. 2 if roller blind switch is chosen in parameter 14 (value 2)\n" + + "If devices state is checked before sending asociation then parameter 19 should be set to value 0." + + input name: "param8", type: "number", range: "1..99", defaultValue: "1", required: true, + title: "8. The percentage of a dimming step at automatic control.\n" + + "Available settings: 1-99\n" + + "Default value: 1." + + input name: "param9", type: "number", range: "1..255", defaultValue: "5", required: true, + title: "9. Time of manually moving the Dimmer between the extreme dimming values.\n" + + "Available settings: 1-255 (10ms – 2.5s)\n" + + "Default value: 5." + + input name: "param10", type: "number", range: "0..255", defaultValue: "1", required: true, + title: "10. Time of Automatic moving the Dimmer between the extreme dimming values.\n" + + "Available settings: 0-255 (0ms – 2.5s)\n" + + "0 - this value disables the smooth change in light intensity\n" + + "Default value: 1.\n\n" + + "NOTE value 0 is required for inductive and capacitive devices unsuitable for dimming, (e.g. fluorescent lamps , motors etc.)." + + input name: "param11", type: "number", range: "1..99", defaultValue: "1", required: true, + title: "11. The percentage of a dimming step at manual control.\n" + + "Available settings: 1-99\n" + + "Default value: 1." + + input name: "param12", type: "number", range: "2..99", defaultValue: "99", required: true, + title: "12. Maximum Dimmer level control.\n" + + "Available settings: 2-99\n" + + "Default value: 99." + + input name: "param13", type: "number", range: "1..98", defaultValue: "2", required: true, + title: "13. Minimum Dimmer level control\n" + + "Available settings: 1-98\n" + + "Default value: 2.\n\n" + + "NOTE: The maximum level may not be lower than the minimum level.\n" + + "Recommended values of parameters 12 and 13 (max and min level) for controlling the devices are as follows:\n" + + "- AC motors [min 60%, max 99%]\n" + + "- fluorescent lamps, fluorescent tubes, LED [min 98%, max 99%] [parameter 10 set to 0]" + + input name: "param14", type: "number", range: "0..2", defaultValue: "0", required: true, + title: "14. Switch type. Choose between momentary switch and toggle switch.\n" + + "Available settings:\n" + + "0 = momentary switch,\n" + + "1 = toggle switch,\n" + + "2 = Roller blind switch (UP / DOWN) - two switch keys operate the Dimmer.\n" + + "Default value: 0." + + input name: "param15", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "15. Double click option (set lightning at 100%).\n" + + "Available settings:\n" + + "0 = Double click disabled,\n" + + "1 = Double click enabled.\n" + + "Default value: 1." + + input name: "param16", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "16. Saving the state of the device after a power failure. The Dimmer will return to the last position before power failure.\n" + + "Available settings:\n" + + "0 = the Dimmer does not save the state after a power failure, it returns to 'off' position,\n" + + "1 = the Dimmer saves its state before power failure.\n" + + "Default value: 1." + + input name: "param17", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "17. The function of 3 - way switch, provides the option to double key no. 1. " + + "The Dimmer may control two toggle push-buttons or an infinite number of momentary push-buttons.\n" + + "Available settings:\n" + + "0 = the function of 3-way switch is disabled,\n" + + "1 = the function of 3-way switch is enabled.\n" + + "Default value: 0." + + input name: "param18", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "18. The function of synchronizing the light level for associated devices. The Dimmer communicates the position to the associated device.\n" + + "Available settings:\n" + + "0 = function disabled,\n" + + "1 = function enabled.\n" + + "Default value: 0." + + input name: "param19", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "19. Assigns bistable key status to the device status.\n" + + "Available settings:\n" + + "0 = [On / Off] device changes status on key status change.\n" + + "1 = Device status depends on key status: ON when the key is ON, OFF when the key is OFF.\n" + "Default value: 0.\n\n" + + "Info: Remote control from Fibaro System Is Still Possible. This function is useful When you want display status of external devices, e.g. Motion Sensor, in Fibaro System." + + input name: "param30", type: "number", range: "0..3", defaultValue: "3", required: true, + title: "30. Alarm of any type (general alarm, water flooding alarm, smoke alarm: CO, CO2, temperature alarm).\n" + + "Available settings:\n" + + "0 = DEACTIVATION - the device does not respond to alarm data frames,\n" + + "1 = ALARM DIMMER ON - the device turns on after detecting an alarm,\n" + + "2 = ALARM DIMMER OFF - the device turns off after detecting an alarm,\n" + + "3 = ALARM FLASHING the device periodically changes its status to the opposite, when it detects an alarm within 10 min." + "Default value: 3." + + input name: "param39", type: "number", range: "1..65535", defaultValue: "600", required: true, + title: "39. Active flashing alarm time.\n" + + "Available settings: [1-65535][ms]\n" + + "Default value: 600." + + input name: "param41", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "41. Scene activation functionality.\n" + + "The device offers the possibility of sending commands compatible with Command class scene activation. " + + "Information is sent to devices assigned to association group no. 3. " + + "Controllers such as Home Center 2 are able to interpret such commands and based on these commands they activate scenes, to which specific scene IDs have been assigned. " + + "The user may expand the functionality of the button connected to inputs S1 and S2 by distinguishing the actions of keys connected to those inputs. " + + "For example: double click would activate the scene “goodnight” and triple click would activate the scene “morning”.\n" + + "Available settings:\n" + + "0 = functionality deactivated,\n" + + "1 = functionality activated.\n" + + "Default value: 0.\n\n" + + "Scene ID is determined as follows:\n" + + "Momentary switch:\n" + + "Input S1: holding down ID 12 (option inactive in case of roller blind switch), " + + "releasing ID 13, double click ID 14 (depends on parameters 15 value - 1 = double click active), " + + "triple click ID 15, one click ID 16.\n" + + "Input S2: holding down ID 22 (option inactive in case of roller blind switch), " + + "releasing ID 23, double click ID 24 (depends on parameters 15 value - 1 = double click active) option inactive in case of roller blind switch, " + + "triple click ID 25, one click ID 26.\n\n" + + "Toggle switch:\n" + + "Input S1: holding down ID 12, releasing ID 13, double click ID 14 (depends on parameters 15 value - 1 = double click active), triple click ID 15. " + + "If parameter no. 19 is set to 0: single click ID16 is sent. If parameter no. 19 is set to 1 following IDs are sent: switch from “off” to “on” ID 10, switch from “on” to “off” ID 11.\n" + + "Input S2: holding down ID 22, releasing ID 23, double click ID 24, (depends on parameters 15 value - 1 = double click active), triple click ID 25. " + + "If parameter no.19 set to 0 (default), then one click ID 26 is sent. If parameter no.19 is set to 1 following IDs are sent: switch from “off” to “on” ID 20, switch from “on” to “off” ID 21.\n\n" + + "Roller blind switch:\n" + + "Input S1, Turning on the light: switch from “off” to “on” ID 10, double click ID 14 (depends of parameter 15 value 1 - double click functionality), " + + "triple click ID 15, brighten ID 17, releasing ID 13.\n" + + "Input S2, Turning off the light: switch from “on” to “off” ID 11, triple click ID 25, dim ID 18, releasing ID 13." + + input name: "param20", type: "number", range: "101..170", defaultValue: "110", required: true, + title: "ADVANCED FUNCTION\n\n" + + "20. The function enabling the change of control impulse length. " + + "This function will enable decreasing the minimum level of the Dimmer by extending the control impulse. " + + "By changing the minimum level, the user may completely dim LED bulbs. Not all LED bulbs available on the market have the dimming option.\n" + + "Available settings:\n" + + "Default values: 110 for 50Hz (UK), 101 for 60Hz (USA).\n\n"+ + "WARNING!\nWrong setting of the function may cause incorrect operation of the Dimmer." + + input name: "paramAssociationGroup1", type: "bool", defaultValue: false, required: true, + title: "The Dimmer 1 provides the association of three groups.\n\n" + + "1 = 1st group is assigned to key no. 1,\n" + + "Default value: true" + + input name: "paramAssociationGroup2", type: "bool", defaultValue: false, required: true, + title: "2nd group is assigned to key no. 2\n" + + "Default value: true" + + input name: "paramAssociationGroup3", type: "bool", defaultValue: true, required: true, + title: "3rd group for controllers such Home Center for state reporting,\n" + + "Default value: false" + } +} + +def parse(String description) { + def item1 = [ + canBeCurrentState: false, + linkText: getLinkText(device), + isStateChange: false, + displayed: false, + descriptionText: description, + value: description + ] + def result + def cmd = zwave.parse(description, [0x26: 1, 0x70: 2, 072: 2]) + //log.debug "cmd: ${cmd}" + + if (cmd) { + result = createEvent(cmd, item1) + } + else { + item1.displayed = displayed(description, item1.isStateChange) + result = [item1] + } + + if(result?.descriptionText) + log.debug "Parse returned ${result?.descriptionText}" + + result + +} + +def createEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd, Map map) { + log.debug( "Scene ID: $cmd.sceneId") + log.debug( "Dimming Duration: $cmd.dimmingDuration") + + sendEvent(name: "scene", value: "$cmd.sceneId", data: [switchType: "$settings.param20"], descriptionText: "Scene id $cmd.sceneId was activated", isStateChange: true) + log.debug( "Scene id $cmd.sceneId was activated" ) +} + +def createEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, Map item1) { + def result = doCreateEvent(cmd, item1) + for (int i = 0; i < result.size(); i++) { + result[i].type = "physical" + } + result +} + +def createEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd, Map item1) { + def result = doCreateEvent(cmd, item1) + for (int i = 0; i < result.size(); i++) { + result[i].type = "physical" + } + result +} + +def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelStartLevelChange cmd, Map item1) { + [] +} + +def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelStopLevelChange cmd, Map item1) { + [response(zwave.basicV1.basicGet())] +} + +def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelSet cmd, Map item1) { + def result = doCreateEvent(cmd, item1) + for (int i = 0; i < result.size(); i++) { + result[i].type = "physical" + } + result +} + +def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelReport cmd, Map item1) { + def result = doCreateEvent(cmd, item1) + result[0].descriptionText = "${item1.linkText} is ${item1.value}" + result[0].handlerName = cmd.value ? "statusOn" : "statusOff" + for (int i = 0; i < result.size(); i++) { + result[i].type = "digital" + } + result +} + +def doCreateEvent(physicalgraph.zwave.Command cmd, Map item1) { + def result = [item1] + + item1.name = "switch" + item1.value = cmd.value ? "on" : "off" + item1.handlerName = item1.value + item1.descriptionText = "${item1.linkText} was turned ${item1.value}" + item1.canBeCurrentState = true + item1.isStateChange = isStateChange(device, item1.name, item1.value) + item1.displayed = item1.isStateChange + + if (cmd.value >= 5) { + def item2 = new LinkedHashMap(item1) + item2.name = "level" + item2.value = cmd.value as String + item2.unit = "%" + item2.descriptionText = "${item1.linkText} dimmed ${item2.value} %" + item2.canBeCurrentState = true + item2.isStateChange = isStateChange(device, item2.name, item2.value) + item2.displayed = false + result << item2 + } + result +} + +def createEvent(physicalgraph.zwave.Command cmd, Map map) { + // Handles any Z-Wave commands we aren't interested in + log.debug "UNHANDLED COMMAND $cmd" +} + +def on() { + log.info "on" + delayBetween([zwave.basicV1.basicSet(value: 0xFF).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000) +} + +def off() { + delayBetween ([zwave.basicV1.basicSet(value: 0x00).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000) +} + +def setLevel(value) { + def level = Math.min(value as Integer, 99) + delayBetween ([zwave.basicV1.basicSet(value: level).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000) +} + +def setLevel(value, duration) { + def level = Math.min(value as Integer, 99) + def dimmingDuration = duration < 128 ? duration : 128 + Math.round(duration / 60) + zwave.switchMultilevelV2.switchMultilevelSet(value: level, dimmingDuration: dimmingDuration).format() +} + +def poll() { + zwave.switchMultilevelV1.switchMultilevelGet().format() +} + +def refresh() { + zwave.switchMultilevelV1.switchMultilevelGet().format() +} + +def createEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd, Map item1) { + + log.debug "${device.displayName} parameter '${cmd.parameterNumber}' with a byte size of '${cmd.size}' is set to '${cmd.configurationValue}'" + +} + + def configureParams() { + log.debug "Configuring ${device.displayName} parameters" + def cmds = [] + cmds << zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, scaledConfigurationValue: param1.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 6, size: 1, scaledConfigurationValue: param6.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 7, size: 1, scaledConfigurationValue: param7.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: param8.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 9, size: 1, scaledConfigurationValue: param9.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 10, size: 1, scaledConfigurationValue: param10.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 11, size: 1, scaledConfigurationValue: param11.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 13, size: 1, scaledConfigurationValue: param13.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 15, size: 1, scaledConfigurationValue: param15.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 16, size: 1, scaledConfigurationValue: param16.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 19, size: 1, scaledConfigurationValue: param19.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 20, size: 1, scaledConfigurationValue: param20.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 30, size: 1, scaledConfigurationValue: param30.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 39, size: 1, scaledConfigurationValue: param39.toInteger()).format() + cmds << zwave.configurationV1.configurationSet(parameterNumber: 41, size: 1, scaledConfigurationValue: param41.toInteger()).format() + + // Register for Group 1 + if(paramAssociationGroup1) { + cmds << zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId]).format() + } + else { + cmds << zwave.associationV2.associationRemove(groupingIdentifier:1, nodeId: [zwaveHubNodeId]).format() + } + // Register for Group 2 + if(paramAssociationGroup2) { + cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId: [zwaveHubNodeId]).format() + } + else { + cmds << zwave.associationV2.associationRemove(groupingIdentifier:2, nodeId: [zwaveHubNodeId]).format() + } + // Register for Group 3 + if(paramAssociationGroup3) { + cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId: [zwaveHubNodeId]).format() + } + else { + cmds << zwave.associationV2.associationRemove(groupingIdentifier:3, nodeId: [zwaveHubNodeId]).format() + } + + delayBetween(cmds, 500) +} + +def updated() { + log.debug "updated()" + response(["delay 2000"] + configureParams() + refresh()) +} \ No newline at end of file diff --git a/devicetypes/smartthings/fibaro-dimmer-2.src/fibaro-dimmer-2.groovy b/devicetypes/smartthings/fibaro-dimmer-2.src/fibaro-dimmer-2.groovy new file mode 100644 index 0000000..4717086 --- /dev/null +++ b/devicetypes/smartthings/fibaro-dimmer-2.src/fibaro-dimmer-2.groovy @@ -0,0 +1,787 @@ +/** + * Copyright 2015 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: "Fibaro Dimmer 2", namespace: "smartthings", author: "Rajiv, Elnar Hajiyev") { + capability "Energy Meter" + capability "Actuator" + capability "Switch" + capability "Power Meter" + capability "Polling" + capability "Refresh" + capability "Sensor" + capability "Configuration" + capability "Switch Level" + + //Extending Fibaro Dimmer 2 devices with scene attribute + attribute "scene", "number" + + command "reset" + command "configureAfterSecure" + + fingerprint deviceId: "0x1001", inClusters: "0x5E, 0x20, 0x86, 0x72, 0x26, 0x5A, 0x59, 0x85, 0x73, 0x98, 0x7A, 0x56, 0x70, 0x31, 0x32, 0x8E, 0x60, 0x75, 0x71, 0x27, 0x22, 0xEF, 0x2B" + } + + // simulator metadata + simulator { + status "on": "command: 2003, payload: FF" + status "off": "command: 2003, payload: 00" + status "09%": "command: 2003, payload: 09" + status "10%": "command: 2003, payload: 0A" + status "33%": "command: 2003, payload: 21" + status "66%": "command: 2003, payload: 42" + status "99%": "command: 2003, payload: 63" + + for (int i = 0; i <= 10000; i += 1000) { + status "power ${i} W": new physicalgraph.zwave.Zwave().meterV3.meterReport( + scaledMeterValue: i, precision: 3, meterType: 4, scale: 2, size: 4).incomingMessage() + } + for (int i = 0; i <= 100; i += 10) { + status "energy ${i} kWh": new physicalgraph.zwave.Zwave().meterV3.meterReport( + scaledMeterValue: i, precision: 3, meterType: 0, scale: 0, size: 4).incomingMessage() + } + + ["FF", "00", "09", "0A", "21", "42", "63"].each { val -> + reply "2001$val,delay 100,2602": "command: 2603, payload: $val" + } + } + + // 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.switch.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn" + attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff" + attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn" + } + tileAttribute ("device.level", key: "SLIDER_CONTROL") { + attributeState "level", action:"switch level.setLevel" + } + } + valueTile("power", "device.power", decoration: "flat", width: 2, height: 2) { + state "default", label:'${currentValue} W' + } + valueTile("energy", "device.energy", decoration: "flat", width: 2, height: 2) { + state "default", label:'${currentValue} kWh' + } + standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "default", label:'reset kWh', action:"reset" + } + standardTile("configureAfterSecure", "device.configure", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "configure", label:'', action:"configureAfterSecure", icon:"st.secondary.configure" + } + standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat", width: 2, height: 2) { + state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh" + } + + main(["switch","power","energy"]) + details(["switch","power","energy","configureAfterSecure","refresh","reset"]) + } + + preferences { + def paragraph = "GROUP 0 - The Dimmer 2 behavior - Basic functionalities" + input name: "param1", type: "number", range: "1..98", defaultValue: "1", required: true, + title: paragraph + "\n\n" + + "1. Minimum brightness level. " + + "This parameter is set automatically during the calibration process. " + + "The parameter can be changed manually after the calibration.\n" + + "Available settings: 1-98 - percentage level of brightness.\n" + + "Default value: 1." + + input name: "param2", type: "number", range: "2..99", defaultValue: "99", required: true, + title: "2. Maximum brightness level. " + + "This parameter is set automatically during the calibration process. " + + "The parameter can be changed manually after the calibration.\n" + + "Available settings: 2-99 - percentage level of brightness.\n" + + "Default value: 99." + + input name: "param3", type: "number", range: "1..99", defaultValue: "1", required: true, + title: "3. Incandescence level of dimmable compact fluorescent lamps. " + + "Virtual value set as a percentage level between parameters MIN (1%) and MAX (99%). " + + "The Dimmer 2 will set to this value after first switch on. " + + "It is required for warming up and switching dimmable compact fluorescent lamps and certain types of light sources.\n" + + "Available settings: 1-99 - percentage level of brightness.\n" + + "Default value: 1." + + input name: "param4", type: "number", range: "0..255", defaultValue: "0", required: true, + title: "4. Incandescence time of dimmable compact fluorescent lamps. " + + "This parameter determines the time required for switching compact fluorescent lamps and certain types of light sources. " + + "Setting this parameter to 0 will disable the incandescence functionality.\n" + + "Available settings: 0-255 (0-25.5s).\n" + + "Default value: 0." + + input name: "param5", type: "number", range: "1..99", defaultValue: "1", required: true, + title: "5. Automatic control - dimming step size. " + + "This parameter defines the percentage value of dimming step during the automatic control.\n" + + "Available settings: 1-99 - dimming step percentage value.\n" + + "Default value: 1." + + input name: "param6", type: "number", range: "0..255", defaultValue: "1", required: true, + title: "6. Automatic control - time of a dimming step. " + + "This parameter defines the time of single dimming step set in parameter 5 during the automatic control.\n" + + "Available settings: 0-255 (0-2.55s, in 10ms steps).\n" + + "Default value: 1." + + input name: "param7", type: "number", range: "1..99", defaultValue: "1", required: true, + title: "7. Manual control - dimming step size. " + + "This parameter defines the percentage value of dimming step during the manual control.\n" + + "Available settings: 1-99 - dimming step percentage value.\n" + + "Default value: 1." + + input name: "param8", type: "number", range: "0..255", defaultValue: "5", required: true, + title: "8. Manual control - time of a dimming step. " + + "This parameter defines the time of single dimming step set in parameter 7 during the manual control.\n" + + "Available settings: 0-255 (0-2.55s, in 10ms steps).\n" + + "Default value: 5." + + input name: "param9", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "9. State of the device after a power failure. " + + "The Dimmer 2 will return to the last state before power failure.\n" + + "Available settings:\n" + + "0 = the Dimmer 2 does not save the state before a power failure, it returns to „off” position,\n" + + "1 = the Dimmer 2 restores its state before power failure.\n" + + "Default value: 1." + + input name: "param10", type: "number", range: "0..32767", defaultValue: "0", required: true, + title: "10. Timer functionality (auto - off). " + + "This parameter allows to automatically switch off the device after specified time from switching on the light source. " + + "It may be useful when the Dimmer 2 is installed in the stairway.\n" + + "Available settings: 0 - Function disabled,\n1-32767 - time to turn off measured in seconds (1s-9.1h).\n" + + "Default value: 0." + + input name: "param11", type: "enum", defaultValue: "255", required: true, + options: ["0" : "0", + "1" : "1", + "2" : "2", + "255" : "255"], + title: "11. ALL ON/ALL OFF function. " + + "Parameter allows for activation/deactivation of Z-Wave commands enabling/disabling all devices located in direct range of the main controller.\n" + + "Available settings:\n" + + "0 = All ON not active, All OFF not active,\n" + + "1 = All ON not active, All OFF active,\n" + + "2 = All ON active, All OFF not active,\n" + + "255 = All ON active, All OFF active.\n" + + "Default value: 255." + + input name: "param13", type: "number", range: "0..2", defaultValue: "0", required: true, + title: "13. Force auto-calibration. " + + "Changing value of this parameter will force the calibration process. " + + "During the calibration parameter is set to 1 or 2 and switched to 0 upon completion.\n" + + "Available settings:\n" + + "0 = readout,\n" + + "1 = force auto-calibration of the load without FIBARO Bypass 2,\n" + + "2 = force auto-calibration of the load with FIBARO Bypass 2.\n" + + "Default value: 0." + + input name: "param15", type: "number", range: "0..99", defaultValue: "30", required: true, + title: "15. Burnt out bulb detection. " + + "Function based on the sudden power variation of a specific value, interpreted as a LOAD ERROR.\n" + + "Available settings:\n0 - function disabled,\n" + + "1-99 - percentage value of power variation, compared to standard power consumption, measured during the calibration procedure (to be interpreted as load error/burnt out bulb).\n" + + "Default value: 30." + + input name: "param16", type: "number", range: "0..255", defaultValue: "5", required: true, + title: "16. Time delay of a burnt out bulb (parameter 15) or overload (parameter 39) detection. " + + "Time of delay (in seconds) for power variation detection, interpreted as a LOAD ERROR or OVERLOAD detection (too much power connected to the Dimmer 2).\n" + + "Available settings:\n0 - detection of a burnt out bulb disabled,\n1-255 - delay time in seconds.\n" + + "Default value: 5." + + input name: "param19", type: "number", range: "0..99", defaultValue: "0", required: true, + title: "19. Forced switch on brightness level. " + + "If the parameter is active, switching on the Dimmer 2 (S1 single click) will always set this brightness level.\n" + + "Available settings:\n0 - function disabled,\n1-99 - percentage level of brightness.\n" + + "Default value: 0." + + paragraph = "GROUP 20 - Dimmer 2 operation - Switches" + input name: "param20", type: "number", range: "0..2", defaultValue: "0", required: true, + title: paragraph + "\n\n" + + "20. Switch type. " + + "Choose between momentary, toggle and roller blind switch.\n" + + "Available settings:\n" + + "0 = momentary switch,\n1 = toggle switch,\n2 = roller blind switch - two switches operate the Dimmer 2 (S1 to brighten, S2 to dim).\n" + + "Default value: 0." + + input name: "param21", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "21. The value sent to associated devices on single click. " + + "This parameter defines the value sent to devices associated with Dimmer 2 after its enabling.\n" + + "Available settings:\n" + + "0 = 0xFF value is sent, which will set associated devices to their last saved state,\n" + + "1 = current Dimmer 2 state is sent, which will synchronize brightness level of associated devices (other dimmers for example).\n" + + "Default value: 0." + + input name: "param22", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "22. Assign toggle switch status to the device status. " + + "By default each change of toggle switch position results in action of Dimmer 2 (switch on/off) regardless the physical connection of contacts.\n" + + "Available settings:\n" + + "0 = device changes status on switch status change,\n1 = device status is synchronized with switch status.\n" + + "Default value: 0." + + input name: "param23", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "23. Double click option - set the brightness level to MAX.\n" + + "Available settings:\n" + + "0 = double click disabled,\n" + + "1 = double click enabled.\n" + + "Default value: 1." + + input name: "param24", type: "enum", defaultValue: "0", required: true, + options: ["0" : "0", + "1" : "1", + "2" : "2", + "4" : "4", + "8" : "8", + "16" : "16"], + title: "24. Command frames sent in 2nd and 3rd association groups (S1 associations). " + + "Parameter determines, which actions will not result in sending frames to association groups.\n" + + "Available settings:\n" + + "0 = all actions send to association groups,\n" + + "1 = do not send when switching ON (single click),\n" + + "2 = do not send when switching OFF (single click),\n" + + "4 = do not send when changing dimming level (holding and releasing),\n" + + "8 = do not send on double click,\n" + + "16 = send 0xFF value on double click.\n" + + "Default value: 0." + + input name: "param25", type: "enum", defaultValue: "0", required: true, + options: ["0" : "0", + "1" : "1", + "2" : "2", + "4" : "4", + "8" : "8", + "16" : "16"], + title: "25. Command frames sent in 4th and 5th association groups (S2 associations). " + + "Parameter determines, which actions will not result in sending frames to association groups.\n" + + "Available settings:\n" + + "0 = all actions send to association groups,\n" + + "1 = do not send when switching ON (single click),\n" + + "2 = do not send when switching OFF (single click),\n" + + "4 = do not send when changing dimming level (holding and releasing),\n" + + "8 = do not send on double click,\n" + + "16 = send 0xFF value on double click.\n" + + "Default value: 0." + + input name: "param26", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "26. The function of 3-way switch. " + + "Switch no. 2 controls the Dimmer 2 additionally (in 3-way switch mode). Function disabled for parameter 20 set to 2 (roller blind switch).\n" + + "Available settings:\n" + + "0 = 3-way switch function for S2 disabled,\n" + + "1 = 3-way switch function for S2 enabled.\n" + + "Default value: 0." + + input name: "param27", type: "enum", defaultValue: "15", required: true, + options: ["0" : "0", + "1" : "1", + "2" : "2", + "4" : "4", + "8" : "8", + "15" : "15"], + title: "27. Associations in Z-Wave network security mode. " + + "This parameter defines how commands are sent in speci ed association groups: as secure or non-secure. " + + "Parameter is active only in Z-Wave network security mode. It does not apply to 1st lifeline group.\n" + + "Available settings:\n" + + "0 = all groups (II-V) sent as non-secure,\n" + + "1 = 2nd group sent as secure,\n" + + "2 = 3rd group sent as secure,\n" + + "4 = 4th group sent as secure,\n" + + "8 = 5th group sent as secure,\n" + + "15 = all groups (II-V) sent as secure.\n" + + "Default value: 15." + + input name: "param28", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "28. Scene activation functionality.\n" + + "Available settings:\n" + + "0 = functionality deactivated,\n" + + "1 = functionality activated.\n" + + "Default value: 0.\n\n" + + "SCENE ID depends on the switch type configurations.\n" + + "Momentary switches:\n" + + "SCENE ID: S1 input:\n\t16 : 1 x click\n\t14 : 2 x click\n\t-- : 3 x click\n\t12 : hold\n\t13 : release\n" + + "SCENE ID: S2 input:\n\t26 : 1 x click\n\t24 : 2 x click\n\t25 : 3 x click\n\t22 : hold\n\t23 : release\n\n" + + "Toggle switches:\n" + + "SCENE ID: S1 input:\n\t10 : OFF to ON\n\t11 : ON to OFF\n\t14 : 2 x click\n\t-- : 3 x click\n" + + "SCENE ID: S2 input:\n\t20 : OFF to ON\n\t21 : ON to OFF\n\t24 : 2 x click\n\t25 : 3 x click\n\n" + + "Roller blinds switches:\n" + + "SCENE ID: S1 input:\n\t10 : turn ON (1 x click)\n\t13 : release\n\t14 : 2 x click\n\t-- : 3 x click\n\t17 : brightening\n" + + "SCENE ID: S2 input:\n\t11 : turn OFF (1 x click)\n\t13 : release\n\t14 : 2 x click\n\t15 : 3 x click\n\t18 : dimming" + + input name: "param29", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "29. Switch functionality of S1 and S2. " + + "This parameter allows for switching the role of keys connected to S1 and S2 without changes in connection.\n" + + "Available settings:\n" + + "0 = standard mode,\n" + + "1 = S1 operates as S2, S2 operates as S1.\n" + + "Default value: 0." + + paragraph = "GROUP 30 - Dimmer 2 operation - Advanced functionality" + input name: "param30", type: "number", range: "0..2", defaultValue: "2", required: true, + title: paragraph + "\n\n" + + "30. Load control mode. " + + "This parameter allows to set the desired load control mode. " + + "The de- vice automatically adjusts correct control mode, but the installer may force its change using this parameter. " + + "Forced auto-calibration will set this parameter’s value to 2.\n" + + "Available settings:\n" + + "0 = forced leading edge control,\n" + + "1 = forced trailing edge control,\n" + + "2 = control mode selected automatically (based on auto-calibration).\n" + + "Default value: 2." + + input name: "param32", type: "number", range: "0..2", defaultValue: "2", required: true, + title: "32. On/Off mode. " + + "This mode is necessary while connecting non-dimmable light sources. " + + "Setting this parameter to 1 automatically ignores brightening/dimming time settings. " + + "Forced auto-calibration will set this parameter’s value to 2.\n" + + "Available settings:\n" + + "0 = on/off mode disabled (dimming is possible),\n" + + "1 = on/off mode enabled (dimming is not possible),\n" + + "2 = mode selected automatically.\n" + + "Default value: 2." + + input name: "param34", type: "number", range: "0..2", defaultValue: "1", required: true, + title: "34. Soft-Start functionality. " + + "Time required to warm up the lament of halogen bulb.\n" + + "Available settings:\n" + + "0 = no soft-start,\n" + + "1 = short soft-start (0.1s),\n" + + "2 = long soft-start (0.5s).\n" + + "Default value: 1." + + input name: "param35", type: "number", range: "0..4", defaultValue: "1", required: true, + title: "35. Auto-calibration after power on. " + + "This parameter determines the trigger of auto-calibration procedure, e.g. power on, load error, etc.\n" + + "Available settings:\n" + + "0 = No auto-calibration of the load after power on,\n" + + "1 = Auto-calibration performed after first power on,\n" + + "2 = Auto-calibration performed after each power on,\n" + + "3 = Auto-calibration performed after first power on or after each LOAD ERROR alarm (no load, load failure, burnt out bulb), if parameter 37 is set to 1 also after alarms: SURGE (Dimmer 2 output overvoltage) and OVERCURRENT (Dimmer 2 output overcurrent),\n" + + "4 = Auto-calibration performed after each power on or after each LOAD ERROR alarm (no load, load failure, burnt out bulb), if parameter 37 is set to 1 also after alarms: SURGE (Dimmer 2 output overvoltage) and OVERCURRENT (Dimmer 2 output overcurrent).\n" + + "Default value: 1." + + input name: "param37", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "37. Behaviour of the Dimmer 2 after OVERCURRENT or SURGE. " + + "Occuring of errors related to surge or overcurrent results in turning off the output to prevent possible malfunction. " + + "By default the device performs three attempts to turn on the load (useful in case of momentary, short failures of the power supply).\n" + + "Available settings:\n" + + "0 = device permanently disabled until re-ena- bling by command or external switch,\n" + + "1 = three attempts to turn on the load.\n" + + "Default value: 1." + + input name: "param39", type: "number", range: "0..350", defaultValue: "250", required: true, + title: "39. Power limit - OVERLOAD. " + + "Reaching the defined value will result in turning off the load. " + + "Additional apparent power limit of 350VA is active by default.\n" + + "Available settings:\n0 - functionality disabled,\n1-350 - 1-350W.\n" + + "Default value: 250." + + paragraph = "GROUP 40 - Dimmer 2 operation - Alarms" + input name: "param40", type: "number", range: "0..3", defaultValue: "3", required: true, + title: paragraph + "\n\n" + + "40. Response to General Purpose Alarm.\n" + + "Available settings:\n" + + "0 = No reaction,\n" + + "1 = Turn on the load,\n" + + "2 = Turn off the load,\n" + + "3 = Load blinking.\n" + + "Default value: 3." + + input name: "param41", type: "number", range: "0..3", defaultValue: "2", required: true, + title: "41. Response to Water Flooding Alarm.\n" + + "Available settings:\n" + + "0 = No reaction,\n" + + "1 = Turn on the load,\n" + + "2 = Turn off the load,\n" + + "3 = Load blinking.\n" + + "Default value: 2." + + input name: "param42", type: "number", range: "0..3", defaultValue: "3", required: true, + title: "42. Response to Smoke, CO or CO2 Alarm.\n" + + "Available settings:\n" + + "0 = No reaction,\n" + + "1 = Turn on the load,\n" + + "2 = Turn off the load,\n" + + "3 = Load blinking.\n" + + "Default value: 3." + + input name: "param43", type: "number", range: "0..3", defaultValue: "1", required: true, + title: "43. Response to Temperature Alarm.\n" + + "Available settings:\n" + + "0 = No reaction,\n" + + "1 = Turn on the load,\n" + + "2 = Turn off the load,\n" + + "3 = Load blinking.\n" + + "Default value: 1." + + input name: "param44", type: "number", range: "1..32767", defaultValue: "600", required: true, + title: "44. Time of alarm state.\n" + + "Available settings: 1-32767 (1-32767 seconds).\n" + + "Default value: 600." + + paragraph = "Alarm settings - reports" + input name: "param45", type: "number", range: "0..1", defaultValue: "1", required: true, + title: paragraph + "\n\n" + + "45. OVERLOAD alarm report (load power consumption too high).\n" + + "Available settings:\n" + + "0 = No reaction,\n" + + "1 = Send an alarm frame.\n" + + "Default value: 1." + + input name: "param46", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "46. LOAD ERROR alarm report (no load, load failure, burnt out bulb).\n" + + "Available settings:\n" + + "0 = No reaction,\n" + + "1 = Send an alarm frame.\n" + + "Default value: 1." + + input name: "param47", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "47. OVERCURRENT alarm report (short circuit, burnt out bulb causing overcurrent).\n" + + "Available settings:\n" + + "0 = No reaction,\n" + + "1 = Send an alarm frame.\n" + + "Default value: 1." + + input name: "param48", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "48. SURGE alarm report (Dimmer 2 output overvoltage).\n" + + "Available settings:\n" + + "0 = No reaction,\n" + + "1 = Send an alarm frame.\n" + + "Default value: 1." + + input name: "param49", type: "number", range: "0..1", defaultValue: "1", required: true, + title: "49. OVERHEAT (critical temperature) and VOLTAGE DROP (low voltage) alarm report.\n" + + "Available settings:\n" + + "0 = No reaction,\n" + + "1 = Send an alarm frame.\n" + + "Default value: 1." + + paragraph = "GROUP 50 - Active power and energy reports" + input name: "param50", type: "number", range: "0..100", defaultValue: "10", required: true, + title: paragraph + "\n\n" + + "50. Active power reports. " + + "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.\n" + + "Available settings:\n0 - power reports disabled,\n1-100 (1-100%) - power report threshold.\n" + + "Default value: 10." + + input name: "param52", type: "number", range: "0..32767", defaultValue: "3600", required: true, + title: "52. Periodic active power and energy reports. " + + "Parameter 52 defines a time period between consecutive reports. Timer is reset and counted from zero after each report.\n" + + "Available settings:\n0 - periodic reports disabled,\n1-32767 (1-32767 seconds).\n" + + "Default value: 3600." + + input name: "param53", type: "number", range: "0..255", defaultValue: "10", required: true, + title: "53. Energy reports. " + + "Energy level change which will result in sending a new energy report.\n" + + "Available settings:\n0 - energy reports disabled,\n1-255 (0.01-2.55 kWh) - report triggering threshold.\n" + + "Default value: 10." + + input name: "param54", type: "number", range: "0..1", defaultValue: "0", required: true, + title: "54. Self-measurement. " + + "The Dimmer 2 may include active power and energy consumed by itself in reports sent to the main controller.\n" + + "Available settings:\n" + + "0 = Self-measurement inactive,\n" + + "1 = Self-measurement active.\n" + + "Default value: 0." + + input name: "param58", type: "number", range: "0..2", defaultValue: "0", required: true, + title: "58. Method of calculating the active power. This parameter defines how to calculate active power. " + + "It is useful in a case of 2-wire connection with light sources other than resistive.\n" + + "Available settings:\n" + + "0 = measurement based on the standard algorithm,\n" + + "1 = approximation based on the calibration data,\n" + + "2 = approximation based on the control angle.\n" + + "Default value: 0." + + input name: "param59", type: "number", range: "0..500", defaultValue: "0", required: true, + title: "59. Approximated power at the maximum brightness level. " + + "This parameter determines the approximate value of the power that will be reported by the device at its maximum brightness level.\n" + + "Available settings: 0-500 (0-500W) - power consumed by the load at the maximum brightness level.\n" + + "Default value: 0." + + input name: "paramAssociationGroup1", type: "bool", defaultValue: true, required: true, + title: "The Dimmer 2 provides the association of five groups.\n\n" + + "1st Association Group „Lifeline”,\n" + + "Default value: true" + + input name: "paramAssociationGroup2", type: "bool", defaultValue: true, required: true, + title: "2nd Association Group „On/Off (S1)”,\n" + + "Default value: true" + + input name: "paramAssociationGroup3", type: "bool", defaultValue: false, required: true, + title: "3rd Association Group „Dimmer (S1)”,\n" + + "Default value: false" + + input name: "paramAssociationGroup4", type: "bool", defaultValue: false, required: true, + title: "4th Association Group „On/Off (S2)”,\n" + + "Default value: false" + + input name: "paramAssociationGroup5", type: "bool", defaultValue: false, required: true, + title: "5th Association Group „Dimmer (S2)”.\n" + + "Default value: false" + } +} + +def parse(String description) { + log.trace(description) + log.debug("RAW command: $description") + def result = null + + if (description != "updated") { + def cmd = zwave.parse(description.replace("98C1", "9881"), [0x20: 1, 0x26: 3, 0x32: 3, 0x25: 1, 0x98: 1, 0x70: 1, 0x85: 2, 0x9B: 1, 0x90: 1, 0x73: 1, 0x30: 1, 0x28: 1, 0x72: 1]) + if (cmd) { + result = zwaveEvent(cmd) + } + } + log.debug "Parsed '${description}' to ${result.inspect()}" + return result +} + +def zwaveEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd) { + log.debug( "Scene ID: $cmd.sceneId") + log.debug( "Dimming Duration: $cmd.dimmingDuration") + + sendEvent(name: "scene", value: "$cmd.sceneId", data: [switchType: "$settings.param20"], descriptionText: "Scene id $cmd.sceneId was activated", isStateChange: true) + log.debug( "Scene id $cmd.sceneId was activated" ) +} + +// Devices that support the Security command class can send messages in an encrypted form; +// they arrive wrapped in a SecurityMessageEncapsulation command and must be unencapsulated +def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) { + log.trace(cmd) + def encapsulatedCommand = cmd.encapsulatedCommand([0x20: 1, 0x26: 3, 0x32: 3, 0x25: 1, 0x98: 1, 0x70: 1, 0x85: 2, 0x9B: 1, 0x90: 1, 0x73: 1, 0x30: 1, 0x28: 1, 0x72: 1]) // can specify command class versions here like in zwave.parse + if (encapsulatedCommand) { + return zwaveEvent(encapsulatedCommand) + } else { + log.warn "Unable to extract encapsulated cmd from $cmd" + createEvent(descriptionText: cmd.toString()) + } +} + +def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) { + log.trace(cmd) + dimmerEvents(cmd) +} + +def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) { + log.trace(cmd) + //dimmerEvents(cmd) +} +def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelReport cmd) { + log.trace(cmd) + dimmerEvents(cmd) +} + +def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) +{ + log.trace(cmd) + dimmerEvents(cmd) +} + + +def dimmerEvents(physicalgraph.zwave.Command cmd) { + log.trace(cmd) + def result = [] + def value = (cmd.value ? "on" : "off") + def switchEvent = createEvent(name: "switch", value: value, descriptionText: "$device.displayName was turned $value") + result << switchEvent + if (cmd.value) { + result << createEvent(name: "level", value: cmd.value, unit: "%") + } + if (switchEvent.isStateChange) { + result << response(["delay 3000", zwave.meterV2.meterGet(scale: 2).format()]) + } + return result +} + +def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd) { + log.trace(cmd) + if (cmd.meterType == 1) { + if (cmd.scale == 0) { + return createEvent(name: "energy", value: cmd.scaledMeterValue, unit: "kWh") + } else if (cmd.scale == 1) { + return createEvent(name: "energy", value: cmd.scaledMeterValue, unit: "kVAh") + } else if (cmd.scale == 2) { + return createEvent(name: "power", value: Math.round(cmd.scaledMeterValue), unit: "W") + } else { + return createEvent(name: "electric", value: cmd.scaledMeterValue, unit: ["pulses", "V", "A", "R/Z", ""][cmd.scale - 3]) + } + } +} + +def zwaveEvent(physicalgraph.zwave.Command cmd) { + log.trace(cmd) + log.debug "No handler for $cmd" + // Handles all Z-Wave commands we aren't interested in + createEvent(descriptionText: cmd.toString(), isStateChange: false) +} + + +def on() { + log.trace("on") + secureSequence([ + zwave.basicV1.basicSet(value: 0xFF), + zwave.switchMultilevelV1.switchMultilevelGet() + ]) +} + +def off() { + log.trace("off") + secureSequence([ + zwave.basicV1.basicSet(value: 0x00), + zwave.switchMultilevelV1.switchMultilevelGet() + ]) +} + +def poll() { + log.trace("poll") + secureSequence([ + zwave.meterV2.meterGet(scale: 0), + zwave.meterV2.meterGet(scale: 2) + ]) +} + +def refresh() { + log.trace("trace") + secureSequence([ + zwave.meterV2.meterGet(scale: 0), + zwave.meterV2.meterGet(scale: 2) + ]) +} + +def reset() { + log.trace("reset") + return secureSequence([ + zwave.switchMultilevelV1.switchMultilevelGet(), + zwave.meterV2.meterReset(), + zwave.meterV2.meterGet(scale: 0), + zwave.meterV2.meterGet(scale: 2) + ]) +} + +def setLevel(level) { + log.trace("setlevel") + if(level > 99) level = 99 + secureSequence([ + zwave.basicV1.basicSet(value: level), + zwave.switchMultilevelV1.switchMultilevelGet() + ], 5000) +} + +def configureAfterSecure() { + log.debug "configureAfterSecure()" + def cmds = secureSequence([ + zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, scaledConfigurationValue: param1.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 2, size: 1, scaledConfigurationValue: param2.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 3, size: 1, scaledConfigurationValue: param3.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 4, size: 2, scaledConfigurationValue: param4.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 5, size: 1, scaledConfigurationValue: param5.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 6, size: 2, scaledConfigurationValue: param6.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 7, size: 1, scaledConfigurationValue: param7.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 8, size: 2, scaledConfigurationValue: param8.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 9, size: 1, scaledConfigurationValue: param9.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 10, size: 2, scaledConfigurationValue: param10.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 11, size: 2, scaledConfigurationValue: param11.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 13, size: 1, scaledConfigurationValue: param13.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 15, size: 1, scaledConfigurationValue: param15.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 16, size: 2, scaledConfigurationValue: param16.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 19, size: 1, scaledConfigurationValue: param19.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 20, size: 1, scaledConfigurationValue: param20.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 21, size: 1, scaledConfigurationValue: param21.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 22, size: 1, scaledConfigurationValue: param22.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 23, size: 1, scaledConfigurationValue: param23.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 24, size: 1, scaledConfigurationValue: param24.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 25, size: 1, scaledConfigurationValue: param25.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 26, size: 1, scaledConfigurationValue: param26.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 27, size: 1, scaledConfigurationValue: param27.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 28, size: 1, scaledConfigurationValue: param28.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 29, size: 1, scaledConfigurationValue: param29.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 30, size: 1, scaledConfigurationValue: param30.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 32, size: 1, scaledConfigurationValue: param32.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 34, size: 1, scaledConfigurationValue: param34.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 35, size: 1, scaledConfigurationValue: param35.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 37, size: 1, scaledConfigurationValue: param37.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 39, size: 2, scaledConfigurationValue: param39.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 40, size: 1, scaledConfigurationValue: param40.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 41, size: 1, scaledConfigurationValue: param41.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 42, size: 1, scaledConfigurationValue: param42.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 43, size: 1, scaledConfigurationValue: param43.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 44, size: 2, scaledConfigurationValue: param44.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 45, size: 1, scaledConfigurationValue: param45.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 46, size: 1, scaledConfigurationValue: param46.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 47, size: 1, scaledConfigurationValue: param47.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 48, size: 1, scaledConfigurationValue: param48.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 49, size: 1, scaledConfigurationValue: param49.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 50, size: 1, scaledConfigurationValue: param50.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 52, size: 2, scaledConfigurationValue: param52.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 53, size: 2, scaledConfigurationValue: param53.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 54, size: 1, scaledConfigurationValue: param54.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 58, size: 1, scaledConfigurationValue: param58.toInteger()), + zwave.configurationV1.configurationSet(parameterNumber: 59, size: 2, scaledConfigurationValue: param59.toInteger()) + ]) + + // Register for Group 1 + if(paramAssociationGroup1) { + cmds << secure(zwave.associationV2.associationSet(groupingIdentifier:1, nodeId: [zwaveHubNodeId])) + } + else { + cmds << secure(zwave.associationV2.associationRemove(groupingIdentifier:1, nodeId: [zwaveHubNodeId])) + } + // Register for Group 2 + if(paramAssociationGroup2) { + cmds << secure(zwave.associationV2.associationSet(groupingIdentifier:2, nodeId: [zwaveHubNodeId])) + } + else { + cmds << secure(zwave.associationV2.associationRemove(groupingIdentifier:2, nodeId: [zwaveHubNodeId])) + } + // Register for Group 3 + if(paramAssociationGroup3) { + cmds << secure(zwave.associationV2.associationSet(groupingIdentifier:3, nodeId: [zwaveHubNodeId])) + } + else { + cmds << secure(zwave.associationV2.associationRemove(groupingIdentifier:3, nodeId: [zwaveHubNodeId])) + } + // Register for Group 4 + if(paramAssociationGroup4) { + cmds << secure(zwave.associationV2.associationSet(groupingIdentifier:4, nodeId: [zwaveHubNodeId])) + } + else { + cmds << secure(zwave.associationV2.associationRemove(groupingIdentifier:4, nodeId: [zwaveHubNodeId])) + } + // Register for Group 5 + if(paramAssociationGroups5) { + cmds << secure(zwave.associationV2.associationSet(groupingIdentifier:5, nodeId: [zwaveHubNodeId])) + } + else { + cmds << secure(zwave.associationV2.associationRemove(groupingIdentifier:5, nodeId: [zwaveHubNodeId])) + } + + cmds +} + +def configure() { + // Wait until after the secure exchange for this + log.debug "configure()" +} + +def updated() { + log.debug "updated()" + response(["delay 2000"] + configureAfterSecure() + refresh()) +} + +private secure(physicalgraph.zwave.Command cmd) { + log.trace(cmd) + zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format() +} + +private secureSequence(commands, delay=200) { + log.debug "$commands" + delayBetween(commands.collect{ secure(it) }, delay) +} \ No newline at end of file diff --git a/smartapps/my-apps/fibaro-dimmer-scenes.src/fibaro-dimmer-scenes.groovy b/smartapps/my-apps/fibaro-dimmer-scenes.src/fibaro-dimmer-scenes.groovy new file mode 100644 index 0000000..76e952b --- /dev/null +++ b/smartapps/my-apps/fibaro-dimmer-scenes.src/fibaro-dimmer-scenes.groovy @@ -0,0 +1,88 @@ +/** + * Copyright 2015 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. + */ +definition( + name: "Fibaro Dimmer Scenes", + namespace: "My Apps", + author: "Elnar Hajiyev", + description: "Smart app that allows to control switches with changes of Fibaro Dimmer Scenes.", + category: "Convenience", + iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet.png", + iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet@2x.png" +) + +preferences { + section("Listen to scenes from this Fibaro Dimmer devices...") { + input "fibaroDevicesSet", "capability.switch", title: "Fibaro Dimmers?", multiple: true, required: true + } + section("When any of these scenes are activated...") { + input "scenesSet1", "enum", title: "Fibaro Dimmer scenes (set 1)?", multiple: true, required: false, + options: ["10","11","12","13", "14", "15", "16", "17", "18", "20", "21", "22", "23", "24", "25", "26"] + } + section("Turn on all of these switches") { + input "switchesSet1", "capability.switch", multiple: true, required: false + } + section("When any of these scenes are activated...") { + input "scenesSet2", "enum", title: "Fibaro Dimmer scenes (set 2)?", multiple: true, required: false, + options: ["10","11","12","13", "14", "15", "16", "17", "18", "20", "21", "22", "23", "24", "25", "26"] + } + section("Turn off all of these switches") { + input "switchesSet2", "capability.switch", multiple: true, required: false + } + section("When any of these scenes are activated...") { + input "scenesSet3", "enum", title: "Fibaro Dimmer scenes (set 3)?", multiple: true, required: false, + options: ["10","11","12","13", "14", "15", "16", "17", "18", "20", "21", "22", "23", "24", "25", "26"] + } + section("Toggle all of these switches") { + input "switchesSet3", "capability.switch", multiple: true, required: false + } +} + +def installed() +{ + subscribe(fibaroDevicesSet, "scene", sceneHandler, [filterEvents: false]) +} + +def updated() +{ + unsubscribe() + subscribe(fibaroDevicesSet, "scene", sceneHandler, [filterEvents: false]) +} + +def sceneHandler(evt) { + log.debug evt.value + log.debug evt.data + + if(scenesSet1 && scenesSet1.contains(evt.value)) { + switchesSet1.on() + } + else if(scenesSet2 && scenesSet2.contains(evt.value)) { + switchesSet2.off() + } + else if(scenesSet3 && scenesSet3.contains(evt.value)) { + toggle(switchesSet3) + } +} + +def toggle(devices) { + log.debug "toggle: $devices = ${devices*.currentValue('switch')}" + + if (devices*.currentValue('switch').contains('off')) { + devices.on() + } + else if (devices*.currentValue('switch').contains('on')) { + devices.off() + } + else { + devices.on() + } +} \ No newline at end of file