Skip to content

Commit

Permalink
Matter-Switch: Improve color temp conversion rounding (#1591)
Browse files Browse the repository at this point in the history
Matter-Switch: Improve color temp conversion rounding

This change adjusts the way that the color temperature bounds are
rounded while converting them from mireds into Kelvin. Previously, they
were rounded to the nearest hundreds value and this sometimes resulted
in the range displayed in the ST app being larger than the range
supported by the device. This change will prevent this from occurring by
rounding the range slightly differently such that it is within the range supported by the
device.
  • Loading branch information
nickolas-deboom authored Sep 5, 2024
1 parent b9f8bfd commit ea8ea75
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
22 changes: 17 additions & 5 deletions drivers/SmartThings/matter-switch/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,26 @@ local function convert_huesat_st_to_matter(val)
return utils.clamp_value(math.floor((val * 0xFE) / 100.0 + 0.5), CURRENT_HUESAT_ATTR_MIN, CURRENT_HUESAT_ATTR_MAX)
end

local function mired_to_kelvin(value)
local function mired_to_kelvin(value, minOrMax)
if value == 0 then -- shouldn't happen, but has
value = 1
log.warn(string.format("Received a color temperature of 0 mireds. Using a color temperature of 1 mired to avoid divide by zero"))
end
-- we divide inside the rounding and multiply outside of it because we expect these
-- bounds to be multiples of 100
return utils.round((MIRED_KELVIN_CONVERSION_CONSTANT / value) / 100) * 100
-- We divide inside the rounding and multiply outside of it because we expect these
-- bounds to be multiples of 100. For the maximum mired value (minimum K value),
-- add 1 before converting and round up to nearest hundreds. For the minimum mired
-- (maximum K value) value, subtract 1 before converting and round down to nearest
-- hundreds. Note that 1 is added/subtracted from the mired value in order to avoid
-- rounding errors from the conversion of Kelvin to mireds.
local kelvin_step_size = 100
local rounding_value = 0.5
if minOrMax == COLOR_TEMP_MIN then
return utils.round(MIRED_KELVIN_CONVERSION_CONSTANT / (kelvin_step_size * (value + 1)) + rounding_value) * kelvin_step_size
elseif minOrMax == COLOR_TEMP_MAX then
return utils.round(MIRED_KELVIN_CONVERSION_CONSTANT / (kelvin_step_size * (value - 1)) - rounding_value) * kelvin_step_size
else
log.warn_with({hub_logs = true}, "Attempted to convert temperature unit for an undefined value")
end
end

--- component_to_endpoint helper function to handle situations where
Expand Down Expand Up @@ -429,7 +441,7 @@ local mired_bounds_handler_factory = function(minOrMax)
device.log.warn_with({hub_logs = true}, string.format("Device reported a color temperature %d mired outside of sane range of %.2f-%.2f", ib.data.value, COLOR_TEMPERATURE_MIRED_MIN, COLOR_TEMPERATURE_MIRED_MAX))
return
end
local temp_in_kelvin = mired_to_kelvin(ib.data.value)
local temp_in_kelvin = mired_to_kelvin(ib.data.value, minOrMax)
set_field_for_endpoint(device, COLOR_TEMP_BOUND_RECEIVED..minOrMax, ib.endpoint_id, temp_in_kelvin)
local min = get_field_for_endpoint(device, COLOR_TEMP_BOUND_RECEIVED..COLOR_TEMP_MIN, ib.endpoint_id)
local max = get_field_for_endpoint(device, COLOR_TEMP_BOUND_RECEIVED..COLOR_TEMP_MAX, ib.endpoint_id)
Expand Down
27 changes: 27 additions & 0 deletions drivers/SmartThings/matter-switch/src/test/test_matter_switch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,33 @@ test.register_message_test(
}
)

test.register_message_test(
"Min and max color temperature attributes set capability constraint using improved temperature conversion rounding",
{
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.ColorControl.attributes.ColorTempPhysicalMinMireds:build_test_report_data(mock_device, 1, 165)
}
},
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.ColorControl.attributes.ColorTempPhysicalMaxMireds:build_test_report_data(mock_device, 1, 365)
}
},
{
channel = "capability",
direction = "send",
message = mock_device:generate_test_message("main", capabilities.colorTemperature.colorTemperatureRange({minimum = 2800, maximum = 6000}))
}
}
)

test.register_message_test(
"Min color temperature outside of range, capability not sent",
{
Expand Down

0 comments on commit ea8ea75

Please sign in to comment.