Hi Paul,
sorry, been away and just seen your message.
See below the handler. The fingerprint is right, but I bit off a bit too much trying to get the custom attributes working from a handler I copied- errors there. That said, spent a lot of time getting the right text for custom attributes in so it might help you get where you want.
Let me know if you get anywhere- I’m up to my ears in work just now and solving more pressing Smartthings issues in the litle time I have- so will be at least 2 - 3 months before I can look at this again!
/**
*
*/
metadata {
definition (name: “Qubino Flush Plus Dimmer”, namespace: “chrisgla”, author: “Chris McGookin”) {
attribute "needUpdate", "string"
capability "Switch"
capability "Polling"
capability "Power Meter"
capability "Energy Meter"
capability "Refresh"
capability "Switch Level"
capability "Sensor"
capability "Actuator"
capability "Configuration"
capability "Zw Multichannel"
command "reset"
command "resetParams2StDefaults"
command "listCurrentParams"
command "updateZwaveParam"
command "test"
command "configure"
fingerprint deviceId: "0x1101", inClusters: "0x5E,0x86,0x72,0x5A,0x73,0x20,0x27,0x25,0x26,0x30,0x71,0x32,0x60,0x85,0x8E,0x59,0x70,0xEF,0x20"
}
simulator {
status "on": "command: 2603, payload: FF"
status "off": "command: 2603, payload: 00"
status "09%": "command: 2603, payload: 09"
status "10%": "command: 2603, payload: 0A"
status "33%": "command: 2603, payload: 21"
status "66%": "command: 2603, payload: 42"
status "99%": "command: 2603, 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"
}
}
tiles {
standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
state "turningOn", label:'${name}', icon:"st.switches.switch.on", backgroundColor:"#79b821"
state "turningOff", label:'${name}', icon:"st.switches.switch.off", backgroundColor:"#ffffff"
}
valueTile("power", "device.power") {
state "default", label:'${currentValue} W'
}
valueTile("energy", "device.energy") {
state "default", label:'${currentValue} kWh'
}
standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat") {
state "default", label:'reset kWh', action:"reset"
}
controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 3, inactiveLabel: false) {
state "level", action:"switch level.setLevel"
}
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}
}
main(["switch","power","energy"])
details(["switch", "power", "energy", "levelSliderControl", "refresh", "reset"])
}
/**
- This will be called each time we update a parameter. Use it to fill our currents parameters as a callback
*/
def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
update_current_properties(cmd)
log.debug “${device.displayName} parameter ‘${cmd.parameterNumber}’ with a byte size of ‘${cmd.size}’ is set to ‘${cmd.configurationValue}’”
}
/**
- parse events into attributes
/
def parse(String description)
{
log.debug "==> New Zwave Event: ${description}"
def result = []
switch(description) {
case ~/Err./:
log.error "Error: $description"
break
// updated is hit when the device is paired.
case “updated”:
result << response(zwave.manufacturerSpecificV2.manufacturerSpecificGet().format())
result << response(zwave.firmwareUpdateMdV2.firmwareMdGet().format())
result << response(configure())
break
default:
def cmd = zwave.parse(description, [0x5E: 2,0x86: 2,0x72: 1,0x5A: 1,0x73: 1,0x20: 1,0x27: 1,0x25: 1,0x26: 3,0x30: 1,0x71: 1,0x60: 4,0x85: 2,0x8E: 3,0x59: 2,0x70: 2,0xEF: 1])
if (cmd) {
result += zwaveEvent(cmd)
}
log.debug "=== Parsed ‘${description}’ to ${result.inspect()}"
if ( result[0] != null ) { result }
}
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
dimmerEvents(cmd)
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
dimmerEvents(cmd)
}
def zwaveEvent(physicalgraph.zwave.commands.switchmultilevelv3.SwitchMultilevelReport cmd) {
dimmerEvents(cmd)
}
def dimmerEvents(physicalgraph.zwave.Command 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.meterV3.meterGet(scale: 2).format()])
}
return result
}
def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport 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 on() {
delayBetween([
zwave.basicV1.basicSet(value: 0xFF).format(),
zwave.switchMultilevelV3.switchMultilevelGet().format(),
], 5000)
}
def off() {
delayBetween([
zwave.basicV1.basicSet(value: 0x00).format(),
zwave.switchMultilevelV3.switchMultilevelGet().format(),
], 5000)
}
def poll() {
delayBetween([
zwave.meterV3.meterGet(scale: 0).format(),
zwave.meterV3.meterGet(scale: 2).format(),
], 1000)
}
def refresh() {
delayBetween([
zwave.switchMultilevelV3.switchMultilevelGet().format(),
zwave.meterV3.meterGet(scale: 0).format(),
zwave.meterV3.meterGet(scale: 2).format(),
], 1000)
}
def setLevel(level) {
if(level > 99) level = 99
delayBetween([
zwave.basicV1.basicSet(value: level).format(),
zwave.switchMultilevelV3.switchMultilevelGet().format()
], 5000)
}
preferences {
input description: "Once you change values on this page, the `Synced` Status will become `pending` status.",
displayDuringSetup: false, type: "paragraph", element: "paragraph"
generate_preferences(configuration_model())
}
/**
- This function generate the preferences menu from the XML file
- each input will be accessible from settings map object.
*/
def generate_preferences(configuration_model)
{
def configuration = parseXml(configuration_model)
configuration.Value.each
{
switch(it.@type)
{
case [“byte”,“short”]:
input “${it.@index}”, “number”,
title:"${it.@index} - ${it.@label}\n" + “${it.Help}”,
defaultValue: “${it.@value}“
break
case “list”:
def items = []
it.Item.each { items << [”${it.@value}”:"${it.@label}"] }
input “${it.@index}”, “enum”,
title:"${it.@index} - ${it.@label}\n" + “${it.Help}”,
defaultValue: “${it.@value}”,
options: items
break
}
}
}
/**
- Triggered when Done button is pushed on Preference Pane
*/
def updated()
{
// Only used to toggle the status if update is needed
update_needed_settings()
sendEvent(name:“needUpdate”, value: device.currentValue(“needUpdate”), displayed:false, isStateChange: true)
}
/**
-
Update current cache properties
*/
def update_current_properties(cmd)
{
def currentProperties = state.currentProperties ?: [:]
currentProperties."${cmd.parameterNumber}" = cmd.configurationValue
if (settings."${cmd.parameterNumber}" != null)
{
if (settings."${cmd.parameterNumber}".toInteger() == cmd2Integer(cmd.configurationValue))
{
sendEvent(name:“needUpdate”, value:“NO”, displayed:false, isStateChange: true)
}
else
{
sendEvent(name:“needUpdate”, value:“YES”, displayed:false, isStateChange: true)
}
}
state.currentProperties = currentProperties
}
/**
-
Update needed settings
*/
def update_needed_settings()
{
def cmds = []
def currentProperties = state.currentProperties ?: [:]
def configuration = parseXml(configuration_model())
def isUpdateNeeded = “NO"
configuration.Value.each
{
if (currentProperties.”${it.@index}" == null)
{
log.debug “Current value of parameter ${it.@index} is unknown"
isUpdateNeeded = “YES”
}
else if (settings.”${it.@index}" != null && cmd2Integer(currentProperties."${it.@index}") != settings."${it.@index}".toInteger())
{
log.debug “Parameter ${it.@index} will be updated to " + settings.”${it.@index}“
isUpdateNeeded = “YES"
switch(it.@type)
{
case [“byte”, “list”]:
cmds << zwave.configurationV2.configurationSet(configurationValue: [(settings.”${it.@index}”).toInteger()], parameterNumber: it.@index.toInteger(), size: 1).format()
breakconfigurationV2.configurationGet
case “short”:
def short valueLow = settings."${it.@index}" & 0xFF
def short valueHigh = (settings."${it.@index}" >> 8) & 0xFF
def value = [valueHigh, valueLow]
cmds << zwave.configurationV2.configurationSet(configurationValue: value, parameterNumber: it.@index.toInteger(), size: 2).format()
break
}
cmds << zwave.configurationV2.configurationGet(parameterNumber: it.@index.toInteger()).format()
}
}
sendEvent(name:“needUpdate”, value: isUpdateNeeded, displayed:false, isStateChange: true)
return cmds
}
/**
-
Try to sync properties with the device
*/
def sync_properties()
{
def currentProperties = state.currentProperties ?: [:]
def configuration = parseXml(configuration_model())
def cmds = []
configuration.Value.each
{
if (! currentProperties."${it.@index}" || currentProperties."${it.@index}" == null)
{
log.debug "Looking for current value of parameter ${it.@index}"
cmds << zwave.configurationV2.configurationGet(parameterNumber: it.@index.toInteger()).format()
}
}
if (device.currentValue(“needUpdate”) == “YES”) { cmds += update_needed_settings() }
return cmds
}
/**
- Configures the device to settings needed by SmartThings at device discovery time.
-
*/
def configure() {
log.debug "Configuring Device For SmartThings Use"
def cmds = []
// Associate Group 3 Device Status (Group 1 is for Basic direct action -switches-, Group 2 for Tamper Alerts System -alarm-)
// Hub need to be Associate to group 3
cmds << zwave.associationV2.associationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:4, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:5, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:6, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:7, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:8, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:9, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:10, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:11, nodeId:[zwaveHubNodeId]).format()
cmds += sync_properties()
delayBetween(cmds , 1500)
}
/**
- Convert 1 and 2 bytes values to integer
*/
def cmd2Integer(array) { array.size() == 1 ? array[0] : ((array[0] & 0xFF) << 8) | (array[1] & 0xFF) }
/**
0 - mono-stable switch type (push button) – button quick press turns between previous set Dimmer value and zero
1 - bi-stable switch type
Default setting: 0
<Value type="byte" index="3" label="Input 2 contact type" min="0" max="1" value="0">
<Help>
0 - NO (normally open) input type
1 - NC (normally close) input type
Default setting: 0
default value 0
0 - NO (normally open) input type
1 - NC (normally close) input type
Default setting: 0
Flush Dimmer module responds to commands ALL ON / ALL OFF that may be sent by the main controller or by other controller belonging to the system.
255 - ALL ON active, ALL OFF active.
0 - ALL ON is not active, ALL OFF is not active
1 - ALL ON is not active, ALL OFF active
2 - ALL ON active, ALL OFF is not active
Default setting: 255
0 - Auto OFF disabled
1 - 32536 Auto OFF enabled after 1 - 32536 seconds, step is 1 second.
Default setting: 0
0 - Auto ON disabled
1 - 32536 Auto ON enabled after 1 - 32536 seconds, step is 1 second.
Default setting: 0
Dimming is done by push button or switch connected to I1 (by default). Enabling 3way switch, dimming can be controlled by push button or switch connected to I1 and I2.
0 - single push button (connected to I1)
1 - 3 way switch (connected to I1 and I2)
Default setting: 0
If Double click function is enabled, a fast double click on the push button will set dimming power at maximum dimming value.
0 - single push button (connected to I1)
1 - 3 way switch (connected to I1 and I2)
Default setting: 0
0 - Flush Dimmer module saves its state before power failure (it returns to the last position saved before a power failure).
1 - Flush Dimmer module does not save the state after a power failure, it returns to "off" position.
Default setting: 0
Set value means percentage, set value from 0 - 100=0% - 100%
0 - reporting disabled
1 - 100 = 1% - 100% Reporting enabled. Power report is sent only when actual power in Watts in real time changes for more than set percentage comparing to previous actual power in Watts, step is 1%.
NOTE: if power changed is less than 1W, the report is not sent, independent of percentage set.
Default setting: 5
Set value means time interval (0 - 32767) in seconds, when power report is sent
0 - reporting disabled
1 - 32767 = 1 second - 32767 seconds. Reporting enabled. Power report is sent at defined interval.
Default setting: 0
1- 98 = 1% - 98%, step is 1%. Minimum dimming value set by entered value.
Default setting: 1
2- 99 = 2% - 99%, step is 1%. Maximum dimming value set by entered value.
Default setting: 99
Set value in milliseconds of moving the Dimmer between min. and max. dimming values by short press of push button I1 or controlled through UI (BasicSet).
50 - 255 = 500 ms - 2550 ms (2,55s), step is 10 ms
Default setting: 100 = 1 seconds
Time to move between min. and max dimming values by continuous press of push button I1 or associated device.
1- 255 = 1 second – 255 seconds
Default setting: 3 seconds
This parameter is used with association group 3.
A receiving device SHOULD respect the start level if the Ignore Start Level bit is 0. A receiving device MUST ignore the start level if the Ignore Start Level bit is 1.
0 - respect start level
1 - ignore start level
Default setting: 0
This parameter is used with association group 3.
The Duration field MUST specify the time that the transition should take from the current value to the new target value.
A supporting device SHOULD respect the specified Duration value.
0 (dimming duration according to parameter 66)
1 - 127 (from 1 to 127 seconds)
Default setting: 0
Enabling I2 means that Endpoint I2 will be present on UI.
Disabling it will result in hiding the endpoint according to the parameter set value.
Additionally, a Notification Type and Event can be selected for the endpoint.
1 - 6 notification sensor:
1 - Home Security; Motion Detection, unknown loc.
2 - CO; Carbon Monoxide detected, unknown loc..
3 - CO2; Carbon Dioxide detected, unknown loc.
4 - Water Alarm; Water Leak detected, unknown loc.
5 - Heat Alarm; Overheat detected, unknown loc.
6 - Smoke Alarm; Smoke detected, unknown loc.
0 - Endpoint, I2 disabled
sensor binary (9): GENERIC_TYPE_SENSOR_BINARY, SPECIFIC_TYPE_NOT_USED
9 - Sensor binary
Default setting: 1
NOTE 1: After parameter change, first exclude module (without setting parameters to default value) then wait at least 30s and then re include the module!
NOTE 2: When the parameter is set to value 9 the notifications are send for Home Security
Enabling I3 means that Endpoint I3 will be present on UI.
Disabling it will result in hiding the endpoint according to the parameter set value.
Additionally, a Notification Type and Event can be selected for the endpoint.
1 - 6 notification sensor:
1 - Home Security; Motion Detection, unknown loc.
2 - CO; Carbon Monoxide detected, unknown loc..
3 - CO2; Carbon Dioxide detected, unknown loc.
4 - Water Alarm; Water Leak detected, unknown loc.
5 - Heat Alarm; Overheat detected, unknown loc.
6 - Smoke Alarm; Smoke detected, unknown loc.
0 - Endpoint, I3 disabled
sensor binary (9): GENERIC_TYPE_SENSOR_BINARY, SPECIFIC_TYPE_NOT_USED
9 - Sensor binary
Default setting: 1
NOTE 1: After parameter change, first exclude module (without setting parameters to default value) then wait at least 30s and then re include the module!
NOTE 2: When the parameter is set to value 9 the notifications are send for Home Security
Set value is added or subtracted to actual measured value by sensor.
32536 - offset is 0.0C
From 1 to 100 - value from 0.1 °C to 10.0 °C is added to actual measured temperature.
From 1001 to 1100 - value from -0.1 °C to -10.0 °C is subtracted to actual measured temperature.
Default setting: 32536
If digital temperature sensor is connected, module reports measured temperature on temperature change defined by this parameter.
Default setting: 5 = 0.5 degrees centigrade
0 - reporting disabled
1 - 127 = 0,1°C - 12,7°C, step is 0,1°C
def createEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd, Map item1) {
log.debug "manufacturerId: ${cmd.manufacturerId}"
log.debug "manufacturerName: ${cmd.manufacturerName}"
log.debug "productId: ${cmd.productId}"
log.debug “productTypeId: ${cmd.productTypeId}”
}
def createEvent(physicalgraph.zwave.commands.versionv1.VersionReport cmd, Map item1) {
updateDataValue(“applicationVersion”, “${cmd.applicationVersion}”)
log.debug "applicationVersion: ${cmd.applicationVersion}"
log.debug "applicationSubVersion: ${cmd.applicationSubVersion}"
log.debug "zWaveLibraryType: ${cmd.zWaveLibraryType}"
log.debug "zWaveProtocolVersion: ${cmd.zWaveProtocolVersion}"
log.debug “zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}”
}
def createEvent(physicalgraph.zwave.commands.firmwareupdatemdv1.FirmwareMdReport cmd, Map item1) {
log.debug "checksum: ${cmd.checksum}"
log.debug "firmwareId: ${cmd.firmwareId}"
log.debug “manufacturerId: ${cmd.manufacturerId}”
'''
// log.debug “Parse received ${description}”
}