Matter Driver Object

Methods


getClusterIdByName

Return Matter cluster information

Signature

Long getClusterIdByName(String clusterName)

Parameters

clusterName - the string value to lookup

Returns

Long - cluster id, null if no matching entry found

getClusterName

Return Matter cluster information

Signature

String getClusterName(Long clusterId)

Parameters

clusterId - the long value to lookup

Returns

String - string name of cluster

parseDescriptionAsMap

Parse a matter message into a Map.

Signature

Map parseDescriptionAsMap(String description)

Parameters

description - the Matter message to parse

Returns

Map - a Map of key/value pairs that have been parsed from the Matter message.

unsubscribe

Unsubscribe from attribute changes

Signature

String unsubscribe()

Returns

String - Matter command string to unsubscribe from attributes/events

subscribe

Subscribe to attribute changes

Signature

String subscribe(Integer minReportTime, Integer maxReportTime, List<Map<String, String>> attributePaths)

Parameters

minReportTime - requested minimum reporting interval in seconds
maxReportTime - requested maximum reporting interval in seconds
attributePaths - List of attribute path maps to subscribe to

Returns

String - Matter command subscribe command string

attributePath

Generate attribute path Map

Signature

Map<String,String> attributePath(String ep, Integer cluster, Integer attr)
Map<String,String> attributePath(Integer ep, Integer cluster, Integer attr)

Parameters

ep - device endpoint
cluster - cluster id
attr - attribute id

Returns

Map<String,String> - attributePath map

readAttributes

Read attribute value

Signature

String readAttributes(List<Map<String, String attributePaths)

Parameters

attributePaths - List of attribute path maps

Returns

String - Matter read attributes 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

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

cmdField

Generate command field map

Signature

Map<String,String> cmdField(Integer type, Integer num, String data)

Parameters

type - Matter data type
num - field number
data - hex string of attribute value to write

Returns

Map<String,String> - cmdField map

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

on

Generate the on command for the on/off Matter cluster

Signature

String on()

Returns

String - Matter command string

off

Generate the on command for the on/off Matter cluster

Signature

String off()

Returns

String - Matter command string

setLevel

Generate the set level command

Signature

String setLevel(Number level, Number transition)

Parameters

level - Level to set the device to
transition - Transition time (optional)

Returns

String - Matter set level command

setColor

Generate the set color command

Signature

String setHue(Map value)

Parameters

value - Hubitat COLOR_MAP

Returns

String - Matter set color command string

setHue

Generate the set hue command

Signature

String setHue(Integer value, Number transition)

Parameters

value - Integer 0-100 hue value
transition - Transition time (optional)

Returns

String - Matter set hue command string

setSaturation

Generate the set saturation command

Signature

String setSaturation(Integer value, Number transition)

Parameters

value - Integer 0-100 saturation value
transition - Transition time (optional)

Returns

String - Matter set saturation command string

setColorTemperature

Generate the set color temperature command

Signature

String setColorTemperature(Integer value, Number transition)

Parameters

value - Integer color temperature value
transition - Transition time (optional)

Returns

String - Matter set color temperature command string
8 Likes

Is there a further explanation of the matter.cmdField() function.

I'm looking to implement some additional commands and variations on what is supported by current matter object functions like matter.on() or matter.setLevel(), but first was trying to replicate those to understand what is happening

Let's say I have call the function matter.setlevel(127, 3). If I were to log that, I'd get:

he invoke 0x01 0x0008 0x0004 {15240014225011E0018}

The first 3 fields are clear: endpoint, cluster, command. The next field {15240014225011E0018} is what I'm trying to figure out.

I'm assuming that last field is a string produced by two calls to matter.cmdField

Looking at the Level cluster, section 1.6.7.1 of the Matter 1.2 cluster spec, the data fields for command 0x04 are Level (ID=0, type = uint8), and TransitionTime (ID = 1, type = uint16)

I'm assuming that field {15240014225011E0018} may be generated by something like

matter.cmdField(0, (some constant that means uint8), 0x127) + matter.cmdField(1, (some constant that means uint16),0px03)

Am I on the right track? More specifically:

  1. Is the first number to the cmdField command supposed to correspond to the ID in the table of Section 1.6.7.1 of the Matter spec?
  2. Is there a Matter spec. or other place I can look for info as to what is put into the 2nd field? I'm assuming there may be an list of defined data types somewhere that is used.

Thanks to anybody who can help!

1 Like

This is what worked for me for the componentSetPosition(position) method :

.......
    List<Map<String, String>> cmdFields = []
    cmdFields.add(matter.cmdField(0x05, 0x00, zigbee.swapOctets(HexUtils.integerToHexString((100 - position) * 100, 2))))
    cmd = matter.invoke(deviceNumber, 0x0102, 0x05, cmdFields)  // 0x0102 = Window Covering Cluster, 0x05 = GoToLiftPercentage
    sendToDevice(cmd)
......
1 Like

cmdField is used to create the TLV structure the SDK expects when data needs to be sent with a command.

type - Matter data type

  • include hubitat.matter.DataType see DataType details below

num - field number

  • ID of command data field

data - hex string of attribute value to write

  • Raw hex of command field value

Matter Data Types

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

Importable from hubitat.matter.DataType, see matter documentation for more data types.

3 Likes

For more details on the TLV structures see Matter Specification document Appendix A,B & C.

Are there any other Matter-specific libraries to include (in addition to hubitat.matter.DataType)?

1 Like

Nothing yet.

1 Like

Thank you.

Do you need to do any of that byte swapping that used to be done with zigbee or does the command just get it right based on picking the correct data type? I'm assuming the command handles it as long as you pick the correct DataType.XX

If you have multiple parameters, like in the level command I mentioned, do you just add the strings together?
matter.cmdField(0, DataType.UINT8, 0x127) + matter.cmdField(1, DataType.UINT16, 0x03)

1 Like

Just the byte swapping.

No.. More like:

    List<Map<String, String>> fields = []
    fields.add(cmdField(DataType.UINT8, 0, integerTo8bitUnsignedHex((level.toInteger() * 2.54).toInteger())))
    fields.add(cmdField(DataType.UINT16, 1, integerTo16bitUnsignedHex(rate)))
    return matter.invoke(device.endpointId, 0x0008, 0x0004, fields)
1 Like

Thanks. I think I got it now.

1 Like

For anybody else reading this, as a follow-up on the need to byte-reverse certain hex strings, see below for a handy function I wrote for doing this. It will byte reverse any even length string, or if you have multiple parameters, pass them all at once in a list and it will reverse each individually and join them (I'll eventually post to github as a library along with other functions):

For example
byteReverseParameters("123456") gives "563412"
byteReversParameters(["0123", "4567", "10"]) returns "231089674510"

// Matter payloads need hex parameters of greater than 2 characters to be pair-reversed.
// This function takes a list of parameters and pair-reverses those longer than 2 characters.
// Alternatively, it can take a string and pair-reverse that.
// Thus, e.g., ["0123", "456789", "10"] becomes "230189674510" and "123456" becomes "563412"
private String byteReverseParameters(String oneString) { byteReverseParameters([] << oneString) }
private String byteReverseParameters(List<String> parameters) {
	StringBuilder rStr = new StringBuilder(128)
	
	for (hexString in parameters) {
		if (hexString.length() % 2) throw new Exception("In method byteReverseParameters, trying to reverse a hex string that is not an even number of characters in length. Error in Hex String: ${hexString}, All method parameters were ${parameters}.")
		
		for(Integer i = hexString.length() -1 ; i > 0 ; i -= 2) {
			rStr << hexString[i-1..i]
		}	
	}
	return rStr
}
2 Likes

Can someone help me to locate the Matter data types section in the specifications? I am a bit lost trying to find it. What I find in "Matter-1.2-Core-Specification.pdf" section 7.18.1. Base Data Types does not match the Matter Data Types in the table above.

As an example - DataType.UINT8 (8-bit unsigned integer) 0x04

does not match this :

I suppose I am looking at the wrong document or section in the Matter specs?

Particularly, I need to use enum8 and enum16 data types.

See Appendix A all these values are TLV encoded

Unsigned Integer 1-octet (8-bit) = 0x04

1 Like

Thank you!

image

This means, that the decoding of the complex structures like the empty lists will continue to pre presented in TLV encoding format in the map, result from calling matter.parseDescriptionAsMap(description)

Does it mean that the drivers should also be parsing/checking the description String for "value : 1618" and "value: 1718" to distinguish between the legit hex 1618 or hex 1718 values in the parseDescriptionAsMap result?
:thinking:

@jvm33 have you tried subscribing for Events? (cluster 0x003B - Switch) ?

No, but I'm planning to work (this week) on a device that needs that.

Note - in case it isn't clear, the Generic Switch device Type 0x000F and its cluster 0x003B are not really a "switch" - they do not not control a load or turn devices on/off.

Its poorly named, but it is really more like Z-Wave Central Scene -- all the Type 0x000F with its Switch 0x003B cluster is used for is detection of button tapping, hold, and release events. It should have been named "Generic Button" or something less confusing. And unlike Z-Wave, each "button" must sit on its own endpoint. So, for example, if you had a Dimmer device, you might have an endpoint EP#1 of Type 0x0104, and then if you wanted to get button tapping reports, you would need EP#2 of "Generic Switch" type 0x003B for the top paddle tap detection, and EP#3 of type 0x0003B for the bottom paddle tap detection, and then subscribe to attribute reports on EP#1, and event reports on EP#2, EP#3.

I think this is the only device on the market that currently supports a Generic Switch cluster 0x003B: TUO Smart Button with Matter Thread Support

Unlike Z-Wave Plus devices, you can't assume that the "Generic" part is supported!.

For those interested, the relationship between the types is explained in Section 6.6.5 of the Matter Device Library Spec, Version 1.2

1 Like

Hi. Is there a way to encode the binding structure used by the binding cluster (Core Spec. Section 9.6). It is specified as being of type 'list[TargetStruct]' ? If so, can you give an example please? If not, can this be added. Thank you.