Matter: Correct handling of binding to the same node id or group which has this node

Hello,
I am developing an On/Off Light Matter device, which has buttons onboard. Currently, I'd like to make it possible to 'unbound' buttons from controlling On/Off Light device directly to create another endpoint with On/Off Switch device definition. This will allow me then to add my first endpoint (On/Off Light) to groups and then bind my second endpoint (On/Off Switch) to this group or first endpoint. Hovewer, I could not find any information regarding such implementation.

1) Is my scenario of binding two endpoints with the same node id even possible under Matter specification?

My idea, if this is possible under Matter specification, would be then by reading Binding Table Entry data and comparing it with current Fabric Id and Node id data to take decision between directly changing attribute (planned 'commands' would be On/Off/Toggle with immediate execution) of the first endpoint or sending corresponding command to a bound node if it is separate device.

2) What would be my steps to retrieve Fabric Id and Node Id for my device in my firmware (specific functions to call) so I would use it for the implementation of my idea?

Parents
  • Hi,

    Hovewer, I could not find any information regarding such implementation.

    If you haven't seen them already, the Matter documentation + light switch and bulb samples should be a good starting point together with the chip-tool-guide page and the subpages here regarding testing Matter in nRF Connect SDK: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/ug_matter_gs_testing.html

    1) Is my scenario of binding two endpoints with the same node id even possible under Matter specification?

    My idea, if this is possible under Matter specification, would be then by reading Binding Table Entry data and comparing it with current Fabric Id and Node id data to take decision between directly changing attribute (planned 'commands' would be On/Off/Toggle with immediate execution) of the first endpoint or sending corresponding command to a bound node if it is separate device.

    As far as I can see this should be possible. One node may have multiple endpoints and each endpoint is individually addressable, so binding both endpoints should not be an issue.

    2) What would be my steps to retrieve Fabric Id and Node Id for my device in my firmware (specific functions to call) so I would use it for the implementation of my idea?

    I will have to look some more for how to retrieve the Fabric Id and Node Id, but initially I would recommend you have a look through the Matter documentation pages we have available, as well as investigating the Matter Core spec, cluster spec and device library spec provided by CSA csa-iot.org/.../

    Let me know if this answers your questions,

    Kind regards,
    Andreas

  • Hello,
    The first part of my original question was rather an attempt to confirm my correct interpretation of the Matter specification, that my scenario is actually allowed by it. Thank you for confirmation!

    Before I opened this ticket, I have already tried to 'mix' Light Bulb (as endpoint 1) and Light Switch (as endoint 2) sample apps, with buttons sending commands to bound endpoints. I even successfully managed to bind the two endpoints together through chip-tool binding command and I can even see correct BindingTableEntry with correct Node Id and Endpoint Id in my logs. Hovewer, unchanged BindingHandler implementation, copied from Light Switch app, tries to directly send command via network protocol. And this implementation is, of course. not suitable, as SoC obviously cannot receive command that it is sending right in that moment...

    These findings led me to my question as to how retrieve Fabric Id and Node Id in my application code to compare them with binding table entry, and then directly change attributes of endpoint 1 instead of command send (or change attributes AND send group command if my device is in that group).
    Now that I see that it is possible, I'd like to get specific functions/methods to retrieve Fabric Id and Node id, as it is.

    It seems required information about fabric Id and node Id is stored in Fabrics attribute (Operational Credentials Cluster), but currently I can directly access only Commis­sionedFab­rics and Current­FabricIn­dex, which, unfortunately, are not very helpful in my case.
    Please correct me if I am wrong and there are other methods to access this information from application code.

  • Hello,
    I found the answer to my question after analyzing application source code.

    I can receive pointer to Fabric table through using Server class method GetFabricTable.

    Function that I used to log Fabric Index and Node Id (node identifiers used in Binding Table) is put below:

    void LoggingCurrentFabricIdAndNodeId(void)
    {
    	FabricTable *fabricTable = nullptr;
    	fabricTable = &Server::GetInstance().GetFabricTable();
    	uint16_t fabricTableSize = fabricTable->FabricCount();
    	NodeId nodeIdArray[fabricTableSize];
    	FabricIndex fabricIndexArray[fabricTableSize];
    	uint16_t fabricTableIteration = 0;
    	for (const FabricInfo & fabricInfo : *fabricTable)
        {
    		fabricIndexArray[fabricTableIteration] = fabricInfo.GetFabricIndex();
    		nodeIdArray[fabricTableIteration] = fabricInfo.GetNodeId();
    		LOG_INF("Fabric Table entry #%d: fabricIndex - %d, nodeId - %lld",
    					fabricTableIteration, 
    					fabricIndexArray[fabricTableIteration], 
    					nodeIdArray[fabricTableIteration]);
    		//prepare to write next nodeid fabricindex values
    		fabricTableIteration++;
    	}
    }


    Thank you for help!

Reply
  • Hello,
    I found the answer to my question after analyzing application source code.

    I can receive pointer to Fabric table through using Server class method GetFabricTable.

    Function that I used to log Fabric Index and Node Id (node identifiers used in Binding Table) is put below:

    void LoggingCurrentFabricIdAndNodeId(void)
    {
    	FabricTable *fabricTable = nullptr;
    	fabricTable = &Server::GetInstance().GetFabricTable();
    	uint16_t fabricTableSize = fabricTable->FabricCount();
    	NodeId nodeIdArray[fabricTableSize];
    	FabricIndex fabricIndexArray[fabricTableSize];
    	uint16_t fabricTableIteration = 0;
    	for (const FabricInfo & fabricInfo : *fabricTable)
        {
    		fabricIndexArray[fabricTableIteration] = fabricInfo.GetFabricIndex();
    		nodeIdArray[fabricTableIteration] = fabricInfo.GetNodeId();
    		LOG_INF("Fabric Table entry #%d: fabricIndex - %d, nodeId - %lld",
    					fabricTableIteration, 
    					fabricIndexArray[fabricTableIteration], 
    					nodeIdArray[fabricTableIteration]);
    		//prepare to write next nodeid fabricindex values
    		fabricTableIteration++;
    	}
    }


    Thank you for help!

Children
Related