From 4ad1a400ebe77184258190c30846ca672692c48a Mon Sep 17 00:00:00 2001
From: PKacprowiczS
Date: Tue, 16 Jun 2020 15:31:09 +0200
Subject: [PATCH 1/6] New DTH for Qubino Flush 2 Relay
---
.../qubino-flush-2-relay.groovy | 472 ++++++++++++++++++
1 file changed, 472 insertions(+)
create mode 100644 devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
diff --git a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
new file mode 100644
index 00000000000..5ec40218af1
--- /dev/null
+++ b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
@@ -0,0 +1,472 @@
+/**
+ * Copyright 2020 SRPOL
+ *
+ * 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: "Qubino Flush 2 Relay", namespace: "qubino", author: "SmartThings", mnmn: "SmartThings", vid: "generic-switch-power-energy") {
+ capability "Switch"
+ capability "Power Meter"
+ capability "Energy Meter"
+ capability "Refresh"
+ capability "Actuator"
+ capability "Sensor"
+ capability "Health Check"
+
+ command "reset"
+
+ fingerprint mfr: "0159", prod: "0002", model: "0051", deviceJoinName: "Qubino Switch 1" //Qubino Flush 2 Relay
+ }
+
+ tiles(scale: 2) {
+ multiAttributeTile(name:"switch", type: "generic", 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: "#00a0dc")
+ attributeState("off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff")
+ }
+ }
+ 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("refresh", "device.power", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
+ state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
+ }
+ standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
+ state "default", label:'reset kWh', action:"reset"
+ }
+
+ main(["switch"])
+ details(["switch","power","energy","refresh","reset"])
+ }
+
+ preferences {
+ parameterMap.each {
+ input (title: it.name, description: it.description, type: "paragraph", element: "paragraph")
+
+ switch(it.type) {
+ case "boolRange":
+ input(name: it.key + "Boolean", type: "bool", title: "Enable",
+ description: "If you disable this option, it will overwrite setting below.",
+ defaultValue: it.defaultValue != it.disableValue, required: false
+ )
+ input(name: it.key, type: "number", title: "Set value (range ${it.range})", defaultValue: it.defaultValue,
+ range: it.range, required: false
+ )
+ break
+ case "boolean":
+ input(type: "paragraph", element: "paragraph", description: "Option enabled: ${it.activeDescription}\n" +
+ "Option disabled: ${it.inactiveDescription}"
+ )
+ input(name: it.key, type: "boolean", title: "Enable", defaultValue: it.defaultValue == it.activeOption, required: false)
+ break
+ case "enum":
+ input(name: it.key, title: "Select", type: "enum", options: it.values, defaultValue: it.defaultValue, required: false)
+ break
+ case "range":
+ input(name: it.key, type: "number", title: "Set value (range ${it.range})", defaultValue: it.defaultValue, range: it.range, required: false)
+ break
+ }
+ }
+ }
+}
+
+def installed() {
+ state.numberOfSwitches = 2
+ if (!childDevices) {
+ addChildSwitches(state.numberOfSwitches)
+ }
+ sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID, offlinePingable: "1"])
+ // Preferences template begin
+ state.currentPreferencesState = [:]
+ parameterMap.each {
+ state.currentPreferencesState."$it.key" = [:]
+ state.currentPreferencesState."$it.key".value = getPreferenceValue(it)
+ if (it.type == "boolRange" && getPreferenceValue(it) == it.disableValue) {
+ state.currentPreferencesState."$it.key".status = "disablePending"
+ } else {
+ def preferenceName = it.key + "Boolean"
+ settings."$preferenceName" = true
+ state.currentPreferencesState."$it.key".status = "synced"
+ }
+ }
+ // Preferences template end
+}
+
+def updated() {
+ if (!childDevices) {
+ addChildSwitches(state.numberOfSwitches)
+ }
+ // Preferences template begin
+ parameterMap.each {
+ if (isPreferenceChanged(it)) {
+ log.debug "Preference ${it.key} has been updated from value: ${state.currentPreferencesState."$it.key".value} to ${settings."$it.key"}"
+ state.currentPreferencesState."$it.key".status = "syncPending"
+ if (it.type == "boolRange") {
+ def preferenceName = it.key + "Boolean"
+ if (settings."$preferenceName" != null) {
+ if (!settings."$preferenceName") {
+ state.currentPreferencesState."$it.key".status = "disablePending"
+ } else if (state.currentPreferencesState."$it.key".status == "disabled") {
+ state.currentPreferencesState."$it.key".status = "syncPending"
+ }
+ } else {
+ state.currentPreferencesState."$it.key".status = "syncPending"
+ }
+ }
+ } else if (!state.currentPreferencesState."$it.key".value) {
+ log.warn "Preference ${it.key} no. ${it.parameterNumber} has no value. Please check preference declaration for errors."
+ }
+ }
+ syncConfiguration()
+ // Preferences template end
+}
+
+private syncConfiguration() {
+ def commands = []
+ parameterMap.each {
+ try {
+ if (state.currentPreferencesState."$it.key".status == "syncPending") {
+ commands += encap(zwave.configurationV2.configurationSet(scaledConfigurationValue: getCommandValue(it), parameterNumber: it.parameterNumber, size: it.size))
+ commands += encap(zwave.configurationV2.configurationGet(parameterNumber: it.parameterNumber))
+ } else if (state.currentPreferencesState."$it.key".status == "disablePending") {
+ commands += encap(zwave.configurationV2.configurationSet(scaledConfigurationValue: it.disableValue, parameterNumber: it.parameterNumber, size: it.size))
+ commands += encap(zwave.configurationV2.configurationGet(parameterNumber: it.parameterNumber))
+ }
+ } catch (e) {
+ log.warn "There's been an issue with preference: ${it.key}"
+ }
+ }
+ sendHubCommand(commands)
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd, ep = null) {
+ // Preferences template begin
+ log.debug "Configuration report: ${cmd}"
+ def preference = parameterMap.find( {it.parameterNumber == cmd.parameterNumber} )
+ def key = preference.key
+ def preferenceValue = getPreferenceValue(preference, cmd.scaledConfigurationValue)
+ if (settings."$key" == preferenceValue) {
+ state.currentPreferencesState."$key".value = settings."$key"
+ state.currentPreferencesState."$key".status = "synced"
+ } else if (preference.type == "boolRange") {
+ if (state.currentPreferencesState."$key".status == "disablePending" && preferenceValue == preference.disableValue) {
+ state.currentPreferencesState."$key".status = "disabled"
+ } else {
+ runIn(5, "syncConfiguration", [overwrite: true])
+ }
+ } else {
+ state.currentPreferencesState."$key"?.status = "syncPending"
+ runIn(5, "syncConfiguration", [overwrite: true])
+ }
+ // Preferences template end
+}
+
+private getPreferenceValue(preference, value = "default") {
+ def integerValue = value == "default" ? preference.defaultValue : value.intValue()
+ switch (preference.type) {
+ case "enum":
+ return String.valueOf(integerValue)
+ case "boolean":
+ return String.valueOf(preference.optionActive == integerValue)
+ default:
+ return integerValue
+ }
+}
+
+private getCommandValue(preference) {
+ def parameterKey = preference.key
+ switch (preference.type) {
+ case "boolean":
+ return settings."$parameterKey" ? preference.optionActive : preference.optionInactive
+ case "boolRange":
+ def parameterKeyBoolean = parameterKey + "Boolean"
+ return settings."$parameterKeyBoolean" == null || settings."$parameterKeyBoolean" ? settings."$parameterKey" : preference.disableValue
+ case "range":
+ return settings."$parameterKey"
+ default:
+ return Integer.parseInt(settings."$parameterKey")
+ }
+}
+
+private isPreferenceChanged(preference) {
+ if (settings."$preference.key" != null) {
+ def value = state.currentPreferencesState."$preference.key"
+ switch (preference.type) {
+ case "boolRange":
+ def boolName = preference.key + "Boolean"
+ if (state.currentPreferencesState."$preference.key".status == "disabled") {
+ return settings."$boolName"
+ } else {
+ return state.currentPreferencesState."$preference.key".value != settings."$preference.key" || !settings."$boolName"
+ }
+ default:
+ return state.currentPreferencesState."$preference.key".value != settings."$preference.key"
+ }
+ } else {
+ return false
+ }
+}
+
+def parse(String description) {
+ def result = null
+ if (description.startsWith("Err")) {
+ result = createEvent(descriptionText:description, isStateChange:true)
+ } else if (description != "updated") {
+ def cmd = zwave.parse(description)
+ if (cmd) {
+ result = zwaveEvent(cmd, null)
+ }
+ }
+ log.debug "parsed '${description}' to ${result.inspect()}"
+ result
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.securityv1.SecurityMessageEncapsulation cmd, ep = null) {
+ log.debug "Security Message Encap ${cmd}"
+ def encapsulatedCommand = cmd.encapsulatedCommand()
+ if (encapsulatedCommand) {
+ zwaveEvent(encapsulatedCommand, null)
+ } else {
+ log.warn "Unable to extract encapsulated cmd from $cmd"
+ createEvent(descriptionText: cmd.toString())
+ }
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd, ep = null) {
+ log.debug "Multichannel command ${cmd}" + (ep ? " from endpoint $ep" : "")
+ if (cmd.commandClass == 0x6C && cmd.parameter.size >= 4) { // Supervision encapsulated Message
+ // Supervision header is 4 bytes long, two bytes dropped here are the latter two bytes of the supervision header
+ cmd.parameter = cmd.parameter.drop(2)
+ // Updated Command Class/Command now with the remaining bytes
+ cmd.commandClass = cmd.parameter[0]
+ cmd.command = cmd.parameter[1]
+ cmd.parameter = cmd.parameter.drop(2)
+ }
+ def encapsulatedCommand = cmd.encapsulatedCommand()
+ zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, ep = null) {
+ log.debug "Basic ${cmd}" + (ep ? " from endpoint $ep" : "")
+ changeSwitch(ep, cmd)
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd, ep = null) {
+ log.debug "Binary ${cmd}" + (ep ? " from endpoint $ep" : "")
+ changeSwitch(ep, cmd)
+}
+
+private changeSwitch(endpoint, cmd) {
+ def value = cmd.value ? "on" : "off"
+ if (endpoint == 1) {
+ createEvent(name: "switch", value: value, isStateChange: true, descriptionText: "Switch ${endpoint} is ${value}")
+ } else if (endpoint) {
+ String childDni = "${device.deviceNetworkId}:$endpoint"
+ def child = childDevices.find { it.deviceNetworkId == childDni }
+ child?.sendEvent(name: "switch", value: value, isStateChange: true, descriptionText: "Switch ${endpoint} is ${value}")
+ }
+}
+
+def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd, ep = null) {
+ log.debug "Meter ${cmd}" + (ep ? " from endpoint $ep" : "")
+ if (ep == 1) {
+ createEvent(createMeterEventMap(cmd))
+ } else if (ep) {
+ String childDni = "${device.deviceNetworkId}:$ep"
+ def child = childDevices.find { it.deviceNetworkId == childDni }
+ child?.sendEvent(createMeterEventMap(cmd))
+ }
+}
+
+private createMeterEventMap(cmd) {
+ def eventMap = [:]
+ if (cmd.meterType == 1) {
+ if (cmd.scale == 0) {
+ eventMap.name = "energy"
+ eventMap.value = cmd.scaledMeterValue
+ eventMap.unit = "kWh"
+ } else if (cmd.scale == 2) {
+ eventMap.name = "power"
+ eventMap.value = Math.round(cmd.scaledMeterValue)
+ eventMap.unit = "W"
+ }
+ }
+ eventMap
+}
+
+def zwaveEvent(physicalgraph.zwave.Command cmd, ep) {
+ log.warn "Unhandled ${cmd}" + (ep ? " from endpoint $ep" : "")
+}
+
+def on() {
+ onOffCmd(0xFF)
+}
+
+def off() {
+ onOffCmd(0x00)
+}
+
+def ping() {
+ refresh()
+}
+
+def childOnOff(deviceNetworkId, value) {
+ def switchId = getSwitchId(deviceNetworkId)
+ if (switchId != null) sendHubCommand onOffCmd(value, switchId)
+}
+
+private onOffCmd(value, endpoint = 1) {
+ delayBetween([
+ encap(zwave.basicV1.basicSet(value: value), endpoint),
+ encap(zwave.basicV1.basicGet(), endpoint),
+ ])
+}
+
+private refreshAll(includeMeterGet = true) {
+
+ def endpoints = [1]
+
+ childDevices.each {
+ def switchId = getSwitchId(it.deviceNetworkId)
+ if (switchId != null) {
+ endpoints << switchId
+ }
+ }
+ sendHubCommand refresh(endpoints,includeMeterGet)
+}
+
+def childRefresh(deviceNetworkId, includeMeterGet = true) {
+ def switchId = getSwitchId(deviceNetworkId)
+ if (switchId != null) {
+ sendHubCommand refresh([switchId],includeMeterGet)
+ }
+}
+
+def refresh(endpoints = [1], includeMeterGet = true) {
+
+ def cmds = []
+
+ endpoints.each {
+ cmds << [encap(zwave.basicV1.basicGet(), it)]
+ if (includeMeterGet) {
+ cmds << encap(zwave.meterV3.meterGet(scale: 0), it)
+ cmds << encap(zwave.meterV3.meterGet(scale: 2), it)
+ }
+ }
+
+ delayBetween(cmds, 200)
+}
+
+private resetAll() {
+ childDevices.each { childReset(it.deviceNetworkId) }
+ sendHubCommand reset()
+}
+
+def childReset(deviceNetworkId) {
+ def switchId = getSwitchId(deviceNetworkId)
+ if (switchId != null) {
+ log.debug "Child reset switchId: ${switchId}"
+ sendHubCommand reset(switchId)
+ }
+}
+
+def reset(endpoint = 1) {
+ log.debug "Resetting endpoint: ${endpoint}"
+ delayBetween([
+ encap(zwave.meterV3.meterReset(), endpoint),
+ encap(zwave.meterV3.meterGet(scale: 0), endpoint),
+ "delay 500"
+ ], 500)
+}
+
+def getSwitchId(deviceNetworkId) {
+ def split = deviceNetworkId?.split(":")
+ return (split.length > 1) ? split[1] as Integer : null
+}
+
+private encap(cmd, endpoint = null) {
+ if (cmd) {
+ if (endpoint) {
+ cmd = zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint: endpoint).encapsulate(cmd)
+ }
+
+ if (zwaveInfo.zw.contains("s")) {
+ zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
+ } else {
+ cmd.format()
+ }
+ }
+}
+
+private addChildSwitches(numberOfSwitches) {
+ for (def endpoint : 2..numberOfSwitches) {
+ try {
+ String childDni = "${device.deviceNetworkId}:$endpoint"
+ def componentLabel = device.displayName[0..-2] + "${endpoint}"
+ addChildDevice("smartthings", "Child Metering Switch", childDni, device.getHub().getId(), [
+ completedSetup : true,
+ label : componentLabel,
+ isComponent : false
+ ])
+ } catch(Exception e) {
+ log.warn "Exception: ${e}"
+ }
+ }
+}
+
+private getParameterMap() {[
+ [
+ name: "Input 1 switch type", key: "input1SwitchType", type: "enum",
+ parameterNumber: 1, size: 1, defaultValue: 1,
+ values: [
+ 0: "Mono-stable switch type (push button)",
+ 1: "Bi-stable switch type",
+ ],
+ description: "Input 1 switch type"
+ ],
+ [
+ name: "Input 2 switch type", key: "input2SwitchType", type: "enum",
+ parameterNumber: 2, size: 1, defaultValue: 1,
+ values: [
+ 0: "Mono-stable switch type (push button)",
+ 1: "Bi-stable switch type",
+ ],
+ description: "Input 2 switch type"
+ ],
+ [
+ name: "Saving the state of the relays Q1 and Q2 after a power failure", key: "savingTheStateOfTheRelaysQ1AndQ2AfterAPowerFailure", type: "boolean",
+ parameterNumber: 30, size: 1, defaultValue: 0,
+ optionInactive: 0, inactiveDescription: "State is saved and brought back after a power failure",
+ optionActive: 1, activeDescription: "State is not saved, outputs will be off after a power failure",
+ description: "Saving the state of the relays Q1 and Q2 after a power failure"
+ ],
+ [
+ name: "Output Q1 Switch selection", key: "outputQ1SwitchSelection", type: "enum",
+ parameterNumber: 63, size: 1, defaultValue: 0,
+ values: [
+ 0: "When system is turned off the output is 0V (NC).",
+ 1: "When system is turned off the output is 230V (NO).",
+ ],
+ description: "Set value means the type of the device that is connected to the Q1 output. The device type can be normally open (NO) or normally close (NC). "
+ ],
+ [
+ name: "Output Q2 Switch selection", key: "outputQ2SwitchSelection", type: "enum",
+ parameterNumber: 64, size: 1, defaultValue: 0,
+ values: [
+ 0: "When system is turned off the output is 0V (NC).",
+ 1: "When system is turned off the output is 230V (NO).",
+ ],
+ description: "Set value means the type of the device that is connected to the Q2 output. The device type can be normally open (NO) or normally close (NC). "
+ ]
+]}
\ No newline at end of file
From d7d9baa7854d8bc1d68157de2aebe0bf38c01207 Mon Sep 17 00:00:00 2001
From: PKacprowiczS
Date: Wed, 17 Jun 2020 16:44:51 +0200
Subject: [PATCH 2/6] Added temperature sensor to DTH and removed not used
boilerplate
---
.../qubino-flush-2-relay.groovy | 114 +++++++-----------
1 file changed, 46 insertions(+), 68 deletions(-)
diff --git a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
index 5ec40218af1..f89c0b59b8a 100644
--- a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
+++ b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
@@ -55,15 +55,6 @@ metadata {
input (title: it.name, description: it.description, type: "paragraph", element: "paragraph")
switch(it.type) {
- case "boolRange":
- input(name: it.key + "Boolean", type: "bool", title: "Enable",
- description: "If you disable this option, it will overwrite setting below.",
- defaultValue: it.defaultValue != it.disableValue, required: false
- )
- input(name: it.key, type: "number", title: "Set value (range ${it.range})", defaultValue: it.defaultValue,
- range: it.range, required: false
- )
- break
case "boolean":
input(type: "paragraph", element: "paragraph", description: "Option enabled: ${it.activeDescription}\n" +
"Option disabled: ${it.inactiveDescription}"
@@ -73,9 +64,6 @@ metadata {
case "enum":
input(name: it.key, title: "Select", type: "enum", options: it.values, defaultValue: it.defaultValue, required: false)
break
- case "range":
- input(name: it.key, type: "number", title: "Set value (range ${it.range})", defaultValue: it.defaultValue, range: it.range, required: false)
- break
}
}
}
@@ -92,13 +80,9 @@ def installed() {
parameterMap.each {
state.currentPreferencesState."$it.key" = [:]
state.currentPreferencesState."$it.key".value = getPreferenceValue(it)
- if (it.type == "boolRange" && getPreferenceValue(it) == it.disableValue) {
- state.currentPreferencesState."$it.key".status = "disablePending"
- } else {
- def preferenceName = it.key + "Boolean"
- settings."$preferenceName" = true
- state.currentPreferencesState."$it.key".status = "synced"
- }
+ def preferenceName = it.key + "Boolean"
+ settings."$preferenceName" = true
+ state.currentPreferencesState."$it.key".status = "synced"
}
// Preferences template end
}
@@ -112,18 +96,6 @@ def updated() {
if (isPreferenceChanged(it)) {
log.debug "Preference ${it.key} has been updated from value: ${state.currentPreferencesState."$it.key".value} to ${settings."$it.key"}"
state.currentPreferencesState."$it.key".status = "syncPending"
- if (it.type == "boolRange") {
- def preferenceName = it.key + "Boolean"
- if (settings."$preferenceName" != null) {
- if (!settings."$preferenceName") {
- state.currentPreferencesState."$it.key".status = "disablePending"
- } else if (state.currentPreferencesState."$it.key".status == "disabled") {
- state.currentPreferencesState."$it.key".status = "syncPending"
- }
- } else {
- state.currentPreferencesState."$it.key".status = "syncPending"
- }
- }
} else if (!state.currentPreferencesState."$it.key".value) {
log.warn "Preference ${it.key} no. ${it.parameterNumber} has no value. Please check preference declaration for errors."
}
@@ -159,12 +131,6 @@ def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport
if (settings."$key" == preferenceValue) {
state.currentPreferencesState."$key".value = settings."$key"
state.currentPreferencesState."$key".status = "synced"
- } else if (preference.type == "boolRange") {
- if (state.currentPreferencesState."$key".status == "disablePending" && preferenceValue == preference.disableValue) {
- state.currentPreferencesState."$key".status = "disabled"
- } else {
- runIn(5, "syncConfiguration", [overwrite: true])
- }
} else {
state.currentPreferencesState."$key"?.status = "syncPending"
runIn(5, "syncConfiguration", [overwrite: true])
@@ -189,11 +155,6 @@ private getCommandValue(preference) {
switch (preference.type) {
case "boolean":
return settings."$parameterKey" ? preference.optionActive : preference.optionInactive
- case "boolRange":
- def parameterKeyBoolean = parameterKey + "Boolean"
- return settings."$parameterKeyBoolean" == null || settings."$parameterKeyBoolean" ? settings."$parameterKey" : preference.disableValue
- case "range":
- return settings."$parameterKey"
default:
return Integer.parseInt(settings."$parameterKey")
}
@@ -201,18 +162,7 @@ private getCommandValue(preference) {
private isPreferenceChanged(preference) {
if (settings."$preference.key" != null) {
- def value = state.currentPreferencesState."$preference.key"
- switch (preference.type) {
- case "boolRange":
- def boolName = preference.key + "Boolean"
- if (state.currentPreferencesState."$preference.key".status == "disabled") {
- return settings."$boolName"
- } else {
- return state.currentPreferencesState."$preference.key".value != settings."$preference.key" || !settings."$boolName"
- }
- default:
- return state.currentPreferencesState."$preference.key".value != settings."$preference.key"
- }
+ return state.currentPreferencesState."$preference.key".value != settings."$preference.key"
} else {
return false
}
@@ -305,6 +255,29 @@ private createMeterEventMap(cmd) {
eventMap
}
+def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelReport cmd, ep = null) {
+ log.debug "SensorMultilevelReport ${cmd}" + (ep ? " from endpoint $ep" : "")
+ def result = []
+
+ def map = [:]
+ switch (cmd.sensorType) {
+ case 1:
+ map.name = "temperature"
+ def cmdScale = cmd.scale == 1 ? "F" : "C"
+ map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
+ map.unit = getTemperatureScale()
+ break
+ default:
+ map.descriptionText = cmd.toString()
+ }
+ def child = childDevices.find { it.deviceNetworkId == state.temperatureSensorDni }
+ if (!child) {
+ addChildTemperatureSensor()
+ }
+ child?.sendEvent(map)
+ createEvent(map)
+}
+
def zwaveEvent(physicalgraph.zwave.Command cmd, ep) {
log.warn "Unhandled ${cmd}" + (ep ? " from endpoint $ep" : "")
}
@@ -333,19 +306,6 @@ private onOffCmd(value, endpoint = 1) {
])
}
-private refreshAll(includeMeterGet = true) {
-
- def endpoints = [1]
-
- childDevices.each {
- def switchId = getSwitchId(it.deviceNetworkId)
- if (switchId != null) {
- endpoints << switchId
- }
- }
- sendHubCommand refresh(endpoints,includeMeterGet)
-}
-
def childRefresh(deviceNetworkId, includeMeterGet = true) {
def switchId = getSwitchId(deviceNetworkId)
if (switchId != null) {
@@ -369,7 +329,11 @@ def refresh(endpoints = [1], includeMeterGet = true) {
}
private resetAll() {
- childDevices.each { childReset(it.deviceNetworkId) }
+ childDevices.each {
+ if (it.deviceNetworkId != state.temperatureSensorDni) {
+ childReset(it.deviceNetworkId)
+ }
+ }
sendHubCommand reset()
}
@@ -425,6 +389,20 @@ private addChildSwitches(numberOfSwitches) {
}
}
+private addChildTemperatureSensor() {
+ try {
+ String childDni = "${device.deviceNetworkId}:${state.numberOfSwitches + 1}"
+ state.temperatureSensorDni = childDni
+ addChildDevice("qubino", "Child Temperature Sensor", childDni, device.getHub().getId(), [
+ completedSetup : true,
+ label : "Qubino Temperature Sensor",
+ isComponent : false
+ ])
+ } catch(Exception e) {
+ log.warn "Exception: ${e}"
+ }
+}
+
private getParameterMap() {[
[
name: "Input 1 switch type", key: "input1SwitchType", type: "enum",
From 0be4ea386574f2dc0d6f47c31c6a77f2ad5b60c7 Mon Sep 17 00:00:00 2001
From: Przemyslaw Kacprowicz
Date: Wed, 24 Jun 2020 11:13:25 +0200
Subject: [PATCH 3/6] fixup! Added temperature sensor to DTH and removed not
used boilerplate
---
.../qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy | 1 +
1 file changed, 1 insertion(+)
diff --git a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
index f89c0b59b8a..6bd51e3b652 100644
--- a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
+++ b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
@@ -273,6 +273,7 @@ def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelR
def child = childDevices.find { it.deviceNetworkId == state.temperatureSensorDni }
if (!child) {
addChildTemperatureSensor()
+ child = childDevices.find { it.deviceNetworkId == state.temperatureSensorDni }
}
child?.sendEvent(map)
createEvent(map)
From da2ed9dc86ea01eef892bd385ae5dbfc547977e3 Mon Sep 17 00:00:00 2001
From: PKacprowiczS
Date: Thu, 25 Jun 2020 07:41:41 +0200
Subject: [PATCH 4/6] Quick refactoring temperature sensor child device
initialization
---
.../qubino-flush-2-relay.src/qubino-flush-2-relay.groovy | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
index 6bd51e3b652..1087225b022 100644
--- a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
+++ b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
@@ -272,8 +272,7 @@ def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv5.SensorMultilevelR
}
def child = childDevices.find { it.deviceNetworkId == state.temperatureSensorDni }
if (!child) {
- addChildTemperatureSensor()
- child = childDevices.find { it.deviceNetworkId == state.temperatureSensorDni }
+ child = addChildTemperatureSensor()
}
child?.sendEvent(map)
createEvent(map)
@@ -394,11 +393,12 @@ private addChildTemperatureSensor() {
try {
String childDni = "${device.deviceNetworkId}:${state.numberOfSwitches + 1}"
state.temperatureSensorDni = childDni
- addChildDevice("qubino", "Child Temperature Sensor", childDni, device.getHub().getId(), [
+ def childDevice = addChildDevice("qubino", "Child Temperature Sensor", childDni, device.getHub().getId(), [
completedSetup : true,
label : "Qubino Temperature Sensor",
isComponent : false
])
+ childDevice
} catch(Exception e) {
log.warn "Exception: ${e}"
}
From f31521581f97bc0b3105c3dbf89e58221fc100ef Mon Sep 17 00:00:00 2001
From: PKacprowiczS
Date: Mon, 29 Jun 2020 11:34:07 +0200
Subject: [PATCH 5/6] Renamed temperature sensor's DTH
---
.../qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
index 1087225b022..be60b0cced4 100644
--- a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
+++ b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
@@ -393,7 +393,7 @@ private addChildTemperatureSensor() {
try {
String childDni = "${device.deviceNetworkId}:${state.numberOfSwitches + 1}"
state.temperatureSensorDni = childDni
- def childDevice = addChildDevice("qubino", "Child Temperature Sensor", childDni, device.getHub().getId(), [
+ def childDevice = addChildDevice("qubino", "Qubino Temperature Sensor", childDni, device.getHub().getId(), [
completedSetup : true,
label : "Qubino Temperature Sensor",
isComponent : false
From c570a088d1b40e16d0166bd5e82f140fa7f138f8 Mon Sep 17 00:00:00 2001
From: PKacprowiczS
Date: Thu, 2 Jul 2020 15:15:18 +0200
Subject: [PATCH 6/6] Removed offlinePingable flag, changed zwaveEvent method
call
---
.../qubino-flush-2-relay.src/qubino-flush-2-relay.groovy | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
index be60b0cced4..431dadc8a5e 100644
--- a/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
+++ b/devicetypes/qubino/qubino-flush-2-relay.src/qubino-flush-2-relay.groovy
@@ -74,7 +74,7 @@ def installed() {
if (!childDevices) {
addChildSwitches(state.numberOfSwitches)
}
- sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID, offlinePingable: "1"])
+ sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
// Preferences template begin
state.currentPreferencesState = [:]
parameterMap.each {
@@ -175,7 +175,7 @@ def parse(String description) {
} else if (description != "updated") {
def cmd = zwave.parse(description)
if (cmd) {
- result = zwaveEvent(cmd, null)
+ result = zwaveEvent(cmd)
}
}
log.debug "parsed '${description}' to ${result.inspect()}"