For a typical ZCL application developed from the samples, what is the recommended way to send a ZCL command from the application to a local endpoint?
For example, consider an application with a single OnOff output endpoint. Such a device will typically have a manual operation switch on it. Pressing this switch toggles the output.
When the output is toggled, there are various attributes that must be adjusted on the endpoint (onOff, global scene etc.) as well as potentially change notifications and messages sent to other bound devices. All of this logic is taken care of by the ZCL SDK layer, but it's necessary to trigger it.
If there is only a single endpoint, then sending a ZCL command with eCLD_OnOffCommandSend won't work as there is no source endpoint. There are internal commands in the ZCL (e.g. eCLD_OnOffHandleOnCommand), but these are internal.
Additionally, if there is a second endpoint on the device that can send a eCLD_OnOffCommandSend message, then what needs to be done to have the device respond to it? We have a device with onOff client and onOff server, and sending this command doesn't work. The cause seems to be because when sending from the local application to a local endpoint, then the message is sent with no security, which causes it be ignored. The sending code is as follows:
uint8 u8Seq;
tsZCL_Address sAddress;
sAddress.eAddressMode = E_ZCL_AM_SHORT_NO_ACK;
sAddress.uAddress.u16DestinationAddress = ZPS_u16AplZdoGetNwkAddr();
status = eCLD_OnOffCommandSend(
ROUTER_SWITCH_ENDPOINT,
ROUTER_RELAY_ENDPOINT,
&sAddress,
&u8Seq,
E_CLD_ONOFF_CMD_TOGGLE);This returns success, and a ZPS_EVENT_APS_DATA_INDICATION event is generated, which is received by the app and then dispatched to the stack with vZCL_EventHandler. The stack does no further processing.
In the case of receiving a toggle command from an external node, the same ZPS_EVENT_APS_DATA_INDICATION message is received and dispatched, but the stack responds as it should to the command.
Looking at the details of the message in both scenarios, the only difference is that the eSecurityStatus field of the event is 0xAC (secured with network key) when received from en external node, and 0xAF (unsecured) when generated locally with the above command.
If we change the value of eSecurityStatus in the event to 0xAC before sending it to the stack with vZCL_EventHandler, then the stack responds as expected.
So two questions:
1) What is the recommended method when there is no additional endpoint to send a message?
2) How can a local message like this be sent with the correct security settings?
Thanks,
Hello,
Hope you are doing well. What SDK version are you using? What example are you using as a base?
What modifications did you implement?
When you talk about local message, are you referring to a message to itself? (same device, different endpoint).
Regards,
Ricardo
Hi Ricardo,
Thanks for your reply.
We are using SDK_2.x_JN5189DK6 version 2.6.15.
The code was developed from the JN-AN-1243 BDB sample. The changes are simply to change the endpoint from from a BaseDevice to an OnOffOutput device, inline with the process described in JN-AN-1257 (developing clusters).
Yes, I am referring to sending a message to itself. As described in my post, for a home automation device with a single endpoint that implements the server onOff cluster (e.g. plug in appliance switch), it is typically necessary to toggle the output via a physical switch on the device. When the output is toggled, the ZCL layer must be made aware of this. Manually writing the onOff attribute to the correct value is simple enough, but there are various knock-on effects - the global scene attribute might need to be updated, bound devices need to be notified, timed off attributes might need to be updated etc. The ZCL layer of the SDK already handles all of this on receipt of an onOff toggle message, so it seems like re-implementing all of that logic in the app doesn't make sense. So I was asking how to trigger this from the local application?
Separately, for a device that has another endpoint that implements the client onOff cluster (e.g. wall switch with both output relay and switches), then it would seem that the appropriate method would be to send a message from that client endpoint to the onOff server endpoint (both on the local device). The code in the original post shows an example of this. As described, the result is that the ZCL layer doesn't respond to the message unless we manually change the security status value before forwarding the message.
Best regards
Hello,
eCLD_OnOffCommandSend is an implementation of a specific command for on/off cluster.
This uses the eZCL_CustomCommandSend, which has the destination address of the node.
But, the easiest way for your application, would be to modify directly on your application the state of the endpoint.
Regards,
Ricardo
Hi Ricardo,
Thanks for taking the time to respond. Apologies for the delayed reply - I've been on leave.
When you suggest to modify the endpoint directly as the easiest approach, did you mean to manually adjust the attributes in the application code? This is relatively easy, but managing the dependent effects (wait time attributes, global scene, bound clients etc.) in line with the ZCL spec requires re-implementing logic that already exists in the NXP onOff ZCL code.
In the case of a wall switch with onOff client endpoint (the switch) and onOff server endpoint (the relay), the switch will often already send onOff commands to other bound devices. Using different logic when addressing the local endpoint seems odd.
Sending the ZCL command to the local endpoint certainly seems to be the simplest and most correct correct approach. The fact that it works correctly (aside from requiring the security status to be changed) also suggests that it is intended to work, but perhaps I'm wrong on that. It's hard to tell as the relevant code is closed source.
Appreciate any further insight.
Regards,