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 864e3115bc06a9..383ec206a83df7 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 @@ -1294,7 +1294,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1420,11 +1421,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1530,8 +1526,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1575,10 +1570,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1597,8 +1588,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index c4a159841dc100..3e22d18fc3cfe3 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -5073,7 +5073,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -5199,11 +5200,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5309,8 +5305,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5354,10 +5349,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5376,8 +5367,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ @@ -8672,18 +8661,6 @@ endpoint 1 { ram attribute minSetpointDeadBand default = 0x19; ram attribute controlSequenceOfOperation default = 0x04; ram attribute systemMode default = 0x01; - callback attribute presetTypes; - callback attribute scheduleTypes; - ram attribute numberOfPresets default = 0; - ram attribute numberOfSchedules default = 0; - ram attribute numberOfScheduleTransitionPerDay default = 0xFF; - ram attribute activePresetHandle; - ram attribute activeScheduleHandle; - callback attribute presets; - callback attribute schedules; - ram attribute presetsSchedulesEditable; - ram attribute temperatureSetpointHoldPolicy default = 0; - ram attribute setpointHoldExpiryTimestamp; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; 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 2ed20d53a62605..5c91e24632e365 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 @@ -14781,7 +14781,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14797,7 +14797,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14845,7 +14845,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14861,7 +14861,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14877,7 +14877,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14893,7 +14893,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14909,7 +14909,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -16415,214 +16415,6 @@ "maxInterval": 65344, "reportableChange": 0 }, - { - "name": "PresetTypes", - "code": 72, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ScheduleTypes", - "code": 73, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "NumberOfPresets", - "code": 74, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "NumberOfSchedules", - "code": 75, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "NumberOfScheduleTransitionPerDay", - "code": 77, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0xFF", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ActivePresetHandle", - "code": 78, - "mfgCode": null, - "side": "server", - "type": "octet_string", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ActiveScheduleHandle", - "code": 79, - "mfgCode": null, - "side": "server", - "type": "octet_string", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "Presets", - "code": 80, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "Schedules", - "code": 81, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "PresetsSchedulesEditable", - "code": 82, - "mfgCode": null, - "side": "server", - "type": "boolean", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "TemperatureSetpointHoldPolicy", - "code": 83, - "mfgCode": null, - "side": "server", - "type": "TemperatureSetpointHoldPolicyBitmap", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "SetpointHoldExpiryTimestamp", - "code": 84, - "mfgCode": null, - "side": "server", - "type": "epoch_s", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "QueuedPreset", - "code": 85, - "mfgCode": null, - "side": "server", - "type": "QueuedPresetStruct", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "GeneratedCommandList", "code": 65528, diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index 946733b5ebe9da..9cdc5293f8869b 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -3568,7 +3568,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -3694,11 +3695,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -3804,8 +3800,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -3849,10 +3844,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -3871,8 +3862,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter index 1976a0d6af169b..9a2e8eb537e820 100644 --- a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter +++ b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter @@ -1217,7 +1217,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1343,11 +1344,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1453,8 +1449,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1498,10 +1493,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1520,8 +1511,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter index b0011ffb37983b..a7a6e1368b2752 100644 --- a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter +++ b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter @@ -1574,7 +1574,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1700,11 +1701,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1810,8 +1806,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1855,10 +1850,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1877,8 +1868,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter index 5a8aefa22762f6..9e1f73b4609e88 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter @@ -1157,7 +1157,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1283,11 +1284,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1393,8 +1389,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1438,10 +1433,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1460,8 +1451,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter index f7ff21337d4e96..e7175b9e4d940e 100644 --- a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter +++ b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter @@ -1377,7 +1377,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1503,11 +1504,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1613,8 +1609,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1658,10 +1653,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1680,8 +1671,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 9c1a05687d3c6a..2020fc07afa5b5 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -4825,7 +4825,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -4951,11 +4952,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5061,8 +5057,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5106,10 +5101,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5128,8 +5119,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring and controlling the functionality of a thermostat. */ @@ -5186,7 +5175,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -5312,11 +5302,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5422,8 +5407,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5467,10 +5451,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5489,8 +5469,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring the user interface of a thermostat (which may be remote from the thermostat). */ diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index a48b8accff55c5..e36ddc7914dd4d 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -4782,7 +4782,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -4908,11 +4909,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5018,8 +5014,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5063,10 +5058,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5085,8 +5076,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring and controlling the functionality of a thermostat. */ @@ -5143,7 +5132,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -5269,11 +5259,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5379,8 +5364,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5424,10 +5408,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5446,8 +5426,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring the user interface of a thermostat (which may be remote from the thermostat). */ diff --git a/examples/thermostat/linux/BUILD.gn b/examples/thermostat/linux/BUILD.gn index 89d24bff8a0835..71c0eccfcfae50 100644 --- a/examples/thermostat/linux/BUILD.gn +++ b/examples/thermostat/linux/BUILD.gn @@ -20,6 +20,8 @@ executable("thermostat-app") { "include/low-power/LowPowerManager.cpp", "include/low-power/LowPowerManager.h", "main.cpp", + "thermostat-delegate-impl.cpp", + "thermostat-manager.cpp", ] deps = [ @@ -28,6 +30,8 @@ executable("thermostat-app") { "${chip_root}/src/lib", ] + include_dirs = [ "include" ] + cflags = [ "-Wconversion" ] output_dir = root_out_dir diff --git a/examples/thermostat/linux/include/thermostat-delegate-impl.h b/examples/thermostat/linux/include/thermostat-delegate-impl.h new file mode 100644 index 00000000000000..c4daef5fde1d6a --- /dev/null +++ b/examples/thermostat/linux/include/thermostat-delegate-impl.h @@ -0,0 +1,100 @@ +/* + * + * 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. + */ + +#pragma once + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +/** + * The ThermostatDelegate class serves as the instance delegate for storing Presets related information and providing it to the + * Thermostat server code. It also manages the presets attribute and provides methods to write to presets, edit presets, maintain a + * pending presets list and either commit the presets when requested or discard the changes. It also provides APIs to get and set + * the attribute values. + * + */ + +static constexpr uint8_t kMaxNumberOfPresetTypes = 6; + +// TODO: #34556 Support multiple presets of each type. +// We will support only one preset of each preset type. +static constexpr uint8_t kMaxNumberOfPresetsOfEachType = 1; + +class ThermostatDelegate : public Delegate +{ +public: + static inline ThermostatDelegate & GetInstance() { return sInstance; } + + CHIP_ERROR GetPresetTypeAtIndex(size_t index, Structs::PresetTypeStruct::Type & presetType) override; + + uint8_t GetNumberOfPresets() override; + + CHIP_ERROR GetPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) override; + + CHIP_ERROR GetActivePresetHandle(MutableByteSpan & activePresetHandle) override; + + CHIP_ERROR SetActivePresetHandle(const DataModel::Nullable & newActivePresetHandle) override; + + CHIP_ERROR AppendToPendingPresetList(const Structs::PresetStruct::Type & preset) override; + + CHIP_ERROR GetPendingPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) override; + + CHIP_ERROR ApplyPendingPresets() override; + + void ClearPendingPresetList() override; + +private: + static ThermostatDelegate sInstance; + + ThermostatDelegate(); + ~ThermostatDelegate() = default; + + ThermostatDelegate(const ThermostatDelegate &) = delete; + ThermostatDelegate & operator=(const ThermostatDelegate &) = delete; + + /** + * @brief Initializes the preset types array with all preset types corresponding to PresetScenarioEnum. + */ + void InitializePresetTypes(); + + /** + * @brief Initializes the presets array with some sample presets for testing. + */ + void InitializePresets(); + + uint8_t mNumberOfPresets; + + Structs::PresetTypeStruct::Type mPresetTypes[kMaxNumberOfPresetTypes]; + PresetStructWithOwnedMembers mPresets[kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType]; + PresetStructWithOwnedMembers mPendingPresets[kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType]; + + uint8_t mNextFreeIndexInPendingPresetsList; + uint8_t mNextFreeIndexInPresetsList; + + uint8_t mActivePresetHandleData[kPresetHandleSize]; + size_t mActivePresetHandleDataSize; +}; + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/thermostat/linux/include/thermostat-manager.h b/examples/thermostat/linux/include/thermostat-manager.h new file mode 100644 index 00000000000000..274f66c66917cf --- /dev/null +++ b/examples/thermostat/linux/include/thermostat-manager.h @@ -0,0 +1,73 @@ +/* + * + * 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. + */ + +#pragma once + +#include + +class ThermostatManager +{ +public: + CHIP_ERROR Init(); + + /// @brief Callback called when any attribute changed on the device + void AttributeChangeHandler(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t * value, uint16_t size); + + chip::app::Clusters::Thermostat::SystemModeEnum GetSystemMode(); + chip::app::Clusters::Thermostat::ThermostatRunningModeEnum GetRunningMode(); + int16_t GetCurrentTemperature(); + int16_t GetCurrentHeatingSetPoint(); + int16_t GetCurrentCoolingSetPoint(); + uint8_t GetNumberOfPresets(); + CHIP_ERROR SetSystemMode(chip::app::Clusters::Thermostat::SystemModeEnum systemMode); + CHIP_ERROR SetRunningMode(chip::app::Clusters::Thermostat::ThermostatRunningModeEnum runningMode); + CHIP_ERROR SetCurrentTemperature(int16_t temperature); + CHIP_ERROR SetCurrentHeatingSetPoint(int16_t heatingSetpoint); + CHIP_ERROR SetCurrentCoolingSetPoint(int16_t coolingSetpoint); + +private: + friend ThermostatManager & ThermostatMgr(); + + chip::app::Clusters::Thermostat::SystemModeEnum mSystemMode; + chip::app::Clusters::Thermostat::ThermostatRunningModeEnum mRunningMode; + int16_t mLocalTemperature; + int16_t mOccupiedCoolingSetpoint; + int16_t mOccupiedHeatingSetpoint; + uint8_t mOccupiedSetback; + + static ThermostatManager sThermostatMgr; + + /// @brief attribute handler for the thermostat endpoint + void ThermostatEndpointAttributeChangeHandler(chip::ClusterId clusterId, chip::AttributeId attributeId, uint8_t * value, + uint16_t size); + void ThermostatClusterAttributeChangeHandler(chip::AttributeId attributeId, uint8_t * value, uint16_t size); + void LocalTemperatureMeasurementEndpointAttributeChangeHandler(chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t * value, uint16_t size); + void LocalTemperatureMeasurementClusterAttributeChangeHandler(chip::AttributeId attributeId, uint8_t * value, uint16_t size); + + /// @brief Main method that evaluates the current thermostat state and updates attributes + void EvalThermostatState(); + void UpdateRunningModeForHeating(); + void UpdateRunningModeForCooling(); +}; + +inline ThermostatManager & ThermostatMgr() +{ + return ThermostatManager::sThermostatMgr; +} diff --git a/examples/thermostat/linux/main.cpp b/examples/thermostat/linux/main.cpp index b9f82696e8ce79..2279f02bef3963 100644 --- a/examples/thermostat/linux/main.cpp +++ b/examples/thermostat/linux/main.cpp @@ -22,6 +22,8 @@ #include #include +#include "thermostat-manager.h" + using namespace chip; using namespace chip::app; // using namespace chip::app::Clusters; @@ -74,7 +76,19 @@ void ApplicationShutdown() {} int main(int argc, char * argv[]) { - VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0); + if (ChipLinuxAppInit(argc, argv) != 0) + { + return -1; + } + ChipLogProgress(Zcl, "Starting Thermostat Manager"); + CHIP_ERROR err = ThermostatManager().Init(); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Failed to initialize thermostat manager: %" CHIP_ERROR_FORMAT, err.Format()); + chip::DeviceLayer::PlatformMgr().Shutdown(); + return -1; + } ChipLinuxAppMainLoop(); return 0; } diff --git a/examples/thermostat/linux/thermostat-delegate-impl.cpp b/examples/thermostat/linux/thermostat-delegate-impl.cpp new file mode 100644 index 00000000000000..fa7bd9a259a475 --- /dev/null +++ b/examples/thermostat/linux/thermostat-delegate-impl.cpp @@ -0,0 +1,234 @@ +/* + * + * 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 "include/thermostat-delegate-impl.h" + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters::Thermostat; +using namespace chip::app::Clusters::Thermostat::Structs; + +ThermostatDelegate ThermostatDelegate::sInstance; + +namespace { + +/** + * @brief Checks if the presets are matching i.e the presetHandles are the same. + * + * @param[in] preset The preset to check. + * @param[in] presetToMatch The preset to match with. + * + * @return true If the presets match, false otherwise. If both preset handles are null, returns false + */ +bool PresetHandlesExistAndMatch(const PresetStructWithOwnedMembers & preset, const PresetStructWithOwnedMembers & presetToMatch) +{ + return !preset.GetPresetHandle().IsNull() && !presetToMatch.GetPresetHandle().IsNull() && + preset.GetPresetHandle().Value().data_equal(presetToMatch.GetPresetHandle().Value()); +} + +} // anonymous namespace + +ThermostatDelegate::ThermostatDelegate() +{ + mNumberOfPresets = kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType; + mNextFreeIndexInPresetsList = 0; + mNextFreeIndexInPendingPresetsList = 0; + + InitializePresetTypes(); + InitializePresets(); + + memset(mActivePresetHandleData, 0, sizeof(mActivePresetHandleData)); + mActivePresetHandleDataSize = 0; +} + +void ThermostatDelegate::InitializePresetTypes() +{ + PresetScenarioEnum presetScenarioEnumArray[kMaxNumberOfPresetTypes] = { + PresetScenarioEnum::kOccupied, PresetScenarioEnum::kUnoccupied, PresetScenarioEnum::kSleep, + PresetScenarioEnum::kWake, PresetScenarioEnum::kVacation, PresetScenarioEnum::kGoingToSleep + }; + static_assert(ArraySize(presetScenarioEnumArray) <= ArraySize(mPresetTypes)); + + uint8_t index = 0; + for (PresetScenarioEnum presetScenario : presetScenarioEnumArray) + { + mPresetTypes[index].presetScenario = presetScenario; + mPresetTypes[index].numberOfPresets = kMaxNumberOfPresetsOfEachType; + mPresetTypes[index].presetTypeFeatures = + (presetScenario == PresetScenarioEnum::kOccupied || presetScenario == PresetScenarioEnum::kUnoccupied) + ? PresetTypeFeaturesBitmap::kAutomatic + : PresetTypeFeaturesBitmap::kSupportsNames; + index++; + } +} + +void ThermostatDelegate::InitializePresets() +{ + // Initialize the presets with 2 built in presets - occupied and unoccupied. + PresetScenarioEnum presetScenarioEnumArray[2] = { PresetScenarioEnum::kOccupied, PresetScenarioEnum::kUnoccupied }; + static_assert(ArraySize(presetScenarioEnumArray) <= ArraySize(mPresets)); + + uint8_t index = 0; + for (PresetScenarioEnum presetScenario : presetScenarioEnumArray) + { + mPresets[index].SetPresetScenario(presetScenario); + + // Set the preset handle to the preset scenario value as a unique id. + const uint8_t handle[] = { static_cast(presetScenario) }; + mPresets[index].SetPresetHandle(DataModel::MakeNullable(ByteSpan(handle))); + mPresets[index].SetName(NullOptional); + int16_t coolingSetpointValue = 2500 + index * 100; + mPresets[index].SetCoolingSetpoint(MakeOptional(coolingSetpointValue)); + + int16_t heatingSetpointValue = 2100 - index * 100; + mPresets[index].SetHeatingSetpoint(MakeOptional(heatingSetpointValue)); + mPresets[index].SetBuiltIn(DataModel::MakeNullable(true)); + index++; + } + + // Set the value of the next free index in the presets list. + mNextFreeIndexInPresetsList = index; +} + +CHIP_ERROR ThermostatDelegate::GetPresetTypeAtIndex(size_t index, PresetTypeStruct::Type & presetType) +{ + if (index < ArraySize(mPresetTypes)) + { + presetType = mPresetTypes[index]; + return CHIP_NO_ERROR; + } + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} + +uint8_t ThermostatDelegate::GetNumberOfPresets() +{ + return mNumberOfPresets; +} + +CHIP_ERROR ThermostatDelegate::GetPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) +{ + if (index < mNextFreeIndexInPresetsList) + { + preset = mPresets[index]; + return CHIP_NO_ERROR; + } + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} + +CHIP_ERROR ThermostatDelegate::GetActivePresetHandle(MutableByteSpan & activePresetHandle) +{ + return CopySpanToMutableSpan(ByteSpan(mActivePresetHandleData, mActivePresetHandleDataSize), activePresetHandle); +} + +CHIP_ERROR ThermostatDelegate::SetActivePresetHandle(const DataModel::Nullable & newActivePresetHandle) +{ + if (!newActivePresetHandle.IsNull()) + { + size_t newActivePresetHandleSize = newActivePresetHandle.Value().size(); + if (newActivePresetHandleSize > sizeof(mActivePresetHandleData)) + { + ChipLogError(NotSpecified, + "Failed to set ActivePresetHandle. newActivePresetHandle size %u is larger than preset handle size %u", + static_cast(newActivePresetHandleSize), static_cast(kPresetHandleSize)); + return CHIP_ERROR_NO_MEMORY; + } + memcpy(mActivePresetHandleData, newActivePresetHandle.Value().data(), newActivePresetHandleSize); + mActivePresetHandleDataSize = newActivePresetHandleSize; + ChipLogDetail(NotSpecified, "Set ActivePresetHandle to "); + ChipLogByteSpan(NotSpecified, newActivePresetHandle.Value()); + } + else + { + memset(mActivePresetHandleData, 0, sizeof(mActivePresetHandleData)); + mActivePresetHandleDataSize = 0; + ChipLogDetail(NotSpecified, "Clear ActivePresetHandle"); + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR ThermostatDelegate::AppendToPendingPresetList(const PresetStruct::Type & preset) +{ + if (mNextFreeIndexInPendingPresetsList < ArraySize(mPendingPresets)) + { + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetPresetScenario(preset.presetScenario); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetPresetHandle(preset.presetHandle); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetName(preset.name); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetCoolingSetpoint(preset.coolingSetpoint); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetHeatingSetpoint(preset.heatingSetpoint); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetBuiltIn(preset.builtIn); + mNextFreeIndexInPendingPresetsList++; + return CHIP_NO_ERROR; + } + return CHIP_ERROR_WRITE_FAILED; +} + +CHIP_ERROR ThermostatDelegate::GetPendingPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) +{ + if (index < mNextFreeIndexInPendingPresetsList) + { + preset = mPendingPresets[index]; + return CHIP_NO_ERROR; + } + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} + +CHIP_ERROR ThermostatDelegate::ApplyPendingPresets() +{ + + // TODO: #34546 - Need to support deletion of presets that are removed from Presets. + for (uint8_t indexInPendingPresets = 0; indexInPendingPresets < mNextFreeIndexInPendingPresetsList; indexInPendingPresets++) + { + const PresetStructWithOwnedMembers & pendingPreset = mPendingPresets[indexInPendingPresets]; + + bool found = false; + for (uint8_t indexInPresets = 0; indexInPresets < mNextFreeIndexInPresetsList; indexInPresets++) + { + if (PresetHandlesExistAndMatch(mPresets[indexInPresets], pendingPreset)) + { + found = true; + + // Replace the preset with the pending preset + mPresets[indexInPresets] = pendingPreset; + } + } + + // If pending preset was not found in the Presets list, append to the Presets list. + if (!found) + { + + mPresets[mNextFreeIndexInPresetsList] = pendingPreset; + + // TODO: #34556 Since we support only one preset of each type, using the octet string containing the preset scenario + // suffices as the unique preset handle. Need to fix this to actually provide unique handles once multiple presets of + // each type are supported. + const uint8_t handle[] = { static_cast(pendingPreset.GetPresetScenario()) }; + mPresets[mNextFreeIndexInPresetsList].SetPresetHandle(DataModel::MakeNullable(ByteSpan(handle))); + mNextFreeIndexInPresetsList++; + } + } + return CHIP_NO_ERROR; +} + +void ThermostatDelegate::ClearPendingPresetList() +{ + mNextFreeIndexInPendingPresetsList = 0; +} diff --git a/examples/thermostat/linux/thermostat-manager.cpp b/examples/thermostat/linux/thermostat-manager.cpp new file mode 100644 index 00000000000000..00266161007d59 --- /dev/null +++ b/examples/thermostat/linux/thermostat-manager.cpp @@ -0,0 +1,515 @@ +/* + * + * 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. + */ + +/********************************************************** + * Includes + *********************************************************/ + +#include "include/thermostat-manager.h" +#include "include/thermostat-delegate-impl.h" + +#include +#include +#include +#include + +/********************************************************** + * Defines and Constants + *********************************************************/ + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::Controller; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Thermostat; +using namespace chip::app::Clusters::Thermostat::Structs; +using namespace chip::app::Clusters::Thermostat::Attributes; +using namespace chip::app::Clusters::TemperatureMeasurement; +using namespace chip::app::Clusters::TemperatureMeasurement::Attributes; +using namespace Protocols::InteractionModel; + +using namespace chip::DeviceLayer; + +static constexpr EndpointId kThermostatEndpoint = 1; + +static constexpr uint16_t kMaxIntervalCeilingSeconds = 3600; + +static const char * SystemModeString(SystemModeEnum systemMode); +static const char * RunningModeString(ThermostatRunningModeEnum runningMode); + +/********************************************************** + * Variable declarations + *********************************************************/ + +ThermostatManager ThermostatManager::sThermostatMgr; + +namespace { + +CHIP_ERROR ChipErrorFromStatusCode(Status status) +{ + StatusIB statusIB(status); + return statusIB.ToChipError(); +} + +template +static void OnAttributeChangeReported(const ConcreteDataAttributePath & path, const DecodableAttributeType & value); + +template <> +void OnAttributeChangeReported(const ConcreteDataAttributePath & path, + const MeasuredValue::TypeInfo::DecodableType & value) +{ + ClusterId clusterId = path.mClusterId; + if (clusterId != TemperatureMeasurement::Id) + { + ChipLogError(AppServer, + "Attribute change reported for TemperatureMeasurement cluster on incorrect cluster id " ChipLogFormatMEI, + ChipLogValueMEI(clusterId)); + return; + } + + AttributeId attributeId = path.mAttributeId; + if (attributeId != MeasuredValue::Id) + { + ChipLogError(AppServer, + "Attribute change reported for TemperatureMeasurement cluster for incorrect attribute" ChipLogFormatMEI, + ChipLogValueMEI(attributeId)); + return; + } + + if (!value.IsNull()) + { + ChipLogDetail(AppServer, "Attribute change reported for TemperatureMeasurement cluster - MeasuredValue is %d", + value.Value()); + } +} + +static void OnError(const ConcreteDataAttributePath * path, ChipError err) +{ + ChipLogError(AppServer, + "Subscribing to cluster Id " ChipLogFormatMEI " and attribute Id " ChipLogFormatMEI + " failed with error %" CHIP_ERROR_FORMAT, + ChipLogValueMEI(path->mClusterId), ChipLogValueMEI(path->mAttributeId), err.Format()); +} + +static void OnSubscriptionEstablished(const ReadClient & client, unsigned int value) +{ + ChipLogDetail(AppServer, "OnSubscriptionEstablished with subscription Id: %d", value); +} + +template +void SubscribeToAttribute(ClusterId clusterId, AttributeId attributeId, const EmberBindingTableEntry & binding, + OperationalDeviceProxy * peer_device) +{ + VerifyOrReturn(peer_device->GetSecureSession().HasValue(), + ChipLogError(AppServer, "SubscribeToAttribute failed. Secure session is null")); + + SubscribeAttribute( + peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, clusterId, attributeId, + &OnAttributeChangeReported, &OnError, 0, kMaxIntervalCeilingSeconds, &OnSubscriptionEstablished, + nullptr, true /* fabricFiltered */, false /* keepExistingSubscription */); +} + +static void ThermostatBoundDeviceChangedHandler(const EmberBindingTableEntry & binding, OperationalDeviceProxy * peer_device, + void * context) +{ + VerifyOrReturn(binding.clusterId.has_value(), ChipLogError(AppServer, "Cluster Id is null")); + ClusterId clusterId = binding.clusterId.value(); + + switch (clusterId) + { + case TemperatureMeasurement::Id: + + // Subscribe to the MeasuredValue attribute + SubscribeToAttribute(clusterId, MeasuredValue::Id, binding, peer_device); + break; + default: + ChipLogError(AppServer, "Unsupported Cluster Id"); + break; + } +} + +void NotifyBoundClusterChangedForAllClusters() +{ + BindingManager::GetInstance().NotifyBoundClusterChanged(kThermostatEndpoint, TemperatureMeasurement::Id, nullptr); +} + +static void OnPlatformChipDeviceEvent(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) +{ + if (event->Type == DeviceLayer::DeviceEventType::kBindingsChangedViaCluster) + { + NotifyBoundClusterChangedForAllClusters(); + } +} + +void InitBindingManager(intptr_t context) +{ + auto & server = Server::GetInstance(); + CHIP_ERROR error = BindingManager::GetInstance().Init( + { &server.GetFabricTable(), server.GetCASESessionManager(), &server.GetPersistentStorage() }); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Failed to init binding manager"); + } + + BindingManager::GetInstance().RegisterBoundDeviceChangedHandler(ThermostatBoundDeviceChangedHandler); + NotifyBoundClusterChangedForAllClusters(); +} + +} // anonymous namespace + +CHIP_ERROR ThermostatManager::Init() +{ + // Init binding manager + + DeviceLayer::PlatformMgr().AddEventHandler(OnPlatformChipDeviceEvent, reinterpret_cast(this)); + DeviceLayer::PlatformMgr().ScheduleWork(InitBindingManager); + + mLocalTemperature = GetCurrentTemperature(); + mSystemMode = GetSystemMode(); + mRunningMode = GetRunningMode(); + mOccupiedCoolingSetpoint = GetCurrentCoolingSetPoint(); + mOccupiedHeatingSetpoint = GetCurrentHeatingSetPoint(); + // TODO: Gotta expose this properly on attribute + mOccupiedSetback = 5; // 0.5 C + + ChipLogError(AppServer, + "Initialized a thermostat with \n " + "mSystemMode: %u (%s) \n mRunningMode: %u (%s) \n mLocalTemperature: %d \n mOccupiedHeatingSetpoint: %d \n " + "mOccupiedCoolingSetpoint: %d" + "NumberOfPresets: %d", + to_underlying(mSystemMode), SystemModeString(mSystemMode), to_underlying(mRunningMode), + RunningModeString(mRunningMode), mLocalTemperature, mOccupiedHeatingSetpoint, mOccupiedCoolingSetpoint, + GetNumberOfPresets()); + + // TODO: Should this be called later? + EvalThermostatState(); + + return CHIP_NO_ERROR; +} + +void ThermostatManager::AttributeChangeHandler(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, uint8_t * value, + uint16_t size) +{ + switch (endpointId) + { + case kThermostatEndpoint: + ThermostatEndpointAttributeChangeHandler(clusterId, attributeId, value, size); + break; + + default: + ChipLogError(AppServer, "Attribute change reported for Thermostat on incorrect endpoint. Ignoring."); + break; + } +} + +void ThermostatManager::ThermostatEndpointAttributeChangeHandler(ClusterId clusterId, AttributeId attributeId, uint8_t * value, + uint16_t size) +{ + switch (clusterId) + { + case Thermostat::Id: + ThermostatClusterAttributeChangeHandler(attributeId, value, size); + break; + + default: + ChipLogError(AppServer, + "Attribute change reported for Thermostat on incorrect cluster for the thermostat endpoint. Ignoring."); + break; + } +} + +void ThermostatManager::ThermostatClusterAttributeChangeHandler(AttributeId attributeId, uint8_t * value, uint16_t size) +{ + switch (attributeId) + { + case LocalTemperature::Id: { + memcpy(&mLocalTemperature, value, size); + ChipLogError(AppServer, "Local temperature changed to %d", mLocalTemperature); + EvalThermostatState(); + } + break; + + case OccupiedCoolingSetpoint::Id: { + memcpy(&mOccupiedCoolingSetpoint, value, size); + ChipLogError(AppServer, "Cooling temperature changed to %d", mOccupiedCoolingSetpoint); + EvalThermostatState(); + } + break; + + case OccupiedHeatingSetpoint::Id: { + memcpy(&mOccupiedHeatingSetpoint, value, size); + ChipLogError(AppServer, "Heating temperature changed to %d", mOccupiedHeatingSetpoint); + EvalThermostatState(); + } + break; + + case SystemMode::Id: { + mSystemMode = static_cast(*value); + ChipLogError(AppServer, "System mode changed to %u (%s)", *value, SystemModeString(mSystemMode)); + EvalThermostatState(); + } + break; + + case ThermostatRunningMode::Id: { + mRunningMode = static_cast(*value); + ChipLogError(AppServer, "Running mode changed to %u (%s)", *value, RunningModeString(mRunningMode)); + } + break; + + default: { + ChipLogError(AppServer, "Unhandled thermostat attribute %x", attributeId); + return; + } + break; + } +} + +SystemModeEnum ThermostatManager::GetSystemMode() +{ + SystemModeEnum systemMode; + SystemMode::Get(kThermostatEndpoint, &systemMode); + return systemMode; +} + +ThermostatRunningModeEnum ThermostatManager::GetRunningMode() +{ + ThermostatRunningModeEnum runningMode; + ThermostatRunningMode::Get(kThermostatEndpoint, &runningMode); + return runningMode; +} + +int16_t ThermostatManager::GetCurrentTemperature() +{ + DataModel::Nullable currentTemperature; + currentTemperature.SetNull(); + LocalTemperature::Get(kThermostatEndpoint, currentTemperature); + return currentTemperature.ValueOr(0); +} + +int16_t ThermostatManager::GetCurrentHeatingSetPoint() +{ + int16_t heatingSetpoint; + OccupiedHeatingSetpoint::Get(kThermostatEndpoint, &heatingSetpoint); + return heatingSetpoint; +} + +int16_t ThermostatManager::GetCurrentCoolingSetPoint() +{ + int16_t coolingSetpoint; + OccupiedCoolingSetpoint::Get(kThermostatEndpoint, &coolingSetpoint); + return coolingSetpoint; +} + +uint8_t ThermostatManager::GetNumberOfPresets() +{ + return ThermostatDelegate::GetInstance().GetNumberOfPresets(); +} + +CHIP_ERROR ThermostatManager::SetSystemMode(SystemModeEnum systemMode) +{ + uint8_t systemModeValue = to_underlying(systemMode); + if (mSystemMode == systemMode) + { + ChipLogDetail(AppServer, "Already in system mode: %u (%s)", systemModeValue, SystemModeString(systemMode)); + return CHIP_NO_ERROR; + } + + ChipLogError(AppServer, "Setting system mode: %u (%s)", systemModeValue, SystemModeString(systemMode)); + return ChipErrorFromStatusCode(SystemMode::Set(kThermostatEndpoint, systemMode)); +} + +CHIP_ERROR ThermostatManager::SetRunningMode(ThermostatRunningModeEnum runningMode) +{ + uint8_t runningModeValue = to_underlying(runningMode); + if (mRunningMode == runningMode) + { + ChipLogDetail(AppServer, "Already in running mode: %u (%s)", runningModeValue, RunningModeString(runningMode)); + return CHIP_NO_ERROR; + } + + ChipLogError(AppServer, "Setting running mode: %u (%s)", runningModeValue, RunningModeString(runningMode)); + return ChipErrorFromStatusCode(ThermostatRunningMode::Set(kThermostatEndpoint, runningMode)); +} + +CHIP_ERROR ThermostatManager::SetCurrentTemperature(int16_t temperature) +{ + return ChipErrorFromStatusCode(LocalTemperature::Set(kThermostatEndpoint, temperature)); +} + +CHIP_ERROR ThermostatManager::SetCurrentHeatingSetPoint(int16_t heatingSetpoint) +{ + return ChipErrorFromStatusCode(OccupiedHeatingSetpoint::Set(kThermostatEndpoint, heatingSetpoint)); +} + +CHIP_ERROR ThermostatManager::SetCurrentCoolingSetPoint(int16_t coolingSetpoint) +{ + return ChipErrorFromStatusCode(OccupiedCoolingSetpoint::Set(kThermostatEndpoint, coolingSetpoint)); +} + +void ThermostatManager::EvalThermostatState() +{ + ChipLogError(AppServer, + "Eval Thermostat Running Mode \n " + "mSystemMode: %u (%s) \n mRunningMode: %u (%s) \n mLocalTemperature: %d \n mOccupiedHeatingSetpoint: %d \n " + "mOccupiedCoolingSetpoint: %d", + to_underlying(mSystemMode), SystemModeString(mSystemMode), to_underlying(mRunningMode), + RunningModeString(mRunningMode), mLocalTemperature, mOccupiedHeatingSetpoint, mOccupiedCoolingSetpoint); + + switch (mSystemMode) + { + case SystemModeEnum::kOff: { + SetRunningMode(ThermostatRunningModeEnum::kOff); + break; + } + case SystemModeEnum::kHeat: { + UpdateRunningModeForHeating(); + break; + } + case SystemModeEnum::kCool: { + UpdateRunningModeForCooling(); + break; + } + case SystemModeEnum::kAuto: { + UpdateRunningModeForHeating(); + UpdateRunningModeForCooling(); + break; + } + default: + break; + } +} + +void ThermostatManager::UpdateRunningModeForHeating() +{ + const int16_t heatingOnThreshold = mOccupiedHeatingSetpoint - mOccupiedSetback * 10; + const int16_t heatingOffThreshold = mOccupiedHeatingSetpoint + mOccupiedSetback * 10; + + if (mRunningMode == ThermostatRunningModeEnum::kHeat) + { + if (mLocalTemperature >= heatingOffThreshold) + { + ChipLogDetail(AppServer, "Eval Heat - Turning off"); + SetRunningMode(ThermostatRunningModeEnum::kOff); + } + else + { + ChipLogDetail(AppServer, "Eval Heat - Keep Heating"); + } + } + else + { + if (mLocalTemperature <= heatingOnThreshold) + { + ChipLogDetail(AppServer, "Eval Heat - Turn on"); + SetRunningMode(ThermostatRunningModeEnum::kHeat); + } + else + { + ChipLogDetail(AppServer, "Eval Heat - Nothing to do"); + } + } +} + +void ThermostatManager::UpdateRunningModeForCooling() +{ + const int16_t coolingOffThreshold = mOccupiedCoolingSetpoint - mOccupiedSetback * 10; + const int16_t coolingOnThreshold = mOccupiedCoolingSetpoint + mOccupiedSetback * 10; + + if (mRunningMode == ThermostatRunningModeEnum::kCool) + { + if (mLocalTemperature <= coolingOffThreshold) + { + ChipLogDetail(AppServer, "Eval Cool - Turning off"); + SetRunningMode(ThermostatRunningModeEnum::kOff); + } + else + { + ChipLogDetail(AppServer, "Eval Cool - Keep Cooling"); + } + } + else + { + if (mLocalTemperature >= coolingOnThreshold) + { + ChipLogDetail(AppServer, "Eval Cool - Turn on"); + SetRunningMode(ThermostatRunningModeEnum::kCool); + } + else + { + ChipLogDetail(AppServer, "Eval Cool - Nothing to do"); + } + } +} + +static const char * SystemModeString(SystemModeEnum systemMode) +{ + switch (systemMode) + { + case SystemModeEnum::kOff: + return "Off"; + case SystemModeEnum::kAuto: + return "Auto"; + case SystemModeEnum::kCool: + return "Cool"; + case SystemModeEnum::kHeat: + return "Heat"; + default: + return "Unknown"; + } +} + +static const char * RunningModeString(ThermostatRunningModeEnum runningMode) +{ + switch (runningMode) + { + case ThermostatRunningModeEnum::kOff: + return "Off"; + case ThermostatRunningModeEnum::kCool: + return "Cool"; + case ThermostatRunningModeEnum::kHeat: + return "Heat"; + default: + return "Unknown"; + } +} + +void MatterPostAttributeChangeCallback(const ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, uint8_t * value) +{ + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + ChipLogProgress(AppServer, "Cluster callback: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + ChipLogProgress(AppServer, + "Attribute ID changed: " ChipLogFormatMEI " Endpoint: %d ClusterId: " ChipLogFormatMEI + " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), attributePath.mEndpointId, ChipLogValueMEI(clusterId), type, *value, size); + + ThermostatMgr().AttributeChangeHandler(attributePath.mEndpointId, clusterId, attributeId, value, size); +} + +void emberAfThermostatClusterInitCallback(EndpointId endpoint) +{ + // Register the delegate for the Thermostat + auto & delegate = ThermostatDelegate::GetInstance(); + + // Set the default delegate for endpoint kThermostatEndpoint. + VerifyOrDie(endpoint == kThermostatEndpoint); + SetDefaultDelegate(endpoint, &delegate); +} diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter index 00917f2d9a593e..79df2d10f6689a 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter @@ -1968,7 +1968,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -2094,11 +2095,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -2204,8 +2200,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2249,10 +2244,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -2271,8 +2262,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } endpoint 0 { diff --git a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter index a8a65c2c4ad611..2de3fe3041a337 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter @@ -1879,7 +1879,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -2005,11 +2006,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -2115,8 +2111,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2160,10 +2155,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -2182,8 +2173,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } endpoint 0 { diff --git a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter index a775e536ac841e..b9e0674ccb94d1 100644 --- a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter +++ b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter @@ -1576,7 +1576,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1702,11 +1703,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1812,8 +1808,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1857,10 +1852,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1879,8 +1870,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring the user interface of a thermostat (which may be remote from the thermostat). */ diff --git a/examples/thermostat/thermostat-common/thermostat.matter b/examples/thermostat/thermostat-common/thermostat.matter index 2312df8c61fdc1..a7221adec0d64f 100644 --- a/examples/thermostat/thermostat-common/thermostat.matter +++ b/examples/thermostat/thermostat-common/thermostat.matter @@ -1756,7 +1756,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1882,11 +1883,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1992,8 +1988,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2037,10 +2032,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -2059,8 +2050,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring the user interface of a thermostat (which may be remote from the thermostat). */ @@ -2505,13 +2494,22 @@ endpoint 1 { ram attribute minSetpointDeadBand default = 0x19; ram attribute controlSequenceOfOperation default = 0x04; persist attribute systemMode default = 0x01; + callback attribute presetTypes; + ram attribute numberOfPresets default = 0; + ram attribute activePresetHandle; + callback attribute presets; + ram attribute presetsSchedulesEditable; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; - ram attribute featureMap default = 0x23; + ram attribute featureMap default = 0x123; ram attribute clusterRevision default = 6; handle command SetpointRaiseLower; + handle command SetActivePresetRequest; + handle command StartPresetsSchedulesEditRequest; + handle command CancelPresetsSchedulesEditRequest; + handle command CommitPresetsSchedulesRequest; } server cluster ThermostatUserInterfaceConfiguration { diff --git a/examples/thermostat/thermostat-common/thermostat.zap b/examples/thermostat/thermostat-common/thermostat.zap index 288a84a921636c..483b79d7d434f5 100644 --- a/examples/thermostat/thermostat-common/thermostat.zap +++ b/examples/thermostat/thermostat-common/thermostat.zap @@ -4659,6 +4659,38 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "SetActivePresetRequest", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StartPresetsSchedulesEditRequest", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CancelPresetsSchedulesEditRequest", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommitPresetsSchedulesRequest", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -4886,6 +4918,86 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "PresetTypes", + "code": 72, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NumberOfPresets", + "code": 74, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActivePresetHandle", + "code": 78, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Presets", + "code": 80, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PresetsSchedulesEditable", + "code": 82, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -4944,7 +5056,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x23", + "defaultValue": "0x123", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h index f2c082b1d0d4a1..c60950077fb372 100644 --- a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h +++ b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h @@ -355,7 +355,7 @@ } // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 1056 +#define GENERATED_ATTRIBUTE_COUNT 1055 #define GENERATED_ATTRIBUTES \ { \ \ @@ -1400,8 +1400,7 @@ { ZAP_EMPTY_DEFAULT(), 0x00000051, 0, ZAP_TYPE(ARRAY), \ ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* Schedules */ \ { ZAP_EMPTY_DEFAULT(), 0x00000052, 1, ZAP_TYPE(BOOLEAN), 0 }, /* PresetsSchedulesEditable */ \ - { ZAP_SIMPLE_DEFAULT(0), 0x00000053, 1, ZAP_TYPE(BITMAP8), 0 }, /* TemperatureSetpointHoldPolicy */ \ - { ZAP_EMPTY_DEFAULT(), 0x00000054, 4, ZAP_TYPE(EPOCH_S), \ + { ZAP_SIMPLE_DEFAULT(0), 0x00000053, 4, ZAP_TYPE(EPOCH_S), \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* SetpointHoldExpiryTimestamp */ \ { ZAP_SIMPLE_DEFAULT(0x0023), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ { ZAP_SIMPLE_DEFAULT(6), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ @@ -3749,8 +3748,8 @@ /* Endpoint: 1, Cluster: Thermostat (server) */ \ .clusterId = 0x00000201, \ .attributes = ZAP_ATTRIBUTE_INDEX(616), \ - .attributeCount = 28, \ - .clusterSize = 74, \ + .attributeCount = 27, \ + .clusterSize = 73, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ .functions = chipFuncArrayThermostatServer, \ .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 241 ), \ @@ -3761,7 +3760,7 @@ { \ /* Endpoint: 1, Cluster: Fan Control (server) */ \ .clusterId = 0x00000202, \ - .attributes = ZAP_ATTRIBUTE_INDEX(644), \ + .attributes = ZAP_ATTRIBUTE_INDEX(643), \ .attributeCount = 14, \ .clusterSize = 18, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ @@ -3774,7 +3773,7 @@ { \ /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \ .clusterId = 0x00000204, \ - .attributes = ZAP_ATTRIBUTE_INDEX(658), \ + .attributes = ZAP_ATTRIBUTE_INDEX(657), \ .attributeCount = 5, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ @@ -3787,7 +3786,7 @@ { \ /* Endpoint: 1, Cluster: Color Control (server) */ \ .clusterId = 0x00000300, \ - .attributes = ZAP_ATTRIBUTE_INDEX(663), \ + .attributes = ZAP_ATTRIBUTE_INDEX(662), \ .attributeCount = 54, \ .clusterSize = 345, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(SHUTDOWN_FUNCTION), \ @@ -3800,7 +3799,7 @@ { \ /* Endpoint: 1, Cluster: Ballast Configuration (server) */ \ .clusterId = 0x00000301, \ - .attributes = ZAP_ATTRIBUTE_INDEX(717), \ + .attributes = ZAP_ATTRIBUTE_INDEX(716), \ .attributeCount = 16, \ .clusterSize = 58, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3813,7 +3812,7 @@ { \ /* Endpoint: 1, Cluster: Illuminance Measurement (server) */ \ .clusterId = 0x00000400, \ - .attributes = ZAP_ATTRIBUTE_INDEX(733), \ + .attributes = ZAP_ATTRIBUTE_INDEX(732), \ .attributeCount = 7, \ .clusterSize = 15, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3826,7 +3825,7 @@ { \ /* Endpoint: 1, Cluster: Temperature Measurement (server) */ \ .clusterId = 0x00000402, \ - .attributes = ZAP_ATTRIBUTE_INDEX(740), \ + .attributes = ZAP_ATTRIBUTE_INDEX(739), \ .attributeCount = 6, \ .clusterSize = 14, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3839,7 +3838,7 @@ { \ /* Endpoint: 1, Cluster: Pressure Measurement (server) */ \ .clusterId = 0x00000403, \ - .attributes = ZAP_ATTRIBUTE_INDEX(746), \ + .attributes = ZAP_ATTRIBUTE_INDEX(745), \ .attributeCount = 5, \ .clusterSize = 12, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3852,7 +3851,7 @@ { \ /* Endpoint: 1, Cluster: Flow Measurement (server) */ \ .clusterId = 0x00000404, \ - .attributes = ZAP_ATTRIBUTE_INDEX(751), \ + .attributes = ZAP_ATTRIBUTE_INDEX(750), \ .attributeCount = 6, \ .clusterSize = 14, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3865,7 +3864,7 @@ { \ /* Endpoint: 1, Cluster: Relative Humidity Measurement (server) */ \ .clusterId = 0x00000405, \ - .attributes = ZAP_ATTRIBUTE_INDEX(757), \ + .attributes = ZAP_ATTRIBUTE_INDEX(756), \ .attributeCount = 6, \ .clusterSize = 14, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3878,7 +3877,7 @@ { \ /* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \ .clusterId = 0x00000406, \ - .attributes = ZAP_ATTRIBUTE_INDEX(763), \ + .attributes = ZAP_ATTRIBUTE_INDEX(762), \ .attributeCount = 5, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -3891,7 +3890,7 @@ { \ /* Endpoint: 1, Cluster: Carbon Monoxide Concentration Measurement (server) */ \ .clusterId = 0x0000040C, \ - .attributes = ZAP_ATTRIBUTE_INDEX(768), \ + .attributes = ZAP_ATTRIBUTE_INDEX(767), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3904,7 +3903,7 @@ { \ /* Endpoint: 1, Cluster: Carbon Dioxide Concentration Measurement (server) */ \ .clusterId = 0x0000040D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(781), \ + .attributes = ZAP_ATTRIBUTE_INDEX(780), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3917,7 +3916,7 @@ { \ /* Endpoint: 1, Cluster: Nitrogen Dioxide Concentration Measurement (server) */ \ .clusterId = 0x00000413, \ - .attributes = ZAP_ATTRIBUTE_INDEX(794), \ + .attributes = ZAP_ATTRIBUTE_INDEX(793), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3930,7 +3929,7 @@ { \ /* Endpoint: 1, Cluster: Ozone Concentration Measurement (server) */ \ .clusterId = 0x00000415, \ - .attributes = ZAP_ATTRIBUTE_INDEX(807), \ + .attributes = ZAP_ATTRIBUTE_INDEX(806), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3943,7 +3942,7 @@ { \ /* Endpoint: 1, Cluster: PM2.5 Concentration Measurement (server) */ \ .clusterId = 0x0000042A, \ - .attributes = ZAP_ATTRIBUTE_INDEX(820), \ + .attributes = ZAP_ATTRIBUTE_INDEX(819), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3956,7 +3955,7 @@ { \ /* Endpoint: 1, Cluster: Formaldehyde Concentration Measurement (server) */ \ .clusterId = 0x0000042B, \ - .attributes = ZAP_ATTRIBUTE_INDEX(833), \ + .attributes = ZAP_ATTRIBUTE_INDEX(832), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3969,7 +3968,7 @@ { \ /* Endpoint: 1, Cluster: PM1 Concentration Measurement (server) */ \ .clusterId = 0x0000042C, \ - .attributes = ZAP_ATTRIBUTE_INDEX(846), \ + .attributes = ZAP_ATTRIBUTE_INDEX(845), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3982,7 +3981,7 @@ { \ /* Endpoint: 1, Cluster: PM10 Concentration Measurement (server) */ \ .clusterId = 0x0000042D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(859), \ + .attributes = ZAP_ATTRIBUTE_INDEX(858), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3995,7 +3994,7 @@ { \ /* Endpoint: 1, Cluster: Total Volatile Organic Compounds Concentration Measurement (server) */ \ .clusterId = 0x0000042E, \ - .attributes = ZAP_ATTRIBUTE_INDEX(872), \ + .attributes = ZAP_ATTRIBUTE_INDEX(871), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4008,7 +4007,7 @@ { \ /* Endpoint: 1, Cluster: Radon Concentration Measurement (server) */ \ .clusterId = 0x0000042F, \ - .attributes = ZAP_ATTRIBUTE_INDEX(885), \ + .attributes = ZAP_ATTRIBUTE_INDEX(884), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4021,7 +4020,7 @@ { \ /* Endpoint: 1, Cluster: Wake on LAN (server) */ \ .clusterId = 0x00000503, \ - .attributes = ZAP_ATTRIBUTE_INDEX(898), \ + .attributes = ZAP_ATTRIBUTE_INDEX(897), \ .attributeCount = 3, \ .clusterSize = 19, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4034,7 +4033,7 @@ { \ /* Endpoint: 1, Cluster: Low Power (server) */ \ .clusterId = 0x00000508, \ - .attributes = ZAP_ATTRIBUTE_INDEX(901), \ + .attributes = ZAP_ATTRIBUTE_INDEX(900), \ .attributeCount = 2, \ .clusterSize = 6, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4047,7 +4046,7 @@ { \ /* Endpoint: 1, Cluster: Electrical Measurement (server) */ \ .clusterId = 0x00000B04, \ - .attributes = ZAP_ATTRIBUTE_INDEX(903), \ + .attributes = ZAP_ATTRIBUTE_INDEX(902), \ .attributeCount = 13, \ .clusterSize = 32, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4060,7 +4059,7 @@ { \ /* Endpoint: 1, Cluster: Unit Testing (server) */ \ .clusterId = 0xFFF1FC05, \ - .attributes = ZAP_ATTRIBUTE_INDEX(916), \ + .attributes = ZAP_ATTRIBUTE_INDEX(915), \ .attributeCount = 84, \ .clusterSize = 2290, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4073,7 +4072,7 @@ { \ /* Endpoint: 2, Cluster: Identify (server) */ \ .clusterId = 0x00000003, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1000), \ + .attributes = ZAP_ATTRIBUTE_INDEX(999), \ .attributeCount = 4, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION), \ @@ -4086,7 +4085,7 @@ { \ /* Endpoint: 2, Cluster: Groups (server) */ \ .clusterId = 0x00000004, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1004), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1003), \ .attributeCount = 3, \ .clusterSize = 7, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -4099,7 +4098,7 @@ { \ /* Endpoint: 2, Cluster: On/Off (server) */ \ .clusterId = 0x00000006, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1007), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1006), \ .attributeCount = 7, \ .clusterSize = 13, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(SHUTDOWN_FUNCTION), \ @@ -4112,7 +4111,7 @@ { \ /* Endpoint: 2, Cluster: Descriptor (server) */ \ .clusterId = 0x0000001D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1014), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1013), \ .attributeCount = 7, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4125,7 +4124,7 @@ { \ /* Endpoint: 2, Cluster: Power Source (server) */ \ .clusterId = 0x0000002F, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1021), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1020), \ .attributeCount = 9, \ .clusterSize = 72, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4138,7 +4137,7 @@ { \ /* Endpoint: 2, Cluster: Scenes Management (server) */ \ .clusterId = 0x00000062, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1030), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1029), \ .attributeCount = 5, \ .clusterSize = 16, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(SHUTDOWN_FUNCTION), \ @@ -4151,7 +4150,7 @@ { \ /* Endpoint: 2, Cluster: Occupancy Sensing (server) */ \ .clusterId = 0x00000406, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1035), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1034), \ .attributeCount = 5, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -4164,7 +4163,7 @@ { \ /* Endpoint: 65534, Cluster: Descriptor (server) */ \ .clusterId = 0x0000001D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1040), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1039), \ .attributeCount = 6, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4177,7 +4176,7 @@ { \ /* Endpoint: 65534, Cluster: Network Commissioning (server) */ \ .clusterId = 0x00000031, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1046), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1045), \ .attributeCount = 10, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4196,7 +4195,7 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 29, 349 }, { ZAP_CLUSTER_INDEX(29), 74, 3523 }, { ZAP_CLUSTER_INDEX(103), 7, 126 }, \ + { ZAP_CLUSTER_INDEX(0), 29, 349 }, { ZAP_CLUSTER_INDEX(29), 74, 3522 }, { ZAP_CLUSTER_INDEX(103), 7, 126 }, \ { ZAP_CLUSTER_INDEX(110), 2, 0 }, \ } @@ -4209,7 +4208,7 @@ static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, #define ATTRIBUTE_SINGLETONS_SIZE (36) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (3998) +#define ATTRIBUTE_MAX_SIZE (3997) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (4) diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 7a439a4141ce49..098d291b3311f3 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -412,6 +412,14 @@ template("chip_data_model") { "${_app_root}/clusters/${cluster}/DefaultThreadNetworkDirectoryStorage.h", "${_app_root}/clusters/${cluster}/ThreadNetworkDirectoryStorage.h", ] + } else if (cluster == "thermostat-server") { + sources += [ + "${_app_root}/clusters/${cluster}/${cluster}.cpp", + "${_app_root}/clusters/${cluster}/${cluster}.h", + "${_app_root}/clusters/${cluster}/PresetStructWithOwnedMembers.cpp", + "${_app_root}/clusters/${cluster}/PresetStructWithOwnedMembers.h", + "${_app_root}/clusters/${cluster}/thermostat-delegate.h", + ] } else { sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ] } diff --git a/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.cpp b/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.cpp new file mode 100644 index 00000000000000..dfc395f6bee81d --- /dev/null +++ b/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.cpp @@ -0,0 +1,155 @@ +/** + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 "PresetStructWithOwnedMembers.h" + +using namespace chip; +using namespace chip::app; +using namespace DataModel; +using namespace chip::app::Clusters::Thermostat::Structs; + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +PresetStructWithOwnedMembers::PresetStructWithOwnedMembers(const PresetStruct::Type & other) +{ + *this = other; +} + +void PresetStructWithOwnedMembers::operator=(const PresetStruct::Type & other) +{ + SetPresetScenario(other.presetScenario); + CHIP_ERROR err = SetPresetHandle(other.presetHandle); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Failed to set Preset handle with err %" CHIP_ERROR_FORMAT, err.Format()); + } + err = SetName(other.name); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Failed to set Preset name with err %" CHIP_ERROR_FORMAT, err.Format()); + } + SetCoolingSetpoint(other.coolingSetpoint); + SetHeatingSetpoint(other.heatingSetpoint); + SetBuiltIn(other.builtIn); +} + +void PresetStructWithOwnedMembers::SetPresetScenario(PresetScenarioEnum enumValue) +{ + presetScenario = enumValue; +} + +CHIP_ERROR PresetStructWithOwnedMembers::SetPresetHandle(const Nullable & newPresetHandle) +{ + if (!newPresetHandle.IsNull()) + { + size_t newPresetHandleSize = newPresetHandle.Value().size(); + if (newPresetHandleSize > kPresetHandleSize) + { + ChipLogError(Zcl, "Failed to set Preset handle. New preset handle size (%u) > allowed preset handle size (%u)", + static_cast(newPresetHandleSize), static_cast(kPresetNameSize)); + return CHIP_ERROR_NO_MEMORY; + } + MutableByteSpan targetSpan(presetHandleData); + ReturnErrorOnFailure(CopySpanToMutableSpan(newPresetHandle.Value(), targetSpan)); + presetHandle.SetNonNull(targetSpan); + } + else + { + presetHandle.SetNull(); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR PresetStructWithOwnedMembers::SetName(const Optional> & newName) +{ + if (newName.HasValue() && !newName.Value().IsNull()) + { + size_t newNameSize = newName.Value().Value().size(); + if (newNameSize > kPresetNameSize) + { + ChipLogError(Zcl, "Failed to set Preset name. New name size (%u) > allowed preset name size (%u)", + static_cast(newNameSize), static_cast(kPresetNameSize)); + return CHIP_ERROR_NO_MEMORY; + } + MutableCharSpan targetSpan(presetNameData); + CharSpan newNameSpan = newName.Value().Value(); + ReturnErrorOnFailure(CopyCharSpanToMutableCharSpan(newNameSpan, targetSpan)); + + DataModel::Nullable nullableCharSpan; + nullableCharSpan.SetNonNull(targetSpan); + name.SetValue(nullableCharSpan); + } + else + { + name.ClearValue(); + } + return CHIP_NO_ERROR; +} + +void PresetStructWithOwnedMembers::SetCoolingSetpoint(const Optional & newCoolingSetpoint) +{ + coolingSetpoint = newCoolingSetpoint; +} + +void PresetStructWithOwnedMembers::SetHeatingSetpoint(const Optional & newHeatingSetpoint) +{ + heatingSetpoint = newHeatingSetpoint; +} + +void PresetStructWithOwnedMembers::SetBuiltIn(DataModel::Nullable newBuiltIn) +{ + builtIn = newBuiltIn; +} + +PresetScenarioEnum PresetStructWithOwnedMembers::GetPresetScenario() const +{ + return presetScenario; +} + +DataModel::Nullable PresetStructWithOwnedMembers::GetPresetHandle() const +{ + return presetHandle; +} + +Optional> PresetStructWithOwnedMembers::GetName() const +{ + return name; +} + +Optional PresetStructWithOwnedMembers::GetCoolingSetpoint() const +{ + return coolingSetpoint; +} + +Optional PresetStructWithOwnedMembers::GetHeatingSetpoint() const +{ + return heatingSetpoint; +} + +DataModel::Nullable PresetStructWithOwnedMembers::GetBuiltIn() const +{ + return builtIn; +} + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.h b/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.h new file mode 100644 index 00000000000000..7161fb874989e2 --- /dev/null +++ b/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.h @@ -0,0 +1,72 @@ +/** + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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. + */ + +/**************************************************************************** + * @file + * @brief This class has a struct PresetStructWithOwnedMembers that inherits from + * Structs::PresetStruct::Type and manages the storage of the preset handle + * member which it owns. + * + ******************************************************************************* + ******************************************************************************/ + +#pragma once + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +static constexpr size_t kPresetHandleSize = 16; + +static constexpr size_t kPresetNameSize = 64; + +struct PresetStructWithOwnedMembers : protected Structs::PresetStruct::Type +{ +public: + PresetStructWithOwnedMembers() = default; + PresetStructWithOwnedMembers(const Structs::PresetStruct::Type & other); + void operator=(const Structs::PresetStruct::Type & other); + + void SetPresetScenario(PresetScenarioEnum enumValue); + CHIP_ERROR SetPresetHandle(const DataModel::Nullable & newPresetHandle); + CHIP_ERROR SetName(const Optional> & newName); + void SetCoolingSetpoint(const Optional & newCoolingSetpoint); + void SetHeatingSetpoint(const Optional & newHeatingSetpoint); + void SetBuiltIn(DataModel::Nullable newBuiltIn); + + PresetScenarioEnum GetPresetScenario() const; + DataModel::Nullable GetPresetHandle() const; + Optional> GetName() const; + Optional GetCoolingSetpoint() const; + Optional GetHeatingSetpoint() const; + DataModel::Nullable GetBuiltIn() const; + + using Structs::PresetStruct::Type::Encode; + using Structs::PresetStruct::Type::kIsFabricScoped; + +private: + uint8_t presetHandleData[kPresetHandleSize] = { 0 }; + char presetNameData[kPresetNameSize]; +}; + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thermostat-server/thermostat-delegate.h b/src/app/clusters/thermostat-server/thermostat-delegate.h new file mode 100644 index 00000000000000..86c1e532b92fc2 --- /dev/null +++ b/src/app/clusters/thermostat-server/thermostat-delegate.h @@ -0,0 +1,129 @@ +/** + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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 "PresetStructWithOwnedMembers.h" +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +/** @brief + * Defines methods for implementing application-specific logic for handling Presets in the thermostat cluster. + * It defines the interfaces that a thermostat should implement to enable support for reading and writing the + * Presets attribute and reading and writing the ActivePresetHandle attribute. + */ +class Delegate +{ +public: + Delegate() = default; + + virtual ~Delegate() = default; + + /** + * @brief Get the preset type at a given index in the PresetTypes attribute + * + * @param[in] index The index of the preset type in the list. + * @param[out] presetType The preset type at the given index in the list. + * @return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the preset types list. + */ + virtual CHIP_ERROR GetPresetTypeAtIndex(size_t index, Structs::PresetTypeStruct::Type & presetType) = 0; + + /** + * @brief Get the NumberOfPresets attribute value. + * + * @return The max number of presets supported. Return 0 if not set. + */ + virtual uint8_t GetNumberOfPresets() = 0; + + /** + * @brief Get the preset at a given index in the Presets attribute. + * + * @param[in] index The index of the preset in the list. + * @param[out] preset The PresetStructWithOwnedMembers struct that has the data from the preset + * at the given index in the Presets attribute list. + * @return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the presets list. + */ + virtual CHIP_ERROR GetPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) = 0; + + /** + * @brief Get the ActivePresetHandle attribute value. + * + * @param[out] activePresetHandle The MutableByteSpan to copy the active preset handle into. On success, + * the callee must update the length to the length of the copied data. If the value of + * the attribute is null, the callee must set the MutableByteSpan to empty. + */ + virtual CHIP_ERROR GetActivePresetHandle(MutableByteSpan & activePresetHandle) = 0; + + /** + * @brief Set the ActivePresetHandle attribute value. + * + * @param[in] newActivePresetHandle The octet string to set the active preset handle to. + */ + virtual CHIP_ERROR SetActivePresetHandle(const DataModel::Nullable & newActivePresetHandle) = 0; + + /** + * @brief Appends a preset to the pending presets list maintained by the delegate. + * The delegate must ensure it makes a copy of the provided preset and the data + * of its preset handle, if any. For example, it could create a PresetStructWithOwnedMembers + * from the provided preset. + * + * @param[in] preset The preset to add to the list. + * + * @return CHIP_NO_ERROR if the preset was appended to the list successfully. + * @return CHIP_ERROR if there was an error adding the preset to the list. + */ + virtual CHIP_ERROR AppendToPendingPresetList(const Structs::PresetStruct::Type & preset) = 0; + + /** + * @brief Get the Preset at a given index in the pending presets list. + * + * @param[in] index The index of the preset in the list. + * @param[out] preset The PresetStructWithOwnedMembers struct that has the data from the pending preset + * list at the given index. + * @return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the pending presets list. + */ + virtual CHIP_ERROR GetPendingPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) = 0; + + /** + * @brief Updates the presets attribute with the content of the pending presets list. If the preset in the pending presets list + * matches i.e. has the same presetHandle as an existing entry in the Presets attribute, the thermostat will update the entry + * with the new preset values, otherwise it will add a new preset to the Presets attribute. For new presets that get added, + * it is the responsibility of this API to allocate unique preset handles to the presets before saving the preset. This will be + * called when the Thermostat receives a CommitPresetsSchedulesRequest command to commit the pending preset changes. + * + * @return CHIP_NO_ERROR if the updates to the presets attribute has been committed successfully. + * @return CHIP_ERROR if the updates to the presets attribute failed to commit for some reason. + * + */ + virtual CHIP_ERROR ApplyPendingPresets() = 0; + + /** + * @brief Clears the pending presets list. + * + */ + virtual void ClearPendingPresetList() = 0; +}; + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thermostat-server/thermostat-server.cpp b/src/app/clusters/thermostat-server/thermostat-server.cpp index c650a30c871989..71c2f3d6fd6260 100644 --- a/src/app/clusters/thermostat-server/thermostat-server.cpp +++ b/src/app/clusters/thermostat-server/thermostat-server.cpp @@ -15,7 +15,9 @@ * limitations under the License. */ -#include +#include "thermostat-server.h" +#include "PresetStructWithOwnedMembers.h" + #include #include @@ -26,11 +28,13 @@ #include #include #include +#include using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::Thermostat; +using namespace chip::app::Clusters::Thermostat::Structs; using namespace chip::app::Clusters::Thermostat::Attributes; using imcode = Protocols::InteractionModel::Status; @@ -65,16 +69,645 @@ constexpr int8_t kDefaultDeadBand = 25; // 2.5C is the default namespace { -class ThermostatAttrAccess : public AttributeAccessInterface +ThermostatAttrAccess gThermostatAttrAccess; + +static_assert(kThermostatEndpointCount <= kEmberInvalidEndpointIndex, "Thermostat Delegate table size error"); + +Delegate * gDelegateTable[kThermostatEndpointCount] = { nullptr }; + +Delegate * GetDelegate(EndpointId endpoint) +{ + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= ArraySize(gDelegateTable) ? nullptr : gDelegateTable[ep]); +} + +/** + * @brief Check if a preset is valid. + * + * @param[in] preset The preset to check. + * + * @return true If the preset is valid i.e the PresetHandle (if not null) fits within size constraints and the presetScenario enum + * value is valid. Otherwise, return false. + */ +bool IsValidPresetEntry(const PresetStruct::Type & preset) +{ + // Check that the preset handle is not too long. + if (!preset.presetHandle.IsNull() && preset.presetHandle.Value().size() > kPresetHandleSize) + { + return false; + } + + // Ensure we have a valid PresetScenario. + return (preset.presetScenario != PresetScenarioEnum::kUnknownEnumValue); +} + +/** + * @brief Callback that is called when the timeout for editing the presets expires. + * + * @param[in] systemLayer The system layer. + * @param[in] callbackContext The context passed to the timer callback. + */ +void TimerExpiredCallback(System::Layer * systemLayer, void * callbackContext) +{ + EndpointId endpoint = static_cast(reinterpret_cast(callbackContext)); + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrReturn(delegate != nullptr, ChipLogError(Zcl, "Delegate is null. Unable to handle timer expired")); + + delegate->ClearPendingPresetList(); + gThermostatAttrAccess.SetPresetsEditable(endpoint, false); +} + +/** + * @brief Schedules a timer for the given timeout in seconds. + * + * @param[in] endpoint The endpoint to use. + * @param[in] timeoutSeconds The timeout in seconds. + */ +void ScheduleTimer(EndpointId endpoint, uint16_t timeoutSeconds) +{ + DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(timeoutSeconds), TimerExpiredCallback, + reinterpret_cast(static_cast(endpoint))); +} + +/** + * @brief Clears the currently scheduled timer. + * + * @param[in] endpoint The endpoint to use. + */ +void ClearTimer(EndpointId endpoint) +{ + DeviceLayer::SystemLayer().CancelTimer(TimerExpiredCallback, reinterpret_cast(static_cast(endpoint))); +} + +/** + * @brief Extends the currently scheduled timer to a new timeout value in seconds + * + * @param[in] endpoint The endpoint to use. + * @param[in] timeoutSeconds The timeout in seconds to extend the timer to. + */ +void ExtendTimer(EndpointId endpoint, uint16_t timeoutSeconds) +{ + DeviceLayer::SystemLayer().ExtendTimerTo(System::Clock::Seconds16(timeoutSeconds), TimerExpiredCallback, + reinterpret_cast(static_cast(endpoint))); +} + +/** + * @brief Checks if the preset is built-in + * + * @param[in] preset The preset to check. + * + * @return true If the preset is built-in, false otherwise. + */ +bool IsBuiltIn(const PresetStructWithOwnedMembers & preset) +{ + return preset.GetBuiltIn().ValueOr(false); +} + +/** + * @brief Checks if the presets are matching i.e the presetHandles are the same. + * + * @param[in] preset The preset to check. + * @param[in] presetToMatch The preset to match with. + * + * @return true If the presets match, false otherwise. If both preset handles are null, returns false + */ +bool PresetHandlesExistAndMatch(const PresetStructWithOwnedMembers & preset, const PresetStructWithOwnedMembers & presetToMatch) +{ + return !preset.GetPresetHandle().IsNull() && !presetToMatch.GetPresetHandle().IsNull() && + preset.GetPresetHandle().Value().data_equal(presetToMatch.GetPresetHandle().Value()); +} + +/** + * @brief Get the source scoped node id. + * + * @param[in] commandObj The command handler object. + * + * @return The scoped node id of the source node. If the scoped node id is not retreived, return ScopedNodeId(). + */ +ScopedNodeId GetSourceScopedNodeId(CommandHandler * commandObj) +{ + ScopedNodeId sourceNodeId = ScopedNodeId(); + auto sessionHandle = commandObj->GetExchangeContext()->GetSessionHandle(); + + if (sessionHandle->IsSecureSession()) + { + sourceNodeId = sessionHandle->AsSecureSession()->GetPeer(); + } + else if (sessionHandle->IsGroupSession()) + { + sourceNodeId = sessionHandle->AsIncomingGroupSession()->GetPeer(); + } + return sourceNodeId; +} + +/** + * @brief Utility to clean up state by clearing the pending presets list, canceling the timer + * and setting PresetsEditable to false and clear the originator scoped node id. + * + * @param[in] delegate The delegate to use. + * @param[in] endpoint The endpoint to use. + */ +void CleanUp(Delegate * delegate, EndpointId endpoint) +{ + if (delegate != nullptr) + { + delegate->ClearPendingPresetList(); + } + ClearTimer(endpoint); + gThermostatAttrAccess.SetPresetsEditable(endpoint, false); + gThermostatAttrAccess.SetOriginatorScopedNodeId(endpoint, ScopedNodeId()); +} + +/** + * @brief Sends a response for the command and cleans up state by calling CleanUp() + * + * @param[in] delegate The delegate to use. + * @param[in] endpoint The endpoint to use. + * @param[in] commandObj The command handler to use to add the status response. + * @param[in] commandPath The command path. + * @param[in] status The status code to send as the response. + * + * @return true to indicate the response has been sent and command has been handled. + */ +bool SendResponseAndCleanUp(Delegate * delegate, EndpointId endpoint, CommandHandler * commandObj, + const ConcreteCommandPath & commandPath, imcode status) +{ + commandObj->AddStatus(commandPath, status); + CleanUp(delegate, endpoint); + return true; +} + +/** + * @brief Finds an entry in the pending presets list that matches a preset. + * The presetHandle of the two presets must match. + * + * @param[in] delegate The delegate to use. + * @param[in] presetToMatch The preset to match with. + * + * @return true if a matching entry was found in the pending presets list, false otherwise. + */ +bool MatchingPendingPresetExists(Delegate * delegate, const PresetStructWithOwnedMembers & presetToMatch) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers preset; + CHIP_ERROR err = delegate->GetPendingPresetAtIndex(i, preset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "MatchingPendingPresetExists: GetPendingPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, + err.Format()); + return false; + } + + if (PresetHandlesExistAndMatch(preset, presetToMatch)) + { + return true; + } + } + return false; +} + +/** + * @brief Finds and returns an entry in the Presets attribute list that matches a preset. + * The presetHandle of the two presets must match. + * + * @param[in] delegate The delegate to use. + * @param[in] presetToMatch The preset to match with. + * @param[out] matchingPreset The preset in the Presets attribute list that has the same PresetHandle as the presetToMatch. + * + * @return true if a matching entry was found in the presets attribute list, false otherwise. + */ +bool GetMatchingPresetInPresets(Delegate * delegate, const PresetStructWithOwnedMembers & presetToMatch, + PresetStructWithOwnedMembers & matchingPreset) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + for (uint8_t i = 0; true; i++) + { + CHIP_ERROR err = delegate->GetPresetAtIndex(i, matchingPreset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "GetMatchingPresetInPresets: GetPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, err.Format()); + return false; + } + + if (PresetHandlesExistAndMatch(matchingPreset, presetToMatch)) + { + return true; + } + } + return false; +} + +/** + * @brief Checks if the given preset handle is present in the presets attribute + * @param[in] delegate The delegate to use. + * @param[in] presetHandleToMatch The preset handle to match with. + * + * @return true if the given preset handle is present in the presets attribute list, false otherwise. + */ +bool IsPresetHandlePresentInPresets(Delegate * delegate, const ByteSpan & presetHandleToMatch) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + PresetStructWithOwnedMembers matchingPreset; + for (uint8_t i = 0; true; i++) + { + CHIP_ERROR err = delegate->GetPresetAtIndex(i, matchingPreset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return false; + } + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "IsPresetHandlePresentInPresets: GetPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, + err.Format()); + return false; + } + + if (!matchingPreset.GetPresetHandle().IsNull() && matchingPreset.GetPresetHandle().Value().data_equal(presetHandleToMatch)) + { + return true; + } + } + return false; +} + +/** + * @brief Returns the length of the list of presets if the pending presets were to be applied. The calculation is done by + * adding the number of presets in Presets attribute list to the number of pending presets in the pending + * presets list and subtracting the number of duplicate presets. This is called before changes are actually applied. + * + * @param[in] delegate The delegate to use. + * + * @return count of the updated Presets attribute if the pending presets were applied to it. Return 0 for error cases. + */ +uint8_t CountUpdatedPresetsAfterApplyingPendingPresets(Delegate * delegate) +{ + uint8_t numberOfPresets = 0; + uint8_t numberOfMatches = 0; + uint8_t numberOfPendingPresets = 0; + + VerifyOrReturnValue(delegate != nullptr, 0); + + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers preset; + CHIP_ERROR err = delegate->GetPresetAtIndex(i, preset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "GetUpdatedPresetsCount: GetPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, err.Format()); + return 0; + } + numberOfPresets++; + + bool found = MatchingPendingPresetExists(delegate, preset); + + if (found) + { + numberOfMatches++; + } + } + + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers pendingPreset; + CHIP_ERROR err = delegate->GetPendingPresetAtIndex(i, pendingPreset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "GetUpdatedPresetsCount: GetPendingPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, + err.Format()); + return 0; + } + numberOfPendingPresets++; + } + + // TODO: #34546 - Need to support deletion of presets that are removed from Presets. + // This API needs to modify its logic for the deletion case. + return static_cast(numberOfPresets + numberOfPendingPresets - numberOfMatches); +} + +/** + * @brief Checks if the presetScenario is present in the PresetTypes attribute. + * + * @param[in] delegate The delegate to use. + * @param[in] presetScenario The presetScenario to match with. + * + * @return true if the presetScenario is found, false otherwise. + */ +bool PresetScenarioExistsInPresetTypes(Delegate * delegate, PresetScenarioEnum presetScenario) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + for (uint8_t i = 0; true; i++) + { + PresetTypeStruct::Type presetType; + auto err = delegate->GetPresetTypeAtIndex(i, presetType); + if (err != CHIP_NO_ERROR) + { + return false; + } + + if (presetType.presetScenario == presetScenario) + { + return true; + } + } + return false; +} + +/** + * @brief Returns the count of preset entries in the pending presets list that have the matching presetHandle. + * @param[in] delegate The delegate to use. + * @param[in] presetHandleToMatch The preset handle to match. + * + * @return count of the number of presets found with the matching presetHandle. Returns 0 if no matching presets were found. + */ +uint8_t CountPresetsInPendingListWithPresetHandle(Delegate * delegate, const ByteSpan & presetHandleToMatch) +{ + uint8_t count = 0; + VerifyOrReturnValue(delegate != nullptr, count); + + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers preset; + auto err = delegate->GetPendingPresetAtIndex(i, preset); + if (err != CHIP_NO_ERROR) + { + return count; + } + + DataModel::Nullable presetHandle = preset.GetPresetHandle(); + if (!presetHandle.IsNull() && presetHandle.Value().data_equal(presetHandleToMatch)) + { + count++; + } + } + return count; +} + +/** + * @brief Checks if the presetType for the given preset scenario supports name in the presetTypeFeatures bitmap. + * + * @param[in] delegate The delegate to use. + * @param[in] presetScenario The presetScenario to match with. + * + * @return true if the presetType for the given preset scenario supports name, false otherwise. + */ +bool PresetTypeSupportsNames(Delegate * delegate, PresetScenarioEnum scenario) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + for (uint8_t i = 0; true; i++) + { + PresetTypeStruct::Type presetType; + auto err = delegate->GetPresetTypeAtIndex(i, presetType); + if (err != CHIP_NO_ERROR) + { + return false; + } + + if (presetType.presetScenario == scenario) + { + return (presetType.presetTypeFeatures.Has(PresetTypeFeaturesBitmap::kSupportsNames)); + } + } + return false; +} + +int16_t EnforceHeatingSetpointLimits(int16_t HeatingSetpoint, EndpointId endpoint) +{ + // Optional Mfg supplied limits + int16_t AbsMinHeatSetpointLimit = kDefaultAbsMinHeatSetpointLimit; + int16_t AbsMaxHeatSetpointLimit = kDefaultAbsMaxHeatSetpointLimit; + + // Optional User supplied limits + int16_t MinHeatSetpointLimit = kDefaultMinHeatSetpointLimit; + int16_t MaxHeatSetpointLimit = kDefaultMaxHeatSetpointLimit; + + // Attempt to read the setpoint limits + // Absmin/max are manufacturer limits + // min/max are user imposed min/max + + // Note that the limits are initialized above per the spec limits + // if they are not present Get() will not update the value so the defaults are used + imcode status; + + // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3724 + // behavior is not specified when Abs * values are not present and user values are present + // implemented behavior accepts the user values without regard to default Abs values. + + // Per global matter data model policy + // if a attribute is not present then it's default shall be used. + + status = AbsMinHeatSetpointLimit::Get(endpoint, &AbsMinHeatSetpointLimit); + if (status != imcode::Success) + { + ChipLogError(Zcl, "Warning: AbsMinHeatSetpointLimit missing using default"); + } + + status = AbsMaxHeatSetpointLimit::Get(endpoint, &AbsMaxHeatSetpointLimit); + if (status != imcode::Success) + { + ChipLogError(Zcl, "Warning: AbsMaxHeatSetpointLimit missing using default"); + } + status = MinHeatSetpointLimit::Get(endpoint, &MinHeatSetpointLimit); + if (status != imcode::Success) + { + MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + } + + status = MaxHeatSetpointLimit::Get(endpoint, &MaxHeatSetpointLimit); + if (status != imcode::Success) + { + MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; + } + + // Make sure the user imposed limits are within the manufacturer imposed limits + + // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3725 + // Spec does not specify the behavior is the requested setpoint exceeds the limit allowed + // This implementation clamps at the limit. + + // resolution of 3725 is to clamp. + + if (MinHeatSetpointLimit < AbsMinHeatSetpointLimit) + MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + + if (MaxHeatSetpointLimit > AbsMaxHeatSetpointLimit) + MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; + + if (HeatingSetpoint < MinHeatSetpointLimit) + HeatingSetpoint = MinHeatSetpointLimit; + + if (HeatingSetpoint > MaxHeatSetpointLimit) + HeatingSetpoint = MaxHeatSetpointLimit; + + return HeatingSetpoint; +} + +int16_t EnforceCoolingSetpointLimits(int16_t CoolingSetpoint, EndpointId endpoint) +{ + // Optional Mfg supplied limits + int16_t AbsMinCoolSetpointLimit = kDefaultAbsMinCoolSetpointLimit; + int16_t AbsMaxCoolSetpointLimit = kDefaultAbsMaxCoolSetpointLimit; + + // Optional User supplied limits + int16_t MinCoolSetpointLimit = kDefaultMinCoolSetpointLimit; + int16_t MaxCoolSetpointLimit = kDefaultMaxCoolSetpointLimit; + + // Attempt to read the setpoint limits + // Absmin/max are manufacturer limits + // min/max are user imposed min/max + + // Note that the limits are initialized above per the spec limits + // if they are not present Get() will not update the value so the defaults are used + imcode status; + + // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3724 + // behavior is not specified when Abs * values are not present and user values are present + // implemented behavior accepts the user values without regard to default Abs values. + + // Per global matter data model policy + // if a attribute is not present then it's default shall be used. + + status = AbsMinCoolSetpointLimit::Get(endpoint, &AbsMinCoolSetpointLimit); + if (status != imcode::Success) + { + ChipLogError(Zcl, "Warning: AbsMinCoolSetpointLimit missing using default"); + } + + status = AbsMaxCoolSetpointLimit::Get(endpoint, &AbsMaxCoolSetpointLimit); + if (status != imcode::Success) + { + ChipLogError(Zcl, "Warning: AbsMaxCoolSetpointLimit missing using default"); + } + + status = MinCoolSetpointLimit::Get(endpoint, &MinCoolSetpointLimit); + if (status != imcode::Success) + { + MinCoolSetpointLimit = AbsMinCoolSetpointLimit; + } + + status = MaxCoolSetpointLimit::Get(endpoint, &MaxCoolSetpointLimit); + if (status != imcode::Success) + { + MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; + } + + // Make sure the user imposed limits are within the manufacture imposed limits + // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3725 + // Spec does not specify the behavior is the requested setpoint exceeds the limit allowed + // This implementation clamps at the limit. + + // resolution of 3725 is to clamp. + + if (MinCoolSetpointLimit < AbsMinCoolSetpointLimit) + MinCoolSetpointLimit = AbsMinCoolSetpointLimit; + + if (MaxCoolSetpointLimit > AbsMaxCoolSetpointLimit) + MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; + + if (CoolingSetpoint < MinCoolSetpointLimit) + CoolingSetpoint = MinCoolSetpointLimit; + + if (CoolingSetpoint > MaxCoolSetpointLimit) + CoolingSetpoint = MaxCoolSetpointLimit; + + return CoolingSetpoint; +} + +} // anonymous namespace + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) +{ + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + // if endpoint is found, add the delegate in the delegate table + if (ep < ArraySize(gDelegateTable)) + { + gDelegateTable[ep] = delegate; + } +} + +void ThermostatAttrAccess::SetPresetsEditable(EndpointId endpoint, bool presetEditable) +{ + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + + if (ep < ArraySize(mPresetsEditables)) + { + mPresetsEditables[ep] = presetEditable; + } +} + +bool ThermostatAttrAccess::GetPresetsEditable(EndpointId endpoint) +{ + bool presetEditable = false; + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + + if (ep < ArraySize(mPresetsEditables)) + { + presetEditable = mPresetsEditables[ep]; + } + return presetEditable; +} + +void ThermostatAttrAccess::SetOriginatorScopedNodeId(EndpointId endpoint, ScopedNodeId originatorNodeId) +{ + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + + if (ep < ArraySize(mPresetEditRequestOriginatorNodeIds)) + { + mPresetEditRequestOriginatorNodeIds[ep] = originatorNodeId; + } +} + +ScopedNodeId ThermostatAttrAccess::GetOriginatorScopedNodeId(EndpointId endpoint) { -public: - ThermostatAttrAccess() : AttributeAccessInterface(Optional::Missing(), Thermostat::Id) {} - - CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; - CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override; -}; + ScopedNodeId originatorNodeId = ScopedNodeId(); + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); -ThermostatAttrAccess gThermostatAttrAccess; + if (ep < ArraySize(mPresetEditRequestOriginatorNodeIds)) + { + originatorNodeId = mPresetEditRequestOriginatorNodeIds[ep]; + } + return originatorNodeId; +} CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) { @@ -107,11 +740,72 @@ CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, A } break; case PresetTypes::Id: { - return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { return CHIP_NO_ERROR; }); + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + return aEncoder.EncodeList([delegate](const auto & encoder) -> CHIP_ERROR { + for (uint8_t i = 0; true; i++) + { + PresetTypeStruct::Type presetType; + auto err = delegate->GetPresetTypeAtIndex(i, presetType); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(encoder.Encode(presetType)); + } + }); + } + break; + case NumberOfPresets::Id: { + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + ReturnErrorOnFailure(aEncoder.Encode(delegate->GetNumberOfPresets())); } break; case Presets::Id: { - return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { return CHIP_NO_ERROR; }); + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + return aEncoder.EncodeList([delegate](const auto & encoder) -> CHIP_ERROR { + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers preset; + auto err = delegate->GetPresetAtIndex(i, preset); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(encoder.Encode(preset)); + } + }); + } + break; + case PresetsSchedulesEditable::Id: { + ReturnErrorOnFailure(aEncoder.Encode(GetPresetsEditable(aPath.mEndpointId))); + } + break; + case ActivePresetHandle::Id: { + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + uint8_t buffer[kPresetHandleSize]; + MutableByteSpan activePresetHandle(buffer); + + CHIP_ERROR err = delegate->GetActivePresetHandle(activePresetHandle); + ReturnErrorOnFailure(err); + + if (activePresetHandle.empty()) + { + ReturnErrorOnFailure(aEncoder.EncodeNull()); + } + else + { + ReturnErrorOnFailure(aEncoder.Encode(activePresetHandle)); + } } break; case ScheduleTypes::Id: { @@ -154,10 +848,72 @@ CHIP_ERROR ThermostatAttrAccess::Write(const ConcreteDataAttributePath & aPath, } break; case Presets::Id: { - return CHIP_ERROR_NOT_IMPLEMENTED; + + EndpointId endpoint = aPath.mEndpointId; + Delegate * delegate = GetDelegate(endpoint); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + // Presets are not editable, return INVALID_IN_STATE. + VerifyOrReturnError(GetPresetsEditable(endpoint), CHIP_IM_GLOBAL_STATUS(InvalidInState), + ChipLogError(Zcl, "Presets are not editable")); + + // Check if the OriginatorScopedNodeId at the endpoint is the same as the node editing the presets, + // otherwise return BUSY. + const Access::SubjectDescriptor subjectDescriptor = aDecoder.GetSubjectDescriptor(); + ScopedNodeId scopedNodeId = ScopedNodeId(); + + // Get the node id if the authentication mode is CASE. + if (subjectDescriptor.authMode == Access::AuthMode::kCase) + { + scopedNodeId = ScopedNodeId(subjectDescriptor.subject, subjectDescriptor.fabricIndex); + } + + if (GetOriginatorScopedNodeId(endpoint) != scopedNodeId) + { + ChipLogError(Zcl, "Another node is editing presets. Server is busy. Try again later"); + return CHIP_IM_GLOBAL_STATUS(Busy); + } + + // If the list operation is replace all, clear the existing pending list, iterate over the new presets list + // and add to the pending presets list. + if (!aPath.IsListOperation() || aPath.mListOp == ConcreteDataAttributePath::ListOperation::ReplaceAll) + { + // Clear the pending presets list + delegate->ClearPendingPresetList(); + + Presets::TypeInfo::DecodableType newPresetsList; + ReturnErrorOnFailure(aDecoder.Decode(newPresetsList)); + + // Iterate over the presets and call the delegate to append to the list of pending presets. + auto iter = newPresetsList.begin(); + while (iter.Next()) + { + const PresetStruct::Type & preset = iter.GetValue(); + if (IsValidPresetEntry(preset)) + { + ReturnErrorOnFailure(delegate->AppendToPendingPresetList(preset)); + } + else + { + return CHIP_IM_GLOBAL_STATUS(ConstraintError); + } + } + return iter.GetStatus(); + } + + // If the list operation is AppendItem, call the delegate to append the item to the list of pending presets. + if (aPath.mListOp == ConcreteDataAttributePath::ListOperation::AppendItem) + { + PresetStruct::Type preset; + ReturnErrorOnFailure(aDecoder.Decode(preset)); + if (IsValidPresetEntry(preset)) + { + return delegate->AppendToPendingPresetList(preset); + } + return CHIP_IM_GLOBAL_STATUS(ConstraintError); + } } break; - case Schedules::Id: { return CHIP_ERROR_NOT_IMPLEMENTED; } @@ -169,7 +925,10 @@ CHIP_ERROR ThermostatAttrAccess::Write(const ConcreteDataAttributePath & aPath, return CHIP_NO_ERROR; } -} // anonymous namespace +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip void emberAfThermostatClusterServerInitCallback(chip::EndpointId endpoint) { @@ -496,182 +1255,310 @@ bool emberAfThermostatClusterSetActivePresetRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::SetActivePresetRequest::DecodableType & commandData) { - // TODO - return false; + EndpointId endpoint = commandPath.mEndpointId; + Delegate * delegate = GetDelegate(endpoint); + + if (delegate == nullptr) + { + ChipLogError(Zcl, "Delegate is null"); + commandObj->AddStatus(commandPath, imcode::InvalidInState); + return true; + } + + ByteSpan newPresetHandle = commandData.presetHandle; + + // If the preset handle passed in the command is not present in the Presets attribute, return INVALID_COMMAND. + if (!IsPresetHandlePresentInPresets(delegate, newPresetHandle)) + { + commandObj->AddStatus(commandPath, imcode::InvalidCommand); + return true; + } + + CHIP_ERROR err = delegate->SetActivePresetHandle(DataModel::MakeNullable(newPresetHandle)); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Failed to set ActivePresetHandle with error %" CHIP_ERROR_FORMAT, err.Format()); + commandObj->AddStatus(commandPath, StatusIB(err).mStatus); + return true; + } + + commandObj->AddStatus(commandPath, imcode::Success); + return true; } bool emberAfThermostatClusterStartPresetsSchedulesEditRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::StartPresetsSchedulesEditRequest::DecodableType & commandData) { - // TODO - return false; + ScopedNodeId sourceNodeId = GetSourceScopedNodeId(commandObj); + + EndpointId endpoint = commandPath.mEndpointId; + + // If the presets are editable and the scoped node id of the client sending StartPresetsSchedulesEditRequest command + // is not the same as the one that previously originated a StartPresetsSchedulesEditRequest command, return BUSY. + if (gThermostatAttrAccess.GetPresetsEditable(endpoint) && + (gThermostatAttrAccess.GetOriginatorScopedNodeId(endpoint) != sourceNodeId)) + { + commandObj->AddStatus(commandPath, imcode::Busy); + return true; + } + + // If presets are editable and the scoped node id of the client sending StartPresetsSchedulesEditRequest command + // is the same as the one that previously originated a StartPresetsSchedulesEditRequest command, extend the timer. + if (gThermostatAttrAccess.GetPresetsEditable(endpoint)) + { + ExtendTimer(endpoint, commandData.timeoutSeconds); + commandObj->AddStatus(commandPath, imcode::Success); + return true; + } + + // Set presets editable to true and the scoped originator node id to the source scoped node id, and start a timer with the + // timeout in seconds passed in the command args. Return success. + gThermostatAttrAccess.SetPresetsEditable(endpoint, true); + gThermostatAttrAccess.SetOriginatorScopedNodeId(endpoint, sourceNodeId); + ScheduleTimer(endpoint, commandData.timeoutSeconds); + commandObj->AddStatus(commandPath, imcode::Success); + return true; } bool emberAfThermostatClusterCancelPresetsSchedulesEditRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::CancelPresetsSchedulesEditRequest::DecodableType & commandData) { - // TODO - return false; + EndpointId endpoint = commandPath.mEndpointId; + + // If presets are not editable, return INVALID_IN_STATE. + if (!gThermostatAttrAccess.GetPresetsEditable(endpoint)) + { + commandObj->AddStatus(commandPath, imcode::InvalidInState); + return true; + } + + ScopedNodeId sourceNodeId = GetSourceScopedNodeId(commandObj); + + // If the node id sending the CancelPresetsSchedulesRequest command is not the same as the one which send the + // previous StartPresetsSchedulesEditRequest, return UNSUPPORTED_ACCESS. + if (gThermostatAttrAccess.GetOriginatorScopedNodeId(endpoint) != sourceNodeId) + { + commandObj->AddStatus(commandPath, imcode::UnsupportedAccess); + return true; + } + + Delegate * delegate = GetDelegate(endpoint); + + if (delegate == nullptr) + { + ChipLogError(Zcl, "Delegate is null"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } + + // Clear the timer, discard the changes and set PresetsEditable to false. + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::Success); } bool emberAfThermostatClusterCommitPresetsSchedulesRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::CommitPresetsSchedulesRequest::DecodableType & commandData) { - // TODO - return false; -} + EndpointId endpoint = commandPath.mEndpointId; + Delegate * delegate = GetDelegate(endpoint); -bool emberAfThermostatClusterSetTemperatureSetpointHoldPolicyCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::DecodableType & commandData) -{ - // TODO - return false; -} + if (delegate == nullptr) + { + ChipLogError(Zcl, "Delegate is null"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } -int16_t EnforceHeatingSetpointLimits(int16_t HeatingSetpoint, EndpointId endpoint) -{ - // Optional Mfg supplied limits - int16_t AbsMinHeatSetpointLimit = kDefaultAbsMinHeatSetpointLimit; - int16_t AbsMaxHeatSetpointLimit = kDefaultAbsMaxHeatSetpointLimit; + // If presets are not editable, return INVALID_IN_STATE. + if (!gThermostatAttrAccess.GetPresetsEditable(endpoint)) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } - // Optional User supplied limits - int16_t MinHeatSetpointLimit = kDefaultMinHeatSetpointLimit; - int16_t MaxHeatSetpointLimit = kDefaultMaxHeatSetpointLimit; + ScopedNodeId sourceNodeId = GetSourceScopedNodeId(commandObj); - // Attempt to read the setpoint limits - // Absmin/max are manufacturer limits - // min/max are user imposed min/max + // If the node id sending the CommitPresetsSchedulesRequest command is not the same as the one which send the + // StartPresetsSchedulesEditRequest, return UNSUPPORTED_ACCESS. + if (gThermostatAttrAccess.GetOriginatorScopedNodeId(endpoint) != sourceNodeId) + { + commandObj->AddStatus(commandPath, imcode::UnsupportedAccess); + return true; + } - // Note that the limits are initialized above per the spec limits - // if they are not present Get() will not update the value so the defaults are used - imcode status; + PresetStructWithOwnedMembers preset; + CHIP_ERROR err = CHIP_NO_ERROR; - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3724 - // behavior is not specified when Abs * values are not present and user values are present - // implemented behavior accepts the user values without regard to default Abs values. + // For each preset in the presets attribute, check that the matching preset in the pending presets list does not + // violate any spec constraints. + for (uint8_t i = 0; true; i++) + { + err = delegate->GetPresetAtIndex(i, preset); - // Per global matter data model policy - // if a attribute is not present then it's default shall be used. + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, + "emberAfThermostatClusterCommitPresetsSchedulesRequestCallback: GetPresetAtIndex failed with error " + "%" CHIP_ERROR_FORMAT, + err.Format()); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } - status = AbsMinHeatSetpointLimit::Get(endpoint, &AbsMinHeatSetpointLimit); - if (status != imcode::Success) - { - ChipLogError(Zcl, "Warning: AbsMinHeatSetpointLimit missing using default"); + bool found = MatchingPendingPresetExists(delegate, preset); + + // If a built in preset in the Presets attribute list is removed and not found in the pending presets list, return + // CONSTRAINT_ERROR. + if (IsBuiltIn(preset) && !found) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } } - status = AbsMaxHeatSetpointLimit::Get(endpoint, &AbsMaxHeatSetpointLimit); - if (status != imcode::Success) + // If there is an ActivePresetHandle set, find the preset in the pending presets list that matches the ActivePresetHandle + // attribute. If a preset is not found with the same presetHandle, return INVALID_IN_STATE. If there is no ActivePresetHandle + // attribute set, continue with other checks. + uint8_t buffer[kPresetHandleSize]; + MutableByteSpan activePresetHandle(buffer); + + err = delegate->GetActivePresetHandle(activePresetHandle); + + if (err != CHIP_NO_ERROR) { - ChipLogError(Zcl, "Warning: AbsMaxHeatSetpointLimit missing using default"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); } - status = MinHeatSetpointLimit::Get(endpoint, &MinHeatSetpointLimit); - if (status != imcode::Success) + + if (!activePresetHandle.empty()) { - MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + uint8_t count = CountPresetsInPendingListWithPresetHandle(delegate, activePresetHandle); + if (count == 0) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } } - status = MaxHeatSetpointLimit::Get(endpoint, &MaxHeatSetpointLimit); - if (status != imcode::Success) + // For each preset in the pending presets list, check that the preset does not violate any spec constraints. + for (uint8_t i = 0; true; i++) { - MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; - } + PresetStructWithOwnedMembers pendingPreset; + err = delegate->GetPendingPresetAtIndex(i, pendingPreset); - // Make sure the user imposed limits are within the manufacturer imposed limits + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, + "emberAfThermostatClusterCommitPresetsSchedulesRequestCallback: GetPendingPresetAtIndex failed with error " + "%" CHIP_ERROR_FORMAT, + err.Format()); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3725 - // Spec does not specify the behavior is the requested setpoint exceeds the limit allowed - // This implementation clamps at the limit. + bool isPendingPresetWithNullPresetHandle = pendingPreset.GetPresetHandle().IsNull(); - // resolution of 3725 is to clamp. + // If the preset handle is null and the built in field is set to true, return CONSTRAINT_ERROR. + if (isPendingPresetWithNullPresetHandle && IsBuiltIn(pendingPreset)) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } - if (MinHeatSetpointLimit < AbsMinHeatSetpointLimit) - MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + bool foundMatchingPresetInPresets = false; + PresetStructWithOwnedMembers matchingPreset; + if (!isPendingPresetWithNullPresetHandle) + { + foundMatchingPresetInPresets = GetMatchingPresetInPresets(delegate, pendingPreset, matchingPreset); - if (MaxHeatSetpointLimit > AbsMaxHeatSetpointLimit) - MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; + // If the presetHandle for the pending preset is not null and a matching preset is not found in the + // presets attribute list, return NOT_FOUND. + if (!foundMatchingPresetInPresets) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::NotFound); + } - if (HeatingSetpoint < MinHeatSetpointLimit) - HeatingSetpoint = MinHeatSetpointLimit; + // Find the number of presets in the pending preset list that match the preset handle. If there are duplicate + // entries, return CONSTRAINT_ERROR. + uint8_t count = CountPresetsInPendingListWithPresetHandle(delegate, pendingPreset.GetPresetHandle().Value()); + if (count > 1) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } + } - if (HeatingSetpoint > MaxHeatSetpointLimit) - HeatingSetpoint = MaxHeatSetpointLimit; + // If the preset is found in the presets attribute list and the preset is builtIn in the pending presets list + // but not in the presets attribute list, return UNSUPPORTED_ACCESS. + if (foundMatchingPresetInPresets && (IsBuiltIn(pendingPreset) && !IsBuiltIn(matchingPreset))) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::UnsupportedAccess); + } - return HeatingSetpoint; -} + // If the preset is found in the presets attribute list and the preset is builtIn in the presets attribute + // but not in the pending presets list, return UNSUPPORTED_ACCESS. + if (foundMatchingPresetInPresets && (!IsBuiltIn(pendingPreset) && IsBuiltIn(matchingPreset))) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::UnsupportedAccess); + } -int16_t EnforceCoolingSetpointLimits(int16_t CoolingSetpoint, EndpointId endpoint) -{ - // Optional Mfg supplied limits - int16_t AbsMinCoolSetpointLimit = kDefaultAbsMinCoolSetpointLimit; - int16_t AbsMaxCoolSetpointLimit = kDefaultAbsMaxCoolSetpointLimit; + // If the presetScenario is not found in the preset types, return CONSTRAINT_ERROR. + PresetScenarioEnum presetScenario = pendingPreset.GetPresetScenario(); + if (!PresetScenarioExistsInPresetTypes(delegate, presetScenario)) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } - // Optional User supplied limits - int16_t MinCoolSetpointLimit = kDefaultMinCoolSetpointLimit; - int16_t MaxCoolSetpointLimit = kDefaultMaxCoolSetpointLimit; + // If the preset type for the preset scenario does not support names and a name is specified, return CONSTRAINT_ERROR. + if (!PresetTypeSupportsNames(delegate, presetScenario) && pendingPreset.GetName().HasValue()) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } - // Attempt to read the setpoint limits - // Absmin/max are manufacturer limits - // min/max are user imposed min/max + // Enforce the Setpoint Limits for both the cooling and heating setpoints in the pending preset. + Optional coolingSetpointValue = pendingPreset.GetCoolingSetpoint(); + if (coolingSetpointValue.HasValue()) + { + pendingPreset.SetCoolingSetpoint(MakeOptional(EnforceCoolingSetpointLimits(coolingSetpointValue.Value(), endpoint))); + } - // Note that the limits are initialized above per the spec limits - // if they are not present Get() will not update the value so the defaults are used - imcode status; + Optional heatingSetpointValue = pendingPreset.GetHeatingSetpoint(); + if (heatingSetpointValue.HasValue()) + { + pendingPreset.SetHeatingSetpoint(MakeOptional(EnforceHeatingSetpointLimits(heatingSetpointValue.Value(), endpoint))); + } + } - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3724 - // behavior is not specified when Abs * values are not present and user values are present - // implemented behavior accepts the user values without regard to default Abs values. + uint8_t totalCount = CountUpdatedPresetsAfterApplyingPendingPresets(delegate); - // Per global matter data model policy - // if a attribute is not present then it's default shall be used. + uint8_t numberOfPresetsSupported = delegate->GetNumberOfPresets(); - status = AbsMinCoolSetpointLimit::Get(endpoint, &AbsMinCoolSetpointLimit); - if (status != imcode::Success) + if (numberOfPresetsSupported == 0) { - ChipLogError(Zcl, "Warning: AbsMinCoolSetpointLimit missing using default"); + ChipLogError(Zcl, "emberAfThermostatClusterCommitPresetsSchedulesRequestCallback: Failed to get NumberOfPresets"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); } - status = AbsMaxCoolSetpointLimit::Get(endpoint, &AbsMaxCoolSetpointLimit); - if (status != imcode::Success) + // If the expected length of the presets attribute with the applied changes exceeds the total number of presets supported, + // return RESOURCE_EXHAUSTED. Note that the changes are not yet applied. + if (numberOfPresetsSupported > 0 && totalCount > numberOfPresetsSupported) { - ChipLogError(Zcl, "Warning: AbsMaxCoolSetpointLimit missing using default"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ResourceExhausted); } - status = MinCoolSetpointLimit::Get(endpoint, &MinCoolSetpointLimit); - if (status != imcode::Success) - { - MinCoolSetpointLimit = AbsMinCoolSetpointLimit; - } + // TODO: Check if the number of presets for each presetScenario exceeds the max number of presets supported for that + // scenario. We plan to support only one preset for each presetScenario for our use cases so defer this for re-evaluation. - status = MaxCoolSetpointLimit::Get(endpoint, &MaxCoolSetpointLimit); - if (status != imcode::Success) + // Call the delegate API to apply the pending presets to the presets attribute and update it. + err = delegate->ApplyPendingPresets(); + + if (err != CHIP_NO_ERROR) { - MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); } - // Make sure the user imposed limits are within the manufacture imposed limits - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3725 - // Spec does not specify the behavior is the requested setpoint exceeds the limit allowed - // This implementation clamps at the limit. - - // resolution of 3725 is to clamp. - - if (MinCoolSetpointLimit < AbsMinCoolSetpointLimit) - MinCoolSetpointLimit = AbsMinCoolSetpointLimit; - - if (MaxCoolSetpointLimit > AbsMaxCoolSetpointLimit) - MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; - - if (CoolingSetpoint < MinCoolSetpointLimit) - CoolingSetpoint = MinCoolSetpointLimit; - - if (CoolingSetpoint > MaxCoolSetpointLimit) - CoolingSetpoint = MaxCoolSetpointLimit; - - return CoolingSetpoint; + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::Success); } bool emberAfThermostatClusterSetpointRaiseLowerCallback(app::CommandHandler * commandObj, diff --git a/src/app/clusters/thermostat-server/thermostat-server.h b/src/app/clusters/thermostat-server/thermostat-server.h new file mode 100644 index 00000000000000..955ab9e5c5a777 --- /dev/null +++ b/src/app/clusters/thermostat-server/thermostat-server.h @@ -0,0 +1,103 @@ +/** + * + * Copyright (c) 2024 Project CHIP Authors + * + * 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. + */ + +/**************************************************************************** + * @file + * @brief APIs for the Thermostat cluster. + * + ******************************************************************************* + ******************************************************************************/ + +#pragma once + +#include "thermostat-delegate.h" + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +static constexpr size_t kThermostatEndpointCount = + MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; + +/** + * @brief Thermostat Attribute Access Interface. + */ +class ThermostatAttrAccess : public chip::app::AttributeAccessInterface +{ +public: + ThermostatAttrAccess() : AttributeAccessInterface(Optional::Missing(), Thermostat::Id) {} + + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, chip::app::AttributeValueDecoder & aDecoder) override; + + /** + * @brief Sets the scoped node id of the originator that send the last successful + * StartPresetsSchedulesEditRequest for the given endpoint. + * + * @param[in] endpoint The endpoint. + * @param[in] originatorNodeId The originator scoped node id. + */ + void SetOriginatorScopedNodeId(EndpointId endpoint, ScopedNodeId originatorNodeId); + + /** + * @brief Gets the scoped node id of the originator that send the last successful + * StartPresetsSchedulesEditRequest for the given endpoint. + * + * @param[in] endpoint The endpoint. + * + * @return the scoped node id for the given endpoint if set. Otherwise returns ScopedNodeId(). + */ + ScopedNodeId GetOriginatorScopedNodeId(EndpointId endpoint); + + /** + * @brief Sets the presets editable flag for the given endpoint + * + * @param[in] endpoint The endpoint. + * @param[in] presetEditable The value of the presets editable. + */ + void SetPresetsEditable(EndpointId endpoint, bool presetEditable); + + /** + * @brief Gets the prests editable flag value for the given endpoint + * + * @param[in] endpoint The endpoint. + * + * @return the presets editable flag value for the given endpoint if set. Otherwise returns false. + */ + bool GetPresetsEditable(EndpointId endpoint); + +private: + ScopedNodeId mPresetEditRequestOriginatorNodeIds[kThermostatEndpointCount]; + + bool mPresetsEditables[kThermostatEndpointCount]; +}; + +/** + * @brief Sets the default delegate for the specific thermostat features. + * + * @param[in] endpoint The endpoint to set the default delegate on. + * @param[in] delegate The default delegate. + */ +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml index 796209999f1121..f731b66c6a1422 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml @@ -92,12 +92,6 @@ limitations under the License. - - - - - - @@ -206,7 +200,8 @@ limitations under the License. - + + @@ -459,9 +454,8 @@ limitations under the License. PresetsSchedulesEditable - TemperatureSetpointHoldPolicy - SetpointHoldExpiryTimestamp - + SetpointHoldExpiryTimestamp + @@ -513,10 +507,6 @@ limitations under the License. This command is used to notify the server that all edits are done and should be committed. - - This command sets the set point hold policy. - - diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index dd93ed7fe2cc9b..9c93c85f1faa4c 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -6617,7 +6617,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -6743,11 +6744,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -6853,8 +6849,7 @@ cluster Thermostat = 513 { 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 epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -6898,10 +6893,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -6920,8 +6911,6 @@ cluster Thermostat = 513 { 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 sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index e11a47a23a8c7c..6801ed63812eaa 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -40225,8 +40225,7 @@ public static class ThermostatCluster extends BaseChipCluster { private static final long PRESETS_ATTRIBUTE_ID = 80L; private static final long SCHEDULES_ATTRIBUTE_ID = 81L; private static final long PRESETS_SCHEDULES_EDITABLE_ATTRIBUTE_ID = 82L; - private static final long TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID = 83L; - private static final long SETPOINT_HOLD_EXPIRY_TIMESTAMP_ATTRIBUTE_ID = 84L; + private static final long SETPOINT_HOLD_EXPIRY_TIMESTAMP_ATTRIBUTE_ID = 83L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; @@ -40463,26 +40462,6 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public void setTemperatureSetpointHoldPolicy(DefaultClusterCallback callback, Integer temperatureSetpointHoldPolicy) { - setTemperatureSetpointHoldPolicy(callback, temperatureSetpointHoldPolicy, 0); - } - - public void setTemperatureSetpointHoldPolicy(DefaultClusterCallback callback, Integer temperatureSetpointHoldPolicy, int timedInvokeTimeoutMs) { - final long commandId = 11L; - - ArrayList elements = new ArrayList<>(); - final long temperatureSetpointHoldPolicyFieldID = 0L; - BaseTLVType temperatureSetpointHoldPolicytlvValue = new UIntType(temperatureSetpointHoldPolicy); - elements.add(new StructElement(temperatureSetpointHoldPolicyFieldID, temperatureSetpointHoldPolicytlvValue)); - - StructType commandArgs = new StructType(elements); - invoke(new InvokeCallbackImpl(callback) { - @Override - public void onResponse(StructType invokeStructValue) { - callback.onSuccess(); - }}, commandId, commandArgs, timedInvokeTimeoutMs); - } - public interface GetWeeklyScheduleResponseCallback extends BaseClusterCallback { void onSuccess(Integer numberOfTransitionsForSequence, Integer dayOfWeekForSequence, Integer modeForSequence, ArrayList transitions); } @@ -42400,32 +42379,6 @@ public void onSuccess(byte[] tlv) { }, PRESETS_SCHEDULES_EDITABLE_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readTemperatureSetpointHoldPolicyAttribute( - IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID, true); - } - - public void subscribeTemperatureSetpointHoldPolicyAttribute( - IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID, minInterval, maxInterval); - } - public void readSetpointHoldExpiryTimestampAttribute( SetpointHoldExpiryTimestampAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SETPOINT_HOLD_EXPIRY_TIMESTAMP_ATTRIBUTE_ID); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index ab20bdcaa301e9..7c8d9d92ff36aa 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -11897,8 +11897,7 @@ public enum Attribute { Presets(80L), Schedules(81L), PresetsSchedulesEditable(82L), - TemperatureSetpointHoldPolicy(83L), - SetpointHoldExpiryTimestamp(84L), + SetpointHoldExpiryTimestamp(83L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -11953,8 +11952,7 @@ public enum Command { SetActivePresetRequest(6L), StartPresetsSchedulesEditRequest(7L), CancelPresetsSchedulesEditRequest(8L), - CommitPresetsSchedulesRequest(9L), - SetTemperatureSetpointHoldPolicy(11L),; + CommitPresetsSchedulesRequest(9L),; private final long id; Command(long id) { this.id = id; @@ -12074,23 +12072,6 @@ public static StartPresetsSchedulesEditRequestCommandField value(int id) throws } throw new NoSuchFieldError(); } - }public enum SetTemperatureSetpointHoldPolicyCommandField {TemperatureSetpointHoldPolicy(0),; - private final int id; - SetTemperatureSetpointHoldPolicyCommandField(int id) { - this.id = id; - } - - public int getID() { - return id; - } - public static SetTemperatureSetpointHoldPolicyCommandField value(int id) throws NoSuchFieldError { - for (SetTemperatureSetpointHoldPolicyCommandField field : SetTemperatureSetpointHoldPolicyCommandField.values()) { - if (field.getID() == id) { - return field; - } - } - throw new NoSuchFieldError(); - } }@Override public String getAttributeName(long id) throws NoSuchFieldError { return Attribute.value(id).toString(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index ca3d74f1ac3797..242738bcca8278 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -26903,23 +26903,6 @@ public Map> getCommandMap() { ); thermostatClusterInteractionInfoMap.put("commitPresetsSchedulesRequest", thermostatcommitPresetsSchedulesRequestInteractionInfo); - Map thermostatsetTemperatureSetpointHoldPolicyCommandParams = new LinkedHashMap(); - - CommandParameterInfo thermostatsetTemperatureSetpointHoldPolicytemperatureSetpointHoldPolicyCommandParameterInfo = new CommandParameterInfo("temperatureSetpointHoldPolicy", Integer.class, Integer.class); - thermostatsetTemperatureSetpointHoldPolicyCommandParams.put("temperatureSetpointHoldPolicy",thermostatsetTemperatureSetpointHoldPolicytemperatureSetpointHoldPolicyCommandParameterInfo); - InteractionInfo thermostatsetTemperatureSetpointHoldPolicyInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.ThermostatCluster) cluster) - .setTemperatureSetpointHoldPolicy((DefaultClusterCallback) callback - , (Integer) - commandArguments.get("temperatureSetpointHoldPolicy") - ); - }, - () -> new DelegatedDefaultClusterCallback(), - thermostatsetTemperatureSetpointHoldPolicyCommandParams - ); - thermostatClusterInteractionInfoMap.put("setTemperatureSetpointHoldPolicy", thermostatsetTemperatureSetpointHoldPolicyInteractionInfo); - commandMap.put("thermostat", thermostatClusterInteractionInfoMap); Map fanControlClusterInteractionInfoMap = new LinkedHashMap<>(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 45d0e3037631fb..07b3da09bee4a9 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -12905,17 +12905,6 @@ private static Map readThermostatInteractionInfo() { readThermostatPresetsSchedulesEditableCommandParams ); result.put("readPresetsSchedulesEditableAttribute", readThermostatPresetsSchedulesEditableAttributeInteractionInfo); - Map readThermostatTemperatureSetpointHoldPolicyCommandParams = new LinkedHashMap(); - InteractionInfo readThermostatTemperatureSetpointHoldPolicyAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.ThermostatCluster) cluster).readTemperatureSetpointHoldPolicyAttribute( - (ChipClusters.IntegerAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), - readThermostatTemperatureSetpointHoldPolicyCommandParams - ); - result.put("readTemperatureSetpointHoldPolicyAttribute", readThermostatTemperatureSetpointHoldPolicyAttributeInteractionInfo); Map readThermostatSetpointHoldExpiryTimestampCommandParams = new LinkedHashMap(); InteractionInfo readThermostatSetpointHoldExpiryTimestampAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt index ed9077402e96af..66db507eb79cd5 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt @@ -582,33 +582,6 @@ class ThermostatCluster(private val controller: MatterController, private val en logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun setTemperatureSetpointHoldPolicy( - temperatureSetpointHoldPolicy: UByte, - timedInvokeTimeout: Duration? = null, - ) { - val commandId: UInt = 11u - - val tlvWriter = TlvWriter() - tlvWriter.startStructure(AnonymousTag) - - val TAG_TEMPERATURE_SETPOINT_HOLD_POLICY_REQ: Int = 0 - tlvWriter.put( - ContextSpecificTag(TAG_TEMPERATURE_SETPOINT_HOLD_POLICY_REQ), - temperatureSetpointHoldPolicy, - ) - tlvWriter.endStructure() - - val request: InvokeRequest = - InvokeRequest( - CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), - tlvPayload = tlvWriter.getEncoded(), - timedRequest = timedInvokeTimeout, - ) - - val response: InvokeResponse = controller.invoke(request) - logger.log(Level.FINE, "Invoke command succeeded: ${response}") - } - suspend fun readLocalTemperatureAttribute(): LocalTemperatureAttribute { val ATTRIBUTE_ID: UInt = 0u @@ -7557,103 +7530,8 @@ class ThermostatCluster(private val controller: MatterController, private val en } } - suspend fun readTemperatureSetpointHoldPolicyAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 83u - - val attributePath = - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - - val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - - val response = controller.read(readRequest) - - if (response.successes.isEmpty()) { - logger.log(Level.WARNING, "Read command failed") - throw IllegalStateException("Read command failed with failures: ${response.failures}") - } - - logger.log(Level.FINE, "Read command succeeded") - - val attributeData = - response.successes.filterIsInstance().firstOrNull { - it.path.attributeId == ATTRIBUTE_ID - } - - requireNotNull(attributeData) { - "Temperaturesetpointholdpolicy attribute not found in response" - } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - - return decodedValue - } - - suspend fun subscribeTemperatureSetpointHoldPolicyAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 83u - val attributePaths = - listOf( - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - ) - - val subscribeRequest: SubscribeRequest = - SubscribeRequest( - eventPaths = emptyList(), - attributePaths = attributePaths, - minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()), - ) - - return controller.subscribe(subscribeRequest).transform { subscriptionState -> - when (subscriptionState) { - is SubscriptionState.SubscriptionErrorNotification -> { - emit( - UByteSubscriptionState.Error( - Exception( - "Subscription terminated with error code: ${subscriptionState.terminationCause}" - ) - ) - ) - } - is SubscriptionState.NodeStateUpdate -> { - val attributeData = - subscriptionState.updateState.successes - .filterIsInstance() - .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - - requireNotNull(attributeData) { - "Temperaturesetpointholdpolicy attribute not found in Node State update" - } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - - decodedValue?.let { emit(UByteSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(UByteSubscriptionState.SubscriptionEstablished) - } - } - } - } - suspend fun readSetpointHoldExpiryTimestampAttribute(): SetpointHoldExpiryTimestampAttribute { - val ATTRIBUTE_ID: UInt = 84u + val ATTRIBUTE_ID: UInt = 83u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -7697,7 +7575,7 @@ class ThermostatCluster(private val controller: MatterController, private val en minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 84u + val ATTRIBUTE_ID: UInt = 83u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index b6702569d994d9..05d2eec28cd165 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -31025,22 +31025,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jnivalue, value); return value; } - case Attributes::TemperatureSetpointHoldPolicy::Id: { - using TypeInfo = Attributes::TemperatureSetpointHoldPolicy::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Raw()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } case Attributes::SetpointHoldExpiryTimestamp::Id: { using TypeInfo = Attributes::SetpointHoldExpiryTimestamp::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 6621bbc4bea2a6..108f38da1b7207 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -8846,13 +8846,6 @@ class ChipClusters: "args": { }, }, - 0x0000000B: { - "commandId": 0x0000000B, - "commandName": "SetTemperatureSetpointHoldPolicy", - "args": { - "temperatureSetpointHoldPolicy": "int", - }, - }, }, "attributes": { 0x00000000: { @@ -9245,14 +9238,8 @@ class ChipClusters: "reportable": True, }, 0x00000053: { - "attributeName": "TemperatureSetpointHoldPolicy", - "attributeId": 0x00000053, - "type": "int", - "reportable": True, - }, - 0x00000054: { "attributeName": "SetpointHoldExpiryTimestamp", - "attributeId": 0x00000054, + "attributeId": 0x00000053, "type": "int", "reportable": True, }, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index fe9a008e11066e..825b2ccf0acaa8 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -32116,8 +32116,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="presets", Tag=0x00000050, Type=typing.Optional[typing.List[Thermostat.Structs.PresetStruct]]), ClusterObjectFieldDescriptor(Label="schedules", Tag=0x00000051, Type=typing.Optional[typing.List[Thermostat.Structs.ScheduleStruct]]), ClusterObjectFieldDescriptor(Label="presetsSchedulesEditable", Tag=0x00000052, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="temperatureSetpointHoldPolicy", Tag=0x00000053, Type=typing.Optional[uint]), - ClusterObjectFieldDescriptor(Label="setpointHoldExpiryTimestamp", Tag=0x00000054, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="setpointHoldExpiryTimestamp", Tag=0x00000053, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), @@ -32186,7 +32185,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: presets: 'typing.Optional[typing.List[Thermostat.Structs.PresetStruct]]' = None schedules: 'typing.Optional[typing.List[Thermostat.Structs.ScheduleStruct]]' = None presetsSchedulesEditable: 'typing.Optional[bool]' = None - temperatureSetpointHoldPolicy: 'typing.Optional[uint]' = None setpointHoldExpiryTimestamp: 'typing.Union[None, Nullable, uint]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None @@ -32270,7 +32268,8 @@ class PresetScenarioEnum(MatterIntEnum): kSleep = 0x03 kWake = 0x04 kVacation = 0x05 - kUserDefined = 0x06 + kGoingToSleep = 0x06 + kUserDefined = 0xFE # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only # be used by code to process how it handles receiving an unknown @@ -32415,10 +32414,6 @@ class ScheduleTypeFeaturesBitmap(IntFlag): kSupportsNames = 0x4 kSupportsOff = 0x8 - class TemperatureSetpointHoldPolicyBitmap(IntFlag): - kHoldDurationElapsed = 0x1 - kHoldDurationElapsedOrPresetChanged = 0x2 - class Structs: @dataclass class ScheduleTransitionStruct(ClusterObject): @@ -32696,22 +32691,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ]) - @dataclass - class SetTemperatureSetpointHoldPolicy(ClusterCommand): - cluster_id: typing.ClassVar[int] = 0x00000201 - command_id: typing.ClassVar[int] = 0x0000000B - is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None - - @ChipUtility.classproperty - def descriptor(cls) -> ClusterObjectDescriptor: - return ClusterObjectDescriptor( - Fields=[ - ClusterObjectFieldDescriptor(Label="temperatureSetpointHoldPolicy", Tag=0, Type=uint), - ]) - - temperatureSetpointHoldPolicy: 'uint' = 0 - class Attributes: @dataclass class LocalTemperature(ClusterAttributeDescriptor): @@ -33673,22 +33652,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Optional[bool]' = None - @dataclass - class TemperatureSetpointHoldPolicy(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000201 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x00000053 - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - - value: 'typing.Optional[uint]' = None - @dataclass class SetpointHoldExpiryTimestamp(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -33697,7 +33660,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000054 + return 0x00000053 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 204d15937b23ca..0ac6c526d4e28a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -4161,9 +4161,6 @@ static BOOL AttributeIsSpecifiedInThermostatCluster(AttributeId aAttributeId) case Attributes::PresetsSchedulesEditable::Id: { return YES; } - case Attributes::TemperatureSetpointHoldPolicy::Id: { - return YES; - } case Attributes::SetpointHoldExpiryTimestamp::Id: { return YES; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index ca3cc6c5e620eb..7cd192c82730d0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -12470,17 +12470,6 @@ static id _Nullable DecodeAttributeValueForThermostatCluster(AttributeId aAttrib value = [NSNumber numberWithBool:cppValue]; return value; } - case Attributes::TemperatureSetpointHoldPolicy::Id: { - using TypeInfo = Attributes::TemperatureSetpointHoldPolicy::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - NSNumber * _Nonnull value; - value = [NSNumber numberWithUnsignedChar:cppValue.Raw()]; - return value; - } case Attributes::SetpointHoldExpiryTimestamp::Id: { using TypeInfo = Attributes::SetpointHoldExpiryTimestamp::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 2bcdb3fbc3919e..5a65a133266494 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -10021,12 +10021,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPresetsSchedulesRequestParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)commitPresetsSchedulesRequestWithCompletion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -/** - * Command SetTemperatureSetpointHoldPolicy - * - * This command sets the set point hold policy. - */ -- (void)setTemperatureSetpointHoldPolicyWithParams:(MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeLocalTemperatureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeLocalTemperatureWithParams:(MTRSubscribeParams *)params @@ -10446,12 +10440,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributePresetsSchedulesEditableWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeTemperatureSetpointHoldPolicyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeTemperatureSetpointHoldPolicyWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeTemperatureSetpointHoldPolicyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeSetpointHoldExpiryTimestampWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeSetpointHoldExpiryTimestampWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -19852,7 +19840,8 @@ typedef NS_ENUM(uint8_t, MTRThermostatPresetScenario) { MTRThermostatPresetScenarioSleep MTR_PROVISIONALLY_AVAILABLE = 0x03, MTRThermostatPresetScenarioWake MTR_PROVISIONALLY_AVAILABLE = 0x04, MTRThermostatPresetScenarioVacation MTR_PROVISIONALLY_AVAILABLE = 0x05, - MTRThermostatPresetScenarioUserDefined MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRThermostatPresetScenarioGoingToSleep MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRThermostatPresetScenarioUserDefined MTR_PROVISIONALLY_AVAILABLE = 0xFE, } MTR_PROVISIONALLY_AVAILABLE; typedef NS_ENUM(uint8_t, MTRThermostatSetpointChangeSource) { @@ -20009,11 +19998,6 @@ typedef NS_OPTIONS(uint16_t, MTRThermostatScheduleTypeFeaturesBitmap) { MTRThermostatScheduleTypeFeaturesBitmapSupportsOff MTR_PROVISIONALLY_AVAILABLE = 0x8, } MTR_PROVISIONALLY_AVAILABLE; -typedef NS_OPTIONS(uint8_t, MTRThermostatTemperatureSetpointHoldPolicyBitmap) { - MTRThermostatTemperatureSetpointHoldPolicyBitmapHoldDurationElapsed MTR_PROVISIONALLY_AVAILABLE = 0x1, - MTRThermostatTemperatureSetpointHoldPolicyBitmapHoldDurationElapsedOrPresetChanged MTR_PROVISIONALLY_AVAILABLE = 0x2, -} MTR_PROVISIONALLY_AVAILABLE; - typedef NS_ENUM(uint8_t, MTRFanControlAirflowDirection) { MTRFanControlAirflowDirectionForward MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00, MTRFanControlAirflowDirectionReverse MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x01, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 641fea65515da4..b86c955162ba7f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -67977,30 +67977,6 @@ - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPrese queue:self.callbackQueue completion:responseHandler]; } -- (void)setTemperatureSetpointHoldPolicyWithParams:(MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams *)params completion:(MTRStatusCompletion)completion -{ - if (params == nil) { - params = [[MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams - alloc] init]; - } - - auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); - }; - - auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - - using RequestType = Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Type; - [self.device _invokeKnownCommandWithEndpointID:self.endpointID - clusterID:@(RequestType::GetClusterId()) - commandID:@(RequestType::GetCommandId()) - commandPayload:params - timedInvokeTimeout:timedInvokeTimeoutMs - serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:nil - queue:self.callbackQueue - completion:responseHandler]; -} - (void)readAttributeLocalTemperatureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { @@ -71122,42 +71098,6 @@ + (void)readAttributePresetsSchedulesEditableWithClusterStateCache:(MTRClusterSt completion:completion]; } -- (void)readAttributeTemperatureSetpointHoldPolicyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldPolicy::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeTemperatureSetpointHoldPolicyWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldPolicy::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeTemperatureSetpointHoldPolicyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldPolicy::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeSetpointHoldExpiryTimestampWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Thermostat::Attributes::SetpointHoldExpiryTimestamp::TypeInfo; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 2178edd403cfe4..a1cad5bc1daac7 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -3487,8 +3487,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterThermostatAttributePresetsID MTR_PROVISIONALLY_AVAILABLE = 0x00000050, MTRAttributeIDTypeClusterThermostatAttributeSchedulesID MTR_PROVISIONALLY_AVAILABLE = 0x00000051, MTRAttributeIDTypeClusterThermostatAttributePresetsSchedulesEditableID MTR_PROVISIONALLY_AVAILABLE = 0x00000052, - MTRAttributeIDTypeClusterThermostatAttributeTemperatureSetpointHoldPolicyID MTR_PROVISIONALLY_AVAILABLE = 0x00000053, - MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID MTR_PROVISIONALLY_AVAILABLE = 0x00000054, + MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID MTR_PROVISIONALLY_AVAILABLE = 0x00000053, MTRAttributeIDTypeClusterThermostatAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterThermostatAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterThermostatAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -6609,7 +6608,6 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterThermostatCommandStartPresetsSchedulesEditRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, MTRCommandIDTypeClusterThermostatCommandCancelPresetsSchedulesEditRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000008, MTRCommandIDTypeClusterThermostatCommandCommitPresetsSchedulesRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000009, - MTRCommandIDTypeClusterThermostatCommandSetTemperatureSetpointHoldPolicyID MTR_PROVISIONALLY_AVAILABLE = 0x0000000B, // Cluster FanControl deprecated command id names diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 575661bfa078bd..b203f24497beba 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -5769,10 +5769,6 @@ result = @"PresetsSchedulesEditable"; break; - case MTRAttributeIDTypeClusterThermostatAttributeTemperatureSetpointHoldPolicyID: - result = @"TemperatureSetpointHoldPolicy"; - break; - case MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID: result = @"SetpointHoldExpiryTimestamp"; break; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index cefb92935beab4..f3b47900708ab6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -4653,7 +4653,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPresetsSchedulesRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)commitPresetsSchedulesRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)setTemperatureSetpointHoldPolicyWithParams:(MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeLocalTemperatureWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -4833,8 +4832,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributePresetsSchedulesEditableWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeTemperatureSetpointHoldPolicyWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeSetpointHoldExpiryTimestampWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 8c38a6c584b79e..ee4a956c548363 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -13331,33 +13331,6 @@ - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPrese completion:responseHandler]; } -- (void)setTemperatureSetpointHoldPolicyWithParams:(MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion -{ - if (params == nil) { - params = [[MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams - alloc] init]; - } - - auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); - }; - - auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - - using RequestType = Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Type; - [self.device _invokeKnownCommandWithEndpointID:self.endpointID - clusterID:@(RequestType::GetClusterId()) - commandID:@(RequestType::GetCommandId()) - commandPayload:params - expectedValues:expectedValues - expectedValueInterval:expectedValueIntervalMs - timedInvokeTimeout:timedInvokeTimeoutMs - serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:nil - queue:self.callbackQueue - completion:responseHandler]; -} - - (NSDictionary * _Nullable)readAttributeLocalTemperatureWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeLocalTemperatureID) params:params]; @@ -13977,11 +13950,6 @@ - (void)writeAttributeSchedulesWithValue:(NSDictionary *)dataVal return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributePresetsSchedulesEditableID) params:params]; } -- (NSDictionary * _Nullable)readAttributeTemperatureSetpointHoldPolicyWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeTemperatureSetpointHoldPolicyID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeSetpointHoldExpiryTimestampWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID) params:params]; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 3746227a4f9d21..f51f2e2c8c5396 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -7948,36 +7948,6 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end -MTR_PROVISIONALLY_AVAILABLE -@interface MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams : NSObject - -@property (nonatomic, copy) NSNumber * _Nonnull temperatureSetpointHoldPolicy MTR_PROVISIONALLY_AVAILABLE; -/** - * Controls whether the command is a timed command (using Timed Invoke). - * - * If nil (the default value), a regular invoke is done for commands that do - * not require a timed invoke and a timed invoke with some default timed request - * timeout is done for commands that require a timed invoke. - * - * If not nil, a timed invoke is done, with the provided value used as the timed - * request timeout. The value should be chosen small enough to provide the - * desired security properties but large enough that it will allow a round-trip - * from the sever to the client (for the status response and actual invoke - * request) within the timeout window. - * - */ -@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; - -/** - * Controls how much time, in seconds, we will allow for the server to process the command. - * - * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. - * - * If nil, the framework will try to select an appropriate timeout value itself. - */ -@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; -@end - MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) @interface MTRFanControlClusterStepParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index 8d18518670e808..6d6b7ace93c3cc 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -22650,85 +22650,6 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams -- (instancetype)init -{ - if (self = [super init]) { - - _temperatureSetpointHoldPolicy = @(0); - _timedInvokeTimeoutMs = nil; - _serverSideProcessingTimeout = nil; - } - return self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone; -{ - auto other = [[MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams alloc] init]; - - other.temperatureSetpointHoldPolicy = self.temperatureSetpointHoldPolicy; - other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; - other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; - - return other; -} - -- (NSString *)description -{ - NSString * descriptionString = [NSString stringWithFormat:@"<%@: temperatureSetpointHoldPolicy:%@; >", NSStringFromClass([self class]), _temperatureSetpointHoldPolicy]; - return descriptionString; -} - -@end - -@implementation MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams (InternalMethods) - -- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader -{ - chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Type encodableStruct; - ListFreer listFreer; - { - encodableStruct.temperatureSetpointHoldPolicy = static_cast>(self.temperatureSetpointHoldPolicy.unsignedCharValue); - } - - auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); - if (buffer.IsNull()) { - return CHIP_ERROR_NO_MEMORY; - } - - chip::System::PacketBufferTLVWriter writer; - // Commands never need chained buffers, since they cannot be chunked. - writer.Init(std::move(buffer), /* useChainedBuffers = */ false); - - ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); - - ReturnErrorOnFailure(writer.Finalize(&buffer)); - - reader.Init(std::move(buffer)); - return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); -} - -- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error -{ - chip::System::PacketBufferTLVReader reader; - CHIP_ERROR err = [self _encodeToTLVReader:reader]; - if (err != CHIP_NO_ERROR) { - if (error) { - *error = [MTRError errorForCHIPErrorCode:err]; - } - return nil; - } - - auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); - if (decodedObj == nil) { - if (error) { - *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; - } - } - return decodedObj; -} -@end - @implementation MTRFanControlClusterStepParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index 67c37229a00dcc..cc995035f0907b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -1492,12 +1492,6 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams (InternalMethods) - -- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; - -@end - @interface MTRFanControlClusterStepParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 0c974b62593860..466bba42d3a81c 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -26208,56 +26208,6 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value) } // namespace PresetsSchedulesEditable -namespace TemperatureSetpointHoldPolicy { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * value) -{ - using Traits = NumericAttributeTraits>; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); -} - -} // namespace TemperatureSetpointHoldPolicy - namespace SetpointHoldExpiryTimestamp { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index 45b29d719e47eb..aa215c07fbc1cd 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -4093,17 +4093,6 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, MarkAttributeDirty markDirty); } // namespace PresetsSchedulesEditable -namespace TemperatureSetpointHoldPolicy { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * - value); // TemperatureSetpointHoldPolicyBitmap -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty); -} // namespace TemperatureSetpointHoldPolicy - namespace SetpointHoldExpiryTimestamp { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // epoch_s Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index f1aa9705d7c8c3..29323ab7ca3769 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -6360,12 +6360,6 @@ bool emberAfThermostatClusterCancelPresetsSchedulesEditRequestCallback( bool emberAfThermostatClusterCommitPresetsSchedulesRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::CommitPresetsSchedulesRequest::DecodableType & commandData); -/** - * @brief Thermostat Cluster SetTemperatureSetpointHoldPolicy Command callback (from client) - */ -bool emberAfThermostatClusterSetTemperatureSetpointHoldPolicyCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::DecodableType & commandData); /** * @brief Fan Control Cluster Step Command callback (from client) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h index af96e92e1dc3a7..689e8fc0a88058 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h @@ -2701,6 +2701,7 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(Thermostat::PresetScena case EnumType::kSleep: case EnumType::kWake: case EnumType::kVacation: + case EnumType::kGoingToSleep: case EnumType::kUserDefined: return val; default: diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 8a15f1f0b1bac1..aac4e46a8dbcb6 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -3964,13 +3964,14 @@ enum class ControlSequenceOfOperationEnum : uint8_t // Enum for PresetScenarioEnum enum class PresetScenarioEnum : uint8_t { - kUnspecified = 0x00, - kOccupied = 0x01, - kUnoccupied = 0x02, - kSleep = 0x03, - kWake = 0x04, - kVacation = 0x05, - kUserDefined = 0x06, + kUnspecified = 0x00, + kOccupied = 0x01, + kUnoccupied = 0x02, + kSleep = 0x03, + kWake = 0x04, + kVacation = 0x05, + kGoingToSleep = 0x06, + kUserDefined = 0xFE, // All received enum values that are not listed above will be mapped // to kUnknownEnumValue. This is a helper enum value that should only // be used by code to process how it handles receiving and unknown @@ -4162,13 +4163,6 @@ enum class ScheduleTypeFeaturesBitmap : uint16_t kSupportsNames = 0x4, kSupportsOff = 0x8, }; - -// Bitmap for TemperatureSetpointHoldPolicyBitmap -enum class TemperatureSetpointHoldPolicyBitmap : uint8_t -{ - kHoldDurationElapsed = 0x1, - kHoldDurationElapsedOrPresetChanged = 0x2, -}; } // namespace Thermostat namespace FanControl { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 2a3e9856803f68..e9758165204fd1 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -21358,40 +21358,6 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace CommitPresetsSchedulesRequest. -namespace SetTemperatureSetpointHoldPolicy { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const -{ - DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kTemperatureSetpointHoldPolicy), temperatureSetpointHoldPolicy); - return encoder.Finalize(); -} - -CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) -{ - detail::StructDecodeIterator __iterator(reader); - while (true) - { - auto __element = __iterator.Next(); - if (std::holds_alternative(__element)) - { - return std::get(__element); - } - - CHIP_ERROR err = CHIP_NO_ERROR; - const uint8_t __context_tag = std::get(__element); - - if (__context_tag == to_underlying(Fields::kTemperatureSetpointHoldPolicy)) - { - err = DataModel::Decode(reader, temperatureSetpointHoldPolicy); - } - else - { - } - - ReturnErrorOnFailure(err); - } -} -} // namespace SetTemperatureSetpointHoldPolicy. } // namespace Commands namespace Attributes { @@ -21519,8 +21485,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, schedules); case Attributes::PresetsSchedulesEditable::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, presetsSchedulesEditable); - case Attributes::TemperatureSetpointHoldPolicy::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, temperatureSetpointHoldPolicy); case Attributes::SetpointHoldExpiryTimestamp::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, setpointHoldExpiryTimestamp); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 81be5e1224e81d..ca860cc22e8580 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -29360,11 +29360,6 @@ struct Type; struct DecodableType; } // namespace CommitPresetsSchedulesRequest -namespace SetTemperatureSetpointHoldPolicy { -struct Type; -struct DecodableType; -} // namespace SetTemperatureSetpointHoldPolicy - } // namespace Commands namespace Commands { @@ -29700,40 +29695,6 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace CommitPresetsSchedulesRequest -namespace SetTemperatureSetpointHoldPolicy { -enum class Fields : uint8_t -{ - kTemperatureSetpointHoldPolicy = 0, -}; - -struct Type -{ -public: - // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand - static constexpr CommandId GetCommandId() { return Commands::SetTemperatureSetpointHoldPolicy::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } - - chip::BitMask temperatureSetpointHoldPolicy = - static_cast>(0); - - CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; - - using ResponseType = DataModel::NullObjectType; - - static constexpr bool MustUseTimedInvoke() { return false; } -}; - -struct DecodableType -{ -public: - static constexpr CommandId GetCommandId() { return Commands::SetTemperatureSetpointHoldPolicy::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } - - chip::BitMask temperatureSetpointHoldPolicy = - static_cast>(0); - CHIP_ERROR Decode(TLV::TLVReader & reader); -}; -}; // namespace SetTemperatureSetpointHoldPolicy } // namespace Commands namespace Attributes { @@ -30468,18 +30429,6 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace PresetsSchedulesEditable -namespace TemperatureSetpointHoldPolicy { -struct TypeInfo -{ - using Type = chip::BitMask; - using DecodableType = chip::BitMask; - using DecodableArgType = chip::BitMask; - - static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::TemperatureSetpointHoldPolicy::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace TemperatureSetpointHoldPolicy namespace SetpointHoldExpiryTimestamp { struct TypeInfo { @@ -30611,8 +30560,6 @@ struct TypeInfo Attributes::Presets::TypeInfo::DecodableType presets; Attributes::Schedules::TypeInfo::DecodableType schedules; Attributes::PresetsSchedulesEditable::TypeInfo::DecodableType presetsSchedulesEditable = static_cast(0); - Attributes::TemperatureSetpointHoldPolicy::TypeInfo::DecodableType temperatureSetpointHoldPolicy = - static_cast>(0); Attributes::SetpointHoldExpiryTimestamp::TypeInfo::DecodableType setpointHoldExpiryTimestamp; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index c1d26d64c5d27b..b1594019530084 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -5186,12 +5186,8 @@ namespace PresetsSchedulesEditable { static constexpr AttributeId Id = 0x00000052; } // namespace PresetsSchedulesEditable -namespace TemperatureSetpointHoldPolicy { -static constexpr AttributeId Id = 0x00000053; -} // namespace TemperatureSetpointHoldPolicy - namespace SetpointHoldExpiryTimestamp { -static constexpr AttributeId Id = 0x00000054; +static constexpr AttributeId Id = 0x00000053; } // namespace SetpointHoldExpiryTimestamp namespace GeneratedCommandList { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index 926df4190a620e..3b43aaa04ff534 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -1338,10 +1338,6 @@ namespace CommitPresetsSchedulesRequest { static constexpr CommandId Id = 0x00000009; } // namespace CommitPresetsSchedulesRequest -namespace SetTemperatureSetpointHoldPolicy { -static constexpr CommandId Id = 0x0000000B; -} // namespace SetTemperatureSetpointHoldPolicy - } // namespace Commands } // namespace Thermostat diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 273f743a19cf00..96251683bc82d8 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -9435,7 +9435,6 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand | * StartPresetsSchedulesEditRequest | 0x07 | | * CancelPresetsSchedulesEditRequest | 0x08 | | * CommitPresetsSchedulesRequest | 0x09 | -| * SetTemperatureSetpointHoldPolicy | 0x0B | |------------------------------------------------------------------------------| | Attributes: | | | * LocalTemperature | 0x0000 | @@ -9498,8 +9497,7 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand | * Presets | 0x0050 | | * Schedules | 0x0051 | | * PresetsSchedulesEditable | 0x0052 | -| * TemperatureSetpointHoldPolicy | 0x0053 | -| * SetpointHoldExpiryTimestamp | 0x0054 | +| * SetpointHoldExpiryTimestamp | 0x0053 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -9857,44 +9855,6 @@ class ThermostatCommitPresetsSchedulesRequest : public ClusterCommand chip::app::Clusters::Thermostat::Commands::CommitPresetsSchedulesRequest::Type mRequest; }; -/* - * Command SetTemperatureSetpointHoldPolicy - */ -class ThermostatSetTemperatureSetpointHoldPolicy : public ClusterCommand -{ -public: - ThermostatSetTemperatureSetpointHoldPolicy(CredentialIssuerCommands * credsIssuerConfig) : - ClusterCommand("set-temperature-setpoint-hold-policy", credsIssuerConfig) - { - AddArgument("TemperatureSetpointHoldPolicy", 0, UINT8_MAX, &mRequest.temperatureSetpointHoldPolicy); - ClusterCommand::AddArguments(); - } - - CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, - commandId, endpointIds.at(0)); - return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); - } - - CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, - groupId); - - return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); - } - -private: - chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Type mRequest; -}; - /*----------------------------------------------------------------------------*\ | Cluster FanControl | 0x0202 | |------------------------------------------------------------------------------| @@ -22991,7 +22951,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // - make_unique(credsIssuerConfig), // // // Attributes // @@ -23073,8 +23032,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "schedules", Attributes::Schedules::Id, credsIssuerConfig), // make_unique(Id, "presets-schedules-editable", Attributes::PresetsSchedulesEditable::Id, credsIssuerConfig), // - make_unique(Id, "temperature-setpoint-hold-policy", Attributes::TemperatureSetpointHoldPolicy::Id, - credsIssuerConfig), // make_unique(Id, "setpoint-hold-expiry-timestamp", Attributes::SetpointHoldExpiryTimestamp::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // @@ -23243,9 +23200,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c Id, "schedules", Attributes::Schedules::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "presets-schedules-editable", 0, 1, Attributes::PresetsSchedulesEditable::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "temperature-setpoint-hold-policy", 0, UINT8_MAX, Attributes::TemperatureSetpointHoldPolicy::Id, - WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>(Id, "setpoint-hold-expiry-timestamp", 0, UINT32_MAX, Attributes::SetpointHoldExpiryTimestamp::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -23344,8 +23298,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "schedules", Attributes::Schedules::Id, credsIssuerConfig), // make_unique(Id, "presets-schedules-editable", Attributes::PresetsSchedulesEditable::Id, credsIssuerConfig), // - make_unique(Id, "temperature-setpoint-hold-policy", Attributes::TemperatureSetpointHoldPolicy::Id, - credsIssuerConfig), // make_unique(Id, "setpoint-hold-expiry-timestamp", Attributes::SetpointHoldExpiryTimestamp::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index c6c1231bab95d1..e6fa05f0ba1d1d 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -14980,11 +14980,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("PresetsSchedulesEditable", 1, value); } - case Thermostat::Attributes::TemperatureSetpointHoldPolicy::Id: { - chip::BitMask value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("TemperatureSetpointHoldPolicy", 1, value); - } case Thermostat::Attributes::SetpointHoldExpiryTimestamp::Id: { chip::app::DataModel::Nullable value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 8ebe6735d29dd0..a203b988880e5e 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -106873,7 +106873,6 @@ class SubscribeAttributePumpConfigurationAndControlClusterRevision : public Subs | * StartPresetsSchedulesEditRequest | 0x07 | | * CancelPresetsSchedulesEditRequest | 0x08 | | * CommitPresetsSchedulesRequest | 0x09 | -| * SetTemperatureSetpointHoldPolicy | 0x0B | |------------------------------------------------------------------------------| | Attributes: | | | * LocalTemperature | 0x0000 | @@ -106936,8 +106935,7 @@ class SubscribeAttributePumpConfigurationAndControlClusterRevision : public Subs | * Presets | 0x0050 | | * Schedules | 0x0051 | | * PresetsSchedulesEditable | 0x0052 | -| * TemperatureSetpointHoldPolicy | 0x0053 | -| * SetpointHoldExpiryTimestamp | 0x0054 | +| * SetpointHoldExpiryTimestamp | 0x0053 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -107420,59 +107418,6 @@ class ThermostatCommitPresetsSchedulesRequest : public ClusterCommand { private: }; -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL -/* - * Command SetTemperatureSetpointHoldPolicy - */ -class ThermostatSetTemperatureSetpointHoldPolicy : public ClusterCommand { -public: - ThermostatSetTemperatureSetpointHoldPolicy() - : ClusterCommand("set-temperature-setpoint-hold-policy") - { -#if MTR_ENABLE_PROVISIONAL - AddArgument("TemperatureSetpointHoldPolicy", 0, UINT8_MAX, &mRequest.temperatureSetpointHoldPolicy); -#endif // MTR_ENABLE_PROVISIONAL - ClusterCommand::AddArguments(); - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); - __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams alloc] init]; - params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; -#if MTR_ENABLE_PROVISIONAL - params.temperatureSetpointHoldPolicy = [NSNumber numberWithUnsignedChar:mRequest.temperatureSetpointHoldPolicy.Raw()]; -#endif // MTR_ENABLE_PROVISIONAL - uint16_t repeatCount = mRepeatCount.ValueOr(1); - uint16_t __block responsesNeeded = repeatCount; - while (repeatCount--) { - [cluster setTemperatureSetpointHoldPolicyWithParams:params completion: - ^(NSError * _Nullable error) { - responsesNeeded--; - if (error != nil) { - mError = error; - LogNSError("Error", error); - RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); - } - if (responsesNeeded == 0) { - SetCommandExitStatus(mError); - } - }]; - } - return CHIP_NO_ERROR; - } - -private: - chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Type mRequest; -}; - #endif // MTR_ENABLE_PROVISIONAL /* @@ -113736,91 +113681,6 @@ class SubscribeAttributeThermostatPresetsSchedulesEditable : public SubscribeAtt #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute TemperatureSetpointHoldPolicy - */ -class ReadThermostatTemperatureSetpointHoldPolicy : public ReadAttribute { -public: - ReadThermostatTemperatureSetpointHoldPolicy() - : ReadAttribute("temperature-setpoint-hold-policy") - { - } - - ~ReadThermostatTemperatureSetpointHoldPolicy() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Thermostat::Attributes::TemperatureSetpointHoldPolicy::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); - __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeTemperatureSetpointHoldPolicyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"Thermostat.TemperatureSetpointHoldPolicy response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Thermostat TemperatureSetpointHoldPolicy read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeThermostatTemperatureSetpointHoldPolicy : public SubscribeAttribute { -public: - SubscribeAttributeThermostatTemperatureSetpointHoldPolicy() - : SubscribeAttribute("temperature-setpoint-hold-policy") - { - } - - ~SubscribeAttributeThermostatTemperatureSetpointHoldPolicy() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Thermostat::Attributes::TemperatureSetpointHoldPolicy::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); - __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeTemperatureSetpointHoldPolicyWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"Thermostat.TemperatureSetpointHoldPolicy response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute SetpointHoldExpiryTimestamp */ @@ -194926,9 +194786,6 @@ void registerClusterThermostat(Commands & commands) #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // #endif // MTR_ENABLE_PROVISIONAL make_unique(Id), // make_unique(Id), // @@ -195104,10 +194961,6 @@ void registerClusterThermostat(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), //