Skip to content

Commit

Permalink
Updated WHM XML to align to spec PR 10028 (#34560)
Browse files Browse the repository at this point in the history
* Updated XML to align to spec PR 10028, (Adds Events and simplifies data types and command).

* Bumped cluster revision to 2

* Added missing Descriptions to the Events to avoid ZAP regen_all.py failing with unhelpful error message.

* Updated autogen'd files from regen_all.py

* Renamed WaterHeaterTypeBitmap/WaterHeaterDemandBitmap -> WaterHeaterHeatSourceBitmap. Added boostInfo structure into command. Now All-clusters-app compiles again. Some brief reformatting.

* Added missing new Java files.

* Updated test scripts to work with new types and boostInfo structure. Added to the tests.yaml which was missing.

* Corrected test-runner command linewrap issue

* Removed featureSet command flag in test runner which is not in All-cluster-app.

* Added missing apiMaturity="provisional" to WaterHeaterHeatSourceBitmap.

* Update .github/workflows/tests.yaml

* Re-aligned the XML after some late changes to the constraints in the spec.

---------

Co-authored-by: Hasty Granbery <hasty@granbery.org>
  • Loading branch information
jamesharrow and hasty authored Aug 8, 2024
1 parent bf9d431 commit c4cdbf6
Show file tree
Hide file tree
Showing 46 changed files with 1,800 additions and 493 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4386,7 +4386,7 @@ cluster ElectricalEnergyMeasurement = 145 {

/** This cluster is used to allow clients to control the operation of a hot water heating appliance so that it can be used with energy management. */
provisional cluster WaterHeaterManagement = 148 {
revision 1;
revision 2;

enum BoostStateEnum : enum8 {
kInactive = 0;
Expand All @@ -4398,24 +4398,32 @@ provisional cluster WaterHeaterManagement = 148 {
kTankPercent = 0x2;
}

bitmap WaterHeaterDemandBitmap : bitmap8 {
bitmap WaterHeaterHeatSourceBitmap : bitmap8 {
kImmersionElement1 = 0x1;
kImmersionElement2 = 0x2;
kHeatPump = 0x4;
kBoiler = 0x8;
kOther = 0x10;
}

bitmap WaterHeaterTypeBitmap : bitmap8 {
kImmersionElement1 = 0x1;
kImmersionElement2 = 0x2;
kHeatPump = 0x4;
kBoiler = 0x8;
kOther = 0x10;
struct WaterHeaterBoostInfoStruct {
elapsed_s duration = 0;
optional boolean oneShot = 1;
optional boolean emergencyBoost = 2;
optional temperature temporarySetpoint = 3;
optional percent targetPercentage = 4;
optional percent targetReheat = 5;
}

info event BoostStarted = 0 {
WaterHeaterBoostInfoStruct boostInfo = 0;
}

readonly attribute WaterHeaterTypeBitmap heaterTypes = 0;
readonly attribute WaterHeaterDemandBitmap heatDemand = 1;
info event BoostEnded = 1 {
}

readonly attribute WaterHeaterHeatSourceBitmap heaterTypes = 0;
readonly attribute WaterHeaterHeatSourceBitmap heatDemand = 1;
readonly attribute optional int16u tankVolume = 2;
readonly attribute optional energy_mwh estimatedHeatRequired = 3;
readonly attribute optional percent tankPercentage = 4;
Expand All @@ -4428,12 +4436,7 @@ provisional cluster WaterHeaterManagement = 148 {
readonly attribute int16u clusterRevision = 65533;

request struct BoostRequest {
elapsed_s duration = 0;
optional boolean oneShot = 1;
optional boolean emergencyBoost = 2;
optional temperature temporarySetpoint = 3;
optional percent targetPercentage = 4;
optional percent targetReheat = 5;
WaterHeaterBoostInfoStruct boostInfo = 0;
}

/** Allows a client to request that the water heater is put into a Boost state. */
Expand Down
189 changes: 118 additions & 71 deletions examples/all-clusters-app/all-clusters-common/include/WhmDelegate.h

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class WhmManufacturer
/**
* @brief Called to determine which heating sources to use,
*/
BitMask<WaterHeaterDemandBitmap> DetermineHeatingSources();
BitMask<WaterHeaterHeatSourceBitmap> DetermineHeatingSources();

/**
* @brief Turn the heating of the water tank on.
Expand All @@ -83,23 +83,44 @@ class WhmManufacturer
/**
* @brief Called to handle a boost command.
*
* @param duration Indicates the time period in seconds for which the BOOST state is activated before it automatically reverts
* to the previous mode (e.g. OFF, MANUAL or TIMED).
* @param oneShot Indicates whether the BOOST state should be automatically canceled once the hot water has first reached the
* set point temperature (or the TemporarySetpoint temperature, if specified) for the TargetPercentage (if
* specified).
* @param emergencyBoost Indicates that the consumer wants the water to be heated as quickly as practicable. This MAY cause
* multiple heat sources to be activated (e.g. a heat pump and direct electric heating element).
* @param temporarySetpoint Indicates the target temperature to which to heat the hot water for this Boost command. It SHALL be
* used instead of the normal set point temperature whilst the BOOST state is active.
* @param targetPercentage If the tank supports the TankPercent feature, this field indicates the amount of water that SHALL be
* heated by this Boost command before the heater is switched off.
* @param targetReheat If the tank supports the TankPercent feature, and the heating by this Boost command has ceased because
* the TargetPercentage of the water in the tank has been heated to the set point (or TemporarySetpoint if
* included), this field indicates the percentage to which the hot water in the tank SHALL be allowed to fall before again
* beginning to reheat it.
* @param duration Indicates the time period in seconds for which
* the BOOST state is activated before it
* automatically reverts to the previous mode
* (e.g. OFF, MANUAL or TIMED).
*
* @return Success if the boost command is successful; otherwise return the appropriate error.
* @param oneShot Indicates whether the BOOST state should be
* automatically canceled once the hot water has
* first reached the set point temperature (or the
* TemporarySetpoint temperature, if specified)
* for the TargetPercentage (if specified).
*
* @param emergencyBoost Indicates that the consumer wants the water to
* be heated as quickly as practicable. This MAY
* cause multiple heat sources to be activated
* (e.g. a heat pump and direct electric heating
* element).
*
* @param temporarySetpoint Indicates the target temperature to which to
* heat the hot water for this Boost command. It
* SHALL be used instead of the normal set point
* temperature whilst the BOOST state is active.
*
* @param targetPercentage If the tank supports the TankPercent feature,
* this field indicates the amount of water that
* SHALL be heated by this Boost command before
* the heater is switched off.
*
* @param targetReheat If the tank supports the TankPercent feature,
* and the heating by this Boost command has
* ceased because the TargetPercentage of the
* water in the tank has been heated to the set
* point (or TemporarySetpoint if included), this
* field indicates the percentage to which the hot
* water in the tank SHALL be allowed to fall
* before again beginning to reheat it.
*
* @return Success if the boost command is successful; otherwise return the
* appropriate error.
*/
Protocols::InteractionModel::Status BoostCommandStarted(uint32_t duration, Optional<bool> oneShot,
Optional<bool> emergencyBoost, Optional<int16_t> temporarySetpoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ void WaterHeaterManagementDelegate::SetWhmManufacturer(WhmManufacturer & whmManu
*
*********************************************************************************/

BitMask<WaterHeaterTypeBitmap> WaterHeaterManagementDelegate::GetHeaterTypes()
BitMask<WaterHeaterHeatSourceBitmap> WaterHeaterManagementDelegate::GetHeaterTypes()
{
return mHeaterTypes;
}

BitMask<WaterHeaterDemandBitmap> WaterHeaterManagementDelegate::GetHeatDemand()
BitMask<WaterHeaterHeatSourceBitmap> WaterHeaterManagementDelegate::GetHeatDemand()
{
return mHeatDemand;
}
Expand All @@ -80,7 +80,7 @@ BoostStateEnum WaterHeaterManagementDelegate::GetBoostState()
return mBoostState;
}

void WaterHeaterManagementDelegate::SetHeaterTypes(BitMask<WaterHeaterTypeBitmap> heaterTypes)
void WaterHeaterManagementDelegate::SetHeaterTypes(BitMask<WaterHeaterHeatSourceBitmap> heaterTypes)
{
if (mHeaterTypes != heaterTypes)
{
Expand All @@ -90,7 +90,7 @@ void WaterHeaterManagementDelegate::SetHeaterTypes(BitMask<WaterHeaterTypeBitmap
}
}

void WaterHeaterManagementDelegate::SetHeatDemand(BitMask<WaterHeaterDemandBitmap> heatDemand)
void WaterHeaterManagementDelegate::SetHeatDemand(BitMask<WaterHeaterHeatSourceBitmap> heatDemand)
{
if (mHeatDemand != heatDemand)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ CHIP_ERROR WhmManufacturer::Init()
return CHIP_ERROR_UNINITIALIZED;
}

dg->SetHeaterTypes(BitMask<WaterHeaterTypeBitmap>(WaterHeaterTypeBitmap::kImmersionElement1));
dg->SetHeatDemand(BitMask<WaterHeaterDemandBitmap>(WaterHeaterDemandBitmap::kImmersionElement1));
dg->SetHeaterTypes(BitMask<WaterHeaterHeatSourceBitmap>(WaterHeaterHeatSourceBitmap::kImmersionElement1));
dg->SetHeatDemand(BitMask<WaterHeaterHeatSourceBitmap>(WaterHeaterHeatSourceBitmap::kImmersionElement1));
dg->SetEstimatedHeatRequired(10000);

return CHIP_NO_ERROR;
Expand All @@ -55,36 +55,36 @@ CHIP_ERROR WhmManufacturer::Shutdown()
return CHIP_NO_ERROR;
}

BitMask<WaterHeaterDemandBitmap> WhmManufacturer::DetermineHeatingSources()
BitMask<WaterHeaterHeatSourceBitmap> WhmManufacturer::DetermineHeatingSources()
{
WaterHeaterManagementDelegate * dg = GetWhmManufacturer()->GetWhmDelegate();
if (dg == nullptr)
{
ChipLogError(AppServer, "WhmDelegate is not initialized");
return BitMask<WaterHeaterDemandBitmap>(0);
return BitMask<WaterHeaterHeatSourceBitmap>(0);
}

// A list of valid heaterTypes
uint8_t waterHeaterTypeValues[] = {
static_cast<uint8_t>(WaterHeaterTypeBitmap::kImmersionElement1),
static_cast<uint8_t>(WaterHeaterTypeBitmap::kImmersionElement2),
static_cast<uint8_t>(WaterHeaterTypeBitmap::kHeatPump),
static_cast<uint8_t>(WaterHeaterTypeBitmap::kBoiler),
static_cast<uint8_t>(WaterHeaterTypeBitmap::kOther),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kImmersionElement1),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kImmersionElement2),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kHeatPump),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kBoiler),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kOther),
};

// The corresponding list of valid headerDemands
uint8_t waterHeaterDemandValues[] = {
static_cast<uint8_t>(WaterHeaterDemandBitmap::kImmersionElement1),
static_cast<uint8_t>(WaterHeaterDemandBitmap::kImmersionElement2),
static_cast<uint8_t>(WaterHeaterDemandBitmap::kHeatPump),
static_cast<uint8_t>(WaterHeaterDemandBitmap::kBoiler),
static_cast<uint8_t>(WaterHeaterDemandBitmap::kOther),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kImmersionElement1),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kImmersionElement2),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kHeatPump),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kBoiler),
static_cast<uint8_t>(WaterHeaterHeatSourceBitmap::kOther),
};

// Iterate across the valid waterHeaterTypes seeing which heating sources are available based on heaterTypes.
// Set the corresponding bit in the heaterDemand bitmap.
BitMask<WaterHeaterTypeBitmap> heaterTypes = dg->GetHeaterTypes();
BitMask<WaterHeaterHeatSourceBitmap> heaterTypes = dg->GetHeaterTypes();

uint8_t heaterDemandMask = 0;
for (uint16_t idx = 0; idx < static_cast<uint16_t>(sizeof(waterHeaterTypeValues) / sizeof(waterHeaterTypeValues[0])); idx++)
Expand All @@ -96,7 +96,7 @@ BitMask<WaterHeaterDemandBitmap> WhmManufacturer::DetermineHeatingSources()
}
}

return BitMask<WaterHeaterDemandBitmap>(heaterDemandMask);
return BitMask<WaterHeaterHeatSourceBitmap>(heaterDemandMask);
}

Status WhmManufacturer::TurnHeatingOn(bool emergencyBoost)
Expand All @@ -111,12 +111,12 @@ Status WhmManufacturer::TurnHeatingOn(bool emergencyBoost)
{
// emergencyBoost that the consumer wants the water to be heated as quickly as practicable.
// Thus, cause multiple heat sources to be activated
dg->SetHeatDemand(BitMask<WaterHeaterDemandBitmap>(WaterHeaterDemandBitmap::kImmersionElement1,
WaterHeaterDemandBitmap::kImmersionElement2));
dg->SetHeatDemand(BitMask<WaterHeaterHeatSourceBitmap>(WaterHeaterHeatSourceBitmap::kImmersionElement1,
WaterHeaterHeatSourceBitmap::kImmersionElement2));
}
else
{
dg->SetHeatDemand(BitMask<WaterHeaterDemandBitmap>(WaterHeaterDemandBitmap::kImmersionElement1));
dg->SetHeatDemand(BitMask<WaterHeaterHeatSourceBitmap>(WaterHeaterHeatSourceBitmap::kImmersionElement1));
}

return status;
Expand All @@ -130,7 +130,7 @@ Status WhmManufacturer::TurnHeatingOff()

WaterHeaterManagementDelegate * dg = GetWhmDelegate();

dg->SetHeatDemand(BitMask<WaterHeaterDemandBitmap>(0));
dg->SetHeatDemand(BitMask<WaterHeaterHeatSourceBitmap>(0));

return status;
}
Expand Down Expand Up @@ -167,7 +167,7 @@ void SetTestEventTrigger_BasicInstallationTestEvent()
// Simulate installation in a 100L tank full of water at 20C, with a target temperature of 60C, in OFF mode
dg->SetTankVolume(100);
dg->SetTargetWaterTemperature(6000);
dg->SetHeaterTypes(BitMask<WaterHeaterTypeBitmap>(WaterHeaterTypeBitmap::kImmersionElement1));
dg->SetHeaterTypes(BitMask<WaterHeaterHeatSourceBitmap>(WaterHeaterHeatSourceBitmap::kImmersionElement1));
dg->DrawOffHotWater(100, 2000);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ void Instance::InvokeCommand(HandlerContext & handlerContext)

void Instance::HandleBoost(HandlerContext & ctx, const Commands::Boost::DecodableType & commandData)
{
uint32_t duration = commandData.duration;
Optional<bool> oneShot = commandData.oneShot;
Optional<bool> emergencyBoost = commandData.emergencyBoost;
Optional<int16_t> temporarySetpoint = commandData.temporarySetpoint;
Optional<Percent> targetPercentage = commandData.targetPercentage;
Optional<Percent> targetReheat = commandData.targetReheat;
uint32_t duration = commandData.boostInfo.duration;
Optional<bool> oneShot = commandData.boostInfo.oneShot;
Optional<bool> emergencyBoost = commandData.boostInfo.emergencyBoost;
Optional<int16_t> temporarySetpoint = commandData.boostInfo.temporarySetpoint;
Optional<Percent> targetPercentage = commandData.boostInfo.targetPercentage;
Optional<Percent> targetReheat = commandData.boostInfo.targetReheat;

// Notify the appliance if the appliance hardware cannot be adjusted, then return Failure
if (HasFeature(WaterHeaterManagement::Feature::kTankPercent))
Expand Down
Loading

0 comments on commit c4cdbf6

Please sign in to comment.