Coverage Report

Created: 2026-07-10 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/connectedhomeip/examples/thermostat/thermostat-common/include/thermostat-delegate-impl.h
Line
Count
Source
1
/*
2
 *
3
 *    Copyright (c) 2024-2025 Project CHIP Authors
4
 *    All rights reserved.
5
 *
6
 *    Licensed under the Apache License, Version 2.0 (the "License");
7
 *    you may not use this file except in compliance with the License.
8
 *    You may obtain a copy of the License at
9
 *
10
 *        http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 *    Unless required by applicable law or agreed to in writing, software
13
 *    distributed under the License is distributed on an "AS IS" BASIS,
14
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 *    See the License for the specific language governing permissions and
16
 *    limitations under the License.
17
 */
18
19
#pragma once
20
21
#include <app/clusters/thermostat-server/ThermostatDelegate.h>
22
23
namespace chip {
24
namespace app {
25
namespace Clusters {
26
namespace Thermostat {
27
28
/**
29
 * The ThermostatDelegate class serves as the instance delegate for storing Presets related information and providing it to the
30
 * Thermostat server code. It also manages the presets attribute and provides methods to write to presets, edit presets, maintain a
31
 * pending presets list and either commit the presets when requested or discard the changes. It also provides APIs to get and set
32
 * the attribute values.
33
 *
34
 */
35
36
static constexpr uint8_t kMaxNumberOfPresetTypes = 6;
37
38
static constexpr uint8_t kMaxNumberOfThermostatSuggestions = 5;
39
40
static constexpr uint8_t kMaxNumberOfScheduleTypes = 2;
41
42
// TODO: #34556 Support multiple presets/schedules of each type.
43
// We will support only one preset of each preset/schedule type.
44
static constexpr uint8_t kMaxNumberOfPresetsOfEachType   = 1;
45
static constexpr uint8_t kMaxNumberOfSchedulesOfEachType = 1;
46
47
// For testing the use case where number of presets added exceeds the number of presets supported, we will have the value of
48
// kMaxNumberOfPresetsSupported < kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType
49
static constexpr uint8_t kMaxNumberOfPresetsSupported = kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType - 1;
50
51
static constexpr uint8_t kMaxNumberOfSchedulesSupported = kMaxNumberOfScheduleTypes * kMaxNumberOfSchedulesOfEachType - 1;
52
53
class ThermostatDelegate : public Delegate
54
{
55
public:
56
0
    static inline ThermostatDelegate & GetInstance() { return sInstance; }
57
58
    std::optional<System::Clock::Milliseconds16> GetMaxAtomicWriteTimeout(chip::AttributeId attributeId) override;
59
60
    CHIP_ERROR GetPresetTypeAtIndex(size_t index, Structs::PresetTypeStruct::Type & presetType) override;
61
62
    uint8_t GetNumberOfPresets() override;
63
64
    CHIP_ERROR GetPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) override;
65
66
    CHIP_ERROR GetActivePresetHandle(DataModel::Nullable<MutableByteSpan> & activePresetHandle) override;
67
68
    CHIP_ERROR SetActivePresetHandle(const DataModel::Nullable<ByteSpan> & newActivePresetHandle) override;
69
70
    void InitializePendingPresets() override;
71
72
    CHIP_ERROR AppendToPendingPresetList(const PresetStructWithOwnedMembers & preset) override;
73
74
    CHIP_ERROR GetPendingPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) override;
75
76
    CHIP_ERROR CommitPendingPresets() override;
77
78
    void ClearPendingPresetList() override;
79
80
    uint8_t GetMaxThermostatSuggestions() override;
81
82
    uint8_t GetNumberOfThermostatSuggestions() override;
83
84
    CHIP_ERROR GetThermostatSuggestionAtIndex(size_t index,
85
                                              ThermostatSuggestionStructWithOwnedMembers & thermostatSuggestion) override;
86
87
    void GetCurrentThermostatSuggestion(
88
        DataModel::Nullable<ThermostatSuggestionStructWithOwnedMembers> & currentThermostatSuggestion) override;
89
90
    DataModel::Nullable<ThermostatSuggestionNotFollowingReasonBitmap> GetThermostatSuggestionNotFollowingReason() override;
91
92
    CHIP_ERROR AppendToThermostatSuggestionsList(const Structs::ThermostatSuggestionStruct::Type & thermostatSuggestion) override;
93
94
    CHIP_ERROR RemoveFromThermostatSuggestionsList(size_t indexToRemove) override;
95
96
    CHIP_ERROR GetUniqueID(uint8_t & uniqueID) override;
97
98
    CHIP_ERROR ReEvaluateCurrentSuggestion() override;
99
100
    CHIP_ERROR GetScheduleTypeAtIndex(size_t index, Structs::ScheduleTypeStruct::Type & scheduleType) override;
101
102
private:
103
    static ThermostatDelegate sInstance;
104
105
    ThermostatDelegate();
106
    ~ThermostatDelegate();
107
108
    ThermostatDelegate(const ThermostatDelegate &)             = delete;
109
    ThermostatDelegate & operator=(const ThermostatDelegate &) = delete;
110
111
    /**
112
     * @brief Initializes the preset types array with all preset types corresponding to PresetScenarioEnum.
113
     */
114
    void InitializePresetTypes();
115
116
    /**
117
     * @brief Initializes the presets array with some sample presets for testing.
118
     */
119
    void InitializePresets();
120
121
    /**
122
     * @brief return the index of the thermostat suggestion in the ThermostatSuggestions attribute with the earliest EffectiveTime
123
     * field. If there are no entries or an error occurs, returns the value in the MaxThermostatSuggestions attribute as an
124
     * invalid index.
125
     *
126
     */
127
    size_t GetThermostatSuggestionIndexWithEarliestEffectiveTime(System::Clock::Seconds32 currentMatterEpochTimestamp);
128
129
    CHIP_ERROR StartExpirationTimer(System::Clock::Seconds32 timeout);
130
131
    static void TimerExpiredCallback(System::Layer * systemLayer, void * appState);
132
133
    void CancelExpirationTimer();
134
135
    CHIP_ERROR SetThermostatSuggestionNotFollowingReason(
136
        const DataModel::Nullable<ThermostatSuggestionNotFollowingReasonBitmap> & thermostatSuggestionNotFollowingReason);
137
138
    void SetCurrentThermostatSuggestion(size_t index);
139
140
    bool HaveSuggestionWithID(uint8_t uniqueIDToFind);
141
142
    uint8_t mNumberOfPresets;
143
144
    Structs::PresetTypeStruct::Type mPresetTypes[kMaxNumberOfPresetTypes];
145
    PresetStructWithOwnedMembers mPresets[kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType];
146
    PresetStructWithOwnedMembers mPendingPresets[kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType];
147
148
    uint8_t mNextFreeIndexInPendingPresetsList;
149
    uint8_t mNextFreeIndexInPresetsList;
150
151
    uint8_t mActivePresetHandleData[kPresetHandleSize];
152
    size_t mActivePresetHandleDataSize;
153
    bool mActivePresetHandleIsNull = true;
154
155
    uint8_t mMaxThermostatSuggestions;
156
    ThermostatSuggestionStructWithOwnedMembers mThermostatSuggestions[kMaxNumberOfThermostatSuggestions];
157
    uint8_t mNextFreeIndexInThermostatSuggestionsList;
158
    uint8_t mUniqueID;
159
160
    // TODO: #39949 - This information should be stored in the cluster instance.
161
    size_t mIndexOfCurrentSuggestion;
162
    DataModel::Nullable<ThermostatSuggestionNotFollowingReasonBitmap> mThermostatSuggestionNotFollowingReason;
163
164
    bool mIsExpirationTimerRunning = false;
165
166
    uint8_t mMaxNumberOfSchedulesAllowedPerScheduleType;
167
168
    Structs::ScheduleTypeStruct::Type mScheduleTypes[kMaxNumberOfScheduleTypes];
169
170
    /**
171
     * @brief Initializes the schedules types array with example schedule types.
172
     */
173
    void InitializeScheduleTypes();
174
};
175
176
} // namespace Thermostat
177
} // namespace Clusters
178
} // namespace app
179
} // namespace chip