Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] LevelControl cluster is not working with dynamic endpoints #25401

Open
8TRobi8 opened this issue Mar 1, 2023 · 12 comments
Open

[BUG] LevelControl cluster is not working with dynamic endpoints #25401

8TRobi8 opened this issue Mar 1, 2023 · 12 comments

Comments

@8TRobi8
Copy link

8TRobi8 commented Mar 1, 2023

Reproduction steps

I am working on a bridge device and have just tried the LevelControl cluster with a dynamic endpoint. The minLevel and maxLevel attributes are not read from the Application layer and are always zero. Therefore, the move-to-level command's Level value is irrelevant, since the range check changes the value always to zero.

The attributes are always read from the Application layer in other cluster server implementation with the ::Get call, but in the LevelControl cluster the minLevel and maxLevel attributes are not read.

I've made a little change in the moveToLevelHandler function of level-control.cpp and now it works. I don't know if this is the best solution, I've not digged so deep in this cluster server, but it works for me. :) It would be better to do this attribute read at initialization, since it won't change during runtime.

I've put these lines before the range check in moveToLevelHandler function:
// Get minLevel and maxLevel values status = Attributes::MinLevel::Get(endpoint, &state->minLevel); if (status != EMBER_ZCL_STATUS_SUCCESS) { emberAfLevelControlClusterPrintln("ERR: reading minimum level %x", status); return status; } status = Attributes::MaxLevel::Get(endpoint, &state->maxLevel); if (status != EMBER_ZCL_STATUS_SUCCESS) { emberAfLevelControlClusterPrintln("ERR: reading maximum level %x", status); return status; }

Bug prevalence

Whenever I try to change the level.

GitHub hash of the SDK that was being used

4088a77

Platform

core

Platform Version(s)

No response

Anything else?

No response

@bzbarsky-apple
Copy link
Contributor

bzbarsky-apple commented Mar 1, 2023

It sounds like you are not calling emberAfLevelControlClusterServerInitCallback for your endpoint. When you set up your dynamic endpoint cluster definitions, are you including that function in the cluster definition? Note that the convenience macros for defining dynamic endpoint clusters (DECLARE_DYNAMIC_CLUSTER) will not define this for you.

@bzbarsky-apple
Copy link
Contributor

bzbarsky-apple commented Mar 1, 2023

See also #24645 which is a similar issue for dynamic-bridge. If that's what you're using, this is a duplicate of that issue. If you're doing something else and defining the clusters yourself, then those definitions need to be fixed accordingly...

And yes, we need a better setup for this.

@8TRobi8
Copy link
Author

8TRobi8 commented Mar 1, 2023

Thank you for your prompt reply!

I've just checked the linked issue and it looks similar. I used the "bridge-app" as the basis, not the "dynamic-bridge", but I think the end result is the same. I simply use the mentioned DECLARE_DYNAMIC_CLUSTER macro.
Basically, I understand what is needed, but I miss the consistent behavior of the core. I've already integrated the OnOff, ModeSelect, Thermostat, DoorLock, WindowCovering, Illuminance/Temperature/RelativeHumidityMeasurement clusters where I have used only the macro mentioned above and all of them are working without any specific ember* call. Why is it required for LevelControl? (Just to be clear, I don't want to argufy, I just want to understand why it works like that.)

@bzbarsky-apple
Copy link
Contributor

Skipping init callbacks will in fact lead to incorrect behavior for OnOff (will not handle StartupOnOff attribute correctly), ModeSelect (will not handle StartUpMode correctly). The other clusters you list don't have any init logic, so not calling that non-existent logic is not a problem.

@nmtoan91
Copy link

@bzbarsky-apple
I got the same error.
I'm new to this C, could you show me how I can call the emberAfLevelControlClusterServerInitCallback() function in my main.cpp file?

Is this a local function in /app/clusters/level-control/level-control.cpp?
What header should I include then

@bzbarsky-apple
Copy link
Contributor

bzbarsky-apple commented Apr 18, 2023

could you show me how I can call the emberAfLevelControlClusterServerInitCallback() function in my main.cpp file

You wouldn't. You would include the function pointer in your cluster definition on the endpoint, and then initializing the endpoint will call it.

The function is declared in app-common/zap-generated/callback.h

@nmtoan91
Copy link

could you show me how I can call the emberAfLevelControlClusterServerInitCallback() function in my main.cpp file

You wouldn't. You would include the function pointer in your cluster definition on the endpoint, and then initializing the endpoint will call it.

The function is declared in app-common/zap-generated/callback.h

Thank you for your reply. But could you provide me some detail or sample code please.

I define the cluster by marco:

DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedDimmableLightClusters)
    DECLARE_DYNAMIC_CLUSTER(OnOff::Id, onOffAttrs, onOffIncomingCommands, nullptr),
    DECLARE_DYNAMIC_CLUSTER(LevelControl::Id, dimmableAttrs, levelControlIncomingCommands, nullptr),
    DECLARE_DYNAMIC_CLUSTER(Descriptor::Id, descriptorAttrs, nullptr, nullptr),
    DECLARE_DYNAMIC_CLUSTER(BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs2, nullptr,nullptr) 
DECLARE_DYNAMIC_CLUSTER_LIST_END;
DECLARE_DYNAMIC_ENDPOINT(bridgedDimmableLightEndpoint, bridgedDimmableLightClusters); 
DataVersion gDimmableLight1DataVersions[ArraySize(bridgedDimmableLightClusters)]; 

@bzbarsky-apple
Copy link
Contributor

I define the cluster by marco:

Yes, that macro doesn't work right for clusters that need an init function. You'd need to look at what it expands to, do that instead of using the macro, and add the init function to the cluster definition.

Or fix the macro to allow defining an init function.

@nmtoan91
Copy link

Sorry, I'm still not clear about what you mentioned.
As I see it, a cluster is just the struct object of attributes. How can I initiate it?
It would be helpful if you can show me some sample codes.
Thank you,

@nmtoan91
Copy link

@bzbarsky-apple

I managed to solve it by adding emberAfLevelControlClusterServerInitCallback(id); into emberAfSetDynamicEndpoint() function

Thank you

@bzbarsky-apple
Copy link
Contributor

As I see it, a cluster is just the struct object of attributes

It's not. One of the fields in that struct is a list of various functions that can be called in various cases....

@bzbarsky-apple
Copy link
Contributor

As far as sample code, scripts/tools/zap/tests/outputs/lighting-app/app-templates/endpoint_config.h has an example of a level control cluster with the relevant bits hanging off it. See the chipFuncArrayLevelControlServer array definition and use in that file, and the "mask" used for the cluster that says it has those functions attached to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants