Skip to content

Commit 871ee38

Browse files
committed
Address review comments from JamesH
1 parent bb44cf2 commit 871ee38

File tree

9 files changed

+224
-161
lines changed

9 files changed

+224
-161
lines changed

examples/all-clusters-app/all-clusters-common/include/WhmDelegate.h

+22-95
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#pragma once
2020

2121
#include <app-common/zap-generated/cluster-objects.h>
22-
#include <app/clusters/mode-base-server/mode-base-server.h>
2322
#include <app/clusters/water-heater-management-server/water-heater-management-server.h>
2423

2524
#include <protocols/interaction_model/StatusCode.h>
@@ -34,7 +33,7 @@ using ModeTagStructType = detail::Structs::ModeTagStruct::Type;
3433
class WhmManufacturer;
3534

3635
// This is an application level delegate to handle operational state commands according to the specific business logic.
37-
class WaterHeaterManagementDelegate : public WaterHeaterManagement::Delegate, public ModeBase::Delegate
36+
class WaterHeaterManagementDelegate : public WaterHeaterManagement::Delegate
3837
{
3938
public:
4039
WaterHeaterManagementDelegate(EndpointId clustersEndpoint);
@@ -47,29 +46,33 @@ class WaterHeaterManagementDelegate : public WaterHeaterManagement::Delegate, pu
4746

4847
/*********************************************************************************
4948
*
50-
* Methods implementing the WaterHeaterManagement::Delegate interace
49+
* Methods implementing the WaterHeaterManagement::Delegate interface
5150
*
5251
*********************************************************************************/
5352

5453
/**
5554
* @brief Delegate should implement a handler to start boosting the water temperature as required.
56-
* Upon receipt, the Water Heater SHALL transition into the BOOST state, which SHALL cause the water in the tank (or the
57-
* TargetPercentage of the water, if included) to be heated towards the set point (or the TemporarySetpoint, if included), which
58-
* in turn may cause a call for heat, even if the mode is OFF, or is TIMED and it is during one of the Off periods.
55+
* Upon receipt, the Water Heater SHALL transition into the BOOST state, which SHALL cause the
56+
* water in the tank (or the TargetPercentage of the water, if included) to be heated towards
57+
* the set point (or the TemporarySetpoint, if included), which in turn may cause a call for heat,
58+
* even if the mode is OFF, or is TIMED and it is during one of the Off periods.
5959
*
60-
* @param duration Indicates the time period in seconds for which the BOOST state is activated before it automatically reverts
61-
* to the previous mode (e.g. OFF, MANUAL or TIMED).
62-
* @param oneShot Indicates whether the BOOST state should be automatically canceled once the hot water has first reached the
63-
* set point temperature (or the TemporarySetpoint temperature, if specified) for the TargetPercentage (if specified).
64-
* @param emergencyBoost Indicates that the consumer wants the water to be heated as quickly as practicable. This MAY cause
65-
* multiple heat sources to be activated (e.g. a heat pump and direct electric heating element).
66-
* @param temporarySetpoint Indicates the target temperature to which to heat the hot water for this Boost command. It SHALL be
67-
* used instead of the normal set point temperature whilst the BOOST state is active.
68-
* @param targetPercentage If the tank supports the TankPercent feature, this field indicates the amount of water that SHALL be
69-
* heated by this Boost command before the heater is switched off.
70-
* @param targetReheat If the tank supports the TankPercent feature, and the heating by this Boost command has ceased because
71-
* the TargetPercentage of the water in the tank has been heated to the set point (or TemporarySetpoint if included), this field
72-
* indicates the percentage to which the hot water in the tank SHALL be allowed to fall before again beginning to reheat it.
60+
* @param duration Indicates the time period in seconds for which the BOOST state is activated before it
61+
* automatically reverts to the previous mode (e.g. OFF, MANUAL or TIMED).
62+
* @param oneShot Indicates whether the BOOST state should be automatically canceled once the hot water has
63+
* first reached the set point temperature (or the TemporarySetpoint temperature, if specified)
64+
* for the TargetPercentage (if specified).
65+
* @param emergencyBoost Indicates that the consumer wants the water to be heated as quickly as practicable.
66+
* This MAY cause multiple heat sources to be activated (e.g. a heat pump and direct
67+
* electric heating element).
68+
* @param temporarySetpoint Indicates the target temperature to which to heat the hot water for this Boost command.
69+
* It SHALL be used instead of the normal set point temperature whilst the BOOST state is active.
70+
* @param targetPercentage If the tank supports the TankPercent feature, this field indicates the amount of water
71+
* that SHALL be heated by this Boost command before the heater is switched off.
72+
* @param targetReheat If the tank supports the TankPercent feature, and the heating by this Boost command has ceased
73+
* because the TargetPercentage of the water in the tank has been heated to the set point (or
74+
* TemporarySetpoint if included), this field indicates the percentage to which the hot water in
75+
* the tank SHALL be allowed to fall before again beginning to reheat it.
7376
*
7477
* @return Success if the boost command is accepted; otherwise the command SHALL be rejected with appropriate error.
7578
*/
@@ -104,57 +107,6 @@ class WaterHeaterManagementDelegate : public WaterHeaterManagement::Delegate, pu
104107
void SetTankPercentage(Percent tankPercentage);
105108
void SetBoostState(BoostStateEnum boostState);
106109

107-
/*********************************************************************************
108-
*
109-
* Methods implementing the ModeBase::Delegate interface
110-
*
111-
*********************************************************************************/
112-
113-
CHIP_ERROR Init() override;
114-
115-
/**
116-
* Handle application logic when the mode is changing.
117-
*
118-
* @param mode The new mode that the device is requested to transition to.
119-
* @param response A reference to a response that will be sent to the client. The contents of which con be modified by the
120-
* application.
121-
*/
122-
void HandleChangeToMode(uint8_t mode, ModeBase::Commands::ChangeToModeResponse::Type & response) override;
123-
124-
/**
125-
* Get the mode label of the Nth mode in the list of modes.
126-
*
127-
* @param modeIndex The index of the mode to be returned. It is assumed that modes are indexable from 0 and with no gaps.
128-
* @param label A reference to the mutable char span which will be mutated to receive the label on success. Use
129-
* CopyCharSpanToMutableCharSpan to copy into the MutableCharSpan.
130-
*
131-
* @return Returns a CHIP_NO_ERROR if there was no error and the label was returned successfully.
132-
* CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the modeIndex in beyond the list of available labels.
133-
*/
134-
CHIP_ERROR GetModeLabelByIndex(uint8_t modeIndex, MutableCharSpan & label) override;
135-
136-
/**
137-
* Get the mode value of the Nth mode in the list of modes.
138-
*
139-
* @param modeIndex The index of the mode to be returned. It is assumed that modes are indexable from 0 and with no gaps.
140-
* @param value a reference to the uint8_t variable that is to contain the mode value.
141-
*
142-
* @return Returns a CHIP_NO_ERROR if there was no error and the value was returned successfully.
143-
* CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the modeIndex in beyond the list of available values.
144-
*/
145-
CHIP_ERROR GetModeValueByIndex(uint8_t modeIndex, uint8_t & value) override;
146-
147-
/**
148-
* Get the mode tags of the Nth mode in the list of modes.
149-
* @param modeIndex The index of the mode to be returned. It is assumed that modes are indexable from 0 and with no gaps.
150-
* @param tags a reference to an existing and initialised buffer that is to contain the mode tags. std::copy can be used
151-
* to copy into the buffer.
152-
*
153-
* @return Returns a CHIP_NO_ERROR if there was no error and the mode tags were returned successfully.
154-
* CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the modeIndex in beyond the list of available mode tags.
155-
*/
156-
CHIP_ERROR GetModeTagsByIndex(uint8_t modeIndex, DataModel::List<ModeTagStructType> & tags) override;
157-
158110
/*********************************************************************************
159111
*
160112
* WaterHeaterManagementDelegate specific methods
@@ -293,9 +245,6 @@ class WaterHeaterManagementDelegate : public WaterHeaterManagement::Delegate, pu
293245
*
294246
*********************************************************************************/
295247

296-
// Access to the Water Heater Mode instance
297-
ModeBase::Instance mWaterHeaterModeInstance;
298-
299248
// This attribute SHALL indicate the methods to call for heat that the controller supports. If a bit is set then the controller
300249
// supports the corresponding method.
301250
BitMask<WaterHeaterTypeBitmap> mHeaterTypes;
@@ -319,28 +268,6 @@ class WaterHeaterManagementDelegate : public WaterHeaterManagement::Delegate, pu
319268

320269
// This attribute SHALL indicate if the BOOST state, as triggered by a Boost command, is currently active.
321270
BoostStateEnum mBoostState;
322-
323-
/*********************************************************************************
324-
*
325-
* Member variables implementing the ModeBase::Delegate interface
326-
*
327-
*********************************************************************************/
328-
329-
ModeTagStructType modeTagsOff[1] = { { .value = to_underlying(WaterHeaterMode::ModeTag::kOff) } };
330-
ModeTagStructType modeTagsManual[1] = { { .value = to_underlying(WaterHeaterMode::ModeTag::kManual) } };
331-
ModeTagStructType modeTagsTimed[1] = { { .value = to_underlying(WaterHeaterMode::ModeTag::kTimed) } };
332-
333-
const detail::Structs::ModeOptionStruct::Type kModeOptions[3] = {
334-
detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Off"),
335-
.mode = ModeOff,
336-
.modeTags = DataModel::List<const ModeTagStructType>(modeTagsOff) },
337-
detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Manual"),
338-
.mode = ModeManual,
339-
.modeTags = DataModel::List<const ModeTagStructType>(modeTagsManual) },
340-
detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Timed"),
341-
.mode = ModeTimed,
342-
.modeTags = DataModel::List<const ModeTagStructType>(modeTagsTimed) }
343-
};
344271
};
345272

346273
} // namespace WaterHeaterManagement
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
*
3+
* Copyright (c) 2023 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/mode-base-server/mode-base-server.h>
22+
#include <app/util/config.h>
23+
#include <cstring>
24+
#include <utility>
25+
26+
namespace chip {
27+
namespace app {
28+
namespace Clusters {
29+
30+
namespace WaterHeaterMode {
31+
32+
constexpr uint8_t ModeOff = 0;
33+
constexpr uint8_t ModeManual = 1;
34+
constexpr uint8_t ModeTimed = 2;
35+
36+
/// This is an application level delegate to handle WaterHeaterMode commands according to the specific business logic.
37+
class ExampleWaterHeaterModeDelegate : public ModeBase::Delegate
38+
{
39+
private:
40+
using ModeTagStructType = detail::Structs::ModeTagStruct::Type;
41+
ModeTagStructType modeTagsOff[1] = { { .value = to_underlying(ModeTag::kOff) } };
42+
ModeTagStructType modeTagsManual[1] = { { .value = to_underlying(ModeTag::kManual) } };
43+
ModeTagStructType modeTagsTimed[1] = { { .value = to_underlying(ModeTag::kTimed) } };
44+
45+
const detail::Structs::ModeOptionStruct::Type kModeOptions[3] = {
46+
detail::Structs::ModeOptionStruct::Type{
47+
.label = "Off"_span, .mode = ModeOff, .modeTags = DataModel::List<const ModeTagStructType>(modeTagsOff) },
48+
detail::Structs::ModeOptionStruct::Type{
49+
.label = "Manual"_span, .mode = ModeManual, .modeTags = DataModel::List<const ModeTagStructType>(modeTagsManual) },
50+
detail::Structs::ModeOptionStruct::Type{
51+
.label = "Timed"_span, .mode = ModeTimed, .modeTags = DataModel::List<const ModeTagStructType>(modeTagsTimed) }
52+
};
53+
54+
CHIP_ERROR Init() override;
55+
void HandleChangeToMode(uint8_t mode, ModeBase::Commands::ChangeToModeResponse::Type & response) override;
56+
57+
CHIP_ERROR GetModeLabelByIndex(uint8_t modeIndex, MutableCharSpan & label) override;
58+
CHIP_ERROR GetModeValueByIndex(uint8_t modeIndex, uint8_t & value) override;
59+
CHIP_ERROR GetModeTagsByIndex(uint8_t modeIndex, DataModel::List<ModeTagStructType> & tags) override;
60+
61+
public:
62+
~ExampleWaterHeaterModeDelegate() override = default;
63+
};
64+
65+
ModeBase::Instance * Instance();
66+
67+
void Shutdown();
68+
69+
} // namespace WaterHeaterMode
70+
71+
} // namespace Clusters
72+
} // namespace app
73+
} // namespace chip

examples/all-clusters-app/all-clusters-common/src/WhmDelegateImpl.cpp

+7-57
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
*/
1818
#include <app/clusters/water-heater-management-server/water-heater-management-server.h>
1919

20+
2021
#include <WhmDelegate.h>
2122
#include <WhmManufacturer.h>
23+
#include <water-heater-mode.h>
2224

2325
using namespace chip;
2426
using namespace chip::app;
@@ -29,11 +31,9 @@ using Protocols::InteractionModel::Status;
2931

3032
WaterHeaterManagementDelegate::WaterHeaterManagementDelegate(EndpointId clustersEndpoint) :
3133
mpWhmInstance(nullptr), mpWhmManufacturer(nullptr), mBoostTargetTemperatureReached(false),
32-
mWaterHeaterModeInstance(this, clustersEndpoint, WaterHeaterMode::Id, 0), mTankVolume(0), mEstimatedHeatRequired(0),
34+
mTankVolume(0), mEstimatedHeatRequired(0),
3335
mTankPercentage(0), mBoostState(BoostStateEnum::kInactive)
3436
{
35-
// Initialise the WaterHeaterMode instance
36-
mWaterHeaterModeInstance.Init();
3737
}
3838

3939
void WaterHeaterManagementDelegate::SetWaterHeaterManagementInstance(WaterHeaterManagement::Instance & instance)
@@ -287,56 +287,6 @@ Status WaterHeaterManagementDelegate::HandleCancelBoost()
287287
*
288288
*********************************************************************************/
289289

290-
CHIP_ERROR WaterHeaterManagementDelegate::Init()
291-
{
292-
return CHIP_NO_ERROR;
293-
}
294-
295-
void WaterHeaterManagementDelegate::HandleChangeToMode(uint8_t NewMode, ModeBase::Commands::ChangeToModeResponse::Type & response)
296-
{
297-
response.status = to_underlying(ModeBase::StatusCode::kSuccess);
298-
}
299-
300-
CHIP_ERROR WaterHeaterManagementDelegate::GetModeLabelByIndex(uint8_t modeIndex, chip::MutableCharSpan & label)
301-
{
302-
if (modeIndex >= ArraySize(kModeOptions))
303-
{
304-
return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
305-
}
306-
307-
return chip::CopyCharSpanToMutableCharSpan(kModeOptions[modeIndex].label, label);
308-
}
309-
310-
CHIP_ERROR WaterHeaterManagementDelegate::GetModeValueByIndex(uint8_t modeIndex, uint8_t & value)
311-
{
312-
if (modeIndex >= ArraySize(kModeOptions))
313-
{
314-
return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
315-
}
316-
317-
value = kModeOptions[modeIndex].mode;
318-
319-
return CHIP_NO_ERROR;
320-
}
321-
322-
CHIP_ERROR WaterHeaterManagementDelegate::GetModeTagsByIndex(uint8_t modeIndex, DataModel::List<ModeTagStructType> & tags)
323-
{
324-
if (modeIndex >= ArraySize(kModeOptions))
325-
{
326-
return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED;
327-
}
328-
329-
if (tags.size() < kModeOptions[modeIndex].modeTags.size())
330-
{
331-
return CHIP_ERROR_INVALID_ARGUMENT;
332-
}
333-
334-
std::copy(kModeOptions[modeIndex].modeTags.begin(), kModeOptions[modeIndex].modeTags.end(), tags.begin());
335-
tags.reduce_size(kModeOptions[modeIndex].modeTags.size());
336-
337-
return CHIP_NO_ERROR;
338-
}
339-
340290
/*********************************************************************************
341291
*
342292
* WaterHeaterManagementDelegate specific methods
@@ -431,9 +381,9 @@ Status WaterHeaterManagementDelegate::CheckIfHeatNeedsToBeTurnedOnOrOff()
431381

432382
if (!HasWaterTemperatureReachedTarget())
433383
{
434-
uint8_t mode = mInstance->GetCurrentMode();
384+
uint8_t mode = WaterHeaterMode::Instance()->GetCurrentMode();
435385

436-
// The water in the tank is not at the target temperature. See if we heating is currently off
386+
// The water in the tank is not at the target temperature. See if heating is currently off
437387
if (mHeatDemand.Raw() == 0)
438388
{
439389
// Need to track whether the water temperature has reached the target temperature for the boost
@@ -524,13 +474,13 @@ Status WaterHeaterManagementDelegate::CheckIfHeatNeedsToBeTurnedOnOrOff()
524474

525475
void WaterHeaterManagementDelegate::SetWaterHeaterMode(uint8_t modeValue)
526476
{
527-
if (!mInstance->IsSupportedMode(modeValue))
477+
if (!WaterHeaterMode::Instance()->IsSupportedMode(modeValue))
528478
{
529479
ChipLogError(AppServer, "SetWaterHeaterMode bad mode");
530480
return;
531481
}
532482

533-
Status status = mInstance->UpdateCurrentMode(modeValue);
483+
Status status = WaterHeaterMode::Instance()->UpdateCurrentMode(modeValue);
534484
if (status != Status::Success)
535485
{
536486
ChipLogError(AppServer, "SetWaterHeaterMode updateMode failed");

examples/all-clusters-app/all-clusters-common/src/WhmMain.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ CHIP_ERROR WhmInit()
7474
/* Manufacturer may optionally not support all features, commands & attributes */
7575
gWhmInstance = std::make_unique<WaterHeaterManagementInstance>(
7676
EndpointId(WHM_ENDPOINT), *gWhmDelegate,
77-
BitMask<Feature>(Feature::kEnergyManagement, Feature::kTankPercent)); // GetFeatureMapFromCmdLine());
78-
77+
BitMask<Feature>(Feature::kEnergyManagement, Feature::kTankPercent));
7978
if (!gWhmInstance)
8079
{
8180
ChipLogError(AppServer, "Failed to allocate memory for WaterHeaterManagementInstance");

examples/all-clusters-app/all-clusters-common/src/WhmManufacturer.cpp

+10-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <app-common/zap-generated/attributes/Accessors.h>
2626

2727
using namespace chip;
28+
using namespace chip::app::Clusters::WaterHeaterManagement;
2829

2930
using Protocols::InteractionModel::Status;
3031

@@ -44,6 +45,10 @@ CHIP_ERROR WhmManufacturer::Init()
4445

4546
mBoostActive = false;
4647

48+
dg->SetHeaterTypes(BitMask<WaterHeaterTypeBitmap>(WaterHeaterTypeBitmap::kImmersionElement1));
49+
dg->SetHeatDemand(BitMask<WaterHeaterDemandBitmap>(WaterHeaterDemandBitmap::kImmersionElement1));
50+
dg->SetEstimatedHeatRequired(10000);
51+
4752
return CHIP_NO_ERROR;
4853
}
4954

@@ -72,11 +77,11 @@ BitMask<WaterHeaterDemandBitmap> WhmManufacturer::DetermineHeatingSources()
7277

7378
// The corresponding list of valid headerDemands
7479
uint8_t waterHeaterDemandValues[] = {
75-
static_cast<uint8_t>(WaterHeaterTypeBitmap::kImmersionElement1),
76-
static_cast<uint8_t>(WaterHeaterTypeBitmap::kImmersionElement2),
77-
static_cast<uint8_t>(WaterHeaterTypeBitmap::kHeatPump),
78-
static_cast<uint8_t>(WaterHeaterTypeBitmap::kBoiler),
79-
static_cast<uint8_t>(WaterHeaterTypeBitmap::kOther),
80+
static_cast<uint8_t>(WaterHeaterDemandBitmap::kImmersionElement1),
81+
static_cast<uint8_t>(WaterHeaterDemandBitmap::kImmersionElement2),
82+
static_cast<uint8_t>(WaterHeaterDemandBitmap::kHeatPump),
83+
static_cast<uint8_t>(WaterHeaterDemandBitmap::kBoiler),
84+
static_cast<uint8_t>(WaterHeaterDemandBitmap::kOther),
8085
};
8186

8287
// Iterate across the valid waterHeaterTypes seeing which heating sources are available based on heaterTypes.

0 commit comments

Comments
 (0)