Skip to content

Commit

Permalink
Matter-Thermostat: Use endpoint id in limit fields
Browse files Browse the repository at this point in the history
Add endpoint id to temp limit fields. Rework test cases.
  • Loading branch information
nickolas-deboom committed Mar 22, 2024
1 parent de393f9 commit 4e3df75
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 44 deletions.
20 changes: 15 additions & 5 deletions drivers/SmartThings/matter-thermostat/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ local subscribed_attributes = {
}
}

local function get_field_for_endpoint(device, field, endpoint)
return device:get_field(string.format("%s_%d", field, endpoint))
end

local function set_field_for_endpoint(device, field, endpoint, value, persist)
device:set_field(string.format("%s_%d", field, endpoint), value, {persist = persist})
end

local function find_default_endpoint(device, cluster)
local res = device.MATTER_DEFAULT_ENDPOINT
local eps = device:get_endpoints(cluster)
Expand Down Expand Up @@ -209,14 +217,14 @@ local temp_attr_handler_factory = function(minOrMax)
if ib.data.value ~= nil then
local temp = ib.data.value / 100.0
local unit = "C"
device:set_field(minOrMax, temp)
local min = device:get_field(setpoint_limit_device_field.MIN_TEMP)
local max = device:get_field(setpoint_limit_device_field.MAX_TEMP)
set_field_for_endpoint(device, minOrMax, ib.endpoint_id, temp, false)
local min = get_field_for_endpoint(device, setpoint_limit_device_field.MIN_TEMP, ib.endpoint_id)
local max = get_field_for_endpoint(device, setpoint_limit_device_field.MAX_TEMP, ib.endpoint_id)
if min ~= nil and max ~= nil then
if min < max then
device:emit_event_for_endpoint(ib.endpoint_id, capabilities.temperatureMeasurement.temperatureRange({ value = { minimum = min, maximum = max }, unit = unit }))
device:set_field(setpoint_limit_device_field.MIN_TEMP, nil)
device:set_field(setpoint_limit_device_field.MAX_TEMP, nil)
set_field_for_endpoint(device, setpoint_limit_device_field.MIN_TEMP, ib.endpoint_id, nil, false)
set_field_for_endpoint(device, setpoint_limit_device_field.MAX_TEMP, ib.endpoint_id, nil, false)
else
device.log.warn_with({hub_logs = true}, string.format("Device reported a min temperature %d that is not lower than the reported max temperature %d", min, max))
end
Expand Down Expand Up @@ -414,6 +422,7 @@ local heating_setpoint_limit_handler_factory = function(minOrMax)
return function(driver, device, ib, response)
if ib.data.value ~= nil then
local val = ib.data.value / 100.0
print("setting %s to %d", minOrMax, val)
device:set_field(minOrMax, val)
local min = device:get_field(setpoint_limit_device_field.MIN_HEAT)
local max = device:get_field(setpoint_limit_device_field.MAX_HEAT)
Expand All @@ -432,6 +441,7 @@ local cooling_setpoint_limit_handler_factory = function(minOrMax)
return function(driver, device, ib, response)
if ib.data.value ~= nil then
local val = ib.data.value / 100.0
print("setting %s to %d", minOrMax, val)
device:set_field(minOrMax, val)
local min = device:get_field(setpoint_limit_device_field.MIN_COOL)
local max = device:get_field(setpoint_limit_device_field.MAX_COOL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,45 +79,6 @@ local function test_init()
read_limits:merge(clusters.TemperatureMeasurement.attributes.MaxMeasuredValue:read())
test.socket.matter:__expect_send({mock_device.id, read_limits})

--Populate setpoint limits
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.AbsMinHeatSetpointLimit:build_test_report_data(mock_device, 1, 1000)
})
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit:build_test_report_data(mock_device, 1, 3222)
})
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.AbsMinCoolSetpointLimit:build_test_report_data(mock_device, 1, 1000) --10.0 celcius
})
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.AbsMaxCoolSetpointLimit:build_test_report_data(mock_device, 1, 3222) --32.22 celcius
})
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.MinSetpointDeadBand:build_test_report_data(mock_device, 1, 16) --1.6 celcius
})
test.socket.matter:__queue_receive({
mock_device.id,
clusters.TemperatureMeasurement.attributes.MinMeasuredValue:build_test_report_data(mock_device, 1, 500) --5.0 celsius
})
test.socket.matter:__queue_receive({
mock_device.id,
clusters.TemperatureMeasurement.attributes.MaxMeasuredValue:build_test_report_data(mock_device, 1, 4000) --40.0 celsius
})

test.socket.capability:__expect_send(
mock_device:generate_test_message("main", capabilities.thermostatHeatingSetpoint.heatingSetpointRange({ value = { minimum = 10.00, maximum = 32.22 }, unit = "C" }))
)
test.socket.capability:__expect_send(
mock_device:generate_test_message("main", capabilities.thermostatCoolingSetpoint.coolingSetpointRange({ value = { minimum = 10.00, maximum = 32.22 }, unit = "C" }))
)
test.socket.capability:__expect_send(
mock_device:generate_test_message("main", capabilities.temperatureMeasurement.temperatureRange({ value = { minimum = 5.00, maximum = 40.00 }, unit = "C" }))
)
test.mock_device.add_test_device(mock_device)
end
test.set_test_init_function(test_init)
Expand Down Expand Up @@ -152,6 +113,10 @@ end
test.register_coroutine_test(
"Heat setpoint lower than min",
function()
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.AbsMinHeatSetpointLimit:build_test_report_data(mock_device, 1, 1000)
})
configure(mock_device)
test.socket.capability:__queue_receive({
mock_device.id,
Expand All @@ -166,6 +131,10 @@ test.register_coroutine_test(
test.register_coroutine_test(
"Cool setpoint lower than min",
function()
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.AbsMinCoolSetpointLimit:build_test_report_data(mock_device, 1, 1000)
})
configure(mock_device)
test.socket.capability:__queue_receive({
mock_device.id,
Expand All @@ -180,6 +149,10 @@ test.register_coroutine_test(
test.register_coroutine_test(
"Heat setpoint higher than max",
function()
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit:build_test_report_data(mock_device, 1, 3222)
})
configure(mock_device)
test.socket.capability:__queue_receive({
mock_device.id,
Expand All @@ -194,6 +167,10 @@ test.register_coroutine_test(
test.register_coroutine_test(
"Cool setpoint higher than max",
function()
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.AbsMaxCoolSetpointLimit:build_test_report_data(mock_device, 1, 3222)
})
configure(mock_device)
test.socket.capability:__queue_receive({
mock_device.id,
Expand All @@ -208,6 +185,10 @@ test.register_coroutine_test(
test.register_coroutine_test(
"Heat setpoint inside deadband",
function()
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.MinSetpointDeadBand:build_test_report_data(mock_device, 1, 16) --1.6 celcius
})
configure(mock_device)
test.socket.capability:__queue_receive({
mock_device.id,
Expand All @@ -222,6 +203,10 @@ test.register_coroutine_test(
test.register_coroutine_test(
"Cool setpoint inside deadband",
function()
test.socket.matter:__queue_receive({
mock_device.id,
clusters.Thermostat.attributes.MinSetpointDeadBand:build_test_report_data(mock_device, 1, 16) --1.6 celcius
})
configure(mock_device)
test.socket.capability:__queue_receive({
mock_device.id,
Expand All @@ -233,6 +218,60 @@ test.register_coroutine_test(
end
)

test.register_message_test(
"Min and max heating setpoint attributes set capability constraint",
{
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.Thermostat.attributes.AbsMinCoolSetpointLimit:build_test_report_data(mock_device, 1, 1000)
}
},
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.Thermostat.attributes.AbsMaxCoolSetpointLimit:build_test_report_data(mock_device, 1, 3222)
}
},
{
channel = "capability",
direction = "send",
message = mock_device:generate_test_message("main", capabilities.thermostatCoolingSetpoint.coolingSetpointRange({ value = { minimum = 10.00, maximum = 32.22 }, unit = "C" }))
}
}
)

test.register_message_test(
"Min and max cooling setpoint attributes set capability constraint",
{
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.Thermostat.attributes.AbsMinHeatSetpointLimit:build_test_report_data(mock_device, 1, 1000)
}
},
{
channel = "matter",
direction = "receive",
message = {
mock_device.id,
clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit:build_test_report_data(mock_device, 1, 3222)
}
},
{
channel = "capability",
direction = "send",
message = mock_device:generate_test_message("main", capabilities.thermostatHeatingSetpoint.heatingSetpointRange({ value = { minimum = 10.00, maximum = 32.22 }, unit = "C" }))
}
}
)

test.register_message_test(
"Min and max temperature attributes set capability constraint",
{
Expand Down

0 comments on commit 4e3df75

Please sign in to comment.