Repository navigation
Matter Thermostat driver ignores configurable Min/Max heating and cooling setpoint limits #3263
Description
Summary
The Matter Thermostat driver uses only the absolute setpoint limits (AbsMin* / AbsMax*) for SmartThings range events and command validation. It does not handle the configurable limits:
MinHeatSetpointLimitMaxHeatSetpointLimitMinCoolSetpointLimitMaxCoolSetpointLimit
This can make the SmartThings range wider than the range currently permitted by the Matter device and can cause the driver to send a setpoint write that the device rejects with CONSTRAINT_ERROR.
Validated against main commit 43f47501b217336d17ed2fc92b64d08971f305ce.
Current implementation
In drivers/SmartThings/matter-thermostat/src/init.lua, the Thermostat handlers and subscriptions include only the absolute limits:
clusters.Thermostat.attributes.AbsMinHeatSetpointLimit
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit
clusters.Thermostat.attributes.AbsMinCoolSetpointLimit
clusters.Thermostat.attributes.AbsMaxCoolSetpointLimitThe resulting cached limits are then used by attribute_handlers.lua for range events and by capability_handlers.lua for command validation.
Reproduction
For a heating thermostat reporting:
AbsMinHeatSetpointLimit = 5.00 C
AbsMaxHeatSetpointLimit = 30.00 C
MinHeatSetpointLimit = 10.00 C
MaxHeatSetpointLimit = 25.00 C
the driver currently exposes/validates against 5-30 C.
A setHeatingSetpoint(7) command therefore passes local validation even though 7 C is below the device's configured MinHeatSetpointLimit and may be rejected by the device.
The same issue applies to cooling.
Expected behavior
If configurable limits are supported and reported, they should define the effective SmartThings setpoint range and command-validation range. The absolute limits should remain the hard/fallback bounds.
Proposed fix
Keep absolute and configurable limits separately, subscribe to both, and prefer the configurable value when calculating the effective limit.
For example:
-- fields.lua
ABS_MIN_HEAT = "ABS_MIN_HEAT"
ABS_MAX_HEAT = "ABS_MAX_HEAT"
ABS_MIN_COOL = "ABS_MIN_COOL"
ABS_MAX_COOL = "ABS_MAX_COOL"Register the configurable attributes in init.lua in addition to the existing absolute ones:
[clusters.Thermostat.attributes.MinHeatSetpointLimit.ID] =
attribute_handlers.heat_setpoint_limit_factory(fields.setpoint_limit_device_field.MIN_HEAT),
[clusters.Thermostat.attributes.MaxHeatSetpointLimit.ID] =
attribute_handlers.heat_setpoint_limit_factory(fields.setpoint_limit_device_field.MAX_HEAT),
[clusters.Thermostat.attributes.MinCoolSetpointLimit.ID] =
attribute_handlers.cool_setpoint_limit_factory(fields.setpoint_limit_device_field.MIN_COOL),
[clusters.Thermostat.attributes.MaxCoolSetpointLimit.ID] =
attribute_handlers.cool_setpoint_limit_factory(fields.setpoint_limit_device_field.MAX_COOL),and add them to the corresponding subscribed_attributes entries.
A common helper can then be used by both range emission and command validation:
function ThermostatUtils.get_effective_setpoint_limit(
device, configured_field, absolute_field, default_value)
return device:get_field(configured_field)
or device:get_field(absolute_field)
or default_value
endFor heating:
local min = thermostat_utils.get_effective_setpoint_limit(
device,
fields.setpoint_limit_device_field.MIN_HEAT,
fields.setpoint_limit_device_field.ABS_MIN_HEAT,
MIN_TEMP_IN_C
)
local max = thermostat_utils.get_effective_setpoint_limit(
device,
fields.setpoint_limit_device_field.MAX_HEAT,
fields.setpoint_limit_device_field.ABS_MAX_HEAT,
MAX_TEMP_IN_C
)The same logic applies to cooling.
If this is combined with the separate multi-endpoint state fix, these fields should be stored/read per thermostat endpoint rather than device-wide.
Regression test
With absolute heat limits 5-30 C and configurable limits 10-25 C, verify that:
- the emitted SmartThings range is 10-25 C;
- 7 C and 28 C are rejected locally;
- a value inside 10-25 C is written;
- a device without configurable-limit reports still falls back to the absolute limits.
Activity
ldeora commentedon Oct 8, 2026
Additional real-device observation
I tested a modified version of the Matter Thermostat driver with a heating-only thermostat on endpoint
0x09.The device reports:
However, its
AttributeListdoes not contain any of the four configurable setpoint-limit attributes:MinHeatSetpointLimitMaxHeatSetpointLimitMinCoolSetpointLimitMaxCoolSetpointLimitWhen the modified driver requests these attributes, the device returns
UNSUPPORTED_ATTRIBUTEfor all four.The driver correctly falls back to the absolute limits and exposes a heating range of 5–30 °C.
This does not reproduce the original defect, which concerns devices that do support configurable limits. However, it confirms an important requirement for the proposed fix: configurable limits must take precedence when supported, while devices without them must continue to use the absolute limits.
Ideally, requests and subscriptions for these optional attributes should also be filtered against the endpoint's
AttributeListto avoid unnecessaryUNSUPPORTED_ATTRIBUTEresponses.