diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index c126624fbf0e62..38335a2bbe64d9 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -11269,6 +11269,21 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "min setpoint dead band", + "code": 25, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x19", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "control sequence of operation", "code": 27, diff --git a/examples/thermostat/thermostat-common/thermostat.zap b/examples/thermostat/thermostat-common/thermostat.zap index e6796f6cf952e4..250d291859f63e 100644 --- a/examples/thermostat/thermostat-common/thermostat.zap +++ b/examples/thermostat/thermostat-common/thermostat.zap @@ -10284,6 +10284,21 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "min setpoint dead band", + "code": 25, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x19", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "control sequence of operation", "code": 27, diff --git a/src/app/clusters/thermostat-server/thermostat-server.cpp b/src/app/clusters/thermostat-server/thermostat-server.cpp index ce1d1b7d55a65d..214bbda4f5f206 100644 --- a/src/app/clusters/thermostat-server/thermostat-server.cpp +++ b/src/app/clusters/thermostat-server/thermostat-server.cpp @@ -51,6 +51,23 @@ constexpr int16_t kDefaultHeatingSetpoint = 2000; constexpr int16_t kDefaultCoolingSetpoint = 2600; constexpr uint8_t kInvalidControlSequenceOfOperation = 0xff; constexpr uint8_t kInvalidRequestedSystemMode = 0xff; +constexpr int8_t kDefaultDeadBand = 25; // 2.5C is the default + +// IMPORTANT NOTE: +// No Side effects are permitted in emberAfThermostatClusterServerPreAttributeChangedCallback +// If a setpoint changes is required as a result of setpoint limit change +// it does not happen here. It is the responsibility of the device to adjust the setpoint(s) +// as required in emberAfThermostatClusterServerPostAttributeChangedCallback +// limit change validation assures that there is at least 1 setpoint that will be valid + +#define FEATURE_MAP_HEAT 0x01 +#define FEATURE_MAP_COOL 0x02 +#define FEATURE_MAP_OCC 0x04 +#define FEATURE_MAP_SCH 0x08 +#define FEATURE_MAP_SB 0x10 +#define FEATURE_MAP_AUTO 0x20 + +#define FEATURE_MAP_OVERIDE FEATURE_MAP_HEAT | FEATURE_MAP_COOL | FEATURE_MAP_AUTO void emberAfThermostatClusterServerInitCallback() { @@ -68,155 +85,243 @@ void emberAfThermostatClusterServerInitCallback() // or should this just be the responsibility of the thermostat application? } +using imcode = Protocols::InteractionModel::Status; + Protocols::InteractionModel::Status MatterThermostatClusterServerPreAttributeChangedCallback(const app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value) { - EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; - EndpointId endpoint = attributePath.mEndpointId; + EndpointId endpoint = attributePath.mEndpointId; int16_t requested; - switch (attributePath.mAttributeId) + // Limits will be needed for all checks + // so we just get them all now + int16_t AbsMinHeatSetpointLimit; + int16_t AbsMaxHeatSetpointLimit; + int16_t MinHeatSetpointLimit; + int16_t MaxHeatSetpointLimit; + int16_t AbsMinCoolSetpointLimit; + int16_t AbsMaxCoolSetpointLimit; + int16_t MinCoolSetpointLimit; + int16_t MaxCoolSetpointLimit; + int8_t DeadBand = 0; + int16_t DeadBandTemp = 0; + uint32_t FeatureMap = 0; + bool AutoSupported = false; + bool HeatSupported = false; + bool CoolSupported = false; + bool OccupancySupported = false; + int16_t OccupiedCoolingSetpoint; + int16_t OccupiedHeatingSetpoint; + int16_t UnoccupiedCoolingSetpoint; + int16_t UnoccupiedHeatingSetpoint; + +// TODO re-enable reading reaturemap once https://github.com/project-chip/connectedhomeip/pull/9725 is merged +#ifndef FEATURE_MAP_OVERIDE + emberAfReadServerAttribute(endpoint, Thermostat::Id, chip::app::Clusters::Globals::Attributes::Ids::FeatureMap, + (uint8_t *) &FeatureMap, sizeof(FeatureMap)); +#else + FeatureMap = FEATURE_MAP_OVERIDE; +#endif + + if (FeatureMap & 1 << 5) // Bit 5 is Auto Mode supported { - case OccupiedHeatingSetpoint::Id: { - int16_t AbsMinHeatSetpointLimit; - int16_t AbsMaxHeatSetpointLimit; - int16_t MinHeatSetpointLimit; - int16_t MaxHeatSetpointLimit; + AutoSupported = true; + if (MinSetpointDeadBand::Get(endpoint, &DeadBand) != EMBER_ZCL_STATUS_SUCCESS) + { + DeadBand = kDefaultDeadBand; + } + DeadBandTemp = static_cast(DeadBand * 10); + } + if (FeatureMap & 1 << 0) + HeatSupported = true; + + if (FeatureMap & 1 << 1) + CoolSupported = true; + + if (FeatureMap & 1 << 2) + OccupancySupported = true; + + if (AbsMinCoolSetpointLimit::Get(endpoint, &AbsMinCoolSetpointLimit) != EMBER_ZCL_STATUS_SUCCESS) + AbsMinCoolSetpointLimit = kDefaultAbsMinCoolSetpointLimit; - status = AbsMinHeatSetpointLimit::Get(endpoint, &AbsMinHeatSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + if (AbsMaxCoolSetpointLimit::Get(endpoint, &AbsMaxCoolSetpointLimit) != EMBER_ZCL_STATUS_SUCCESS) + AbsMaxCoolSetpointLimit = kDefaultAbsMaxCoolSetpointLimit; + + if (MinCoolSetpointLimit::Get(endpoint, &MinCoolSetpointLimit) != EMBER_ZCL_STATUS_SUCCESS) + MinCoolSetpointLimit = AbsMinCoolSetpointLimit; + + if (MaxCoolSetpointLimit::Get(endpoint, &MaxCoolSetpointLimit) != EMBER_ZCL_STATUS_SUCCESS) + MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; + + if (AbsMinHeatSetpointLimit::Get(endpoint, &AbsMinHeatSetpointLimit) != EMBER_ZCL_STATUS_SUCCESS) + AbsMinHeatSetpointLimit = kDefaultAbsMinHeatSetpointLimit; + + if (AbsMaxHeatSetpointLimit::Get(endpoint, &AbsMaxHeatSetpointLimit) != EMBER_ZCL_STATUS_SUCCESS) + AbsMaxHeatSetpointLimit = kDefaultAbsMaxHeatSetpointLimit; + + if (MinHeatSetpointLimit::Get(endpoint, &MinHeatSetpointLimit) != EMBER_ZCL_STATUS_SUCCESS) + MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + + if (MaxHeatSetpointLimit::Get(endpoint, &MaxHeatSetpointLimit) != EMBER_ZCL_STATUS_SUCCESS) + MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; + + if (CoolSupported) + if (OccupiedCoolingSetpoint::Get(endpoint, &OccupiedCoolingSetpoint) != EMBER_ZCL_STATUS_SUCCESS) { - AbsMinHeatSetpointLimit = kDefaultAbsMinHeatSetpointLimit; + ChipLogError(Zcl, "Error: Can not read Occupied Cooling Setpoint"); + return imcode::Failure; } - status = AbsMaxHeatSetpointLimit::Get(endpoint, &AbsMaxHeatSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + if (HeatSupported) + if (OccupiedHeatingSetpoint::Get(endpoint, &OccupiedHeatingSetpoint) != EMBER_ZCL_STATUS_SUCCESS) { - AbsMaxHeatSetpointLimit = kDefaultAbsMaxHeatSetpointLimit; + ChipLogError(Zcl, "Error: Can not read Occupied Heating Setpoint"); + return imcode::Failure; } - status = MinHeatSetpointLimit::Get(endpoint, &MinHeatSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + if (CoolSupported && OccupancySupported) + if (UnoccupiedCoolingSetpoint::Get(endpoint, &UnoccupiedCoolingSetpoint) != EMBER_ZCL_STATUS_SUCCESS) { - MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + ChipLogError(Zcl, "Error: Can not read Unoccupied Cooling Setpoint"); + return imcode::Failure; } - status = MaxHeatSetpointLimit::Get(endpoint, &MaxHeatSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + if (HeatSupported && OccupancySupported) + if (UnoccupiedHeatingSetpoint::Get(endpoint, &UnoccupiedHeatingSetpoint) != EMBER_ZCL_STATUS_SUCCESS) { - MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; + ChipLogError(Zcl, "Error: Can not read Unoccupied Heating Setpoint"); + return imcode::Failure; } + switch (attributePath.mAttributeId) + { + case OccupiedHeatingSetpoint::Id: { requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); - if (requested < AbsMinHeatSetpointLimit || requested < MinHeatSetpointLimit || requested > AbsMaxHeatSetpointLimit || - requested > MaxHeatSetpointLimit) - status = EMBER_ZCL_STATUS_INVALID_VALUE; - else - status = EMBER_ZCL_STATUS_SUCCESS; - - break; + if (!HeatSupported) + return imcode::UnsupportedAttribute; + else if (requested < AbsMinHeatSetpointLimit || requested < MinHeatSetpointLimit || requested > AbsMaxHeatSetpointLimit || + requested > MaxHeatSetpointLimit) + return imcode::InvalidValue; + else if (AutoSupported) + { + if (requested > OccupiedCoolingSetpoint - DeadBandTemp) + return imcode::InvalidValue; + } + return imcode::Success; } case OccupiedCoolingSetpoint::Id: { - int16_t AbsMinCoolSetpointLimit; - int16_t AbsMaxCoolSetpointLimit; - int16_t MinCoolSetpointLimit; - int16_t MaxCoolSetpointLimit; - - status = AbsMinCoolSetpointLimit::Get(endpoint, &AbsMinCoolSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); + if (!CoolSupported) + return imcode::UnsupportedAttribute; + else if (requested < AbsMinCoolSetpointLimit || requested < MinCoolSetpointLimit || requested > AbsMaxCoolSetpointLimit || + requested > MaxCoolSetpointLimit) + return imcode::InvalidValue; + else if (AutoSupported) { - AbsMinCoolSetpointLimit = kDefaultAbsMinCoolSetpointLimit; + if (requested < OccupiedHeatingSetpoint + DeadBandTemp) + return imcode::InvalidValue; } + return imcode::Success; + } - status = AbsMaxCoolSetpointLimit::Get(endpoint, &AbsMaxCoolSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + case UnoccupiedHeatingSetpoint::Id: { + requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); + if (!(HeatSupported && OccupancySupported)) + return imcode::UnsupportedAttribute; + else if (requested < AbsMinHeatSetpointLimit || requested < MinHeatSetpointLimit || requested > AbsMaxHeatSetpointLimit || + requested > MaxHeatSetpointLimit) + return imcode::InvalidValue; + else if (AutoSupported) { - AbsMaxCoolSetpointLimit = kDefaultAbsMaxCoolSetpointLimit; + if (requested > UnoccupiedCoolingSetpoint - DeadBandTemp) + return imcode::InvalidValue; } - - status = MinCoolSetpointLimit::Get(endpoint, &MinCoolSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + return imcode::Success; + } + case UnoccupiedCoolingSetpoint::Id: { + requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); + if (!(CoolSupported && OccupancySupported)) + return imcode::UnsupportedAttribute; + else if (requested < AbsMinCoolSetpointLimit || requested < MinCoolSetpointLimit || requested > AbsMaxCoolSetpointLimit || + requested > MaxCoolSetpointLimit) + return imcode::InvalidValue; + else if (AutoSupported) { - MinCoolSetpointLimit = AbsMinCoolSetpointLimit; + if (requested < UnoccupiedHeatingSetpoint + DeadBandTemp) + return imcode::InvalidValue; } + return imcode::Success; + } - status = MaxCoolSetpointLimit::Get(endpoint, &MaxCoolSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + case MinHeatSetpointLimit::Id: { + requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); + if (!HeatSupported) + return imcode::UnsupportedAttribute; + else if (requested < AbsMinHeatSetpointLimit || requested > MaxHeatSetpointLimit || requested > AbsMaxHeatSetpointLimit) + return imcode::InvalidValue; + else if (AutoSupported) { - MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; + if (requested > MinCoolSetpointLimit - DeadBandTemp) + return imcode::InvalidValue; } - requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); - if (requested < AbsMinCoolSetpointLimit || requested < MinCoolSetpointLimit || requested > AbsMaxCoolSetpointLimit || - requested > MaxCoolSetpointLimit) - status = EMBER_ZCL_STATUS_INVALID_VALUE; - else - status = EMBER_ZCL_STATUS_SUCCESS; - - break; + return imcode::Success; } - - case MinHeatSetpointLimit::Id: case MaxHeatSetpointLimit::Id: { - int16_t AbsMinHeatSetpointLimit; - int16_t AbsMaxHeatSetpointLimit; - - status = AbsMinHeatSetpointLimit::Get(endpoint, &AbsMinHeatSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); + if (!HeatSupported) + return imcode::UnsupportedAttribute; + else if (requested < AbsMinHeatSetpointLimit || requested < MinHeatSetpointLimit || requested > AbsMaxHeatSetpointLimit) + return imcode::InvalidValue; + else if (AutoSupported) { - AbsMinHeatSetpointLimit = kDefaultAbsMinHeatSetpointLimit; + if (requested > MaxCoolSetpointLimit - DeadBandTemp) + return imcode::InvalidValue; } - - status = AbsMaxHeatSetpointLimit::Get(endpoint, &AbsMaxHeatSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + return imcode::Success; + } + case MinCoolSetpointLimit::Id: { + requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); + if (!CoolSupported) + return imcode::UnsupportedAttribute; + else if (requested < AbsMinCoolSetpointLimit || requested > MaxCoolSetpointLimit || requested > AbsMaxCoolSetpointLimit) + return imcode::InvalidValue; + else if (AutoSupported) { - AbsMaxHeatSetpointLimit = kDefaultAbsMaxHeatSetpointLimit; + if (requested < MinHeatSetpointLimit + DeadBandTemp) + return imcode::InvalidValue; } - - requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); - if (requested < AbsMinHeatSetpointLimit || requested > AbsMaxHeatSetpointLimit) - status = EMBER_ZCL_STATUS_INVALID_VALUE; - else - status = EMBER_ZCL_STATUS_SUCCESS; - - break; + return imcode::Success; } - case MinCoolSetpointLimit::Id: case MaxCoolSetpointLimit::Id: { - int16_t AbsMinCoolSetpointLimit; - int16_t AbsMaxCoolSetpointLimit; - - status = AbsMinCoolSetpointLimit::Get(endpoint, &AbsMinCoolSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) - { - AbsMinCoolSetpointLimit = kDefaultAbsMinCoolSetpointLimit; - } - - status = AbsMaxCoolSetpointLimit::Get(endpoint, &AbsMaxCoolSetpointLimit); - if (status != EMBER_ZCL_STATUS_SUCCESS) + requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); + if (!CoolSupported) + return imcode::UnsupportedAttribute; + else if (requested < AbsMinCoolSetpointLimit || requested < MinCoolSetpointLimit || requested > AbsMaxCoolSetpointLimit) + return imcode::InvalidValue; + else if (AutoSupported) { - AbsMaxCoolSetpointLimit = kDefaultAbsMaxCoolSetpointLimit; + if (requested < MaxHeatSetpointLimit + DeadBandTemp) + return imcode::InvalidValue; } - - requested = static_cast(chip::Encoding::LittleEndian::Get16(value)); - if (requested < AbsMinCoolSetpointLimit || requested > AbsMaxCoolSetpointLimit) - status = EMBER_ZCL_STATUS_INVALID_VALUE; - else - status = EMBER_ZCL_STATUS_SUCCESS; - - break; + return imcode::Success; + } + case MinSetpointDeadBand::Id: { + requested = *value; + if (!AutoSupported) + return imcode::UnsupportedAttribute; + else if (requested < 0 || requested > 25) + return imcode::InvalidValue; + return imcode::Success; } case ControlSequenceOfOperation::Id: { uint8_t requestedCSO; requestedCSO = *value; if (requestedCSO > EMBER_ZCL_THERMOSTAT_CONTROL_SEQUENCE_COOLING_AND_HEATING_WITH_REHEAT) - status = EMBER_ZCL_STATUS_INVALID_VALUE; - else - status = EMBER_ZCL_STATUS_SUCCESS; - - break; + return imcode::InvalidValue; + return imcode::Success; } case SystemMode::Id: { @@ -227,7 +332,7 @@ MatterThermostatClusterServerPreAttributeChangedCallback(const app::ConcreteAttr if (ControlSequenceOfOperation > EMBER_ZCL_THERMOSTAT_CONTROL_SEQUENCE_COOLING_AND_HEATING_WITH_REHEAT || RequestedSystemMode > EMBER_ZCL_THERMOSTAT_SYSTEM_MODE_FAN_ONLY) { - status = EMBER_ZCL_STATUS_INVALID_VALUE; + return imcode::InvalidValue; } else { @@ -237,26 +342,25 @@ MatterThermostatClusterServerPreAttributeChangedCallback(const app::ConcreteAttr case EMBER_ZCL_THERMOSTAT_CONTROL_SEQUENCE_COOLING_WITH_REHEAT: if (RequestedSystemMode == EMBER_ZCL_THERMOSTAT_SYSTEM_MODE_HEAT || RequestedSystemMode == EMBER_ZCL_THERMOSTAT_SYSTEM_MODE_EMERGENCY_HEATING) - status = EMBER_ZCL_STATUS_INVALID_VALUE; - break; + return imcode::InvalidValue; + else + return imcode::Success; case EMBER_ZCL_THERMOSTAT_CONTROL_SEQUENCE_HEATING_ONLY: case EMBER_ZCL_THERMOSTAT_CONTROL_SEQUENCE_HEATING_WITH_REHEAT: if (RequestedSystemMode == EMBER_ZCL_THERMOSTAT_SYSTEM_MODE_COOL || RequestedSystemMode == EMBER_ZCL_THERMOSTAT_SYSTEM_MODE_PRECOOLING) - status = EMBER_ZCL_STATUS_INVALID_VALUE; - break; + return imcode::InvalidValue; + else + return imcode::Success; default: - break; + return imcode::Success; } } - break; } default: - break; + return imcode::Success; } - - return app::ToInteractionModelStatus(status); } bool emberAfThermostatClusterClearWeeklyScheduleCallback(app::CommandHandler * commandObj, @@ -444,82 +548,229 @@ bool emberAfThermostatClusterSetpointRaiseLowerCallback(app::CommandHandler * co int16_t HeatingSetpoint = kDefaultHeatingSetpoint, CoolingSetpoint = kDefaultCoolingSetpoint; // Set to defaults to be safe EmberAfStatus status = EMBER_ZCL_STATUS_FAILURE; - EmberAfStatus ReadStatus = EMBER_ZCL_STATUS_FAILURE; - EmberAfStatus WriteCoolingSetpointStatus = EMBER_ZCL_STATUS_SUCCESS, WriteHeatingSetpointStatus = EMBER_ZCL_STATUS_SUCCESS; + EmberAfStatus WriteCoolingSetpointStatus = EMBER_ZCL_STATUS_FAILURE; + EmberAfStatus WriteHeatingSetpointStatus = EMBER_ZCL_STATUS_FAILURE; + bool AutoSupported = false; + bool HeatSupported = false; + bool CoolSupported = false; + int16_t DeadBandTemp = 0; + int8_t DeadBand = 0; + uint32_t FeatureMap = 0; + + // TODO re-enable reading reaturemap once https://github.com/project-chip/connectedhomeip/pull/9725 is merged +#ifndef FEATURE_MAP_OVERIDE + emberAfReadServerAttribute(endpoint, Thermostat::Id, chip::app::Clusters::Globals::Attributes::Ids::FeatureMap, + (uint8_t *) &FeatureMap, sizeof(FeatureMap)); +#else + FeatureMap = FEATURE_MAP_OVERIDE; +#endif + + if (FeatureMap & 1 << 5) // Bit 5 is Auto Mode supported + { + AutoSupported = true; + if (MinSetpointDeadBand::Get(aEndpointId, &DeadBand) != EMBER_ZCL_STATUS_SUCCESS) + DeadBand = kDefaultDeadBand; + DeadBandTemp = static_cast(DeadBand * 10); + } + if (FeatureMap & 1 << 0) + HeatSupported = true; + + if (FeatureMap & 1 << 1) + CoolSupported = true; switch (mode) { case EMBER_ZCL_SETPOINT_ADJUST_MODE_HEAT_AND_COOL_SETPOINTS: + if (HeatSupported && CoolSupported) + { + int16_t DesiredCoolingSetpoint, CoolLimit, DesiredHeatingSetpoint, HeatLimit; + if (OccupiedCoolingSetpoint::Get(aEndpointId, &CoolingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + { + DesiredCoolingSetpoint = static_cast(CoolingSetpoint + amount * 10); + CoolLimit = static_cast(DesiredCoolingSetpoint - + EnforceCoolingSetpointLimits(DesiredCoolingSetpoint, aEndpointId)); + { + if (OccupiedHeatingSetpoint::Get(aEndpointId, &HeatingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + { + DesiredHeatingSetpoint = static_cast(HeatingSetpoint + amount * 10); + HeatLimit = static_cast(DesiredHeatingSetpoint - + EnforceHeatingSetpointLimits(DesiredHeatingSetpoint, aEndpointId)); + { + if (CoolLimit != 0 || HeatLimit != 0) + { + if (abs(CoolLimit) <= abs(HeatLimit)) + { + // We are limited by the Heating Limit + DesiredHeatingSetpoint = static_cast(DesiredHeatingSetpoint - HeatLimit); + DesiredCoolingSetpoint = static_cast(DesiredCoolingSetpoint - HeatLimit); + } + else + { + // We are limited by Cooling Limit + DesiredHeatingSetpoint = static_cast(DesiredHeatingSetpoint - CoolLimit); + DesiredCoolingSetpoint = static_cast(DesiredCoolingSetpoint - CoolLimit); + } + } + WriteCoolingSetpointStatus = OccupiedCoolingSetpoint::Set(aEndpointId, DesiredCoolingSetpoint); + if (WriteCoolingSetpointStatus != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(Zcl, "Error: SetOccupiedCoolingSetpoint failed!"); + } + WriteHeatingSetpointStatus = OccupiedHeatingSetpoint::Set(aEndpointId, DesiredHeatingSetpoint); + if (WriteHeatingSetpointStatus != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(Zcl, "Error: SetOccupiedHeatingSetpoint failed!"); + } + } + } + } + } + } - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3726 - // Behavior is not specified if the device only contains one mode - // and the both mode command is sent. - // Implemented behavior is not perfect, but spec needs to be clear before changing the implementaion - - // 4.3.7.2.1. Both - // [4.172] The client MAY indicate Both regardless of the server feature support. The server SHALL - // only adjust the setpoint that it supports and not respond with an error. - - // Implementation assumes that the attribute will NOT be present if the device does not support that mode. - - // In auto mode we will need to change both the heating and cooling setpoints - ReadStatus = OccupiedCoolingSetpoint::Get(aEndpointId, &CoolingSetpoint); - if (ReadStatus == EMBER_ZCL_STATUS_SUCCESS) + if (CoolSupported && !HeatSupported) { - CoolingSetpoint = static_cast(CoolingSetpoint + amount * 10); - CoolingSetpoint = EnforceCoolingSetpointLimits(CoolingSetpoint, aEndpointId); - WriteCoolingSetpointStatus = OccupiedCoolingSetpoint::Set(aEndpointId, CoolingSetpoint); - if (WriteCoolingSetpointStatus != EMBER_ZCL_STATUS_SUCCESS) + if (OccupiedCoolingSetpoint::Get(aEndpointId, &CoolingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) { - ChipLogError(Zcl, "Error: SetOccupiedCoolingSetpoint failed!"); + CoolingSetpoint = static_cast(CoolingSetpoint + amount * 10); + CoolingSetpoint = EnforceCoolingSetpointLimits(CoolingSetpoint, aEndpointId); + WriteCoolingSetpointStatus = OccupiedCoolingSetpoint::Set(aEndpointId, CoolingSetpoint); + if (WriteCoolingSetpointStatus != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(Zcl, "Error: SetOccupiedCoolingSetpoint failed!"); + } } } - ReadStatus = OccupiedHeatingSetpoint::Get(aEndpointId, &HeatingSetpoint); - if (ReadStatus == EMBER_ZCL_STATUS_SUCCESS) + if (HeatSupported && !CoolSupported) { - HeatingSetpoint = static_cast(HeatingSetpoint + amount * 10); - HeatingSetpoint = EnforceHeatingSetpointLimits(HeatingSetpoint, aEndpointId); - WriteHeatingSetpointStatus = OccupiedHeatingSetpoint::Set(aEndpointId, HeatingSetpoint); - if (WriteHeatingSetpointStatus != EMBER_ZCL_STATUS_SUCCESS) + if (OccupiedHeatingSetpoint::Get(aEndpointId, &HeatingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) { - ChipLogError(Zcl, "Error: SetOccupiedHeatingSetpoint failed!"); + HeatingSetpoint = static_cast(HeatingSetpoint + amount * 10); + HeatingSetpoint = EnforceHeatingSetpointLimits(HeatingSetpoint, aEndpointId); + WriteHeatingSetpointStatus = OccupiedHeatingSetpoint::Set(aEndpointId, HeatingSetpoint); + if (WriteHeatingSetpointStatus != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(Zcl, "Error: SetOccupiedHeatingSetpoint failed!"); + } } } - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3801 - // Spec behavior is not defined if one was successfull and the other not what should happen. - // this implementation leaves the successfull one changed but will return an error. - if ((WriteCoolingSetpointStatus == EMBER_ZCL_STATUS_SUCCESS) && (WriteHeatingSetpointStatus == EMBER_ZCL_STATUS_SUCCESS)) + + if ((!HeatSupported || WriteHeatingSetpointStatus == EMBER_ZCL_STATUS_SUCCESS) && + (!CoolSupported || WriteCoolingSetpointStatus == EMBER_ZCL_STATUS_SUCCESS)) status = EMBER_ZCL_STATUS_SUCCESS; break; case EMBER_ZCL_SETPOINT_ADJUST_MODE_COOL_SETPOINT: - // In cooling mode we will need to change only the cooling setpoint - ReadStatus = OccupiedCoolingSetpoint::Get(aEndpointId, &CoolingSetpoint); - - if (ReadStatus == EMBER_ZCL_STATUS_SUCCESS) + if (CoolSupported) { - CoolingSetpoint = static_cast(CoolingSetpoint + amount * 10); - CoolingSetpoint = EnforceCoolingSetpointLimits(CoolingSetpoint, aEndpointId); - status = OccupiedCoolingSetpoint::Set(aEndpointId, CoolingSetpoint); + if (OccupiedCoolingSetpoint::Get(aEndpointId, &CoolingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + { + CoolingSetpoint = static_cast(CoolingSetpoint + amount * 10); + CoolingSetpoint = EnforceCoolingSetpointLimits(CoolingSetpoint, aEndpointId); + if (AutoSupported) + { + // Need to check if we can move the cooling setpoint while maintaining the dead band + if (OccupiedHeatingSetpoint::Get(aEndpointId, &HeatingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + { + if (CoolingSetpoint - HeatingSetpoint < DeadBandTemp) + { + // Dead Band Violation + // Try to adjust it + HeatingSetpoint = static_cast(CoolingSetpoint - DeadBandTemp); + if (HeatingSetpoint == EnforceHeatingSetpointLimits(HeatingSetpoint, aEndpointId)) + { + // Desired cooling setpoint is enforcable + // Set the new cooling and heating setpoints + if (OccupiedHeatingSetpoint::Set(aEndpointId, HeatingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + { + if (OccupiedCoolingSetpoint::Set(aEndpointId, CoolingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + status = EMBER_ZCL_STATUS_SUCCESS; + } + else + ChipLogError(Zcl, "Error: SetOccupiedHeatingSetpoint failed!"); + } + else + { + ChipLogError(Zcl, "Error: Could Not adjust heating setpoint to maintain dead band!"); + status = EMBER_ZCL_STATUS_INVALID_ARGUMENT; + } + } + else + status = OccupiedCoolingSetpoint::Set(aEndpointId, CoolingSetpoint); + } + else + ChipLogError(Zcl, "Error: GetOccupiedHeatingSetpoint failed!"); + } + else + { + status = OccupiedCoolingSetpoint::Set(aEndpointId, CoolingSetpoint); + } + } + else + ChipLogError(Zcl, "Error: GetOccupiedCoolingSetpoint failed!"); } + else + status = EMBER_ZCL_STATUS_INVALID_ARGUMENT; break; case EMBER_ZCL_SETPOINT_ADJUST_MODE_HEAT_SETPOINT: - // In cooling mode we will need to change only the cooling setpoint - ReadStatus = OccupiedHeatingSetpoint::Get(aEndpointId, &HeatingSetpoint); - if (ReadStatus == EMBER_ZCL_STATUS_SUCCESS) + if (HeatSupported) { - HeatingSetpoint = static_cast(HeatingSetpoint + amount * 10); - HeatingSetpoint = EnforceHeatingSetpointLimits(HeatingSetpoint, aEndpointId); - status = OccupiedHeatingSetpoint::Set(aEndpointId, HeatingSetpoint); + if (OccupiedHeatingSetpoint::Get(aEndpointId, &HeatingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + { + HeatingSetpoint = static_cast(HeatingSetpoint + amount * 10); + HeatingSetpoint = EnforceHeatingSetpointLimits(HeatingSetpoint, aEndpointId); + if (AutoSupported) + { + // Need to check if we can move the cooling setpoint while maintaining the dead band + if (OccupiedCoolingSetpoint::Get(aEndpointId, &CoolingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + { + if (CoolingSetpoint - HeatingSetpoint < DeadBandTemp) + { + // Dead Band Violation + // Try to adjust it + CoolingSetpoint = static_cast(HeatingSetpoint + DeadBandTemp); + if (CoolingSetpoint == EnforceCoolingSetpointLimits(CoolingSetpoint, aEndpointId)) + { + // Desired cooling setpoint is enforcable + // Set the new cooling and heating setpoints + if (OccupiedCoolingSetpoint::Set(aEndpointId, CoolingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + { + if (OccupiedHeatingSetpoint::Set(aEndpointId, HeatingSetpoint) == EMBER_ZCL_STATUS_SUCCESS) + status = EMBER_ZCL_STATUS_SUCCESS; + } + else + ChipLogError(Zcl, "Error: SetOccupiedCoolingSetpoint failed!"); + } + else + { + ChipLogError(Zcl, "Error: Could Not adjust cooling setpoint to maintain dead band!"); + status = EMBER_ZCL_STATUS_INVALID_ARGUMENT; + } + } + else + status = OccupiedHeatingSetpoint::Set(aEndpointId, HeatingSetpoint); + } + else + ChipLogError(Zcl, "Error: GetOccupiedCoolingSetpoint failed!"); + } + else + { + status = OccupiedHeatingSetpoint::Set(aEndpointId, HeatingSetpoint); + } + } + else + ChipLogError(Zcl, "Error: GetOccupiedHeatingSetpoint failed!"); } + else + status = EMBER_ZCL_STATUS_INVALID_ARGUMENT; break; default: - // Nothing to do here + status = EMBER_ZCL_STATUS_INVALID_ARGUMENT; break; } + emberAfSendImmediateDefaultResponse(status); return true; } diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index 9587df8099dea4..569a7c54a82022 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -7399,6 +7399,21 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "min setpoint dead band", + "code": 25, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "25", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "control sequence of operation", "code": 27, diff --git a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp index aea41f7831cb30..df3c922d48cb6b 100644 --- a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp +++ b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp @@ -27589,6 +27589,58 @@ JNI_METHOD(void, ThermostatCluster, writeMaxCoolSetpointLimitAttribute) onFailure.release(); } +JNI_METHOD(void, ThermostatCluster, readMinSetpointDeadBandAttribute) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback) +{ + chip::DeviceLayer::StackLock lock; + std::unique_ptr onSuccess( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onSuccess.get() != nullptr, + ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY)); + + std::unique_ptr onFailure( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onFailure.get() != nullptr, + ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY)); + + CHIP_ERROR err = CHIP_NO_ERROR; + ThermostatCluster * cppCluster = reinterpret_cast(clusterPtr); + VerifyOrReturn(cppCluster != nullptr, + ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE)); + + err = cppCluster->ReadAttributeMinSetpointDeadBand(onSuccess->Cancel(), onFailure->Cancel()); + VerifyOrReturn(err == CHIP_NO_ERROR, ReturnIllegalStateException(env, callback, "Error reading attribute", err)); + + onSuccess.release(); + onFailure.release(); +} + +JNI_METHOD(void, ThermostatCluster, writeMinSetpointDeadBandAttribute) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jint value) +{ + chip::DeviceLayer::StackLock lock; + std::unique_ptr onSuccess( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onSuccess.get() != nullptr, + ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY)); + + std::unique_ptr onFailure( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onFailure.get() != nullptr, + ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY)); + + CHIP_ERROR err = CHIP_NO_ERROR; + ThermostatCluster * cppCluster = reinterpret_cast(clusterPtr); + VerifyOrReturn(cppCluster != nullptr, + ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE)); + + err = cppCluster->WriteAttributeMinSetpointDeadBand(onSuccess->Cancel(), onFailure->Cancel(), static_cast(value)); + VerifyOrReturn(err == CHIP_NO_ERROR, ReturnIllegalStateException(env, callback, "Error writing attribute", err)); + + onSuccess.release(); + onFailure.release(); +} + JNI_METHOD(void, ThermostatCluster, readControlSequenceOfOperationAttribute) (JNIEnv * env, jobject self, jlong clusterPtr, jobject callback) { diff --git a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java index af12c13132cc5a..8c8d987eccc811 100644 --- a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java @@ -6293,6 +6293,14 @@ public void writeMaxCoolSetpointLimitAttribute(DefaultClusterCallback callback, writeMaxCoolSetpointLimitAttribute(chipClusterPtr, callback, value); } + public void readMinSetpointDeadBandAttribute(IntegerAttributeCallback callback) { + readMinSetpointDeadBandAttribute(chipClusterPtr, callback); + } + + public void writeMinSetpointDeadBandAttribute(DefaultClusterCallback callback, int value) { + writeMinSetpointDeadBandAttribute(chipClusterPtr, callback, value); + } + public void readControlSequenceOfOperationAttribute(IntegerAttributeCallback callback) { readControlSequenceOfOperationAttribute(chipClusterPtr, callback); } @@ -6387,6 +6395,12 @@ private native void readMaxCoolSetpointLimitAttribute( private native void writeMaxCoolSetpointLimitAttribute( long chipClusterPtr, DefaultClusterCallback callback, int value); + private native void readMinSetpointDeadBandAttribute( + long chipClusterPtr, IntegerAttributeCallback callback); + + private native void writeMinSetpointDeadBandAttribute( + long chipClusterPtr, DefaultClusterCallback callback, int value); + private native void readControlSequenceOfOperationAttribute( long chipClusterPtr, IntegerAttributeCallback callback); diff --git a/src/controller/python/chip/clusters/CHIPClusters.cpp b/src/controller/python/chip/clusters/CHIPClusters.cpp index 2fadb2cf7286be..ae4439ca46155c 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.cpp +++ b/src/controller/python/chip/clusters/CHIPClusters.cpp @@ -7449,6 +7449,26 @@ chip::ChipError::StorageType chip_ime_WriteAttribute_Thermostat_MaxCoolSetpointL return cluster.WriteAttributeMaxCoolSetpointLimit(gDefaultSuccessCallback.Cancel(), gDefaultFailureCallback.Cancel(), value) .AsInteger(); } +chip::ChipError::StorageType chip_ime_ReadAttribute_Thermostat_MinSetpointDeadBand(chip::Controller::Device * device, + chip::EndpointId ZCLendpointId, + chip::GroupId /* ZCLgroupId */) +{ + VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + chip::Controller::ThermostatCluster cluster; + cluster.Associate(device, ZCLendpointId); + return cluster.ReadAttributeMinSetpointDeadBand(gInt8sAttributeCallback.Cancel(), gDefaultFailureCallback.Cancel()).AsInteger(); +} + +chip::ChipError::StorageType chip_ime_WriteAttribute_Thermostat_MinSetpointDeadBand(chip::Controller::Device * device, + chip::EndpointId ZCLendpointId, chip::GroupId, + int8_t value) +{ + VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + chip::Controller::ThermostatCluster cluster; + cluster.Associate(device, ZCLendpointId); + return cluster.WriteAttributeMinSetpointDeadBand(gDefaultSuccessCallback.Cancel(), gDefaultFailureCallback.Cancel(), value) + .AsInteger(); +} chip::ChipError::StorageType chip_ime_ReadAttribute_Thermostat_ControlSequenceOfOperation(chip::Controller::Device * device, chip::EndpointId ZCLendpointId, chip::GroupId /* ZCLgroupId */) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 340432d9e6fcc9..ef7ac88c515259 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -3437,6 +3437,12 @@ class ChipClusters: "type": "int", "writable": True, }, + 0x00000019: { + "attributeName": "MinSetpointDeadBand", + "attributeId": 0x00000019, + "type": "int", + "writable": True, + }, 0x0000001B: { "attributeName": "ControlSequenceOfOperation", "attributeId": 0x0000001B, @@ -6404,6 +6410,12 @@ def ClusterThermostat_ReadAttributeMaxCoolSetpointLimit(self, device: ctypes.c_v def ClusterThermostat_WriteAttributeMaxCoolSetpointLimit(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, value: int): return self._chipLib.chip_ime_WriteAttribute_Thermostat_MaxCoolSetpointLimit(device, ZCLendpoint, ZCLgroupid, value) + def ClusterThermostat_ReadAttributeMinSetpointDeadBand(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): + return self._chipLib.chip_ime_ReadAttribute_Thermostat_MinSetpointDeadBand(device, ZCLendpoint, ZCLgroupid) + + def ClusterThermostat_WriteAttributeMinSetpointDeadBand(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int, value: int): + return self._chipLib.chip_ime_WriteAttribute_Thermostat_MinSetpointDeadBand(device, ZCLendpoint, ZCLgroupid, value) + def ClusterThermostat_ReadAttributeControlSequenceOfOperation(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): return self._chipLib.chip_ime_ReadAttribute_Thermostat_ControlSequenceOfOperation(device, ZCLendpoint, ZCLgroupid) @@ -9129,6 +9141,14 @@ def InitLib(self, chipLib): self._chipLib.chip_ime_WriteAttribute_Thermostat_MaxCoolSetpointLimit.argtypes = [ ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_int16] self._chipLib.chip_ime_WriteAttribute_Thermostat_MaxCoolSetpointLimit.restype = ctypes.c_uint32 + # Cluster Thermostat ReadAttribute MinSetpointDeadBand + self._chipLib.chip_ime_ReadAttribute_Thermostat_MinSetpointDeadBand.argtypes = [ + ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] + self._chipLib.chip_ime_ReadAttribute_Thermostat_MinSetpointDeadBand.restype = ctypes.c_uint32 + # Cluster Thermostat WriteAttribute MinSetpointDeadBand + self._chipLib.chip_ime_WriteAttribute_Thermostat_MinSetpointDeadBand.argtypes = [ + ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16, ctypes.c_int8] + self._chipLib.chip_ime_WriteAttribute_Thermostat_MinSetpointDeadBand.restype = ctypes.c_uint32 # Cluster Thermostat ReadAttribute ControlSequenceOfOperation self._chipLib.chip_ime_ReadAttribute_Thermostat_ControlSequenceOfOperation.argtypes = [ ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h index 93a0e97b4c38c7..41a737061619df 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h @@ -1663,6 +1663,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)readAttributeMaxCoolSetpointLimitWithResponseHandler:(ResponseHandler)responseHandler; - (void)writeAttributeMaxCoolSetpointLimitWithValue:(int16_t)value responseHandler:(ResponseHandler)responseHandler; +- (void)readAttributeMinSetpointDeadBandWithResponseHandler:(ResponseHandler)responseHandler; +- (void)writeAttributeMinSetpointDeadBandWithValue:(int8_t)value responseHandler:(ResponseHandler)responseHandler; + - (void)readAttributeControlSequenceOfOperationWithResponseHandler:(ResponseHandler)responseHandler; - (void)writeAttributeControlSequenceOfOperationWithValue:(uint8_t)value responseHandler:(ResponseHandler)responseHandler; diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm index d6515e7b8b36e3..d85ad132704ad2 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm @@ -5092,6 +5092,20 @@ new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Canc }); } +- (void)readAttributeMinSetpointDeadBandWithResponseHandler:(ResponseHandler)responseHandler +{ + new CHIPInt8sAttributeCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + return self.cppCluster.ReadAttributeMinSetpointDeadBand(success, failure); + }); +} + +- (void)writeAttributeMinSetpointDeadBandWithValue:(int8_t)value responseHandler:(ResponseHandler)responseHandler +{ + new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + return self.cppCluster.WriteAttributeMinSetpointDeadBand(success, failure, value); + }); +} + - (void)readAttributeControlSequenceOfOperationWithResponseHandler:(ResponseHandler)responseHandler { new CHIPInt8uAttributeCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { diff --git a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m index 5d0a2a2f3299f8..f293dd48ef42db 100644 --- a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m @@ -18611,6 +18611,44 @@ - (void)testSendClusterThermostatWriteAttributeMaxCoolSetpointLimitWithValue [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } +- (void)testSendClusterThermostatReadAttributeMinSetpointDeadBandWithResponseHandler +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"ThermostatReadAttributeMinSetpointDeadBandWithResponseHandler"]; + + CHIPDevice * device = GetConnectedDevice(); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPThermostat * cluster = [[CHIPThermostat alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster readAttributeMinSetpointDeadBandWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"Thermostat MinSetpointDeadBand Error: %@", err); + XCTAssertEqual(err.code, 0); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + +- (void)testSendClusterThermostatWriteAttributeMinSetpointDeadBandWithValue +{ + XCTestExpectation * expectation = [self expectationWithDescription:@"ThermostatWriteAttributeMinSetpointDeadBandWithValue"]; + + CHIPDevice * device = GetConnectedDevice(); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPThermostat * cluster = [[CHIPThermostat alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + int8_t value = 0x0A; + [cluster writeAttributeMinSetpointDeadBandWithValue:value + responseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"Thermostat MinSetpointDeadBand Error: %@", err); + XCTAssertEqual(err.code, 0); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} - (void)testSendClusterThermostatReadAttributeControlSequenceOfOperationWithResponseHandler { XCTestExpectation * expectation = diff --git a/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h b/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h index 0f388d2b5d047e..7c6f85d4b79d3d 100644 --- a/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h +++ b/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h @@ -1961,7 +1961,7 @@ #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 481 +#define GENERATED_ATTRIBUTE_COUNT 482 #define GENERATED_ATTRIBUTES \ { \ \ @@ -2342,7 +2342,8 @@ { 0x0017, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), \ ZAP_SIMPLE_DEFAULT(0x0640) }, /* min cool setpoint limit */ \ { 0x0018, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), \ - ZAP_SIMPLE_DEFAULT(0x0C80) }, /* max cool setpoint limit */ \ + ZAP_SIMPLE_DEFAULT(0x0C80) }, /* max cool setpoint limit */ \ + { 0x0019, ZAP_TYPE(INT8S), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x19) }, /* min setpoint dead band */ \ { 0x001B, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), \ ZAP_SIMPLE_DEFAULT(0x04) }, /* control sequence of operation */ \ { 0x001C, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x01) }, /* system mode */ \ @@ -2809,101 +2810,101 @@ chipFuncArrayPumpConfigurationAndControlServer \ }, /* Endpoint: 1, Cluster: Pump Configuration and Control (server) */ \ { \ - 0x0201, ZAP_ATTRIBUTE_INDEX(278), 18, 33, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0201, ZAP_ATTRIBUTE_INDEX(278), 19, 34, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Thermostat (server) */ \ { \ - 0x0204, ZAP_ATTRIBUTE_INDEX(296), 4, 5, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0204, ZAP_ATTRIBUTE_INDEX(297), 4, 5, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \ { 0x0300, \ - ZAP_ATTRIBUTE_INDEX(300), \ + ZAP_ATTRIBUTE_INDEX(301), \ 53, \ 341, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayColorControlServer }, /* Endpoint: 1, Cluster: Color Control (server) */ \ { \ - 0x0400, ZAP_ATTRIBUTE_INDEX(353), 6, 11, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0400, ZAP_ATTRIBUTE_INDEX(354), 6, 11, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Illuminance Measurement (server) */ \ { \ - 0x0402, ZAP_ATTRIBUTE_INDEX(359), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0402, ZAP_ATTRIBUTE_INDEX(360), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Temperature Measurement (server) */ \ { \ - 0x0403, ZAP_ATTRIBUTE_INDEX(363), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0403, ZAP_ATTRIBUTE_INDEX(364), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Pressure Measurement (server) */ \ { \ - 0x0404, ZAP_ATTRIBUTE_INDEX(367), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0404, ZAP_ATTRIBUTE_INDEX(368), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Flow Measurement (server) */ \ { \ - 0x0405, ZAP_ATTRIBUTE_INDEX(371), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0405, ZAP_ATTRIBUTE_INDEX(372), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Relative Humidity Measurement (server) */ \ { 0x0406, \ - ZAP_ATTRIBUTE_INDEX(375), \ + ZAP_ATTRIBUTE_INDEX(376), \ 4, \ 5, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayOccupancySensingServer }, /* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \ { 0x0500, \ - ZAP_ATTRIBUTE_INDEX(379), \ + ZAP_ATTRIBUTE_INDEX(380), \ 6, \ 16, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION) | \ ZAP_CLUSTER_MASK(MESSAGE_SENT_FUNCTION), \ chipFuncArrayIasZoneServer }, /* Endpoint: 1, Cluster: IAS Zone (server) */ \ { \ - 0x0503, ZAP_ATTRIBUTE_INDEX(385), 2, 35, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0503, ZAP_ATTRIBUTE_INDEX(386), 2, 35, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Wake on LAN (server) */ \ { \ - 0x0504, ZAP_ATTRIBUTE_INDEX(387), 4, 322, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0504, ZAP_ATTRIBUTE_INDEX(388), 4, 322, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: TV Channel (server) */ \ { \ - 0x0505, ZAP_ATTRIBUTE_INDEX(391), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0505, ZAP_ATTRIBUTE_INDEX(392), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Target Navigator (server) */ \ { \ - 0x0506, ZAP_ATTRIBUTE_INDEX(393), 9, 59, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0506, ZAP_ATTRIBUTE_INDEX(394), 9, 59, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Media Playback (server) */ \ { \ - 0x0507, ZAP_ATTRIBUTE_INDEX(402), 3, 257, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0507, ZAP_ATTRIBUTE_INDEX(403), 3, 257, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Media Input (server) */ \ { \ - 0x0508, ZAP_ATTRIBUTE_INDEX(405), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0508, ZAP_ATTRIBUTE_INDEX(406), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Low Power (server) */ \ { \ - 0x0509, ZAP_ATTRIBUTE_INDEX(406), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0509, ZAP_ATTRIBUTE_INDEX(407), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Keypad Input (server) */ \ { \ - 0x050A, ZAP_ATTRIBUTE_INDEX(407), 3, 510, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050A, ZAP_ATTRIBUTE_INDEX(408), 3, 510, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Content Launcher (server) */ \ { \ - 0x050B, ZAP_ATTRIBUTE_INDEX(410), 3, 257, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050B, ZAP_ATTRIBUTE_INDEX(411), 3, 257, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Audio Output (server) */ \ { \ - 0x050C, ZAP_ATTRIBUTE_INDEX(413), 4, 258, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050C, ZAP_ATTRIBUTE_INDEX(414), 4, 258, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Application Launcher (server) */ \ { \ - 0x050D, ZAP_ATTRIBUTE_INDEX(417), 8, 108, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050D, ZAP_ATTRIBUTE_INDEX(418), 8, 108, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Application Basic (server) */ \ { \ - 0x050E, ZAP_ATTRIBUTE_INDEX(425), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050E, ZAP_ATTRIBUTE_INDEX(426), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Account Login (server) */ \ { \ - 0x050F, ZAP_ATTRIBUTE_INDEX(426), 26, 2609, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050F, ZAP_ATTRIBUTE_INDEX(427), 26, 2609, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Test Cluster (server) */ \ { \ - 0x0B04, ZAP_ATTRIBUTE_INDEX(452), 12, 28, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0B04, ZAP_ATTRIBUTE_INDEX(453), 12, 28, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Electrical Measurement (server) */ \ { \ - 0xF000, ZAP_ATTRIBUTE_INDEX(464), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0xF000, ZAP_ATTRIBUTE_INDEX(465), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Binding (server) */ \ { 0x0006, \ - ZAP_ATTRIBUTE_INDEX(465), \ + ZAP_ATTRIBUTE_INDEX(466), \ 7, \ 13, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayOnOffServer }, /* Endpoint: 2, Cluster: On/Off (server) */ \ { \ - 0x001D, ZAP_ATTRIBUTE_INDEX(472), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x001D, ZAP_ATTRIBUTE_INDEX(473), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 2, Cluster: Descriptor (server) */ \ { 0x0406, \ - ZAP_ATTRIBUTE_INDEX(477), \ + ZAP_ATTRIBUTE_INDEX(478), \ 4, \ 5, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -2915,7 +2916,7 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 18, 3376 }, { ZAP_CLUSTER_INDEX(18), 42, 6520 }, { ZAP_CLUSTER_INDEX(60), 3, 20 }, \ + { ZAP_CLUSTER_INDEX(0), 18, 3376 }, { ZAP_CLUSTER_INDEX(18), 42, 6521 }, { ZAP_CLUSTER_INDEX(60), 3, 20 }, \ } // Largest attribute size is needed for various buffers @@ -2925,7 +2926,7 @@ #define ATTRIBUTE_SINGLETONS_SIZE (1518) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (9916) +#define ATTRIBUTE_MAX_SIZE (9917) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (3) diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 2e96e1c9391f32..4d793b89883343 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -20480,6 +20480,7 @@ class ReadTestClusterClusterRevision : public ModelCommand | * MaxHeatSetpointLimit | 0x0016 | | * MinCoolSetpointLimit | 0x0017 | | * MaxCoolSetpointLimit | 0x0018 | +| * MinSetpointDeadBand | 0x0019 | | * ControlSequenceOfOperation | 0x001B | | * SystemMode | 0x001C | | * StartOfWeek | 0x0020 | @@ -21236,6 +21237,73 @@ class WriteThermostatMaxCoolSetpointLimit : public ModelCommand int16_t mValue; }; +/* + * Attribute MinSetpointDeadBand + */ +class ReadThermostatMinSetpointDeadBand : public ModelCommand +{ +public: + ReadThermostatMinSetpointDeadBand() : ModelCommand("read") + { + AddArgument("attr-name", "min-setpoint-dead-band"); + ModelCommand::AddArguments(); + } + + ~ReadThermostatMinSetpointDeadBand() + { + delete onSuccessCallback; + delete onFailureCallback; + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x0201) command (0x00) on endpoint %" PRIu8, endpointId); + + chip::Controller::ThermostatCluster cluster; + cluster.Associate(device, endpointId); + return cluster.ReadAttributeMinSetpointDeadBand(onSuccessCallback->Cancel(), onFailureCallback->Cancel()); + } + +private: + chip::Callback::Callback * onSuccessCallback = + new chip::Callback::Callback(OnInt8sAttributeResponse, this); + chip::Callback::Callback * onFailureCallback = + new chip::Callback::Callback(OnDefaultFailureResponse, this); +}; + +class WriteThermostatMinSetpointDeadBand : public ModelCommand +{ +public: + WriteThermostatMinSetpointDeadBand() : ModelCommand("write") + { + AddArgument("attr-name", "min-setpoint-dead-band"); + AddArgument("attr-value", INT8_MIN, INT8_MAX, &mValue); + ModelCommand::AddArguments(); + } + + ~WriteThermostatMinSetpointDeadBand() + { + delete onSuccessCallback; + delete onFailureCallback; + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x0201) command (0x01) on endpoint %" PRIu8, endpointId); + + chip::Controller::ThermostatCluster cluster; + cluster.Associate(device, endpointId); + return cluster.WriteAttributeMinSetpointDeadBand(onSuccessCallback->Cancel(), onFailureCallback->Cancel(), mValue); + } + +private: + chip::Callback::Callback * onSuccessCallback = + new chip::Callback::Callback(OnDefaultSuccessResponse, this); + chip::Callback::Callback * onFailureCallback = + new chip::Callback::Callback(OnDefaultFailureResponse, this); + int8_t mValue; +}; + /* * Attribute ControlSequenceOfOperation */ @@ -26929,6 +26997,8 @@ void registerClusterThermostat(Commands & commands) make_unique(), // make_unique(), // make_unique(), // + make_unique(), // + make_unique(), // make_unique(), // make_unique(), // make_unique(), // diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp index c7e7fe53cb346b..312940bbb1c296 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp @@ -13001,6 +13001,33 @@ CHIP_ERROR ThermostatCluster::WriteAttributeMaxCoolSetpointLimit(Callback::Cance return mDevice->SendWriteAttributeRequest(std::move(handle), onSuccessCallback, onFailureCallback); } +CHIP_ERROR ThermostatCluster::ReadAttributeMinSetpointDeadBand(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = 0x00000019; + attributePath.mFlags.Set(app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback, + BasicAttributeFilter); +} + +template CHIP_ERROR ClusterBase::WriteAttribute( + const chip::app::Clusters::Thermostat::Attributes::MinSetpointDeadBand::TypeInfo::Type & requestData, void * context, + WriteResponseSuccessCallback successCb, WriteResponseFailureCallback failureCb); + +CHIP_ERROR ThermostatCluster::WriteAttributeMinSetpointDeadBand(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback, int8_t value) +{ + app::WriteClientHandle handle; + ReturnErrorOnFailure( + app::InteractionModelEngine::GetInstance()->NewWriteClient(handle, mDevice->GetInteractionModelDelegate())); + ReturnErrorOnFailure(handle.EncodeAttributeWritePayload( + chip::app::AttributePathParams(mEndpoint, mClusterId, Thermostat::Attributes::MinSetpointDeadBand::Id), value)); + return mDevice->SendWriteAttributeRequest(std::move(handle), onSuccessCallback, onFailureCallback); +} + CHIP_ERROR ThermostatCluster::ReadAttributeControlSequenceOfOperation(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h index 27c639bcb35335..c04236c47b352c 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h @@ -1422,6 +1422,7 @@ class DLL_EXPORT ThermostatCluster : public ClusterBase Callback::Cancelable * onFailureCallback); CHIP_ERROR ReadAttributeMaxCoolSetpointLimit(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); + CHIP_ERROR ReadAttributeMinSetpointDeadBand(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); CHIP_ERROR ReadAttributeControlSequenceOfOperation(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); CHIP_ERROR ReadAttributeSystemMode(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); @@ -1444,6 +1445,8 @@ class DLL_EXPORT ThermostatCluster : public ClusterBase Callback::Cancelable * onFailureCallback, int16_t value); CHIP_ERROR WriteAttributeMaxCoolSetpointLimit(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, int16_t value); + CHIP_ERROR WriteAttributeMinSetpointDeadBand(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, + int8_t value); CHIP_ERROR WriteAttributeControlSequenceOfOperation(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, uint8_t value); CHIP_ERROR WriteAttributeSystemMode(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, diff --git a/zzz_generated/thermostat/zap-generated/endpoint_config.h b/zzz_generated/thermostat/zap-generated/endpoint_config.h index 8db97412cba36e..529680ea8b2d3b 100644 --- a/zzz_generated/thermostat/zap-generated/endpoint_config.h +++ b/zzz_generated/thermostat/zap-generated/endpoint_config.h @@ -1685,7 +1685,7 @@ #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 383 +#define GENERATED_ATTRIBUTE_COUNT 384 #define GENERATED_ATTRIBUTES \ { \ \ @@ -2002,6 +2002,7 @@ { 0x0016, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(3000) }, /* max heat setpoint limit */ \ { 0x0017, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(1600) }, /* min cool setpoint limit */ \ { 0x0018, ZAP_TYPE(INT16S), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(3200) }, /* max cool setpoint limit */ \ + { 0x0019, ZAP_TYPE(INT8S), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x19) }, /* min setpoint dead band */ \ { 0x001B, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), \ ZAP_SIMPLE_DEFAULT(0x04) }, /* control sequence of operation */ \ { 0x001C, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x01) }, /* system mode */ \ @@ -2376,86 +2377,86 @@ 0x0103, ZAP_ATTRIBUTE_INDEX(225), 5, 7, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Barrier Control (server) */ \ { \ - 0x0201, ZAP_ATTRIBUTE_INDEX(230), 18, 33, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0201, ZAP_ATTRIBUTE_INDEX(230), 19, 34, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Thermostat (server) */ \ { 0x0300, \ - ZAP_ATTRIBUTE_INDEX(248), \ + ZAP_ATTRIBUTE_INDEX(249), \ 51, \ 337, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayColorControlServer }, /* Endpoint: 1, Cluster: Color Control (server) */ \ { \ - 0x0402, ZAP_ATTRIBUTE_INDEX(299), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0402, ZAP_ATTRIBUTE_INDEX(300), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Temperature Measurement (server) */ \ { \ - 0x0403, ZAP_ATTRIBUTE_INDEX(303), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0403, ZAP_ATTRIBUTE_INDEX(304), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Pressure Measurement (server) */ \ { \ - 0x0404, ZAP_ATTRIBUTE_INDEX(307), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0404, ZAP_ATTRIBUTE_INDEX(308), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Flow Measurement (server) */ \ { \ - 0x0405, ZAP_ATTRIBUTE_INDEX(311), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0405, ZAP_ATTRIBUTE_INDEX(312), 4, 8, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Relative Humidity Measurement (server) */ \ { 0x0500, \ - ZAP_ATTRIBUTE_INDEX(315), \ + ZAP_ATTRIBUTE_INDEX(316), \ 6, \ 16, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION) | \ ZAP_CLUSTER_MASK(MESSAGE_SENT_FUNCTION), \ chipFuncArrayIasZoneServer }, /* Endpoint: 1, Cluster: IAS Zone (server) */ \ { \ - 0x0503, ZAP_ATTRIBUTE_INDEX(321), 2, 35, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0503, ZAP_ATTRIBUTE_INDEX(322), 2, 35, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Wake on LAN (server) */ \ { \ - 0x0504, ZAP_ATTRIBUTE_INDEX(323), 4, 322, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0504, ZAP_ATTRIBUTE_INDEX(324), 4, 322, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: TV Channel (server) */ \ { \ - 0x0505, ZAP_ATTRIBUTE_INDEX(327), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0505, ZAP_ATTRIBUTE_INDEX(328), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Target Navigator (server) */ \ { \ - 0x0506, ZAP_ATTRIBUTE_INDEX(329), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0506, ZAP_ATTRIBUTE_INDEX(330), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Media Playback (server) */ \ { \ - 0x0507, ZAP_ATTRIBUTE_INDEX(330), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0507, ZAP_ATTRIBUTE_INDEX(331), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Media Input (server) */ \ { \ - 0x0508, ZAP_ATTRIBUTE_INDEX(332), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0508, ZAP_ATTRIBUTE_INDEX(333), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Low Power (server) */ \ { \ - 0x0509, ZAP_ATTRIBUTE_INDEX(333), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x0509, ZAP_ATTRIBUTE_INDEX(334), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Keypad Input (server) */ \ { \ - 0x050A, ZAP_ATTRIBUTE_INDEX(334), 3, 510, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050A, ZAP_ATTRIBUTE_INDEX(335), 3, 510, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Content Launcher (server) */ \ { \ - 0x050B, ZAP_ATTRIBUTE_INDEX(337), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050B, ZAP_ATTRIBUTE_INDEX(338), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Audio Output (server) */ \ { \ - 0x050C, ZAP_ATTRIBUTE_INDEX(339), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050C, ZAP_ATTRIBUTE_INDEX(340), 2, 256, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Application Launcher (server) */ \ { \ - 0x050D, ZAP_ATTRIBUTE_INDEX(341), 8, 108, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050D, ZAP_ATTRIBUTE_INDEX(342), 8, 108, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Application Basic (server) */ \ { \ - 0x050E, ZAP_ATTRIBUTE_INDEX(349), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050E, ZAP_ATTRIBUTE_INDEX(350), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Account Login (server) */ \ { \ - 0x050F, ZAP_ATTRIBUTE_INDEX(350), 21, 1582, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x050F, ZAP_ATTRIBUTE_INDEX(351), 21, 1582, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Test Cluster (server) */ \ { \ - 0xF000, ZAP_ATTRIBUTE_INDEX(371), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0xF000, ZAP_ATTRIBUTE_INDEX(372), 1, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 1, Cluster: Binding (server) */ \ { 0x0006, \ - ZAP_ATTRIBUTE_INDEX(372), \ + ZAP_ATTRIBUTE_INDEX(373), \ 2, \ 3, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ chipFuncArrayOnOffServer }, /* Endpoint: 2, Cluster: On/Off (server) */ \ { \ - 0x001D, ZAP_ATTRIBUTE_INDEX(374), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ + 0x001D, ZAP_ATTRIBUTE_INDEX(375), 5, 2, ZAP_CLUSTER_MASK(SERVER), NULL \ }, /* Endpoint: 2, Cluster: Descriptor (server) */ \ { 0x0406, \ - ZAP_ATTRIBUTE_INDEX(379), \ + ZAP_ATTRIBUTE_INDEX(380), \ 4, \ 5, \ ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -2467,7 +2468,7 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 16, 3347 }, { ZAP_CLUSTER_INDEX(16), 34, 5235 }, { ZAP_CLUSTER_INDEX(50), 3, 10 }, \ + { ZAP_CLUSTER_INDEX(0), 16, 3347 }, { ZAP_CLUSTER_INDEX(16), 34, 5236 }, { ZAP_CLUSTER_INDEX(50), 3, 10 }, \ } // Largest attribute size is needed for various buffers @@ -2477,7 +2478,7 @@ #define ATTRIBUTE_SINGLETONS_SIZE (1518) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (8592) +#define ATTRIBUTE_MAX_SIZE (8593) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (3)