Add Thermostat EP to Air Purifier Example (#31771)
* Adding example thermostat manager
* Integrating thermostat-manager into the Air Purifier Manager and adding to each build
* Restyled by whitespace
* Updating readme's for each example
* Added readme to common folder to outline the PICS implemented as might be useful for anyone trying to quickly interpret functionality
* Added missing include for std::function
* adding thermostat-manager to TI build
---------
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/examples/air-purifier-app/air-purifier-common/README.md b/examples/air-purifier-app/air-purifier-common/README.md
new file mode 100644
index 0000000..2ed26ca
--- /dev/null
+++ b/examples/air-purifier-app/air-purifier-common/README.md
@@ -0,0 +1,353 @@
+# CHIP Air Purifier Example
+
+This example implements the following PICS:
+
+```
+# Fan Control
+FAN.S=1
+FAN.C=0
+FAN.S.F00=1
+FAN.S.F01=1
+FAN.S.F02=1
+FAN.S.F03=1
+FAN.S.F04=1
+FAN.S.F05=1
+FAN.S.A0000=1
+FAN.S.A0001=1
+FAN.S.A0002=1
+FAN.S.A0003=1
+FAN.S.A0004=1
+FAN.S.A0005=1
+FAN.S.A0006=1
+FAN.S.A0007=1
+FAN.S.A0008=1
+FAN.S.A0009=1
+FAN.S.A000A=1
+FAN.S.A000B=1
+FAN.S.C00.Rsp=1
+
+# HEPA Filter Monitoring Cluster
+HEPAFREMON.S=1
+HEPAFREMON.C=0
+HEPAFREMON.S.F00=1
+HEPAFREMON.S.F01=1
+HEPAFREMON.S.F02=1
+HEPAFREMON.S.A0000=1
+HEPAFREMON.S.A0001=1
+HEPAFREMON.S.A0002=1
+HEPAFREMON.S.A0003=1
+HEPAFREMON.S.A0004=1
+HEPAFREMON.S.A0005=1
+HEPAFREMON.S.C00.Rsp=1
+
+# Activated Carbon Filter Monitoring Cluster
+ACFREMON.S=1
+ACFREMON.C=0
+ACFREMON.S.F00=1
+ACFREMON.S.F01=1
+ACFREMON.S.F02=1
+ACFREMON.S.A0000=1
+ACFREMON.S.A0001=1
+ACFREMON.S.A0002=1
+ACFREMON.S.A0003=1
+ACFREMON.S.A0004=1
+ACFREMON.S.A0005=1
+ACFREMON.S.C00.Rsp=1
+
+# Air Quality Cluster
+AIRQUAL.C=0
+AIRQUAL.S=1
+AIRQUAL.S.F00=1
+AIRQUAL.S.F01=1
+AIRQUAL.S.F02=1
+AIRQUAL.S.F03=1
+AIRQUAL.S.A0000=1
+AIRQUAL.M.AirQualityChange=0
+
+# Concentration Measurement CLusters
+CDOCONC.C=0
+CDOCONC.S=1
+CDOCONC.S.F00=1
+CDOCONC.S.F01=1
+CDOCONC.S.F02=1
+CDOCONC.S.F03=1
+CDOCONC.S.F04=1
+CDOCONC.S.F05=1
+CDOCONC.S.A0000=1
+CDOCONC.S.A0001=1
+CDOCONC.S.A0002=1
+CDOCONC.S.A0003=1
+CDOCONC.S.A0004=1
+CDOCONC.S.A0005=1
+CDOCONC.S.A0006=1
+CDOCONC.S.A0007=1
+CDOCONC.S.A0008=1
+CDOCONC.S.A0009=1
+CDOCONC.S.A000a=1
+
+CMOCONC.C=0
+CMOCONC.S=1
+CMOCONC.S.F00=1
+CMOCONC.S.F01=1
+CMOCONC.S.F02=1
+CMOCONC.S.F03=1
+CMOCONC.S.F04=1
+CMOCONC.S.F05=1
+CMOCONC.S.A0000=1
+CMOCONC.S.A0001=1
+CMOCONC.S.A0002=1
+CMOCONC.S.A0003=1
+CMOCONC.S.A0004=1
+CMOCONC.S.A0005=1
+CMOCONC.S.A0006=1
+CMOCONC.S.A0007=1
+CMOCONC.S.A0008=1
+CMOCONC.S.A0009=1
+CMOCONC.S.A000a=1
+
+NDOCONC.C=0
+NDOCONC.S=1
+NDOCONC.S.F00=1
+NDOCONC.S.F01=1
+NDOCONC.S.F02=1
+NDOCONC.S.F03=1
+NDOCONC.S.F04=1
+NDOCONC.S.F05=1
+NDOCONC.S.A0000=1
+NDOCONC.S.A0001=1
+NDOCONC.S.A0002=1
+NDOCONC.S.A0003=1
+NDOCONC.S.A0004=1
+NDOCONC.S.A0005=1
+NDOCONC.S.A0006=1
+NDOCONC.S.A0007=1
+NDOCONC.S.A0008=1
+NDOCONC.S.A0009=1
+NDOCONC.S.A000a=1
+
+OZCONC.C=0
+OZCONC.S=1
+OZCONC.S.F00=1
+OZCONC.S.F01=1
+OZCONC.S.F02=1
+OZCONC.S.F03=1
+OZCONC.S.F04=1
+OZCONC.S.F05=1
+OZCONC.S.A0000=1
+OZCONC.S.A0001=1
+OZCONC.S.A0002=1
+OZCONC.S.A0003=1
+OZCONC.S.A0004=1
+OZCONC.S.A0005=1
+OZCONC.S.A0006=1
+OZCONC.S.A0007=1
+OZCONC.S.A0008=1
+OZCONC.S.A0009=1
+OZCONC.S.A000a=1
+
+PMICONC.C=0
+PMICONC.S=1
+PMICONC.S.F00=1
+PMICONC.S.F01=1
+PMICONC.S.F02=1
+PMICONC.S.F03=1
+PMICONC.S.F04=1
+PMICONC.S.F05=1
+PMICONC.S.A0000=1
+PMICONC.S.A0001=1
+PMICONC.S.A0002=1
+PMICONC.S.A0003=1
+PMICONC.S.A0004=1
+PMICONC.S.A0005=1
+PMICONC.S.A0006=1
+PMICONC.S.A0007=1
+PMICONC.S.A0008=1
+PMICONC.S.A0009=1
+PMICONC.S.A000a=1
+
+FLDCONC.C=0
+FLDCONC.S=1
+FLDCONC.S.F00=1
+FLDCONC.S.F01=1
+FLDCONC.S.F02=1
+FLDCONC.S.F03=1
+FLDCONC.S.F04=1
+FLDCONC.S.F05=1
+FLDCONC.S.A0000=1
+FLDCONC.S.A0001=1
+FLDCONC.S.A0002=1
+FLDCONC.S.A0003=1
+FLDCONC.S.A0004=1
+FLDCONC.S.A0005=1
+FLDCONC.S.A0006=1
+FLDCONC.S.A0007=1
+FLDCONC.S.A0008=1
+FLDCONC.S.A0009=1
+FLDCONC.S.A000a=1
+
+PMHCONC.C=0
+PMHCONC.S=1
+PMHCONC.S.F00=1
+PMHCONC.S.F01=1
+PMHCONC.S.F02=1
+PMHCONC.S.F03=1
+PMHCONC.S.F04=1
+PMHCONC.S.F05=1
+PMHCONC.S.A0000=1
+PMHCONC.S.A0001=1
+PMHCONC.S.A0002=1
+PMHCONC.S.A0003=1
+PMHCONC.S.A0004=1
+PMHCONC.S.A0005=1
+PMHCONC.S.A0006=1
+PMHCONC.S.A0007=1
+PMHCONC.S.A0008=1
+PMHCONC.S.A0009=1
+PMHCONC.S.A000a=1
+
+PMKCONC.C=0
+PMKCONC.S=1
+PMKCONC.S.F00=1
+PMKCONC.S.F01=1
+PMKCONC.S.F02=1
+PMKCONC.S.F03=1
+PMKCONC.S.F04=1
+PMKCONC.S.F05=1
+PMKCONC.S.A0000=1
+PMKCONC.S.A0001=1
+PMKCONC.S.A0002=1
+PMKCONC.S.A0003=1
+PMKCONC.S.A0004=1
+PMKCONC.S.A0005=1
+PMKCONC.S.A0006=1
+PMKCONC.S.A0007=1
+PMKCONC.S.A0008=1
+PMKCONC.S.A0009=1
+PMKCONC.S.A000a=1
+
+TVOCCONC.C=0
+TVOCCONC.S=1
+TVOCCONC.S.F00=1
+TVOCCONC.S.F01=1
+TVOCCONC.S.F02=1
+TVOCCONC.S.F03=1
+TVOCCONC.S.F04=1
+TVOCCONC.S.F05=1
+TVOCCONC.S.A0000=1
+TVOCCONC.S.A0001=1
+TVOCCONC.S.A0002=1
+TVOCCONC.S.A0003=1
+TVOCCONC.S.A0004=1
+TVOCCONC.S.A0005=1
+TVOCCONC.S.A0006=1
+TVOCCONC.S.A0007=1
+TVOCCONC.S.A0008=1
+TVOCCONC.S.A0009=1
+TVOCCONC.S.A000a=1
+
+RNCONC.C=0
+RNCONC.S=1
+RNCONC.S.F00=1
+RNCONC.S.F01=1
+RNCONC.S.F02=1
+RNCONC.S.F03=1
+RNCONC.S.F04=1
+RNCONC.S.F05=1
+RNCONC.S.A0000=1
+RNCONC.S.A0001=1
+RNCONC.S.A0002=1
+RNCONC.S.A0003=1
+RNCONC.S.A0004=1
+RNCONC.S.A0005=1
+RNCONC.S.A0006=1
+RNCONC.S.A0007=1
+RNCONC.S.A0008=1
+RNCONC.S.A0009=1
+RNCONC.S.A000a=1
+
+# Temperature Measurement Cluster
+TMP.S=1
+TMP.S.A0000=1
+TMP.S.A0001=1
+TMP.S.A0002=1
+TMP.S.A0003=1
+TMP.M.ManuallyControlled=0
+
+# Relative Humidity Cluster
+RH.S=1
+RH.S.A0000=1
+RH.S.A0001=1
+RH.S.A0002=1
+RH.S.A0003=1
+RH.M.ManuallyControlled=0
+
+# Thermostat Cluster
+TSTAT.S = 1
+TSTAT.S.F00 = 1
+TSTAT.S.F01 = 0
+TSTAT.S.F02 = 0
+TSTAT.S.F03 = 0
+TSTAT.S.F04 = 0
+TSTAT.S.F05 = 0
+TSTAT.S.F06 = 0
+
+TSTAT.S.A0000 = 1
+TSTAT.S.A0001 = 0
+TSTAT.S.A0002 = 0
+TSTAT.S.A0003 = 1
+TSTAT.S.A0004 = 1
+TSTAT.S.A0005 = 0
+TSTAT.S.A0006 = 0
+TSTAT.S.A0007 = 0
+TSTAT.S.A0008 = 0
+TSTAT.S.A0009 = 0
+TSTAT.S.A0010 = 0
+TSTAT.S.A0011 = 0
+TSTAT.S.A0012 = 1
+TSTAT.S.A0013 = 0
+TSTAT.S.A0014 = 0
+TSTAT.S.A0015 = 0
+TSTAT.S.A0016 = 0
+TSTAT.S.A0017 = 0
+TSTAT.S.A0018 = 0
+TSTAT.S.A0019 = 0
+TSTAT.S.A001a = 0
+TSTAT.S.A001b = 1
+TSTAT.S.A001c = 1
+TSTAT.S.A001d = 0
+TSTAT.S.A001e = 0
+TSTAT.S.A0020 = 0
+TSTAT.S.A0021 = 0
+TSTAT.S.A0022 = 0
+TSTAT.S.A0023 = 0
+TSTAT.S.A0024 = 0
+TSTAT.S.A0025 = 0
+TSTAT.S.A0029 = 1
+TSTAT.S.A0030 = 0
+TSTAT.S.A0031 = 0
+TSTAT.S.A0032 = 0
+TSTAT.S.A0034 = 0
+TSTAT.S.A0035 = 0
+TSTAT.S.A0036 = 0
+TSTAT.S.A0037 = 0
+TSTAT.S.A0038 = 0
+TSTAT.S.A0039 = 0
+TSTAT.S.A003a = 0
+TSTAT.S.A0040 = 0
+TSTAT.S.A0041 = 0
+TSTAT.S.A0042 = 0
+TSTAT.S.A0043 = 0
+TSTAT.S.A0044 = 0
+TSTAT.S.A0045 = 0
+TSTAT.S.A0046 = 0
+TSTAT.S.A0047 = 0
+TSTAT.S.M.MinSetpointDeadBandWritable = 0
+TSTAT.S.M.HVACSystemTypeConfigurationWritable = 0
+
+# Server Commands
+TSTAT.S.C00.Rsp = 1
+TSTAT.S.C01.Rsp = 0
+TSTAT.S.C02.Rsp = 0
+TSTAT.S.C03.Rsp = 0
+TSTAT.S.C04.Rsp = 0
+```
diff --git a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter
index 33de783..ac6dc5a 100644
--- a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter
+++ b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter
@@ -1207,6 +1207,377 @@
command ResetCondition(): DefaultSuccess = 0;
}
+/** An interface for configuring and controlling the functionality of a thermostat. */
+cluster Thermostat = 513 {
+ revision 6;
+
+ enum ACCapacityFormatEnum : enum8 {
+ kBTUh = 0;
+ }
+
+ enum ACCompressorTypeEnum : enum8 {
+ kUnknown = 0;
+ kT1 = 1;
+ kT2 = 2;
+ kT3 = 3;
+ }
+
+ enum ACLouverPositionEnum : enum8 {
+ kClosed = 1;
+ kOpen = 2;
+ kQuarter = 3;
+ kHalf = 4;
+ kThreeQuarters = 5;
+ }
+
+ enum ACRefrigerantTypeEnum : enum8 {
+ kUnknown = 0;
+ kR22 = 1;
+ kR410a = 2;
+ kR407c = 3;
+ }
+
+ enum ACTypeEnum : enum8 {
+ kUnknown = 0;
+ kCoolingFixed = 1;
+ kHeatPumpFixed = 2;
+ kCoolingInverter = 3;
+ kHeatPumpInverter = 4;
+ }
+
+ enum ControlSequenceOfOperationEnum : enum8 {
+ kCoolingOnly = 0;
+ kCoolingWithReheat = 1;
+ kHeatingOnly = 2;
+ kHeatingWithReheat = 3;
+ kCoolingAndHeating = 4;
+ kCoolingAndHeatingWithReheat = 5;
+ }
+
+ enum PresetScenarioEnum : enum8 {
+ kUnspecified = 0;
+ kOccupied = 1;
+ kUnoccupied = 2;
+ kSleep = 3;
+ kWake = 4;
+ kVacation = 5;
+ kUserDefined = 6;
+ }
+
+ enum SetpointChangeSourceEnum : enum8 {
+ kManual = 0;
+ kSchedule = 1;
+ kExternal = 2;
+ }
+
+ enum SetpointRaiseLowerModeEnum : enum8 {
+ kHeat = 0;
+ kCool = 1;
+ kBoth = 2;
+ }
+
+ enum StartOfWeekEnum : enum8 {
+ kSunday = 0;
+ kMonday = 1;
+ kTuesday = 2;
+ kWednesday = 3;
+ kThursday = 4;
+ kFriday = 5;
+ kSaturday = 6;
+ }
+
+ enum SystemModeEnum : enum8 {
+ kOff = 0;
+ kAuto = 1;
+ kCool = 3;
+ kHeat = 4;
+ kEmergencyHeat = 5;
+ kPrecooling = 6;
+ kFanOnly = 7;
+ kDry = 8;
+ kSleep = 9;
+ }
+
+ enum TemperatureSetpointHoldEnum : enum8 {
+ kSetpointHoldOff = 0;
+ kSetpointHoldOn = 1;
+ }
+
+ enum ThermostatRunningModeEnum : enum8 {
+ kOff = 0;
+ kCool = 3;
+ kHeat = 4;
+ }
+
+ bitmap ACErrorCodeBitmap : bitmap32 {
+ kCompressorFail = 0x1;
+ kRoomSensorFail = 0x2;
+ kOutdoorSensorFail = 0x4;
+ kCoilSensorFail = 0x8;
+ kFanFail = 0x10;
+ }
+
+ bitmap Feature : bitmap32 {
+ kHeating = 0x1;
+ kCooling = 0x2;
+ kOccupancy = 0x4;
+ kScheduleConfiguration = 0x8;
+ kSetback = 0x10;
+ kAutoMode = 0x20;
+ kLocalTemperatureNotExposed = 0x40;
+ kMatterScheduleConfiguration = 0x80;
+ kPresets = 0x100;
+ kSetpoints = 0x200;
+ kQueuedPresetsSupported = 0x400;
+ }
+
+ bitmap HVACSystemTypeBitmap : bitmap8 {
+ kCoolingStage = 0x3;
+ kHeatingStage = 0xC;
+ kHeatingIsHeatPump = 0x10;
+ kHeatingUsesFuel = 0x20;
+ }
+
+ bitmap PresetTypeFeaturesBitmap : bitmap16 {
+ kAutomatic = 0x1;
+ kSupportsNames = 0x2;
+ }
+
+ bitmap ProgrammingOperationModeBitmap : bitmap8 {
+ kScheduleActive = 0x1;
+ kAutoRecovery = 0x2;
+ kEconomy = 0x4;
+ }
+
+ bitmap RelayStateBitmap : bitmap16 {
+ kHeat = 0x1;
+ kCool = 0x2;
+ kFan = 0x4;
+ kHeatStage2 = 0x8;
+ kCoolStage2 = 0x10;
+ kFanStage2 = 0x20;
+ kFanStage3 = 0x40;
+ }
+
+ bitmap RemoteSensingBitmap : bitmap8 {
+ kLocalTemperature = 0x1;
+ kOutdoorTemperature = 0x2;
+ kOccupancy = 0x4;
+ }
+
+ bitmap ScheduleDayOfWeekBitmap : bitmap8 {
+ kSunday = 0x1;
+ kMonday = 0x2;
+ kTuesday = 0x4;
+ kWednesday = 0x8;
+ kThursday = 0x10;
+ kFriday = 0x20;
+ kSaturday = 0x40;
+ kAway = 0x80;
+ }
+
+ bitmap ScheduleModeBitmap : bitmap8 {
+ kHeatSetpointPresent = 0x1;
+ kCoolSetpointPresent = 0x2;
+ }
+
+ bitmap ScheduleTypeFeaturesBitmap : bitmap16 {
+ kSupportsPresets = 0x1;
+ kSupportsSetpoints = 0x2;
+ kSupportsNames = 0x4;
+ kSupportsOff = 0x8;
+ }
+
+ bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 {
+ kHoldDurationElapsed = 0x1;
+ kHoldDurationElapsedOrPresetChanged = 0x2;
+ }
+
+ struct ScheduleTransitionStruct {
+ ScheduleDayOfWeekBitmap dayOfWeek = 0;
+ int16u transitionTime = 1;
+ optional octet_string<16> presetHandle = 2;
+ optional SystemModeEnum systemMode = 3;
+ optional temperature coolingSetpoint = 4;
+ optional temperature heatingSetpoint = 5;
+ }
+
+ struct ScheduleStruct {
+ nullable octet_string<16> scheduleHandle = 0;
+ SystemModeEnum systemMode = 1;
+ optional char_string<64> name = 2;
+ optional octet_string<16> presetHandle = 3;
+ ScheduleTransitionStruct transitions[] = 4;
+ optional nullable boolean builtIn = 5;
+ }
+
+ struct PresetStruct {
+ nullable octet_string<16> presetHandle = 0;
+ PresetScenarioEnum presetScenario = 1;
+ optional nullable char_string<64> name = 2;
+ optional temperature coolingSetpoint = 3;
+ optional temperature heatingSetpoint = 4;
+ nullable boolean builtIn = 5;
+ }
+
+ struct PresetTypeStruct {
+ PresetScenarioEnum presetScenario = 0;
+ int8u numberOfPresets = 1;
+ PresetTypeFeaturesBitmap presetTypeFeatures = 2;
+ }
+
+ struct QueuedPresetStruct {
+ nullable octet_string<16> presetHandle = 0;
+ nullable epoch_s transitionTimestamp = 1;
+ }
+
+ struct ScheduleTypeStruct {
+ SystemModeEnum systemMode = 0;
+ int8u numberOfSchedules = 1;
+ ScheduleTypeFeaturesBitmap scheduleTypeFeatures = 2;
+ }
+
+ struct WeeklyScheduleTransitionStruct {
+ int16u transitionTime = 0;
+ nullable temperature heatSetpoint = 1;
+ nullable temperature coolSetpoint = 2;
+ }
+
+ readonly attribute nullable temperature localTemperature = 0;
+ readonly attribute optional nullable temperature outdoorTemperature = 1;
+ readonly attribute optional bitmap8 occupancy = 2;
+ readonly attribute optional temperature absMinHeatSetpointLimit = 3;
+ readonly attribute optional temperature absMaxHeatSetpointLimit = 4;
+ readonly attribute optional temperature absMinCoolSetpointLimit = 5;
+ readonly attribute optional temperature absMaxCoolSetpointLimit = 6;
+ readonly attribute optional int8u PICoolingDemand = 7;
+ readonly attribute optional int8u PIHeatingDemand = 8;
+ attribute access(write: manage) optional bitmap8 HVACSystemTypeConfiguration = 9;
+ attribute access(write: manage) optional int8s localTemperatureCalibration = 16;
+ attribute optional int16s occupiedCoolingSetpoint = 17;
+ attribute optional int16s occupiedHeatingSetpoint = 18;
+ attribute optional int16s unoccupiedCoolingSetpoint = 19;
+ attribute optional int16s unoccupiedHeatingSetpoint = 20;
+ attribute access(write: manage) optional int16s minHeatSetpointLimit = 21;
+ attribute access(write: manage) optional int16s maxHeatSetpointLimit = 22;
+ attribute access(write: manage) optional int16s minCoolSetpointLimit = 23;
+ attribute access(write: manage) optional int16s maxCoolSetpointLimit = 24;
+ attribute access(write: manage) optional int8s minSetpointDeadBand = 25;
+ attribute access(write: manage) optional RemoteSensingBitmap remoteSensing = 26;
+ attribute access(write: manage) ControlSequenceOfOperationEnum controlSequenceOfOperation = 27;
+ attribute access(write: manage) SystemModeEnum systemMode = 28;
+ readonly attribute optional ThermostatRunningModeEnum thermostatRunningMode = 30;
+ readonly attribute optional StartOfWeekEnum startOfWeek = 32;
+ readonly attribute optional int8u numberOfWeeklyTransitions = 33;
+ readonly attribute optional int8u numberOfDailyTransitions = 34;
+ attribute access(write: manage) optional TemperatureSetpointHoldEnum temperatureSetpointHold = 35;
+ attribute access(write: manage) optional nullable int16u temperatureSetpointHoldDuration = 36;
+ attribute access(write: manage) optional ProgrammingOperationModeBitmap thermostatProgrammingOperationMode = 37;
+ readonly attribute optional RelayStateBitmap thermostatRunningState = 41;
+ readonly attribute optional SetpointChangeSourceEnum setpointChangeSource = 48;
+ readonly attribute optional nullable int16s setpointChangeAmount = 49;
+ readonly attribute optional epoch_s setpointChangeSourceTimestamp = 50;
+ attribute access(write: manage) optional nullable int8u occupiedSetback = 52;
+ readonly attribute optional nullable int8u occupiedSetbackMin = 53;
+ readonly attribute optional nullable int8u occupiedSetbackMax = 54;
+ attribute access(write: manage) optional nullable int8u unoccupiedSetback = 55;
+ readonly attribute optional nullable int8u unoccupiedSetbackMin = 56;
+ readonly attribute optional nullable int8u unoccupiedSetbackMax = 57;
+ attribute access(write: manage) optional int8u emergencyHeatDelta = 58;
+ attribute access(write: manage) optional ACTypeEnum ACType = 64;
+ attribute access(write: manage) optional int16u ACCapacity = 65;
+ attribute access(write: manage) optional ACRefrigerantTypeEnum ACRefrigerantType = 66;
+ attribute access(write: manage) optional ACCompressorTypeEnum ACCompressorType = 67;
+ attribute access(write: manage) optional ACErrorCodeBitmap ACErrorCode = 68;
+ attribute access(write: manage) optional ACLouverPositionEnum ACLouverPosition = 69;
+ readonly attribute optional nullable temperature ACCoilTemperature = 70;
+ attribute access(write: manage) optional ACCapacityFormatEnum ACCapacityformat = 71;
+ readonly attribute optional PresetTypeStruct presetTypes[] = 72;
+ readonly attribute optional ScheduleTypeStruct scheduleTypes[] = 73;
+ readonly attribute optional int8u numberOfPresets = 74;
+ readonly attribute optional int8u numberOfSchedules = 75;
+ readonly attribute optional int8u numberOfScheduleTransitions = 76;
+ readonly attribute optional nullable int8u numberOfScheduleTransitionPerDay = 77;
+ readonly attribute optional nullable octet_string<16> activePresetHandle = 78;
+ readonly attribute optional nullable octet_string<16> activeScheduleHandle = 79;
+ attribute access(write: manage) optional PresetStruct presets[] = 80;
+ attribute access(write: manage) optional ScheduleStruct schedules[] = 81;
+ readonly attribute optional boolean presetsSchedulesEditable = 82;
+ readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83;
+ readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84;
+ readonly attribute optional nullable QueuedPresetStruct queuedPreset = 85;
+ readonly attribute command_id generatedCommandList[] = 65528;
+ readonly attribute command_id acceptedCommandList[] = 65529;
+ readonly attribute event_id eventList[] = 65530;
+ readonly attribute attrib_id attributeList[] = 65531;
+ readonly attribute bitmap32 featureMap = 65532;
+ readonly attribute int16u clusterRevision = 65533;
+
+ request struct SetpointRaiseLowerRequest {
+ SetpointRaiseLowerModeEnum mode = 0;
+ int8s amount = 1;
+ }
+
+ response struct GetWeeklyScheduleResponse = 0 {
+ int8u numberOfTransitionsForSequence = 0;
+ ScheduleDayOfWeekBitmap dayOfWeekForSequence = 1;
+ ScheduleModeBitmap modeForSequence = 2;
+ WeeklyScheduleTransitionStruct transitions[] = 3;
+ }
+
+ request struct SetWeeklyScheduleRequest {
+ int8u numberOfTransitionsForSequence = 0;
+ ScheduleDayOfWeekBitmap dayOfWeekForSequence = 1;
+ ScheduleModeBitmap modeForSequence = 2;
+ WeeklyScheduleTransitionStruct transitions[] = 3;
+ }
+
+ request struct GetWeeklyScheduleRequest {
+ ScheduleDayOfWeekBitmap daysToReturn = 0;
+ ScheduleModeBitmap modeToReturn = 1;
+ }
+
+ request struct SetActiveScheduleRequestRequest {
+ octet_string<16> scheduleHandle = 0;
+ }
+
+ request struct SetActivePresetRequestRequest {
+ octet_string<16> presetHandle = 0;
+ optional int16u delayMinutes = 1;
+ }
+
+ request struct StartPresetsSchedulesEditRequestRequest {
+ int16u timeoutSeconds = 0;
+ }
+
+ request struct SetTemperatureSetpointHoldPolicyRequest {
+ TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0;
+ }
+
+ /** Command description for SetpointRaiseLower */
+ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0;
+ /** Command description for SetWeeklySchedule */
+ command access(invoke: manage) SetWeeklySchedule(SetWeeklyScheduleRequest): DefaultSuccess = 1;
+ /** Command description for GetWeeklySchedule */
+ command GetWeeklySchedule(GetWeeklyScheduleRequest): GetWeeklyScheduleResponse = 2;
+ /** This command is used to clear the weekly schedule. The ClearWeeklySchedule command has no payload. */
+ command access(invoke: manage) ClearWeeklySchedule(): DefaultSuccess = 3;
+ /** This command is used to set the active schedule. */
+ command SetActiveScheduleRequest(SetActiveScheduleRequestRequest): DefaultSuccess = 5;
+ /** This command is used to set the active preset. */
+ command SetActivePresetRequest(SetActivePresetRequestRequest): DefaultSuccess = 6;
+ /** This command is used to start editing the presets and schedules. */
+ command access(invoke: manage) StartPresetsSchedulesEditRequest(StartPresetsSchedulesEditRequestRequest): DefaultSuccess = 7;
+ /** This command is used to cancel editing presets and schedules. */
+ command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8;
+ /** This command is used to notify the server that all edits are done and should be committed. */
+ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9;
+ /** This command is sent to cancel a queued preset. */
+ command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10;
+ /** This command sets the set point hold policy. */
+ command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11;
+}
+
/** An interface for controlling a fan in a heating/cooling system. */
provisional cluster FanControl = 514 {
revision 4;
@@ -2407,7 +2778,7 @@
}
}
endpoint 3 {
- device type ma_tempsensor = 770, version 1;
+ device type ma_tempsensor = 770, version 2;
server cluster Identify {
@@ -2451,7 +2822,7 @@
}
}
endpoint 4 {
- device type ma_humiditysensor = 775, version 1;
+ device type ma_humiditysensor = 775, version 2;
server cluster Identify {
@@ -2494,5 +2865,54 @@
ram attribute clusterRevision default = 3;
}
}
+endpoint 5 {
+ device type ma_thermostat = 769, version 2;
+
+
+ server cluster Identify {
+ ram attribute identifyTime default = 0x0;
+ ram attribute identifyType default = 0x00;
+ callback attribute generatedCommandList;
+ callback attribute acceptedCommandList;
+ callback attribute eventList;
+ callback attribute attributeList;
+ ram attribute featureMap default = 0;
+ ram attribute clusterRevision default = 4;
+
+ handle command Identify;
+ handle command TriggerEffect;
+ }
+
+ server cluster Descriptor {
+ callback attribute deviceTypeList;
+ callback attribute serverList;
+ callback attribute clientList;
+ callback attribute partsList;
+ callback attribute generatedCommandList;
+ callback attribute acceptedCommandList;
+ callback attribute eventList;
+ callback attribute attributeList;
+ callback attribute featureMap;
+ callback attribute clusterRevision;
+ }
+
+ server cluster Thermostat {
+ ram attribute localTemperature;
+ ram attribute absMinHeatSetpointLimit default = 1000;
+ ram attribute absMaxHeatSetpointLimit default = 3000;
+ ram attribute occupiedHeatingSetpoint default = 2000;
+ ram attribute controlSequenceOfOperation default = 2;
+ ram attribute systemMode default = 0;
+ ram attribute thermostatRunningState default = 0;
+ callback attribute generatedCommandList;
+ callback attribute acceptedCommandList;
+ callback attribute eventList;
+ callback attribute attributeList;
+ ram attribute featureMap default = 1;
+ ram attribute clusterRevision default = 6;
+
+ handle command SetpointRaiseLower;
+ }
+}
diff --git a/examples/air-purifier-app/air-purifier-common/air-purifier-app.zap b/examples/air-purifier-app/air-purifier-common/air-purifier-app.zap
index d71c47a..b868916 100644
--- a/examples/air-purifier-app/air-purifier-common/air-purifier-app.zap
+++ b/examples/air-purifier-app/air-purifier-common/air-purifier-app.zap
@@ -6514,7 +6514,7 @@
}
],
"deviceVersions": [
- 1
+ 2
],
"deviceIdentifiers": [
770
@@ -7039,7 +7039,7 @@
}
],
"deviceVersions": [
- 1
+ 2
],
"deviceIdentifiers": [
775
@@ -7545,6 +7545,589 @@
]
}
]
+ },
+ {
+ "id": 6,
+ "name": "Anonymous Endpoint Type",
+ "deviceTypeRef": {
+ "code": 769,
+ "profileId": 259,
+ "label": "MA-thermostat",
+ "name": "MA-thermostat"
+ },
+ "deviceTypes": [
+ {
+ "code": 769,
+ "profileId": 259,
+ "label": "MA-thermostat",
+ "name": "MA-thermostat"
+ }
+ ],
+ "deviceVersions": [
+ 2
+ ],
+ "deviceIdentifiers": [
+ 769
+ ],
+ "deviceTypeName": "MA-thermostat",
+ "deviceTypeCode": 769,
+ "deviceTypeProfileId": 259,
+ "clusters": [
+ {
+ "name": "Identify",
+ "code": 3,
+ "mfgCode": null,
+ "define": "IDENTIFY_CLUSTER",
+ "side": "server",
+ "enabled": 1,
+ "commands": [
+ {
+ "name": "Identify",
+ "code": 0,
+ "mfgCode": null,
+ "source": "client",
+ "isIncoming": 1,
+ "isEnabled": 1
+ },
+ {
+ "name": "TriggerEffect",
+ "code": 64,
+ "mfgCode": null,
+ "source": "client",
+ "isIncoming": 1,
+ "isEnabled": 1
+ }
+ ],
+ "attributes": [
+ {
+ "name": "IdentifyTime",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int16u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0x0",
+ "reportable": 0,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "IdentifyType",
+ "code": 1,
+ "mfgCode": null,
+ "side": "server",
+ "type": "IdentifyTypeEnum",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0x00",
+ "reportable": 0,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "GeneratedCommandList",
+ "code": 65528,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AcceptedCommandList",
+ "code": 65529,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "EventList",
+ "code": 65530,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AttributeList",
+ "code": 65531,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "FeatureMap",
+ "code": 65532,
+ "mfgCode": null,
+ "side": "server",
+ "type": "bitmap32",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ClusterRevision",
+ "code": 65533,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int16u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "4",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ }
+ ]
+ },
+ {
+ "name": "Descriptor",
+ "code": 29,
+ "mfgCode": null,
+ "define": "DESCRIPTOR_CLUSTER",
+ "side": "server",
+ "enabled": 1,
+ "attributes": [
+ {
+ "name": "DeviceTypeList",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ServerList",
+ "code": 1,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 0,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ClientList",
+ "code": 2,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 0,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "PartsList",
+ "code": 3,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 0,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "GeneratedCommandList",
+ "code": 65528,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AcceptedCommandList",
+ "code": 65529,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "EventList",
+ "code": 65530,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AttributeList",
+ "code": 65531,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "FeatureMap",
+ "code": 65532,
+ "mfgCode": null,
+ "side": "server",
+ "type": "bitmap32",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ClusterRevision",
+ "code": 65533,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int16u",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "2",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ }
+ ]
+ },
+ {
+ "name": "Thermostat",
+ "code": 513,
+ "mfgCode": null,
+ "define": "THERMOSTAT_CLUSTER",
+ "side": "server",
+ "enabled": 1,
+ "commands": [
+ {
+ "name": "SetpointRaiseLower",
+ "code": 0,
+ "mfgCode": null,
+ "source": "client",
+ "isIncoming": 1,
+ "isEnabled": 1
+ }
+ ],
+ "attributes": [
+ {
+ "name": "LocalTemperature",
+ "code": 0,
+ "mfgCode": null,
+ "side": "server",
+ "type": "temperature",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AbsMinHeatSetpointLimit",
+ "code": 3,
+ "mfgCode": null,
+ "side": "server",
+ "type": "temperature",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "1000",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AbsMaxHeatSetpointLimit",
+ "code": 4,
+ "mfgCode": null,
+ "side": "server",
+ "type": "temperature",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "3000",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "OccupiedHeatingSetpoint",
+ "code": 18,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int16s",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "2000",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ControlSequenceOfOperation",
+ "code": 27,
+ "mfgCode": null,
+ "side": "server",
+ "type": "ControlSequenceOfOperationEnum",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "2",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "SystemMode",
+ "code": 28,
+ "mfgCode": null,
+ "side": "server",
+ "type": "SystemModeEnum",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ThermostatRunningState",
+ "code": 41,
+ "mfgCode": null,
+ "side": "server",
+ "type": "RelayStateBitmap",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "0",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "GeneratedCommandList",
+ "code": 65528,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AcceptedCommandList",
+ "code": 65529,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "EventList",
+ "code": 65530,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "AttributeList",
+ "code": 65531,
+ "mfgCode": null,
+ "side": "server",
+ "type": "array",
+ "included": 1,
+ "storageOption": "External",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "FeatureMap",
+ "code": 65532,
+ "mfgCode": null,
+ "side": "server",
+ "type": "bitmap32",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "1",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ },
+ {
+ "name": "ClusterRevision",
+ "code": 65533,
+ "mfgCode": null,
+ "side": "server",
+ "type": "int16u",
+ "included": 1,
+ "storageOption": "RAM",
+ "singleton": 0,
+ "bounded": 0,
+ "defaultValue": "6",
+ "reportable": 1,
+ "minInterval": 1,
+ "maxInterval": 65534,
+ "reportableChange": 0
+ }
+ ]
+ }
+ ]
}
],
"endpoints": [
@@ -7582,6 +8165,14 @@
"profileId": 259,
"endpointId": 4,
"networkId": 0
+ },
+ {
+ "endpointTypeName": "Anonymous Endpoint Type",
+ "endpointTypeIndex": 5,
+ "profileId": 259,
+ "endpointId": 5,
+ "networkId": 0
}
- ]
+ ],
+ "log": []
}
\ No newline at end of file
diff --git a/examples/air-purifier-app/air-purifier-common/include/air-purifier-manager.h b/examples/air-purifier-app/air-purifier-common/include/air-purifier-manager.h
index 81565d5..e50ccd0 100644
--- a/examples/air-purifier-app/air-purifier-common/include/air-purifier-manager.h
+++ b/examples/air-purifier-app/air-purifier-common/include/air-purifier-manager.h
@@ -22,6 +22,7 @@
#include <filter-delegates.h>
#include <relative-humidity-sensor-manager.h>
#include <temperature-sensor-manager.h>
+#include <thermostat-manager.h>
#pragma once
@@ -52,12 +53,13 @@
AirPurifierManager & operator=(const AirPurifierManager &) = delete;
static void InitInstance(EndpointId aEndpointId = 1, EndpointId aAirQualitySensorEndpointId = 2,
- EndpointId aTemperatureSensorEndpointId = 3, EndpointId aHumiditySensorEndpointId = 4)
+ EndpointId aTemperatureSensorEndpointId = 3, EndpointId aHumiditySensorEndpointId = 4,
+ EndpointId aThermostatEndpointId = 5)
{
if (mInstance == nullptr)
{
mInstance = new AirPurifierManager(aEndpointId, aAirQualitySensorEndpointId, aTemperatureSensorEndpointId,
- aHumiditySensorEndpointId);
+ aHumiditySensorEndpointId, aThermostatEndpointId);
mInstance->Init();
}
};
@@ -89,6 +91,11 @@
*/
Protocols::InteractionModel::Status HandleStep(FanControl::StepDirectionEnum aDirection, bool aWrap, bool aLowestOff) override;
+ /**
+ * @brief Callback that thermostat manager calls when the heating state changes
+ */
+ void HeatingCallback();
+
private:
inline static AirPurifierManager * mInstance;
@@ -96,10 +103,13 @@
EndpointId mAirQualitySensorEndpointId;
EndpointId mTemperatureSensorEndpointId;
EndpointId mHumiditySensorEndpointId;
+ EndpointId mThermostatEndpointId;
uint8_t percentCurrent;
uint8_t speedCurrent;
+ bool fanWasStartedByUser = false;
+
// Set up for Activated Carbon Filter Monitoring
ActivatedCarbonFilterMonitoringDelegate activatedCarbonFilterDelegate;
ResourceMonitoring::Instance activatedCarbonFilterInstance;
@@ -112,6 +122,7 @@
AirQualitySensorManager mAirQualitySensorManager;
TemperatureSensorManager mTemperatureSensorManager;
RelativeHumiditySensorManager mHumiditySensorManager;
+ ThermostatManager mThermostatManager;
// Fan Mode Limits
static constexpr int FAN_MODE_LOW_LOWER_BOUND = 1;
@@ -129,7 +140,7 @@
* @param[in] aHumiditySensorEndpointId Endpoint that the humidity sensor is on
*/
AirPurifierManager(EndpointId aEndpointId, EndpointId aAirQualitySensorEndpointId, EndpointId aTemperatureSensorEndpointId,
- EndpointId aHumiditySensorEndpointId) :
+ EndpointId aHumiditySensorEndpointId, EndpointId aThermostatEndpointId) :
FanControl::Delegate(aEndpointId),
mEndpointId(aEndpointId),
activatedCarbonFilterInstance(&activatedCarbonFilterDelegate, mEndpointId, ActivatedCarbonFilterMonitoring::Id,
@@ -139,7 +150,9 @@
static_cast<uint32_t>(gHepaFilterFeatureMap.to_ulong()),
ResourceMonitoring::DegradationDirectionEnum::kDown, true),
mAirQualitySensorManager(aAirQualitySensorEndpointId), mTemperatureSensorManager(aTemperatureSensorEndpointId),
- mHumiditySensorManager(aHumiditySensorEndpointId){};
+ mHumiditySensorManager(aHumiditySensorEndpointId),
+ mThermostatManager(aThermostatEndpointId, [this]() { HeatingCallback(); })
+ {}
/**
* @brief Handle attribute changes for the Fan Control Cluster
@@ -155,6 +168,12 @@
void FanModeWriteCallback(FanControl::FanModeEnum aNewFanMode);
void SetSpeedSetting(DataModel::Nullable<uint8_t> aNewSpeedSetting);
+ DataModel::Nullable<uint8_t> GetSpeedSetting();
+ DataModel::Nullable<Percent> GetPercentSetting();
+
+ void HandleThermostatAttributeChange(AttributeId attributeId, uint8_t type, uint16_t size, uint8_t * value);
+ void ThermostatHeatingSetpointWriteCallback(int16_t aNewHeatingSetpoint);
+ void ThermostatSystemModeWriteCallback(uint8_t aNewSystemMode);
};
} // namespace Clusters
diff --git a/examples/air-purifier-app/air-purifier-common/include/thermostat-manager.h b/examples/air-purifier-app/air-purifier-common/include/thermostat-manager.h
new file mode 100644
index 0000000..f19e596
--- /dev/null
+++ b/examples/air-purifier-app/air-purifier-common/include/thermostat-manager.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <app-common/zap-generated/attributes/Accessors.h>
+#include <functional>
+
+namespace chip {
+namespace app {
+namespace Clusters {
+
+class ThermostatManager
+{
+public:
+ using HeatingCallbackType = std::function<void()>;
+
+ ThermostatManager(EndpointId aEndpointId, const HeatingCallbackType & callback) :
+ mEndpointId(aEndpointId), heatingCallback(callback)
+ {}
+
+ void Init();
+
+ void HeatingSetpointWriteCallback(int16_t newValue);
+ void SystemModeWriteCallback(uint8_t newValue);
+ void OnLocalTemperatureChangeCallback(int16_t temperature);
+ void SetHeatMode(bool heat);
+
+private:
+ EndpointId mEndpointId;
+
+ void SetHeating(bool isHeating);
+ HeatingCallbackType heatingCallback;
+};
+
+} // namespace Clusters
+} // namespace app
+} // namespace chip
diff --git a/examples/air-purifier-app/air-purifier-common/src/air-purifier-manager.cpp b/examples/air-purifier-app/air-purifier-common/src/air-purifier-manager.cpp
index 93e1e37..7ce8ac5 100644
--- a/examples/air-purifier-app/air-purifier-common/src/air-purifier-manager.cpp
+++ b/examples/air-purifier-app/air-purifier-common/src/air-purifier-manager.cpp
@@ -33,37 +33,31 @@
mAirQualitySensorManager.Init();
mTemperatureSensorManager.Init();
mHumiditySensorManager.Init();
+ mThermostatManager.Init();
- DataModel::Nullable<Percent> percentSetting;
- EmberAfStatus status = FanControl::Attributes::PercentSetting::Get(mEndpointId, percentSetting);
- if (EMBER_ZCL_STATUS_SUCCESS == status)
+ DataModel::Nullable<Percent> percentSetting = GetPercentSetting();
+ if (percentSetting.IsNull())
{
- if (percentSetting.IsNull())
- {
- PercentSettingWriteCallback(0);
- }
- else
- {
- PercentSettingWriteCallback(percentSetting.Value());
- }
+ PercentSettingWriteCallback(0);
+ }
+ else
+ {
+ PercentSettingWriteCallback(percentSetting.Value());
}
- DataModel::Nullable<uint8_t> speedSetting;
- status = FanControl::Attributes::SpeedSetting::Get(mEndpointId, speedSetting);
- if (EMBER_ZCL_STATUS_SUCCESS == status)
+ DataModel::Nullable<uint8_t> speedSetting = GetSpeedSetting();
+ if (speedSetting.IsNull())
{
- if (speedSetting.IsNull())
- {
- SpeedSettingWriteCallback(0);
- }
- else
- {
- SpeedSettingWriteCallback(speedSetting.Value());
- }
+ SpeedSettingWriteCallback(0);
+ }
+ else
+ {
+ SpeedSettingWriteCallback(speedSetting.Value());
}
// Set up some sane initial values for temperature and humidity - note these are fixed values for testing purposes only
mTemperatureSensorManager.OnTemperatureChangeHandler(2000);
+ mThermostatManager.OnLocalTemperatureChangeCallback(2000);
mHumiditySensorManager.OnHumidityChangeHandler(5000);
}
@@ -77,6 +71,11 @@
break;
}
+ case Thermostat::Id: {
+ HandleThermostatAttributeChange(attributeId, type, size, value);
+ break;
+ }
+
default:
break;
}
@@ -92,8 +91,7 @@
uint8_t speedMax;
FanControl::Attributes::SpeedMax::Get(mEndpointId, &speedMax);
- DataModel::Nullable<uint8_t> speedSetting;
- FanControl::Attributes::SpeedSetting::Get(mEndpointId, speedSetting);
+ DataModel::Nullable<uint8_t> speedSetting = GetSpeedSetting();
uint8_t newSpeedSetting = speedSetting.IsNull() ? 0 : speedSetting.Value();
@@ -309,3 +307,68 @@
}
}
}
+
+DataModel::Nullable<uint8_t> AirPurifierManager::GetSpeedSetting()
+{
+ DataModel::Nullable<uint8_t> speedSetting;
+ EmberAfStatus status = FanControl::Attributes::SpeedSetting::Get(mEndpointId, speedSetting);
+
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogError(NotSpecified, "AirPurifierManager::GetSpeedSetting: failed to get SpeedSetting attribute: %d", status);
+ }
+
+ return speedSetting;
+}
+
+DataModel::Nullable<Percent> AirPurifierManager::GetPercentSetting()
+{
+ DataModel::Nullable<Percent> percentSetting;
+ EmberAfStatus status = FanControl::Attributes::PercentSetting::Get(mEndpointId, percentSetting);
+
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ ChipLogError(NotSpecified, "AirPurifierManager::GetPercentSetting: failed to get PercentSetting attribute: %d", status);
+ }
+
+ return percentSetting;
+}
+
+void AirPurifierManager::HandleThermostatAttributeChange(AttributeId attributeId, uint8_t type, uint16_t size, uint8_t * value)
+{
+ switch (attributeId)
+ {
+ case Thermostat::Attributes::OccupiedHeatingSetpoint::Id: {
+ int16_t heatingSetpoint = static_cast<int16_t>(chip::Encoding::LittleEndian::Get16(value));
+ ThermostatHeatingSetpointWriteCallback(heatingSetpoint);
+ break;
+ }
+ case Thermostat::Attributes::SystemMode::Id: {
+ uint8_t systemMode = static_cast<uint8_t>(*value);
+ ThermostatSystemModeWriteCallback(systemMode);
+ break;
+ }
+ }
+}
+
+void AirPurifierManager::ThermostatHeatingSetpointWriteCallback(int16_t aNewHeatingSetpoint)
+{
+ mThermostatManager.HeatingSetpointWriteCallback(aNewHeatingSetpoint);
+}
+
+void AirPurifierManager::ThermostatSystemModeWriteCallback(uint8_t aNewSystemMode)
+{
+ mThermostatManager.SystemModeWriteCallback(aNewSystemMode);
+}
+
+void AirPurifierManager::HeatingCallback()
+{
+ // Check if the Fan is off and if it is, turn it on to 50% speed
+ DataModel::Nullable<uint8_t> speedSetting = GetSpeedSetting();
+
+ if (speedSetting.IsNull() || speedSetting.Value() == 0)
+ {
+ DataModel::Nullable<uint8_t> newSpeedSetting(5);
+ SetSpeedSetting(newSpeedSetting);
+ }
+}
diff --git a/examples/air-purifier-app/air-purifier-common/src/thermostat-manager.cpp b/examples/air-purifier-app/air-purifier-common/src/thermostat-manager.cpp
new file mode 100644
index 0000000..c2536e4
--- /dev/null
+++ b/examples/air-purifier-app/air-purifier-common/src/thermostat-manager.cpp
@@ -0,0 +1,135 @@
+/*
+ *
+ * Copyright (c) 2024 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "thermostat-manager.h"
+
+using namespace chip;
+using namespace chip::app;
+using namespace chip::app::Clusters;
+
+void ThermostatManager::Init()
+{
+ BitMask<Thermostat::Feature> FeatureMap;
+ FeatureMap.Set(Thermostat::Feature::kHeating);
+ EmberAfStatus status = Thermostat::Attributes::FeatureMap::Set(mEndpointId, FeatureMap.Raw());
+
+ status = Thermostat::Attributes::ControlSequenceOfOperation::Set(mEndpointId,
+ Thermostat::ControlSequenceOfOperationEnum::kHeatingOnly);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status,
+ ChipLogError(NotSpecified, "Failed to set Thermostat ControlSequenceOfOperation attribute"));
+
+ status = Thermostat::Attributes::AbsMinHeatSetpointLimit::Set(mEndpointId, 500);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status,
+ ChipLogError(NotSpecified, "Failed to set Thermostat MinHeatSetpointLimit attribute"));
+
+ status = Thermostat::Attributes::AbsMaxHeatSetpointLimit::Set(mEndpointId, 3000);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status,
+ ChipLogError(NotSpecified, "Failed to set Thermostat MaxHeatSetpointLimit attribute"));
+}
+
+void ThermostatManager::HeatingSetpointWriteCallback(int16_t newValue)
+{
+ ChipLogDetail(NotSpecified, "ThermostatManager::HeatingSetpointWriteCallback: %d", newValue);
+ Thermostat::SystemModeEnum systemMode;
+ EmberAfStatus status = Thermostat::Attributes::SystemMode::Get(mEndpointId, &systemMode);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status, ChipLogError(NotSpecified, "Failed to get Thermostat SystemMode attribute"));
+
+ // A new setpoint has been set, so we shall infer that the we want to be in Heating mode
+ if (systemMode == Thermostat::SystemModeEnum::kOff)
+ {
+ SetHeatMode(true);
+ }
+
+ // Check the current temperature and turn on the heater if needed
+ DataModel::Nullable<int16_t> localTemperature;
+ status = Thermostat::Attributes::LocalTemperature::Get(mEndpointId, localTemperature);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status,
+ ChipLogError(NotSpecified, "Failed to get TemperatureMeasurement MeasuredValue attribute"));
+
+ if (localTemperature.Value() < newValue)
+ {
+ SetHeating(true);
+ }
+ else
+ {
+ SetHeating(false);
+ }
+}
+
+void ThermostatManager::SystemModeWriteCallback(uint8_t newValue)
+{
+ ChipLogDetail(NotSpecified, "ThermostatManager::SystemModeWriteCallback: %d", newValue);
+ if ((Thermostat::SystemModeEnum) newValue == Thermostat::SystemModeEnum::kOff)
+ {
+ SetHeating(false);
+ }
+ else if ((Thermostat::SystemModeEnum) newValue == Thermostat::SystemModeEnum::kHeat)
+ {
+ DataModel::Nullable<int16_t> localTemperature;
+ EmberAfStatus status = Thermostat::Attributes::LocalTemperature::Get(mEndpointId, localTemperature);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status,
+ ChipLogError(NotSpecified, "Failed to get TemperatureMeasurement MeasuredValue attribute"));
+
+ int16_t heatingSetpoint;
+ status = Thermostat::Attributes::OccupiedHeatingSetpoint::Get(mEndpointId, &heatingSetpoint);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status,
+ ChipLogError(NotSpecified, "Failed to get Thermostat HeatingSetpoint attribute"));
+
+ if (localTemperature.Value() < heatingSetpoint)
+ {
+ SetHeating(true);
+ }
+ }
+}
+
+void ThermostatManager::OnLocalTemperatureChangeCallback(int16_t temperature)
+{
+ EmberAfStatus status = Thermostat::Attributes::LocalTemperature::Set(mEndpointId, temperature);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status,
+ ChipLogError(NotSpecified, "Failed to set TemperatureMeasurement MeasuredValue attribute"));
+}
+
+void ThermostatManager::SetHeating(bool isHeating)
+{
+ BitMask<Thermostat::RelayStateBitmap> runningState;
+
+ if (isHeating)
+ {
+ runningState.Set(Thermostat::RelayStateBitmap::kHeat);
+
+ if (heatingCallback)
+ {
+ heatingCallback();
+ }
+ }
+ else
+ {
+ runningState.Clear(Thermostat::RelayStateBitmap::kHeat);
+ }
+
+ EmberAfStatus status = Thermostat::Attributes::ThermostatRunningState::Set(mEndpointId, runningState);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status,
+ ChipLogError(NotSpecified, "Failed to set Thermostat RunningState attribute"));
+}
+
+void ThermostatManager::SetHeatMode(bool heat)
+{
+ EmberAfStatus status = Thermostat::Attributes::SystemMode::Set(
+ mEndpointId, heat ? Thermostat::SystemModeEnum::kHeat : Thermostat::SystemModeEnum::kOff);
+ VerifyOrReturn(EMBER_ZCL_STATUS_SUCCESS == status, ChipLogError(NotSpecified, "Failed to set Thermostat SystemMode attribute"));
+}
diff --git a/examples/air-purifier-app/ameba/README.md b/examples/air-purifier-app/ameba/README.md
index be11ad8..ee2a451 100644
--- a/examples/air-purifier-app/ameba/README.md
+++ b/examples/air-purifier-app/ameba/README.md
@@ -10,7 +10,7 @@
- [Commissioning](#commissioning)
- [BLE mode](#ble-mode)
- [IP mode](#ip-mode)
- - [Cluster control](#cluster-control)
+ - [Cluster Control](#cluster-control)
---
@@ -106,6 +106,7 @@
- Air quality sensor on endpoint 2
- Temperature sensor on endpoint 3
- Relative humidity sensor on endpoint 4
+- Thermostat on endpoint 5
Example commands using the chip tool:
diff --git a/examples/air-purifier-app/ameba/main/chipinterface.cpp b/examples/air-purifier-app/ameba/main/chipinterface.cpp
index bcda329..264ad53 100644
--- a/examples/air-purifier-app/ameba/main/chipinterface.cpp
+++ b/examples/air-purifier-app/ameba/main/chipinterface.cpp
@@ -48,6 +48,7 @@
#define AIR_QUALITY_SENSOR_ENDPOINT 2
#define TEMPERATURE_SENSOR_ENDPOINT 3
#define RELATIVE_HUMIDITY_SENSOR_ENDPOINT 4
+#define THERMOSTAT_ENDPOINT 5
using namespace ::chip;
using namespace ::chip::app;
@@ -116,11 +117,12 @@
{
Clusters::AirPurifierManager::InitInstance(EndpointId(AIR_PURIFIER_ENDPOINT), EndpointId(AIR_QUALITY_SENSOR_ENDPOINT),
EndpointId(TEMPERATURE_SENSOR_ENDPOINT),
- EndpointId(RELATIVE_HUMIDITY_SENSOR_ENDPOINT));
+ EndpointId(RELATIVE_HUMIDITY_SENSOR_ENDPOINT), EndpointId(THERMOSTAT_ENDPOINT));
SetParentEndpointForEndpoint(AIR_QUALITY_SENSOR_ENDPOINT, AIR_PURIFIER_ENDPOINT);
SetParentEndpointForEndpoint(TEMPERATURE_SENSOR_ENDPOINT, AIR_PURIFIER_ENDPOINT);
SetParentEndpointForEndpoint(RELATIVE_HUMIDITY_SENSOR_ENDPOINT, AIR_PURIFIER_ENDPOINT);
+ SetParentEndpointForEndpoint(THERMOSTAT_ENDPOINT, AIR_PURIFIER_ENDPOINT);
}
static void InitServer(intptr_t context)
diff --git a/examples/air-purifier-app/cc32xx/BUILD.gn b/examples/air-purifier-app/cc32xx/BUILD.gn
index 51916cc..f79e76c 100755
--- a/examples/air-purifier-app/cc32xx/BUILD.gn
+++ b/examples/air-purifier-app/cc32xx/BUILD.gn
@@ -85,6 +85,7 @@
"${chip_root}/examples/air-purifier-app/air-purifier-common/src/air-purifier-manager.cpp",
"${chip_root}/examples/air-purifier-app/air-purifier-common/src/air-quality-sensor-manager.cpp",
"${chip_root}/examples/air-purifier-app/air-purifier-common/src/filter-delegates.cpp",
+ "${chip_root}/examples/air-purifier-app/air-purifier-common/src/thermostat-manager.cpp",
"${project_dir}/main/AppTask.cpp",
"${project_dir}/main/CHIPDeviceManager.cpp",
"${project_dir}/main/CXXExceptionStubs.cpp",
diff --git a/examples/air-purifier-app/cc32xx/main/AppTask.cpp b/examples/air-purifier-app/cc32xx/main/AppTask.cpp
index e753e5a..0b28425 100644
--- a/examples/air-purifier-app/cc32xx/main/AppTask.cpp
+++ b/examples/air-purifier-app/cc32xx/main/AppTask.cpp
@@ -64,6 +64,7 @@
#define AIR_QUALITY_SENSOR_ENDPOINT 2
#define TEMPERATURE_SENSOR_ENDPOINT 3
#define RELATIVE_HUMIDITY_SENSOR_ENDPOINT 4
+#define THERMOSTAT_ENDPOINT 5
// Added the below three for DNS Server Initialization
using namespace ::chip;
@@ -178,9 +179,11 @@
SetParentEndpointForEndpoint(AIR_QUALITY_SENSOR_ENDPOINT, AIR_PURIFIER_ENDPOINT);
SetParentEndpointForEndpoint(TEMPERATURE_SENSOR_ENDPOINT, AIR_PURIFIER_ENDPOINT);
SetParentEndpointForEndpoint(RELATIVE_HUMIDITY_SENSOR_ENDPOINT, AIR_PURIFIER_ENDPOINT);
+ SetParentEndpointForEndpoint(THERMOSTAT_ENDPOINT, AIR_PURIFIER_ENDPOINT);
AirPurifierManager::InitInstance(EndpointId(AIR_PURIFIER_ENDPOINT), EndpointId(AIR_QUALITY_SENSOR_ENDPOINT),
- EndpointId(TEMPERATURE_SENSOR_ENDPOINT), EndpointId(RELATIVE_HUMIDITY_SENSOR_ENDPOINT));
+ EndpointId(TEMPERATURE_SENSOR_ENDPOINT), EndpointId(RELATIVE_HUMIDITY_SENSOR_ENDPOINT),
+ EndpointId(THERMOSTAT_ENDPOINT));
ConfigurationMgr().LogDeviceConfig();
diff --git a/examples/air-purifier-app/linux/BUILD.gn b/examples/air-purifier-app/linux/BUILD.gn
index 0a0f86c..0f4d2a4 100644
--- a/examples/air-purifier-app/linux/BUILD.gn
+++ b/examples/air-purifier-app/linux/BUILD.gn
@@ -33,6 +33,7 @@
"${chip_root}/examples/air-purifier-app/air-purifier-common/src/air-purifier-manager.cpp",
"${chip_root}/examples/air-purifier-app/air-purifier-common/src/air-quality-sensor-manager.cpp",
"${chip_root}/examples/air-purifier-app/air-purifier-common/src/filter-delegates.cpp",
+ "${chip_root}/examples/air-purifier-app/air-purifier-common/src/thermostat-manager.cpp",
"include/CHIPProjectAppConfig.h",
"main.cpp",
]
diff --git a/examples/air-purifier-app/linux/README.md b/examples/air-purifier-app/linux/README.md
index 88f5be7..d2352bc 100644
--- a/examples/air-purifier-app/linux/README.md
+++ b/examples/air-purifier-app/linux/README.md
@@ -4,9 +4,10 @@
to build and run CHIP Air Purifier Example on A Linux System. This doc is tested
on **Ubuntu 20.04 LTS**.
-The Air Purifier is a composed device with Endpoint 1 being the Air Purifier.
-Endpoint 2 is an Air Quality Sensor, Endpoint 3 is a Relative Humidity Sensor
-and endpoint 4 is a Temperature Sensor.
+The Air Purifier example demonstrates a fully functional Matter Air Purifier
+which is a composed device with Endpoint 1 being the Air Purifier. Endpoint 2 is
+an Air Quality Sensor, Endpoint 3 is a Relative Humidity Sensor, Endpoint 4 is a
+Temperature Sensor and Endpoint 5 is a Thermostat.
To cross-compile this example on x64 host and run on **NXP i.MX 8M Mini**
**EVK**, see the associated
@@ -99,11 +100,11 @@
RX bytes:8609495 acl:14 sco:0 events:217484 errors:0
TX bytes:92185 acl:20 sco:0 commands:5259 errors:0
- - Run Linux Lighting Example App
+ - Run Linux Air Purifier Example App
- $ cd ~/connectedhomeip/examples/lighting-app/linux
- $ sudo out/debug/chip-lighting-app --ble-device [bluetooth device number]
+ $ cd ~/connectedhomeip/examples/air-purifier-app/linux
+ $ sudo out/debug/chip-air-purifier-app --ble-device [bluetooth device number]
# In this example, the device we want to use is hci1
- $ sudo out/debug/chip-lighting-app --ble-device 1
+ $ sudo out/debug/chip-air-purifier-app --ble-device 1
- Test the device using ChipTool on your laptop / workstation etc.
diff --git a/examples/air-purifier-app/linux/main.cpp b/examples/air-purifier-app/linux/main.cpp
index 59ef9cf..98d8d40 100644
--- a/examples/air-purifier-app/linux/main.cpp
+++ b/examples/air-purifier-app/linux/main.cpp
@@ -27,7 +27,7 @@
#define AIR_QUALITY_SENSOR_ENDPOINT 2
#define TEMPERATURE_SENSOR_ENDPOINT 3
#define RELATIVE_HUMIDITY_SENSOR_ENDPOINT 4
-// TODO: Add support for the thermostat endpoint in future PR.
+#define THERMOSTAT_ENDPOINT 5
using namespace chip;
using namespace chip::app;
@@ -48,11 +48,13 @@
void ApplicationInit()
{
AirPurifierManager::InitInstance(EndpointId(AIR_PURIFIER_ENDPOINT), EndpointId(AIR_QUALITY_SENSOR_ENDPOINT),
- EndpointId(TEMPERATURE_SENSOR_ENDPOINT), EndpointId(RELATIVE_HUMIDITY_SENSOR_ENDPOINT));
+ EndpointId(TEMPERATURE_SENSOR_ENDPOINT), EndpointId(RELATIVE_HUMIDITY_SENSOR_ENDPOINT),
+ EndpointId(THERMOSTAT_ENDPOINT));
SetParentEndpointForEndpoint(AIR_QUALITY_SENSOR_ENDPOINT, AIR_PURIFIER_ENDPOINT);
SetParentEndpointForEndpoint(TEMPERATURE_SENSOR_ENDPOINT, AIR_PURIFIER_ENDPOINT);
SetParentEndpointForEndpoint(RELATIVE_HUMIDITY_SENSOR_ENDPOINT, AIR_PURIFIER_ENDPOINT);
+ SetParentEndpointForEndpoint(THERMOSTAT_ENDPOINT, AIR_PURIFIER_ENDPOINT);
}
void ApplicationShutdown()