Sample code of non standard commands

@bcopeland @kkossev @jvm33

I have started to dig into Matter drivers recently. I have reviewed a few drivers including the sample driver provided by Hubitat. The issue i am having is the sample driver from hubitat seems to use custom HE methods to bridge betwen certain device capabilities and matter control. They seem to relate to all of the standard switch and light functions. As such the examples don't seem to have options to invoke matter commands or write to attributes directly.

Are there any written working code samples that can be used to understand how to submit Commands or write to attributes to trigger decice changes.

Try:

invoke

Invokes a command on the device

Signature

  • String invoke(Integer ep, Integer cluster, Integer cmd, List<Map<String, String> cmdFields)
  • String invoke(Integer ep, Integer cluster, Integer cmd)

Parameters

  • ep - Endpoint ID
  • cluster - Cluster for command
  • cmd - Command ID
  • cmdFields - List of command field maps (optional, when values need to be sent with command)

Returns

  • String - Matter command string

writeAttributes

Write attributes to device

Signature

String writeAttributes(List<Map<String, String> attributeWriteRequests)

Parameters

attributeWriteRequests - List of attribute write request maps

Returns

String - Matter write attributes command string

which might be easier with:

attributeWriteRequest

Generate attributeWriteRequest map

Signature

Map<String,String> attributeWriteRequest(String ep, Integer cluster, Integer attr, Integer type, String data)
Map<String,String> attributeWriteRequest(Integer ep, Integer cluster, Integer attr, Integer type, String data)

Parameters

ep - device endpoint
cluster - cluster id
attr - attribute id
type - Matter data type
data - hex string of attribute value to write

Returns

Map<String,String> - attributeWriteRequest map

Data Types

For data types, you can use the numeric values per the Matter spec or conveniences like the following from hubitat.matter.DataType:

  • DataType.INT8 (8-bit signed integer) 0x00
  • DataType.INT16 (16-bit signed integer) 0x01
  • DataType.INT32 (32-bit signed integer) 0x02
  • DataType.INT64 (64-bit signed integer) 0x03
  • DataType.UINT8 (8-bit unsigned integer) 0x04
  • DataType.UINT16 (16-bit unsigned integer) 0x05
  • DataType.UINT32 (32-bit unsigned integer) 0x06
  • DataType.UINT64 (64-bit unsigned integer) 0x07
  • DataType.BOOLEAN_FALSE (False boolean) 0x08
  • DataType.BOOLEAN_TRUE (True boolean) 0x09
  • DataType.FLOAT4 (Single precision) 0x0A
  • DataType.FLOAT8 (Double precision) 0x0B
  • DataType.UTF81 (UTF-8 string 1 octet length) 0x0C
  • DataType.UTF82 (UTF-8 string 2 octet length) 0x0D
  • DataType.UTF84 (UTF-8 string 4 octet length) 0x0E
  • DataType.UTF88 (UTF-8 string 8 octet length) 0x0F
  • DataType.STRING_OCTET1 (Octet string 1 octet length) 0x10
  • DataType.STRING_OCTET2 (Octet string 2 octet length) 0x11
  • DataType.STRING_OCTET4 (Octet string 4 octet length) 0x12
  • DataType.STRING_OCTET8 (Octet string 8 octet length) 0x13
  • DataType.NULL 0x14
  • DataType.STRUCTURE 0x15
  • DataType.ARRAY 0x16
  • DataType.LIST 0x17

This will all be better documented at some point as soon as some formatting issues are figured out. :smiley:

3 Likes

Here are some code samples for using matter.invoke :

void toggle() {
    logDebug 'toggling...'
    setDigitalRequest()
    String cmd = matter.invoke(device.endpointId, 0x0006, 0x0002)
    sendToDevice(cmd)
}

void identify() {
    logDebug 'identifying...'
    String cmd
    Integer time = 10
    List<Map<String, String>> cmdFields = []
    cmdFields.add(matter.cmdField(0x05, 0x00, zigbee.swapOctets(HexUtils.integerToHexString(time, 2))))
    cmd = matter.invoke(device.endpointId, 0x0003, 0x0000, cmdFields)
    sendToDevice(cmd)
}

Tested with Nanoleaf A19 ( * model: NL67)

3 Likes

So I asked this question to look into something with the Set ColorTemp command I was working on. Simply put It always seems that it took forever to change the color temp because it was stepping it. Looking at the spec it looks like this should be avoidable. Here is the routine i finally just got working with your help above.

void setColorTemperature(colortemperature, level=null, transitionTime) {  // New method with Invoke instead of Hubitat calls
    Integer mired = Math.round(1000000/colortemperature)
    Integer transitiontime2 = transitionTime 
    ctValue = zigbee.swapOctets(HexUtils.integerToHexString(mired, 2))
    transition = HexUtils.integerToHexString(transitiontime2,2)

    if (logEnable) log.debug "setcolortemp() ${colortemperature} Hex swapped ${ctValue} Mired value ${mired} transition is ${transition} "
    String cmds 
    if (device.currentValue("switch") == "on"){
        List<Map<String, String>> cmdFields = []
        cmdFields.add(matter.cmdField(0x05, 0x00, ctValue)) 
        cmdFields.add(matter.cmdField(0x05, 0x01, transition))
        log.debug "Endpoint: ${device.endpointId} commands: ${cmdFields}"   
        cmds = matter.invoke(device.endpointId, 0x0300, 0x000A, cmdFields)   
    } else {
        cmds.add(matter.on())
        cmds.add(matter.setColorTemperature(colortemperature.toInteger(), transitionTime))
    } 
    sendToDevice(cmds)    
}

That will invoke the Matter command "MoveToColorTemperature" and specify the temp and transition time. There is something weird about transition time though. When it is set to 0 it is pretty much instantaneous. When set to anything else it takes a while. 1 is faster then 20, but it still take a good while on my device. The device i am testing with is a Govee Outdoor Wall light. Thanks for your help guys. Now i need to work on fan controls.

I think this is a problem some users have discovered with the way many manufacturers have implemented transition times (not per spec) on their devices. You can read discussions from users on another platform here, but this is ultimately a problem with those devices and not specific to that platform or Hubitat either. It also seems to affect mostly (entirely?) Wi-Fi devices, or at least I'm not sure I've seen any Thread devices mentioned (and the fact that many of these likely have the same OEM might be a contributing factor...):

The best thing to do would be for manufacturers to fix their devices. Contacting them may (or may not) help.

The next-best thing is probably to just use a 0 transition time in cases where this matters for you.

1 Like

That wouldn't suprise me.

Ok so this is probably a simple answer, but how have you all handled enumerated types not listed.

Looking through the Matter spec docs I see several instances like the below where attributes use enuamerated types. There are no Enumareted types listed in the list provided above.

image

Does the value just need to be passed, or is a different data value type used to add the value to the attribute write request.

Have you tried looking at the Matter libraries I created here: GitHub - jvmahon/Hubitat-matterTools: Tools for creating Matter drivers for Hubitat

As a starting point, look at the files that include a cluster number like: "matterTools.ColorClusterMethods0x3000 groovy" or "matterTools.OnOffClusterMethods0x0006.groovy"

Some of the files have been documented in the wiki: Home · jvmahon/Hubitat-matterTools Wiki · GitHub but I haven't been able to document them all due to time constraints (that being said, many of the libraries include detailed internal comments).

2 Likes

Well i got it figured out with both of your help and digging through @kkossev beta driver. I know have a fully functional Fan Matter driver that adjusts the speed :slight_smile: Thanks for both of your help.

3 Likes