It was (since deleted) a custom (my me) driver to read the temperature of a SHT30 sensor through a Zigbee cc2530 radio.
I've had others (slightly different) running for a couple of years (C5 --> C8). I've deleted it as a potential lockup cause.
/* Hubitat driver for SHT30 -> PTVO CC2530 Zigbee Board
2022-05-22 SHT30_03
revamped the parse structure
2022-05-25 SHT30_04
Added Max and Min + start schedule Max & Min are currently in Deg C
2022-06-3 SHT30_043b
fixed Dew Point Calculations, fix state.Min.
Released as SHT30_044
2024-08-17 v5.1 with a new ptvo program (may not be related) the 0x000c cluster isn't working.
Temperature = 0x0402, Humidity = 0x0405
todo:
Add Heat Index
Note; enum's will be of Type string no matter what you assign to them.
*/
metadata {
definition(name: "SHT30 Zigbee v5.3", namespace: "johnrob", author: "johnr")
{
capability "Actuator"
capability "Sensor"
capability "Initialize" // runs at restart!
capability "TemperatureMeasurement"
capability "RelativeHumidityMeasurement"
attribute "DewPoint", "string"
attribute "DewPointdepression", "string"
fingerprint profileId: "0104", inClusters: "0000", outClusters: "0000, 0402, 0405"
}
preferences{
input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: false
input name: "logTrace", type: "bool", title: "Enable trace logging", defaultValue: false
input name: "displayUnits", type: "enum", title: "Temperature Units", options: ["1":"°C","0":"°F"], defaultValue: 0, required: false
}
} // --- metadata ---
// -------------------------------------------------------------------------------------------------------------
// ---- parse --------------------------------------------------------------------------------------------------
def parse(String description){
if (logEnable) log.info " Raw Description= $description"
if (description?.startsWith('read attr -')){ // in testing all messages are 'read attr -''
Map descMap = zigbee.parseDescriptionAsMap(description)
if (logEnable) log.info " descMap= $descMap"
if (descMap.cluster == "0402"){
SHThexData = descMap.value // the HEX value is 100 x the actual temperature
float SensorValue = hubitat.helper.HexUtils.hexStringToInt(SHThexData)
if (displayUnits == "0"){ // 0 = °F
SensorValue = SensorValue * 9/5 + 3200
SensorValue = Math.round(SensorValue / 10)
SensorValue = SensorValue / 10
sendEvent(name: "temperature", value: SensorValue , unit:"°F")
}
else{
SensorValue = Math.round(SensorValue / 10)
SensorValue = SensorValue / 10
float dewSensorTempC = SensorValue
sendEvent(name: "temperature", value: SensorValue , unit:"°C")
}
updateMaxMin(SensorValue)
} // if 0402
else if (descMap.cluster == "0405"){ // || descMap.cluster == "0405")
SHThexData = descMap.value
float SensorValue = hubitat.helper.HexUtils.hexStringToInt(SHThexData)
SensorValue = Math.round(SensorValue / 10)
SensorValue = SensorValue / 10
sendEvent(name: "humidity", value: SensorValue , unit:"% RH")
}
DewPoint(device.currentValue("temperature"), device.currentValue("humidity"),displayUnits)
} // --- if "read attr" ---
} // --- parse ---
// -------------------------------------------------------------------------------------------------------------
// ---- methods ------------------------------------------------------------------------------------------------
def initialize(){
if (logTrace) log.info " running Intitialize....$displayUnits"
state.clear()
state.Max = 1
state.Min = 1000
//state.Units = "°F"
if (displayUnits == "0"){
state.Units = "°F"}
else
{state.Units = "°C"}
unschedule("clearMaxMin")
schedule("0 58 23 1/1 * ? *", "clearMaxMin") // execute handlerMethod every day at 23:58.
runIn(310, clearMaxMin,[overwrite: true]) // [] because overwrite is a map
}
def clearMaxMin(){
state.Max = SensorValue
state.Min = SensorValue
}
def updateMaxMin(updateValue){
if (logEnable) log.info " in updateMaxMin $updateValue"
if(updateValue > state.Max){
state.Max = updateValue
}
if (state.Min == null){
state.Min = updateValue
}
if(updateValue < state.Min){
state.Min = updateValue
}
}
def DewPoint(dTemp,dHumidity,dUints){
// Td = T - ((100 - RH)/5) where T and Td are in °C
if (dUnits == "0"){ //°F
def RH = dTemp - 9 * (100-dHumidity)/25
RH = Math.round(RH)
sendEvent(name:"DewPoint", value: RH, displayed:true)
sendEvent(name:"DewPointdepression", value: Math.round(dTemp - RH), displayed:true)
log.info "DewPoint depression $DewPointdepression"
}
else{
def RH = dTemp - (100 - dHumidity)/5
RH = Math.round(RH)
sendEvent(name:"DewPoint", value: RH, displayed:true)
sendEvent(name:"DewPointdepression", value: Math.round(dTemp - RH), displayed:true)
}
} // --- end DewPoint ----------------------------------------------------------------------
// -_-_ end of code _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
// _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
/*
device.currentValue("temperature")
int hexStringToInt(String value)
Variables definitions:
fSensorValue = temperature in °F
cSensorValue = temperature in °C
hSensorValue = Humidity in %
HeatIndex = tbd
You generally want to only pass isStateChange as true manually if you actually want to force all events to run even if the value
is the same as the previous value. For instance, a button being pressed may have the same value
as before (ie, pressed) but you want all actions to occur again.
Not passing the isStateChange field at all will cause SendEvent to look at the existing value of the attribute
and set false if the same, true if different.
Always passing isStateChange to true for something like temperature would cause all your rules to run every time
even if the temperature didn't change from the last sample.
This usually isn't what you'd want unless you're time recording every value forever.
*/