/*
Govee RGBW driver
Copyright 2023 Hubitat Inc. All Rights Reserved
2023-11-02 2.3.7 mavrrick
-initial pub
*/
import groovy.transform.Field
@Field static final String DEVICE_TYPE = 'MATTER_BULB'
//transitionTime options
@Field static Map ttOpts = [
defaultValue: '0',
defaultText: 'ASAP',
options:['0':'ASAP', '1':'1s', '2':'2s', '5':'5s']
]
import groovy.transform.Field
import hubitat.helper.HexUtils
metadata {
definition (name: "Govee RGBW Matter ", namespace: "Mavrrick", author: "Mavrrick") {
capability 'Actuator'
capability 'Switch'
capability 'SwitchLevel'
//capability 'Configuration'
capability 'Color Control'
capability "ColorTemperature"
capability 'Light'
capability 'Initialize'
capability 'Refresh'
fingerprint endpointId:"01", inClusters:"0003,0004,0005,0006,0008,001D,0050,0300", outClusters:"", manufacturer:"Shenzhen Qianyan Technology", controllerType:"MAT"
}
preferences {
input(name:'transitionTime', type:'enum', title:"Level transition time (default:${ttOpts.defaultText})", options:ttOpts.options, defaultValue:ttOpts.defaultValue)
input(name:"logEnable", type:"bool", title:"Enable debug logging", defaultValue:false)
input(name:"txtEnable", type:"bool", title:"Enable descriptionText logging", defaultValue:true)
}
}
// ~~~~~ start include (11) Mavrrick.Govee_Matter ~~~~~
library ( // library marker Mavrrick.Govee_Matter, line 1
author: "Mavrrick", // library marker Mavrrick.Govee_Matter, line 2
category: "Govee", // library marker Mavrrick.Govee_Matter, line 3
description: "Govee_Matter", // library marker Mavrrick.Govee_Matter, line 4
name: "Govee_Matter", // library marker Mavrrick.Govee_Matter, line 5
namespace: "Mavrrick", // library marker Mavrrick.Govee_Matter, line 6
documentationLink: "http://www.example.com/" // library marker Mavrrick.Govee_Matter, line 7
) // library marker Mavrrick.Govee_Matter, line 8
//parsers // library marker Mavrrick.Govee_Matter, line 10
void parse(String description) { // library marker Mavrrick.Govee_Matter, line 11
Map descMap // library marker Mavrrick.Govee_Matter, line 13
try { // library marker Mavrrick.Govee_Matter, line 14
descMap = matter.parseDescriptionAsMap(description) // library marker Mavrrick.Govee_Matter, line 15
} catch (e) { // library marker Mavrrick.Govee_Matter, line 16
logWarn "parse: exception ${e}
Failed to parse description: ${description}" // library marker Mavrrick.Govee_Matter, line 17
return // library marker Mavrrick.Govee_Matter, line 18
} // library marker Mavrrick.Govee_Matter, line 19
logDebug "parse: descMap:${descMap} description:${description}" // library marker Mavrrick.Govee_Matter, line 20
if (descMap == null) { // library marker Mavrrick.Govee_Matter, line 21
logWarn "parse: descMap is null description:${description}" // library marker Mavrrick.Govee_Matter, line 22
return // library marker Mavrrick.Govee_Matter, line 23
} // library marker Mavrrick.Govee_Matter, line 24
if (descMap.attrId == 'FFFB') { // parse the AttributeList first! // library marker Mavrrick.Govee_Matter, line 25
pareseAttributeList(descMap) // library marker Mavrrick.Govee_Matter, line 26
return // library marker Mavrrick.Govee_Matter, line 27
} // library marker Mavrrick.Govee_Matter, line 28
switch (descMap.cluster) { // library marker Mavrrick.Govee_Matter, line 29
case '0000' : // library marker Mavrrick.Govee_Matter, line 30
if (descMap.attrId == '4000') { //software build ? // library marker Mavrrick.Govee_Matter, line 31
updateDataValue('softwareBuild', descMap.value ?: 'unknown') // library marker Mavrrick.Govee_Matter, line 32
} // library marker Mavrrick.Govee_Matter, line 33
else { // library marker Mavrrick.Govee_Matter, line 34
logWarn "skipped softwareBuild, attribute:${descMap.attrId}, value:${descMap.value}" // library marker Mavrrick.Govee_Matter, line 35
} // library marker Mavrrick.Govee_Matter, line 36
break // library marker Mavrrick.Govee_Matter, line 37
case '0003' : // Identify // library marker Mavrrick.Govee_Matter, line 38
// gatherAttributesValuesInfo(descMap, IdentifyClusterAttributes) // library marker Mavrrick.Govee_Matter, line 39
break // library marker Mavrrick.Govee_Matter, line 40
case '0004' : // Groups // library marker Mavrrick.Govee_Matter, line 41
// gatherAttributesValuesInfo(descMap, GroupsClusterAttributes) // library marker Mavrrick.Govee_Matter, line 42
break // library marker Mavrrick.Govee_Matter, line 43
case '0005' : // Scenes // library marker Mavrrick.Govee_Matter, line 44
// gatherAttributesValuesInfo(descMap, ScenesClusterAttributes) // library marker Mavrrick.Govee_Matter, line 45
case '0006' : // On/Off Cluster // library marker Mavrrick.Govee_Matter, line 46
// gatherAttributesValuesInfo(descMap, OnOffClusterAttributes) // library marker Mavrrick.Govee_Matter, line 47
parseOnOffCluster(descMap) // library marker Mavrrick.Govee_Matter, line 48
break // library marker Mavrrick.Govee_Matter, line 49
case '0202' : // Fan Control Cluster // library marker Mavrrick.Govee_Matter, line 50
if (descMap.attrId == "0000") { //fan speed // library marker Mavrrick.Govee_Matter, line 51
sendSpeedEvent(descMap.value) // library marker Mavrrick.Govee_Matter, line 52
} // library marker Mavrrick.Govee_Matter, line 53
break // library marker Mavrrick.Govee_Matter, line 54
case '0008' : // LevelControl // library marker Mavrrick.Govee_Matter, line 55
if (descMap.attrId == '0000') { //current level // library marker Mavrrick.Govee_Matter, line 56
sendLevelEvent(descMap.value) // library marker Mavrrick.Govee_Matter, line 57
} // library marker Mavrrick.Govee_Matter, line 58
else { // library marker Mavrrick.Govee_Matter, line 59
logWarn "skipped level, attribute:${descMap.attrId}, value:${descMap.value}" // library marker Mavrrick.Govee_Matter, line 60
} // library marker Mavrrick.Govee_Matter, line 61
// gatherAttributesValuesInfo(descMap, LevelControlClusterAttributes) // library marker Mavrrick.Govee_Matter, line 62
break // library marker Mavrrick.Govee_Matter, line 63
case '001D' : // Descriptor, ep:00 // library marker Mavrrick.Govee_Matter, line 64
// gatherAttributesValuesInfo(descMap, DescriptorClusterAttributes) // library marker Mavrrick.Govee_Matter, line 65
break // library marker Mavrrick.Govee_Matter, line 66
case '002F' : // PowerSource, ep:02 // parse: descMap:[endpoint:02, cluster:002F, attrId:000C, value:C8, clusterInt:47, attrInt:12] description:read attr - endpoint: 02, cluster: 002F, attrId: 000C, value: 04C8 // library marker Mavrrick.Govee_Matter, line 67
parseBatteryEvent(descMap) // library marker Mavrrick.Govee_Matter, line 68
// gatherAttributesValuesInfo(descMap, PowerSourceClusterAttributes) // library marker Mavrrick.Govee_Matter, line 69
break // library marker Mavrrick.Govee_Matter, line 70
case '0028' : // BasicInformation, ep:00 // library marker Mavrrick.Govee_Matter, line 71
// gatherAttributesValuesInfo(descMap, BasicInformationClusterAttributes) // library marker Mavrrick.Govee_Matter, line 72
break // library marker Mavrrick.Govee_Matter, line 73
case '0045' : // BooleanState // library marker Mavrrick.Govee_Matter, line 74
// gatherAttributesValuesInfo(descMap, BoleanStateClusterAttributes) // library marker Mavrrick.Govee_Matter, line 75
parseContactEvent(descMap) // library marker Mavrrick.Govee_Matter, line 76
break // library marker Mavrrick.Govee_Matter, line 77
case '0300' : // ColorControl // library marker Mavrrick.Govee_Matter, line 78
if (descMap.attrId == '0000') { //hue // library marker Mavrrick.Govee_Matter, line 79
sendHueEvent(descMap.value) // library marker Mavrrick.Govee_Matter, line 80
} else if (descMap.attrId == '0001') { //saturation // library marker Mavrrick.Govee_Matter, line 81
sendSaturationEvent(descMap.value) // library marker Mavrrick.Govee_Matter, line 82
} // library marker Mavrrick.Govee_Matter, line 83
else if (descMap.attrId == '0007') { //color temperature // library marker Mavrrick.Govee_Matter, line 84
sendCTEvent(descMap.value) // library marker Mavrrick.Govee_Matter, line 85
} // library marker Mavrrick.Govee_Matter, line 86
else if (descMap.attrId == '0008') { //color mode // library marker Mavrrick.Govee_Matter, line 87
logDebug "parse: skipped color mode:${descMap}" // library marker Mavrrick.Govee_Matter, line 88
} // library marker Mavrrick.Govee_Matter, line 89
else { // library marker Mavrrick.Govee_Matter, line 90
logWarn "parse: skipped color, attribute:${descMap.attrId}, value:${descMap.value}" // library marker Mavrrick.Govee_Matter, line 91
} // library marker Mavrrick.Govee_Matter, line 92
// gatherAttributesValuesInfo(descMap, ColorControlClusterAttributes) // library marker Mavrrick.Govee_Matter, line 93
break // library marker Mavrrick.Govee_Matter, line 94
default : // library marker Mavrrick.Govee_Matter, line 95
logWarn "parse: skipped:${descMap}" // library marker Mavrrick.Govee_Matter, line 96
} // library marker Mavrrick.Govee_Matter, line 97
} // library marker Mavrrick.Govee_Matter, line 98
void parseOnOffCluster(Map descMap) { // library marker Mavrrick.Govee_Matter, line 100
logDebug "parseOnOffCluster: descMap:${descMap}" // library marker Mavrrick.Govee_Matter, line 101
if (descMap.cluster != '0006') { // library marker Mavrrick.Govee_Matter, line 102
logWarn "parseOnOffCluster: unexpected cluster:${descMap.cluster} (attrId:${descMap.attrId})" // library marker Mavrrick.Govee_Matter, line 103
return // library marker Mavrrick.Govee_Matter, line 104
} // library marker Mavrrick.Govee_Matter, line 105
Integer attrInt = descMap.attrInt as Integer // library marker Mavrrick.Govee_Matter, line 106
Integer value // library marker Mavrrick.Govee_Matter, line 107
//String descriptionText = '' // library marker Mavrrick.Govee_Matter, line 108
//Map eventMap = [:] // library marker Mavrrick.Govee_Matter, line 109
String attrName = OnOffClusterAttributes[attrInt] ?: GlobalElementsAttributes[attrInt] ?: UNKNOWN // library marker Mavrrick.Govee_Matter, line 110
switch (descMap.attrId) { // library marker Mavrrick.Govee_Matter, line 112
case '0000' : // Switch // library marker Mavrrick.Govee_Matter, line 113
sendSwitchEvent(descMap.value) // library marker Mavrrick.Govee_Matter, line 114
break // library marker Mavrrick.Govee_Matter, line 115
case '4000' : // GlobalSceneControl // library marker Mavrrick.Govee_Matter, line 116
if (logEnable) { logInfo "parse: Switch: GlobalSceneControl = ${descMap.value}" } // library marker Mavrrick.Govee_Matter, line 117
if (state.onOff == null) { state.onOff = [:] } ; state.onOff['GlobalSceneControl'] = descMap.value // library marker Mavrrick.Govee_Matter, line 118
break // library marker Mavrrick.Govee_Matter, line 119
case '4001' : // OnTime // library marker Mavrrick.Govee_Matter, line 120
if (logEnable) { logInfo "parse: Switch: OnTime = ${descMap.value}" } // library marker Mavrrick.Govee_Matter, line 121
if (state.onOff == null) { state.onOff = [:] } ; state.onOff['OnTime'] = descMap.value // library marker Mavrrick.Govee_Matter, line 122
break // library marker Mavrrick.Govee_Matter, line 123
case '4002' : // OffWaitTime // library marker Mavrrick.Govee_Matter, line 124
if (logEnable) { logInfo "parse: Switch: OffWaitTime = ${descMap.value}" } // library marker Mavrrick.Govee_Matter, line 125
if (state.onOff == null) { state.onOff = [:] } ; state.onOff['OffWaitTime'] = descMap.value // library marker Mavrrick.Govee_Matter, line 126
break // library marker Mavrrick.Govee_Matter, line 127
case '4003' : // StartUpOnOff // library marker Mavrrick.Govee_Matter, line 128
value = descMap.value as int // library marker Mavrrick.Govee_Matter, line 129
String startUpOnOffText = "parse: Switch: StartUpOnOff = ${descMap.value} (${StartUpOnOffEnumOpts[value] ?: UNKNOWN})" // library marker Mavrrick.Govee_Matter, line 130
if (logEnable) { logInfo "${startUpOnOffText}" } // library marker Mavrrick.Govee_Matter, line 131
if (state.onOff == null) { state.onOff = [:] } ; state.onOff['StartUpOnOff'] = descMap.value // library marker Mavrrick.Govee_Matter, line 132
break // library marker Mavrrick.Govee_Matter, line 133
case ['FFF8', 'FFF9', 'FFFA', 'FFFB', 'FFFC', 'FFFD', '00FE'] : // library marker Mavrrick.Govee_Matter, line 134
if (logEnable) { // library marker Mavrrick.Govee_Matter, line 135
logInfo "parse: Switch: ${attrName} = ${descMap.value}" // library marker Mavrrick.Govee_Matter, line 136
} // library marker Mavrrick.Govee_Matter, line 137
break // library marker Mavrrick.Govee_Matter, line 138
default : // library marker Mavrrick.Govee_Matter, line 139
logWarn "parseOnOffCluster: unexpected attrId:${descMap.attrId} (raw:${descMap.value})" // library marker Mavrrick.Govee_Matter, line 140
} // library marker Mavrrick.Govee_Matter, line 141
} // library marker Mavrrick.Govee_Matter, line 142
/// Event Processing // library marker Mavrrick.Govee_Matter, line 144
private void sendSpeedEvent(String rawValue) { // library marker Mavrrick.Govee_Matter, line 146
Integer intValue = hexStrToUnsignedInt(rawValue) // library marker Mavrrick.Govee_Matter, line 147
switch(intValue) { // library marker Mavrrick.Govee_Matter, line 149
case 0 : // library marker Mavrrick.Govee_Matter, line 150
value = "off"; // library marker Mavrrick.Govee_Matter, line 151
break; // library marker Mavrrick.Govee_Matter, line 152
case 8: // library marker Mavrrick.Govee_Matter, line 153
value = "speed 1"; // library marker Mavrrick.Govee_Matter, line 154
break; // library marker Mavrrick.Govee_Matter, line 155
case 16: // library marker Mavrrick.Govee_Matter, line 156
value = "speed 2"; // library marker Mavrrick.Govee_Matter, line 157
break; // library marker Mavrrick.Govee_Matter, line 158
case 24: // library marker Mavrrick.Govee_Matter, line 159
value = "speed3 (low)"; // library marker Mavrrick.Govee_Matter, line 160
break; // library marker Mavrrick.Govee_Matter, line 161
case 32: // library marker Mavrrick.Govee_Matter, line 162
value = "speed 4"; // library marker Mavrrick.Govee_Matter, line 163
break; // library marker Mavrrick.Govee_Matter, line 164
case 40: // library marker Mavrrick.Govee_Matter, line 165
value = "speed 5"; // library marker Mavrrick.Govee_Matter, line 166
break; // library marker Mavrrick.Govee_Matter, line 167
case 48: // library marker Mavrrick.Govee_Matter, line 168
value = "speed 6 (medium)"; // library marker Mavrrick.Govee_Matter, line 169
break; // library marker Mavrrick.Govee_Matter, line 170
case 56: // library marker Mavrrick.Govee_Matter, line 171
value = "speed 7"; // library marker Mavrrick.Govee_Matter, line 172
break; // library marker Mavrrick.Govee_Matter, line 173
case 64: // library marker Mavrrick.Govee_Matter, line 174
value = "speed 8"; // library marker Mavrrick.Govee_Matter, line 175
break; // library marker Mavrrick.Govee_Matter, line 176
case 72: // library marker Mavrrick.Govee_Matter, line 177
value = "speed 9"; // library marker Mavrrick.Govee_Matter, line 178
break; // library marker Mavrrick.Govee_Matter, line 179
case 81: // library marker Mavrrick.Govee_Matter, line 180
value = "speed 10"; // library marker Mavrrick.Govee_Matter, line 181
break; // library marker Mavrrick.Govee_Matter, line 182
case 90: // library marker Mavrrick.Govee_Matter, line 183
value = "speed 11"; // library marker Mavrrick.Govee_Matter, line 184
break; // library marker Mavrrick.Govee_Matter, line 185
case 100: // library marker Mavrrick.Govee_Matter, line 186
value = "speed12 (high)"; // library marker Mavrrick.Govee_Matter, line 187
break; // library marker Mavrrick.Govee_Matter, line 188
} // library marker Mavrrick.Govee_Matter, line 189
// if (device.currentValue("switch") == value) return // library marker Mavrrick.Govee_Matter, line 191
String descriptionText = "${device.displayName} was set to speed ${value}" // library marker Mavrrick.Govee_Matter, line 192
if (txtEnable) log.info descriptionText // library marker Mavrrick.Govee_Matter, line 193
sendEvent(name:"speed", value:value, descriptionText:descriptionText) // library marker Mavrrick.Govee_Matter, line 194
} // library marker Mavrrick.Govee_Matter, line 195
//events // library marker Mavrrick.Govee_Matter, line 197
private void sendSwitchEvent(String rawValue) { // library marker Mavrrick.Govee_Matter, line 198
String value = rawValue == "01" ? "on" : "off" // library marker Mavrrick.Govee_Matter, line 199
if (device.currentValue("switch") == value) return // library marker Mavrrick.Govee_Matter, line 200
String descriptionText = "${device.displayName} was turned ${value}" // library marker Mavrrick.Govee_Matter, line 201
if (txtEnable) log.info descriptionText // library marker Mavrrick.Govee_Matter, line 202
sendEvent(name:"switch", value:value, descriptionText:descriptionText) // library marker Mavrrick.Govee_Matter, line 203
} // library marker Mavrrick.Govee_Matter, line 204
private void sendLevelEvent(String rawValue) { // library marker Mavrrick.Govee_Matter, line 206
Integer value = Math.round(hexStrToUnsignedInt(rawValue) / 2.55) // library marker Mavrrick.Govee_Matter, line 207
if (value == 0 || value == device.currentValue("level")) return // library marker Mavrrick.Govee_Matter, line 208
String descriptionText = "${device.displayName} level was set to ${value}%" // library marker Mavrrick.Govee_Matter, line 209
if (txtEnable) log.info descriptionText // library marker Mavrrick.Govee_Matter, line 210
sendEvent(name:"level", value:value, descriptionText:descriptionText, unit: "%") // library marker Mavrrick.Govee_Matter, line 211
} // library marker Mavrrick.Govee_Matter, line 212
private void sendHueEvent(String rawValue, Boolean presetColor = false) { // library marker Mavrrick.Govee_Matter, line 214
Integer value = hex254ToInt100(rawValue) // library marker Mavrrick.Govee_Matter, line 215
sendRGBNameEvent(value) // library marker Mavrrick.Govee_Matter, line 216
String descriptionText = "${device.displayName} hue was set to ${value}%" // library marker Mavrrick.Govee_Matter, line 217
if (txtEnable) log.info descriptionText // library marker Mavrrick.Govee_Matter, line 218
sendEvent(name:"hue", value:value, descriptionText:descriptionText, unit: "%") // library marker Mavrrick.Govee_Matter, line 219
} // library marker Mavrrick.Govee_Matter, line 220
private void sendSaturationEvent(String rawValue, Boolean presetColor = false) { // library marker Mavrrick.Govee_Matter, line 222
Integer value = hex254ToInt100(rawValue) // library marker Mavrrick.Govee_Matter, line 223
sendRGBNameEvent(null,value) // library marker Mavrrick.Govee_Matter, line 224
String descriptionText = "${device.displayName} saturation was set to ${value}%" // library marker Mavrrick.Govee_Matter, line 225
if (txtEnable) log.info descriptionText // library marker Mavrrick.Govee_Matter, line 226
sendEvent(name:"saturation", value:value, descriptionText:descriptionText, unit: "%") // library marker Mavrrick.Govee_Matter, line 227
} // library marker Mavrrick.Govee_Matter, line 228
private void sendRGBNameEvent(hue, sat = null){ // library marker Mavrrick.Govee_Matter, line 230
String genericName // library marker Mavrrick.Govee_Matter, line 231
if (device.currentValue("saturation") == 0) { // library marker Mavrrick.Govee_Matter, line 232
genericName = "White" // library marker Mavrrick.Govee_Matter, line 233
} else if (hue == null) { // library marker Mavrrick.Govee_Matter, line 234
return // library marker Mavrrick.Govee_Matter, line 235
} else { // library marker Mavrrick.Govee_Matter, line 236
genericName = colorRGBName.find{k , v -> hue < k}.value // library marker Mavrrick.Govee_Matter, line 237
} // library marker Mavrrick.Govee_Matter, line 238
if (genericName == device.currentValue("colorName")) return // library marker Mavrrick.Govee_Matter, line 239
String descriptionText = "${device.displayName} color is ${genericName}" // library marker Mavrrick.Govee_Matter, line 240
if (txtEnable) log.info descriptionText // library marker Mavrrick.Govee_Matter, line 241
sendEvent(name: "colorName", value: genericName ,descriptionText: descriptionText) // library marker Mavrrick.Govee_Matter, line 242
} // library marker Mavrrick.Govee_Matter, line 243
private void sendCTEvent(String rawValue, Boolean presetColor = false) { // library marker Mavrrick.Govee_Matter, line 245
value = (Math.round(10000/(hexStrToUnsignedInt(rawValue))))*100 // library marker Mavrrick.Govee_Matter, line 246
String descriptionText = "${device.displayName} ColorTemp was set to ${value}K" // library marker Mavrrick.Govee_Matter, line 247
if (txtEnable) log.info descriptionText // library marker Mavrrick.Govee_Matter, line 248
sendEvent(name:"colorTemperature", value:value, descriptionText:descriptionText, unit: "K") // library marker Mavrrick.Govee_Matter, line 249
} // library marker Mavrrick.Govee_Matter, line 251
// Capability Commands // library marker Mavrrick.Govee_Matter, line 253
//// On/off Switch commands // library marker Mavrrick.Govee_Matter, line 255
void on() { // library marker Mavrrick.Govee_Matter, line 256
logDebug 'switching on()' // library marker Mavrrick.Govee_Matter, line 257
// setDigitalRequest() // 3 seconds // library marker Mavrrick.Govee_Matter, line 258
sendToDevice(matter.on()) // library marker Mavrrick.Govee_Matter, line 259
} // library marker Mavrrick.Govee_Matter, line 260
void off() { // library marker Mavrrick.Govee_Matter, line 262
logDebug 'switching off()' // library marker Mavrrick.Govee_Matter, line 263
// setDigitalRequest() // library marker Mavrrick.Govee_Matter, line 264
sendToDevice(matter.off()) // library marker Mavrrick.Govee_Matter, line 265
} // library marker Mavrrick.Govee_Matter, line 266
void toggle() { // library marker Mavrrick.Govee_Matter, line 268
logDebug 'toggling...' // library marker Mavrrick.Govee_Matter, line 269
setDigitalRequest() // library marker Mavrrick.Govee_Matter, line 270
String cmd = matter.invoke(device.endpointId, 0x0006, 0x0002) // library marker Mavrrick.Govee_Matter, line 271
sendToDevice(cmd) // library marker Mavrrick.Govee_Matter, line 272
} // library marker Mavrrick.Govee_Matter, line 273
//// Level control commands related to Light Devices // library marker Mavrrick.Govee_Matter, line 275
void setLevel(Object value, Object rate=0) { //new set level routine to enable immediate change // library marker Mavrrick.Govee_Matter, line 276
logDebug "setLevel(${value}, ${rate})" // library marker Mavrrick.Govee_Matter, line 277
Integer newLevel = value // library marker Mavrrick.Govee_Matter, line 278
Integer transitiontime2 = rate // library marker Mavrrick.Govee_Matter, line 279
newLevel2 = int100ToHex254(newLevel) // library marker Mavrrick.Govee_Matter, line 280
transition = HexUtils.integerToHexString(transitiontime2,2) // library marker Mavrrick.Govee_Matter, line 281
String cmds // library marker Mavrrick.Govee_Matter, line 283
if (device.currentValue("switch") == "on"){ // library marker Mavrrick.Govee_Matter, line 284
List