Skip to content

fan_control: add FindClusterOnEndpoint wrapper - #1817

Open
dietolive-tw wants to merge 1 commit into
espressif:mainfrom
dietolive-tw:add-fan-find-cluster
Open

fan_control: add FindClusterOnEndpoint wrapper#1817
dietolive-tw wants to merge 1 commit into
espressif:mainfrom
dietolive-tw:add-fan-find-cluster

Conversation

@dietolive-tw

Copy link
Copy Markdown

fan_control: add FindClusterOnEndpoint wrapper

The flow_measurement and relative_humidity_measurement integration.cpp files provide a namespace-level FindClusterOnEndpoint() wrapper so application code can access the codegen cluster instance and call methods like SetPercentCurrent() directly. fan_control was missing this wrapper.

The upstream CodegenIntegration.h declares FindClusterOnEndpoint(), but the matching CodegenIntegration.cpp is excluded from the esp-matter build by CMakeLists.txt (EXCLUDE_SRCS_LIST for Codegen*.cpp). Without this wrapper in integration.cpp (the file actually compiled), app code that calls FindClusterOnEndpoint gets a link error.

Add it following the flow_measurement pattern.

Refs: pattern from clusters/flow_measurement/integration.cpp

Description

fan_control was missing the namespace-level FindClusterOnEndpoint()
wrapper that flow_measurement and relative_humidity_measurement
already provide in their integration.cpp files.

The upstream CodegenIntegration.h declares FindClusterOnEndpoint(),
but the matching CodegenIntegration.cpp is excluded from the esp-matter
build by CMakeLists.txt (EXCLUDE_SRCS_LIST for Codegen*.cpp).
Without this wrapper in integration.cpp (the file actually compiled),
application code that calls FanControl::FindClusterOnEndpoint() gets
a link error.

This matters for FanControl specifically because of the
PercentCurrent attribute.
FanControlCluster::ApplyFanModeSideEffects() (in connectedhomeip)
updates mFanMode and mPercentSetting for all modes but only updates
mPercentCurrent for kOff. For non-Off modes the spec leaves
PercentCurrent to the application, which must call
SetPercentCurrent() on the cluster instance — and that requires
FindClusterOnEndpoint().

PercentCurrent is non-writable, so writing it via
esp_matter::attribute::update() desyncs the two stores: it writes
the esp-matter storage, but ReadAttribute reads from the codegen
mPercentCurrent. The codegen SetPercentCurrent() is the only
correct path, and this wrapper is what makes it reachable from
application code.

Changes

  • components/esp_matter/data_model_provider/clusters/fan_control/integration.cpp
    • Add FindClusterOnEndpoint(EndpointId) (matches flow_measurement pattern)
FanControlCluster * FindClusterOnEndpoint(EndpointId endpointId)
{
    auto it = gServers.find(endpointId);
    if (it == gServers.end() || !it->second.server.IsConstructed()) {
        return nullptr;
    }
    return &it->second.server.Cluster();
}

Note: fan_control uses it->second.server.IsConstructed() /
it->second.server.Cluster() (the server member), whereas the
measurement clusters use it->second.IsConstructed() /
it->second.Cluster() directly. The wrapper matches the existing access
pattern already used by SetDefaultDelegate() in the same file.

Related

  • Pattern source: components/esp_matter/data_model_provider/clusters/flow_measurement/integration.cpp
  • Pattern source: components/esp_matter/data_model_provider/clusters/relative_humidity_measurement/integration.cpp
  • Build exclusion: components/esp_matter/data_model_provider/CMakeLists.txt (EXCLUDE_SRCS_LIST for Codegen*.cpp)
  • Related upstream code: connectedhomeip/src/app/clusters/fan-control-server/FanControlCluster.cpp (ApplyFanModeSideEffects)

Testing

  • Pattern matches existing flow_measurement/integration.cpp and
    relative_humidity_measurement/integration.cpp — no behavior change for
    apps that do not call the new wrapper.
  • Access pattern (it->second.server.*) matches the existing
    SetDefaultDelegate() in the same file, so the existing gServers map
    layout is respected.
  • Build verified with an out-of-tree ESP-IDF + esp-matter example that
    calls FanControl::SetPercentCurrent(); without this wrapper the link
    step fails with an undefined reference to
    FindClusterOnEndpoint(EndpointId), with it the link succeeds and the
    PercentCurrent attribute reads back the value set via the codegen path
    (verified against Apple Home's fan speed UI).

Checklist

Before submitting a Pull Request, please ensure the following:

  • 🚨 This PR does not introduce breaking changes.
  • All CI checks (GH Actions) pass.
  • Documentation is updated as needed.
  • Tests are updated or added as necessary.
  • Code is well-commented, especially in complex areas.
  • Git history is clean — commits are squashed to the minimum necessary.

@CLAassistant

CLAassistant commented Aug 13, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@shubhamdp

Copy link
Copy Markdown
Collaborator

@dietolive-tw could you please sign the CLA.

The flow_measurement and relative_humidity_measurement integration.cpp files
provide a namespace-level FindClusterOnEndpoint() wrapper so application code
can access the codegen FanControl cluster instance and call methods like
SetPercentCurrent() directly. fan_control was missing this wrapper.

The upstream CodegenIntegration.h declares FindClusterOnEndpoint(), but the
matching CodegenIntegration.cpp is excluded from the esp-matter build by
CMakeLists.txt (EXCLUDE_SRCS_LIST for Codegen*.cpp). Without this wrapper in
integration.cpp (the file actually compiled), app code that calls
FindClusterOnEndpoint gets a link error.

Add it following the flow_measurement pattern.

Refs: pattern from clusters/flow_measurement/integration.cpp
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

Successfully merging this pull request may close these issues.

3 participants