Skip to content

Instantly share code, notes, and snippets.

@dotMorten
Last active September 25, 2015 05:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dotMorten/e3ffea21730f05b7e09b to your computer and use it in GitHub Desktop.
Save dotMorten/e3ffea21730f05b7e09b to your computer and use it in GitHub Desktop.
ZBHT-2
/**
* Smartenit ZHBT-2
*
* Copyright 2015 Morten Nielsen
*
* 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.
*
*/
// ZBHT-2 Smartenit Temperature/Humidity sensor
// http://smartenit.com/product/zbht-2/
// Product brief: http://smartenit.com/sandbox/downloads/ZBHT-2_Product%20Brief.pdf
metadata {
definition (name: "Smartenit ZBHT-2", namespace: "dotMorten", author: "Morten Nielsen") {
capability "Relative Humidity Measurement"
capability "Temperature Measurement"
capability "Sensor"
capability "Battery"
//Manufacturer ID: 0x1075
//Device ID: 0x0302
//profileId
//0104 = Zigbee HA
//Cluster IDs:
//0x0000 Basic
//0x0001 Power Configuration
//0x0003 Identify
//0x0009 Alarms
//0x0402 Temperature Measurement
//0x0405 Relative Humidity Measurement
fingerprint profileId: "0104", inClusters: "0000,0001,0003,0009,0402,0405", manufacturer: "Smartenit", model: "ZBHT-2"
//Question: Do I need outClusters? Most have ' outClusters: "0019" ', but no documentation what that is
}
// simulator metadata
simulator {
for (int i = 0; i <= 100; i += 10) {
status "${i}F": "temperature: $i F"
}
for (int i = 0; i <= 100; i += 10) {
status "${i}%": "humidity: ${i}%"
}
}
// UI tile definitions
tiles {
valueTile("temperature", "device.temperature", width: 2, height: 2) {
state("temperature", label:'${currentValue}°',
backgroundColors:[
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
)
}
valueTile("humidity", "device.humidity") {
state "humidity", label:'${currentValue}%', unit:""
}
main(["temperature", "humidity"])
details(["temperature", "humidity"])
}
}
def refresh() {
log.debug "_____________refresh begin"
[
"st rattr 0x${device.deviceNetworkId} 1 0x0402 0x0000",
"st rattr 0x${device.deviceNetworkId} 1 0x0405 0x0000"
]
}
def configure() {
log.debug "_____________configure begin"
def configCmds = [
"zdo bind 0x${device.deviceNetworkId} ${endpointId} 1 1 {${device.zigbeeId}} {}", "delay 500",
"zcl global send-me-a-report 1 0x20 0x20 30 21600 {01}", //checkin time 6 hrs
"send 0x${device.deviceNetworkId} 1 ${endpointId}", "delay 500",
"zdo bind 0x${device.deviceNetworkId} ${endpointId} 1 0x402 {${device.zigbeeId}} {}", "delay 500",
"zcl global send-me-a-report 0x402 0 0x29 30 3600 {6400}",
"send 0x${device.deviceNetworkId} 1 ${endpointId}", "delay 500",
"zdo bind 0x${device.deviceNetworkId} ${endpointId} 1 0x405 {${device.zigbeeId}} {}", "delay 500",
"zcl global send-me-a-report 0x405 0 0x29 30 3600 {6400}",
"send 0x${device.deviceNetworkId} 1 ${endpointId}", "delay 500"
]
return configCmds + refresh()
}
private getEndpointId() {
new BigInteger(device.endpointId, 16).toString()
}
//Called when the device configuration has been updated
def updated() {
log.debug "___________DEBUG_____________: updated called"
configure()
}
// Parse incoming device messages to generate events
def parse(String description) {
log.debug "__________________Recieved msg:"
log.debug "${description}"
if (description?.startsWith('read attr -')) {
map = parseReportAttributeMessage(description)
def attrresult = map ? createEvent(map) : null
return attrresult;
}
null
}
private Map parseReportAttributeMessage(String description) {
Map descMap = (description - "read attr - ").split(",").inject([:]) { map, param ->
def nameAndValue = param.split(":")
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
}
Map resultMap = [:]
if (descMap.cluster == "0402" && descMap.attrId == "0000") {
def value = getTemperature(descMap.value)
return [
name: 'temperature',
value: value,
descriptionText: ""
]
}
else if (descMap.cluster == "0405" && descMap.attrId == "0000") {
def value = getHumidity(descMap.value)
return [
name: 'humidity',
value: value,
descriptionText: ""
]
}
else if (descMap.cluster == "0001" && descMap.attrId == "0020") {
return getBatteryResult(Integer.parseInt(descMap.value, 16))
}
return resultMap
}
def getTemperature(value) {
def celsius = Integer.parseInt(value, 16).shortValue() / 100
if(getTemperatureScale() == "C"){
return celsius
} else {
return celsiusToFahrenheit(celsius) as Integer
}
}
def getHumidity(value)
{
def humidity = Integer.parseInt(value, 16).shortValue() / 100
return humidity
}
private Map getBatteryResult(rawValue) {
log.debug "Battery"
log.debug rawValue
def linkText = getLinkText(device)
def result = [
name: 'battery',
value: '--'
]
def volts = rawValue / 10
def descriptionText
if (rawValue == 255) {}
else {
if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
}
else {
def minVolts = 2.1
def maxVolts = 3.0
def pct = (volts - minVolts) / (maxVolts - minVolts)
result.value = Math.min(100, (int) pct * 100)
result.descriptionText = "${linkText} battery was ${result.value}%"
}
}
return result
}
@dotMorten
Copy link
Author

@workingmonk Thanks. When pressing the refresh button, I'm told "you are not authorized to perform the requested operation" ?
I'm adding a call to configure and refresh from updated() to trigger running this code - I also press the announce button on the device right before to wake it up so it should respond immediately (hint from a Smartenit guy)

Interestingly enough when I press the "Announce" button on the device, the hue bridge is reporting it:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment