Skip to content

Commit ee21e73

Browse files
Matter Thermostat: Use fanMode capability
This change replaces the use of thermostatFanMode with fanMode, to better align with the fan modes and sequences defined by the Fan Control cluster. Also, fanMode is now used in fan profiles over airConditionerFanMode.
1 parent 8b3c80f commit ee21e73

File tree

8 files changed

+219
-215
lines changed

8 files changed

+219
-215
lines changed

drivers/SmartThings/matter-thermostat/profiles/thermostat-modular.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ components:
66
version: 1
77
- id: thermostatMode
88
version: 1
9-
- id: thermostatFanMode
9+
- id: fanMode
1010
version: 1
1111
optional: true
1212
- id: thermostatHeatingSetpoint

drivers/SmartThings/matter-thermostat/src/init.lua

Lines changed: 104 additions & 187 deletions
Large diffs are not rendered by default.

drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier.lua

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ local mock_device_rock = test.mock_device.build_test_matter_device({
7878
}
7979
},
8080
{
81-
endpoint_id = 1,
82-
clusters = {
83-
{cluster_id = clusters.FanControl.ID, cluster_type = "SERVER"},
84-
{cluster_id = clusters.HepaFilterMonitoring.ID, cluster_type = "SERVER"},
85-
{cluster_id = clusters.ActivatedCarbonFilterMonitoring.ID, cluster_type = "SERVER"},
86-
}
81+
endpoint_id = 1,
82+
clusters = {
83+
{cluster_id = clusters.FanControl.ID, cluster_type = "SERVER"},
84+
{cluster_id = clusters.HepaFilterMonitoring.ID, cluster_type = "SERVER"},
85+
{cluster_id = clusters.ActivatedCarbonFilterMonitoring.ID, cluster_type = "SERVER"},
8786
}
87+
}
8888
}
8989
})
9090

drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier_modular.lua

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-- Copyright 2024 SmartThings
1+
-- Copyright 2025 SmartThings
22
--
33
-- Licensed under the Apache License, Version 2.0 (the "License");
44
-- you may not use this file except in compliance with the License.
@@ -12,28 +12,29 @@
1212
-- See the License for the specific language governing permissions and
1313
-- limitations under the License.
1414
local test = require "integration_test"
15+
test.set_rpc_version(8)
1516
local capabilities = require "st.capabilities"
1617
local t_utils = require "integration_test.utils"
1718
local utils = require "st.utils"
1819
local dkjson = require "dkjson"
19-
2020
local clusters = require "st.matter.clusters"
21+
local version = require "version"
2122

22-
clusters.HepaFilterMonitoring = require "HepaFilterMonitoring"
23-
clusters.ActivatedCarbonFilterMonitoring = require "ActivatedCarbonFilterMonitoring"
24-
clusters.AirQuality = require "AirQuality"
25-
clusters.CarbonMonoxideConcentrationMeasurement = require "CarbonMonoxideConcentrationMeasurement"
26-
clusters.CarbonDioxideConcentrationMeasurement = require "CarbonDioxideConcentrationMeasurement"
27-
clusters.FormaldehydeConcentrationMeasurement = require "FormaldehydeConcentrationMeasurement"
28-
clusters.NitrogenDioxideConcentrationMeasurement = require "NitrogenDioxideConcentrationMeasurement"
29-
clusters.OzoneConcentrationMeasurement = require "OzoneConcentrationMeasurement"
30-
clusters.Pm1ConcentrationMeasurement = require "Pm1ConcentrationMeasurement"
31-
clusters.Pm10ConcentrationMeasurement = require "Pm10ConcentrationMeasurement"
32-
clusters.Pm25ConcentrationMeasurement = require "Pm25ConcentrationMeasurement"
33-
clusters.RadonConcentrationMeasurement = require "RadonConcentrationMeasurement"
34-
clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement = require "TotalVolatileOrganicCompoundsConcentrationMeasurement"
35-
36-
test.set_rpc_version(8)
23+
if version.api < 10 then
24+
clusters.HepaFilterMonitoring = require "HepaFilterMonitoring"
25+
clusters.ActivatedCarbonFilterMonitoring = require "ActivatedCarbonFilterMonitoring"
26+
clusters.AirQuality = require "AirQuality"
27+
clusters.CarbonMonoxideConcentrationMeasurement = require "CarbonMonoxideConcentrationMeasurement"
28+
clusters.CarbonDioxideConcentrationMeasurement = require "CarbonDioxideConcentrationMeasurement"
29+
clusters.FormaldehydeConcentrationMeasurement = require "FormaldehydeConcentrationMeasurement"
30+
clusters.NitrogenDioxideConcentrationMeasurement = require "NitrogenDioxideConcentrationMeasurement"
31+
clusters.OzoneConcentrationMeasurement = require "OzoneConcentrationMeasurement"
32+
clusters.Pm1ConcentrationMeasurement = require "Pm1ConcentrationMeasurement"
33+
clusters.Pm10ConcentrationMeasurement = require "Pm10ConcentrationMeasurement"
34+
clusters.Pm25ConcentrationMeasurement = require "Pm25ConcentrationMeasurement"
35+
clusters.RadonConcentrationMeasurement = require "RadonConcentrationMeasurement"
36+
clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement = require "TotalVolatileOrganicCompoundsConcentrationMeasurement"
37+
end
3738

3839
local mock_device_basic = test.mock_device.build_test_matter_device({
3940
profile = t_utils.get_profile_definition("air-purifier-hepa-ac-wind.yml"),
@@ -162,7 +163,7 @@ local cluster_subscribe_list_configured = {
162163
clusters.Thermostat.attributes.SystemMode,
163164
clusters.Thermostat.attributes.ControlSequenceOfOperation
164165
},
165-
[capabilities.thermostatFanMode.ID] = {
166+
[capabilities.fanMode.ID] = {
166167
clusters.FanControl.attributes.FanModeSequence,
167168
clusters.FanControl.attributes.FanMode
168169
},

drivers/SmartThings/matter-thermostat/src/test/test_matter_fan.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-- Copyright 2024 SmartThings
1+
-- Copyright 2025 SmartThings
22
--
33
-- Licensed under the Apache License, Version 2.0 (the "License");
44
-- you may not use this file except in compliance with the License.
@@ -74,6 +74,7 @@ local mock_device_generic = test.mock_device.build_test_matter_device({
7474

7575
local cluster_subscribe_list = {
7676
clusters.FanControl.attributes.FanMode,
77+
clusters.FanControl.attributes.FanModeSequence,
7778
clusters.FanControl.attributes.PercentCurrent,
7879
clusters.FanControl.attributes.WindSupport,
7980
clusters.FanControl.attributes.WindSetting,
@@ -83,6 +84,7 @@ local cluster_subscribe_list = {
8384

8485
local cluster_subscribe_list_generic = {
8586
clusters.FanControl.attributes.FanMode,
87+
clusters.FanControl.attributes.FanModeSequence,
8688
clusters.FanControl.attributes.PercentCurrent,
8789
}
8890

drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac.lua

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ local function test_init()
142142
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit
143143
},
144144
[capabilities.airConditionerFanMode.ID] = {
145+
clusters.FanControl.attributes.FanModeSequence,
145146
clusters.FanControl.attributes.FanMode
146147
},
147148
[capabilities.fanSpeedPercent.ID] = {
@@ -199,6 +200,7 @@ local function test_init_configure()
199200
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit
200201
},
201202
[capabilities.airConditionerFanMode.ID] = {
203+
clusters.FanControl.attributes.FanModeSequence,
202204
clusters.FanControl.attributes.FanMode
203205
},
204206
[capabilities.fanSpeedPercent.ID] = {
@@ -253,6 +255,7 @@ local function test_init_nostate()
253255
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit
254256
},
255257
[capabilities.airConditionerFanMode.ID] = {
258+
clusters.FanControl.attributes.FanModeSequence,
256259
clusters.FanControl.attributes.FanMode
257260
},
258261
[capabilities.fanSpeedPercent.ID] = {
@@ -401,4 +404,82 @@ test.register_message_test(
401404
}
402405
)
403406

407+
test.register_message_test(
408+
"Test fan mode handler",
409+
{
410+
{
411+
channel = "matter",
412+
direction = "receive",
413+
message = {
414+
mock_device.id,
415+
clusters.FanControl.attributes.FanMode:build_test_report_data(mock_device, 1, clusters.FanControl.attributes.FanMode.OFF)
416+
}
417+
},
418+
{
419+
channel = "capability",
420+
direction = "send",
421+
message = mock_device:generate_test_message("main", capabilities.airConditionerFanMode.fanMode("off"))
422+
},
423+
{
424+
channel = "matter",
425+
direction = "receive",
426+
message = {
427+
mock_device.id,
428+
clusters.FanControl.attributes.FanMode:build_test_report_data(mock_device, 1, clusters.FanControl.attributes.FanMode.LOW)
429+
}
430+
},
431+
{
432+
channel = "capability",
433+
direction = "send",
434+
message = mock_device:generate_test_message("main", capabilities.airConditionerFanMode.fanMode("low"))
435+
},
436+
{
437+
channel = "matter",
438+
direction = "receive",
439+
message = {
440+
mock_device.id,
441+
clusters.FanControl.attributes.FanMode:build_test_report_data(mock_device, 1, clusters.FanControl.attributes.FanMode.HIGH)
442+
}
443+
},
444+
{
445+
channel = "capability",
446+
direction = "send",
447+
message = mock_device:generate_test_message("main", capabilities.airConditionerFanMode.fanMode("high"))
448+
}
449+
}
450+
)
451+
452+
local FanModeSequence = clusters.FanControl.attributes.FanModeSequence
453+
test.register_message_test(
454+
"Room AC fan mode sequence reports should generate the appropriate supported modes",
455+
{
456+
{
457+
channel = "matter",
458+
direction = "receive",
459+
message = {
460+
mock_device.id,
461+
FanModeSequence:build_test_report_data(mock_device, 1, FanModeSequence.OFF_ON)
462+
}
463+
},
464+
{
465+
channel = "capability",
466+
direction = "send",
467+
message = mock_device:generate_test_message("main", capabilities.airConditionerFanMode.supportedAcFanModes({"off", "high"}, {visibility={displayed=false}}))
468+
},
469+
{
470+
channel = "matter",
471+
direction = "receive",
472+
message = {
473+
mock_device.id,
474+
FanModeSequence:build_test_report_data(mock_device, 1, FanModeSequence.OFF_LOW_MED_HIGH_AUTO)
475+
}
476+
},
477+
{
478+
channel = "capability",
479+
direction = "send",
480+
message = mock_device:generate_test_message("main", capabilities.airConditionerFanMode.supportedAcFanModes({"off", "low", "medium", "high", "auto"}, {visibility={displayed=false}}))
481+
}
482+
}
483+
)
484+
404485
test.run_registered_tests()

drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac_modular.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ local function test_init_basic()
134134
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit
135135
},
136136
[capabilities.airConditionerFanMode.ID] = {
137+
clusters.FanControl.attributes.FanModeSequence,
137138
clusters.FanControl.attributes.FanMode
138139
},
139140
[capabilities.fanSpeedPercent.ID] = {
@@ -180,6 +181,7 @@ local subscribed_attributes_no_state = {
180181
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit
181182
},
182183
[capabilities.airConditionerFanMode.ID] = {
184+
clusters.FanControl.attributes.FanModeSequence,
183185
clusters.FanControl.attributes.FanMode
184186
},
185187
[capabilities.fanSpeedPercent.ID] = {
@@ -235,6 +237,7 @@ local function test_init_no_state()
235237
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit
236238
},
237239
[capabilities.airConditionerFanMode.ID] = {
240+
clusters.FanControl.attributes.FanModeSequence,
238241
clusters.FanControl.attributes.FanMode
239242
},
240243
[capabilities.fanSpeedPercent.ID] = {

drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_modular.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-- Copyright 2023 SmartThings
1+
-- Copyright 2025 SmartThings
22
--
33
-- Licensed under the Apache License, Version 2.0 (the "License");
44
-- you may not use this file except in compliance with the License.
@@ -110,7 +110,7 @@ local expected_metadata = {
110110
"main",
111111
{
112112
"relativeHumidityMeasurement",
113-
"thermostatFanMode",
113+
"fanMode",
114114
"thermostatHeatingSetpoint",
115115
"thermostatCoolingSetpoint"
116116
},

0 commit comments

Comments
 (0)