1
- -- Copyright 2022 SmartThings
1
+ -- Copyright 2025 SmartThings
2
2
--
3
3
-- Licensed under the Apache License, Version 2.0 (the "License");
4
4
-- you may not use this file except in compliance with the License.
@@ -17,12 +17,11 @@ local log = require "log"
17
17
local clusters = require " st.matter.clusters"
18
18
local embedded_cluster_utils = require " embedded-cluster-utils"
19
19
local im = require " st.matter.interaction_model"
20
-
21
20
local MatterDriver = require " st.matter.driver"
22
21
local utils = require " st.utils"
22
+ local version = require " version"
23
23
24
24
-- Include driver-side definitions when lua libs api version is < 10
25
- local version = require " version"
26
25
if version .api < 10 then
27
26
clusters .HepaFilterMonitoring = require " HepaFilterMonitoring"
28
27
clusters .ActivatedCarbonFilterMonitoring = require " ActivatedCarbonFilterMonitoring"
@@ -1000,69 +999,67 @@ end
1000
999
1001
1000
local function temp_event_handler (attribute )
1002
1001
return function (driver , device , ib , response )
1003
- if ib .data .value == nil then
1004
- return
1005
- end
1006
- local unit = " C"
1007
-
1008
- -- Only emit the capability for RPC version >= 5, since unit conversion for
1009
- -- range capabilities is only supported in that case.
1010
- if version .rpc >= 5 then
1011
- local event
1012
- if attribute == capabilities .thermostatCoolingSetpoint .coolingSetpoint then
1013
- local range = {
1014
- minimum = device :get_field (setpoint_limit_device_field .MIN_COOL ) or THERMOSTAT_MIN_TEMP_IN_C ,
1015
- maximum = device :get_field (setpoint_limit_device_field .MAX_COOL ) or THERMOSTAT_MAX_TEMP_IN_C ,
1016
- step = 0.1
1017
- }
1018
- event = capabilities .thermostatCoolingSetpoint .coolingSetpointRange ({value = range , unit = unit })
1019
- device :emit_event_for_endpoint (ib .endpoint_id , event )
1020
- elseif attribute == capabilities .thermostatHeatingSetpoint .heatingSetpoint then
1021
- local MAX_TEMP_IN_C = THERMOSTAT_MAX_TEMP_IN_C
1022
- local MIN_TEMP_IN_C = THERMOSTAT_MIN_TEMP_IN_C
1023
- local is_water_heater_device = get_device_type (driver , device ) == WATER_HEATER_DEVICE_TYPE_ID
1024
- if is_water_heater_device then
1025
- MAX_TEMP_IN_C = WATER_HEATER_MAX_TEMP_IN_C
1026
- MIN_TEMP_IN_C = WATER_HEATER_MIN_TEMP_IN_C
1002
+ if ib .data .value ~= nil then
1003
+ local unit = " C"
1004
+
1005
+ -- Only emit the capability for RPC version >= 5, since unit conversion for
1006
+ -- range capabilities is only supported in that case.
1007
+ if version .rpc >= 5 then
1008
+ local event
1009
+ if attribute == capabilities .thermostatCoolingSetpoint .coolingSetpoint then
1010
+ local range = {
1011
+ minimum = device :get_field (setpoint_limit_device_field .MIN_COOL ) or THERMOSTAT_MIN_TEMP_IN_C ,
1012
+ maximum = device :get_field (setpoint_limit_device_field .MAX_COOL ) or THERMOSTAT_MAX_TEMP_IN_C ,
1013
+ step = 0.1
1014
+ }
1015
+ event = capabilities .thermostatCoolingSetpoint .coolingSetpointRange ({value = range , unit = unit })
1016
+ device :emit_event_for_endpoint (ib .endpoint_id , event )
1017
+ elseif attribute == capabilities .thermostatHeatingSetpoint .heatingSetpoint then
1018
+ local MAX_TEMP_IN_C = THERMOSTAT_MAX_TEMP_IN_C
1019
+ local MIN_TEMP_IN_C = THERMOSTAT_MIN_TEMP_IN_C
1020
+ local is_water_heater_device = get_device_type (driver , device ) == WATER_HEATER_DEVICE_TYPE_ID
1021
+ if is_water_heater_device then
1022
+ MAX_TEMP_IN_C = WATER_HEATER_MAX_TEMP_IN_C
1023
+ MIN_TEMP_IN_C = WATER_HEATER_MIN_TEMP_IN_C
1024
+ end
1025
+
1026
+ local range = {
1027
+ minimum = device :get_field (setpoint_limit_device_field .MIN_HEAT ) or MIN_TEMP_IN_C ,
1028
+ maximum = device :get_field (setpoint_limit_device_field .MAX_HEAT ) or MAX_TEMP_IN_C ,
1029
+ step = 0.1
1030
+ }
1031
+ event = capabilities .thermostatHeatingSetpoint .heatingSetpointRange ({value = range , unit = unit })
1032
+ device :emit_event_for_endpoint (ib .endpoint_id , event )
1027
1033
end
1028
-
1029
- local range = {
1030
- minimum = device :get_field (setpoint_limit_device_field .MIN_HEAT ) or MIN_TEMP_IN_C ,
1031
- maximum = device :get_field (setpoint_limit_device_field .MAX_HEAT ) or MAX_TEMP_IN_C ,
1032
- step = 0.1
1033
- }
1034
- event = capabilities .thermostatHeatingSetpoint .heatingSetpointRange ({value = range , unit = unit })
1035
- device :emit_event_for_endpoint (ib .endpoint_id , event )
1036
1034
end
1037
- end
1038
1035
1039
- local temp = ib .data .value / 100.0
1040
- device :emit_event_for_endpoint (ib .endpoint_id , attribute ({value = temp , unit = unit }))
1036
+ local temp = ib .data .value / 100.0
1037
+ device :emit_event_for_endpoint (ib .endpoint_id , attribute ({value = temp , unit = unit }))
1038
+ end
1041
1039
end
1042
1040
end
1043
1041
1044
1042
local temp_attr_handler_factory = function (minOrMax )
1045
1043
return function (driver , device , ib , response )
1046
- if ib .data .value == nil then
1047
- return
1048
- end
1049
- local temp = ib .data .value / 100.0
1050
- local unit = " C"
1051
- temp = utils .clamp_value (temp , THERMOSTAT_MIN_TEMP_IN_C , THERMOSTAT_MAX_TEMP_IN_C )
1052
- set_field_for_endpoint (device , minOrMax , ib .endpoint_id , temp )
1053
- local min = get_field_for_endpoint (device , setpoint_limit_device_field .MIN_TEMP , ib .endpoint_id )
1054
- local max = get_field_for_endpoint (device , setpoint_limit_device_field .MAX_TEMP , ib .endpoint_id )
1055
- if min ~= nil and max ~= nil then
1056
- if min < max then
1057
- -- Only emit the capability for RPC version >= 5 (unit conversion for
1058
- -- temperature range capability is only supported for RPC >= 5)
1059
- if version .rpc >= 5 then
1060
- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .temperatureMeasurement .temperatureRange ({ value = { minimum = min , maximum = max }, unit = unit }))
1044
+ if ib .data .value ~= nil then
1045
+ local temp = ib .data .value / 100.0
1046
+ local unit = " C"
1047
+ temp = utils .clamp_value (temp , THERMOSTAT_MIN_TEMP_IN_C , THERMOSTAT_MAX_TEMP_IN_C )
1048
+ set_field_for_endpoint (device , minOrMax , ib .endpoint_id , temp )
1049
+ local min = get_field_for_endpoint (device , setpoint_limit_device_field .MIN_TEMP , ib .endpoint_id )
1050
+ local max = get_field_for_endpoint (device , setpoint_limit_device_field .MAX_TEMP , ib .endpoint_id )
1051
+ if min ~= nil and max ~= nil then
1052
+ if min < max then
1053
+ -- Only emit the capability for RPC version >= 5 (unit conversion for
1054
+ -- temperature range capability is only supported for RPC >= 5)
1055
+ if version .rpc >= 5 then
1056
+ device :emit_event_for_endpoint (ib .endpoint_id , capabilities .temperatureMeasurement .temperatureRange ({ value = { minimum = min , maximum = max }, unit = unit }))
1057
+ end
1058
+ set_field_for_endpoint (device , setpoint_limit_device_field .MIN_TEMP , ib .endpoint_id , nil )
1059
+ set_field_for_endpoint (device , setpoint_limit_device_field .MAX_TEMP , ib .endpoint_id , nil )
1060
+ else
1061
+ 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 ))
1061
1062
end
1062
- set_field_for_endpoint (device , setpoint_limit_device_field .MIN_TEMP , ib .endpoint_id , nil )
1063
- set_field_for_endpoint (device , setpoint_limit_device_field .MAX_TEMP , ib .endpoint_id , nil )
1064
- else
1065
- 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 ))
1066
1063
end
1067
1064
end
1068
1065
end
@@ -1532,54 +1529,52 @@ end
1532
1529
1533
1530
local heating_setpoint_limit_handler_factory = function (minOrMax )
1534
1531
return function (driver , device , ib , response )
1535
- if ib .data .value == nil then
1536
- return
1537
- end
1538
- local MAX_TEMP_IN_C = THERMOSTAT_MAX_TEMP_IN_C
1539
- local MIN_TEMP_IN_C = THERMOSTAT_MIN_TEMP_IN_C
1540
- local is_water_heater_device = (get_device_type (driver , device ) == WATER_HEATER_DEVICE_TYPE_ID )
1541
- if is_water_heater_device then
1542
- MAX_TEMP_IN_C = WATER_HEATER_MAX_TEMP_IN_C
1543
- MIN_TEMP_IN_C = WATER_HEATER_MIN_TEMP_IN_C
1544
- end
1545
- local val = ib .data .value / 100.0
1546
- val = utils .clamp_value (val , MIN_TEMP_IN_C , MAX_TEMP_IN_C )
1547
- device :set_field (minOrMax , val )
1548
- local min = device :get_field (setpoint_limit_device_field .MIN_HEAT )
1549
- local max = device :get_field (setpoint_limit_device_field .MAX_HEAT )
1550
- if min ~= nil and max ~= nil then
1551
- if min < max then
1552
- -- Only emit the capability for RPC version >= 5 (unit conversion for
1553
- -- heating setpoint range capability is only supported for RPC >= 5)
1554
- if version .rpc >= 5 then
1555
- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .thermostatHeatingSetpoint .heatingSetpointRange ({ value = { minimum = min , maximum = max , step = 0.1 }, unit = " C" }))
1532
+ if ib .data .value ~= nil then
1533
+ local MAX_TEMP_IN_C = THERMOSTAT_MAX_TEMP_IN_C
1534
+ local MIN_TEMP_IN_C = THERMOSTAT_MIN_TEMP_IN_C
1535
+ local is_water_heater_device = (get_device_type (driver , device ) == WATER_HEATER_DEVICE_TYPE_ID )
1536
+ if is_water_heater_device then
1537
+ MAX_TEMP_IN_C = WATER_HEATER_MAX_TEMP_IN_C
1538
+ MIN_TEMP_IN_C = WATER_HEATER_MIN_TEMP_IN_C
1539
+ end
1540
+ local val = ib .data .value / 100.0
1541
+ val = utils .clamp_value (val , MIN_TEMP_IN_C , MAX_TEMP_IN_C )
1542
+ device :set_field (minOrMax , val )
1543
+ local min = device :get_field (setpoint_limit_device_field .MIN_HEAT )
1544
+ local max = device :get_field (setpoint_limit_device_field .MAX_HEAT )
1545
+ if min ~= nil and max ~= nil then
1546
+ if min < max then
1547
+ -- Only emit the capability for RPC version >= 5 (unit conversion for
1548
+ -- heating setpoint range capability is only supported for RPC >= 5)
1549
+ if version .rpc >= 5 then
1550
+ device :emit_event_for_endpoint (ib .endpoint_id , capabilities .thermostatHeatingSetpoint .heatingSetpointRange ({ value = { minimum = min , maximum = max , step = 0.1 }, unit = " C" }))
1551
+ end
1552
+ else
1553
+ device .log .warn_with ({hub_logs = true }, string.format (" Device reported a min heating setpoint %s that is not lower than the reported max %s" , min , max ))
1556
1554
end
1557
- else
1558
- device .log .warn_with ({hub_logs = true }, string.format (" Device reported a min heating setpoint %d that is not lower than the reported max %d" , min , max ))
1559
1555
end
1560
1556
end
1561
1557
end
1562
1558
end
1563
1559
1564
1560
local cooling_setpoint_limit_handler_factory = function (minOrMax )
1565
1561
return function (driver , device , ib , response )
1566
- if ib .data .value == nil then
1567
- return
1568
- end
1569
- local val = ib .data .value / 100.0
1570
- val = utils .clamp_value (val , THERMOSTAT_MIN_TEMP_IN_C , THERMOSTAT_MAX_TEMP_IN_C )
1571
- device :set_field (minOrMax , val )
1572
- local min = device :get_field (setpoint_limit_device_field .MIN_COOL )
1573
- local max = device :get_field (setpoint_limit_device_field .MAX_COOL )
1574
- if min ~= nil and max ~= nil then
1575
- if min < max then
1576
- -- Only emit the capability for RPC version >= 5 (unit conversion for
1577
- -- cooling setpoint range capability is only supported for RPC >= 5)
1578
- if version .rpc >= 5 then
1579
- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .thermostatCoolingSetpoint .coolingSetpointRange ({ value = { minimum = min , maximum = max , step = 0.1 }, unit = " C" }))
1562
+ if ib .data .value ~= nil then
1563
+ local val = ib .data .value / 100.0
1564
+ val = utils .clamp_value (val , THERMOSTAT_MIN_TEMP_IN_C , THERMOSTAT_MAX_TEMP_IN_C )
1565
+ device :set_field (minOrMax , val )
1566
+ local min = device :get_field (setpoint_limit_device_field .MIN_COOL )
1567
+ local max = device :get_field (setpoint_limit_device_field .MAX_COOL )
1568
+ if min ~= nil and max ~= nil then
1569
+ if min < max then
1570
+ -- Only emit the capability for RPC version >= 5 (unit conversion for
1571
+ -- cooling setpoint range capability is only supported for RPC >= 5)
1572
+ if version .rpc >= 5 then
1573
+ device :emit_event_for_endpoint (ib .endpoint_id , capabilities .thermostatCoolingSetpoint .coolingSetpointRange ({ value = { minimum = min , maximum = max , step = 0.1 }, unit = " C" }))
1574
+ end
1575
+ else
1576
+ device .log .warn_with ({hub_logs = true }, string.format (" Device reported a min cooling setpoint %s that is not lower than the reported max %s" , min , max ))
1580
1577
end
1581
- else
1582
- device .log .warn_with ({hub_logs = true }, string.format (" Device reported a min cooling setpoint %d that is not lower than the reported max %d" , min , max ))
1583
1578
end
1584
1579
end
1585
1580
end
0 commit comments