/**
* Zigbee Reporting Configuration HE driver
*
* This is a HE driver to configure the reporting settings for Zigbee devices.
*
* 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.
*
* Based on various other drivers including Hubitat crew examples, David McPaul, Markus Liljergren and many others
*
* ver. 1.0.0 2021-11-07 kkossev - first version (temperature and humidity configuration when the device awakes)
* ver. 1.0.1 2021-11-07 kkossev - added sendConfigurationToDeviceNow
*
*/
public static String version() { return "v1.0.1" }
import hubitat.device.HubAction
import hubitat.device.Protocol
import groovy.transform.Field
import hubitat.helper.HexUtils
import hubitat.device.HubMultiAction
import hubitat.zigbee.zcl.DataType
import hubitat.zigbee.clusters.iaszone.ZoneStatus
import java.util.concurrent.*
// Field annotation makes these variables global to the class
@Field static java.util.concurrent.Semaphore mutex = new java.util.concurrent.Semaphore(1)
@Field static def queueMap = [:]
@Field static def displayCounter
@Field static def timeoutCounter
metadata {
definition (name: "Zigbee Reporting Configuration", namespace: "kkossev", author: "Krassimir Kossev", importUrl: "https://raw.githubusercontent.com/kkossev/Hubitat/main/Drivers/Zigbee%20Reporting%20Configuration/Zigbee%20Reporting%20Configuration.groovy" ) {
capability "TemperatureMeasurement"
capability "RelativeHumidityMeasurement"
capability "PressureMeasurement" // pressure - NUMBER, unit: Pa || psi ???
capability "Battery"
capability "Initialize"
attribute "_1", "string" // when defined as attributes, will be shown on top of the 'Current States' list ...
attribute "_2", "string"
attribute "_3", "string"
command "configureTemperatureReporting", [
[name: "Minimum Reporting Interval (seconds)", type: "ENUM", constraints: ["10", "1", "5", "30", "60", "120", "300", "600"], description: "Select Minimum reporting time (in seconds)"],
[name: "Maximum Reporting Interval (seconds)", type: "ENUM", constraints: ["3600", "120", "300", "600", "900", "1800", "7200", "43200"], description: "Select Maximim reporting time (in seconds)"],
[name: "Minimum measurement change (degrees)", type: "ENUM", constraints: ["0.25", "0.01", "0.05", "0.10", "0.50", "1.00", "2.0", "5.0"], description: "Select Minimum measurement change to be reported"]
]
command "configureHumidityReporting", [
[name: "Minimum Reporting Interval (seconds)", type: "ENUM", constraints: ["10", "1", "5", "30", "60", "120", "300", "600"], description: "Select Minimum reporting time (in seconds)"],
[name: "Maximum Reporting Interval (seconds)", type: "ENUM", constraints: ["3600", "120", "300", "600", "900", "1800", "7200", "43200"], description: "Select Maximim reporting time (in seconds)"],
[name: "Minimum measurement change (percent)", type: "ENUM", constraints: ["1", "0.1", "0.5", "2.5", "5", "10" ], description: "Select Minimum measurement change to be reported (percent)"]
]
/*
command "configurePressureReporting", [
[name: "Minimum Reporting Interval (seconds)", type: "ENUM", constraints: ["10", "1", "5", "30", "60", "120", "300", "600"], description: "Select Minimum reporting time (in seconds)"],
[name: "Maximum Reporting Interval (seconds)", type: "ENUM", constraints: ["3600", "120", "300", "600", "900", "1800", "7200", "43200"], description: "Select Maximim reporting time (in seconds)"],
[name: "Minimum measurement change (Pa)", type: "ENUM", constraints: ["10", "1", "50", "100", "500", "1000", "10000" ], description: "Select Minimum measurement change to be reported (Pa)"]
]
*/
command "sendConfigurationToDeviceWhenAwake"
command "sendConfigurationToDeviceNow"
command "getDeviceInfo"
//command "identify" //, [[name: "identify", type: "STRING", description: "flash a light with a period of 0.5 seconds"]]
//command "test"
fingerprint inClusters: "0000,0001,0003,0004,0006,1000", outClusters: "0019,000A,0003,0004,0005,0006,0008,1000", manufacturer: "ANY", model: "ANY", deviceJoinName: "Zigbee Reporting Configuration"
}
preferences {
input (name: "traceEnable", type: "bool", title: "Enable trace logging", defaultValue: true)
input (name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true)
input (name: "txtEnable", type: "bool", title: "Enable description text logging", defaultValue: true)
input (name: "repairAggressive", type: "bool", title: "Re-pair with aggressive reporting settings", defaultValue: false)
/*
input name: "param1", title: "Selective reporting - Threshold Temperature", description: "°C", type: "enum",
options:[[0:"Disabled (only time-based reports)"], [1:"0.1°C"], [2:"0.2°C"], [3:"0.3°C"], [4:"0.4°C"], [5:"0.5°C"], [10:"1°C"], [15:"1.5°C"], [20:"2°C"], [25:"2.5°C"], [30:"3°C"], [40:"4°C"], [50:"5°C"]],
defaultValue: 5, required: true
*/
// input name: 'loggingDuration', type: 'enum', title: 'Enable Logging?', description: '
Automatically disables after selected time.
', options: [0: 'Disabled', 1800: '30 Minutes', 3600: '1 Hour', 86400: '24 Hours'], defaultValue: 0
}
}
// Constants
@Field static final Integer CONST = 0
// Parse incoming device messages to generate events
//
//parsers
void parse(String description) {
//
deviceReported()
//
Map descMap = zigbee.parseDescriptionAsMap(description)
if (logEnable) log.debug "descMap:${descMap}"
String status
if (descMap.clusterId != null && descMap.profileId == "0104") {
if (descMap.isClusterSpecific == false) { //global commands
processGlobalCommand(descMap)
} else { //cluster specific
switch (descMap.clusterId) {
case "0004": //group
processGroupCommand(descMap)
break
case "0006":
log.info "cluster: ${descMap.clusterId} command: ${descMap.command}"
break
default :
if (logEnable) log.warn "skipped cluster specific command cluster:${descMap.clusterId}, command:${descMap.command}, data:${descMap.data}"
}
}
return
} else if (descMap.profileId == "0000") { //zdo
switch (descMap.clusterId) {
case "8005" : //endpoint response
def endpointCount = descMap.data[4]
def endpointList = descMap.data[5]
log.info "zdo command: cluster: ${descMap.clusterId} (endpoint response) endpointCount = ${endpointCount} endpointList = ${endpointList}"
break
case "8004" : //simple descriptor response
log.info "zdo command: cluster: ${descMap.clusterId} (simple descriptor response)"
break
case "8034" : //leave response
log.info "zdo command: cluster: ${descMap.clusterId} (leave response)"
break
case "8021" : //bind response
log.info "zdo command: cluster: ${descMap.clusterId} (bind response)"
break
case "8022" : //unbind request
log.info "zdo command: cluster: ${descMap.clusterId} (unbind request)"
break
case "0013" : //"device announce"
log.info "zdo command: cluster: ${descMap.clusterId} (device announce)"
if (logEnable) log.trace "device announce..."
break
default :
if (logEnable) log.warn "skipped UNKNOWN zdo cluster: ${descMap.clusterId}"
}
return
}
List