From 3a046367e09b5137a1a28544437b751d7d3e8601 Mon Sep 17 00:00:00 2001 From: Carter Swedal Date: Fri, 4 Nov 2022 13:04:03 -0500 Subject: [PATCH] Add version branching to support AttributeList reads during configure This also adds an AttributeList attribute class to the driver which may not be present in Lua library api versions <=2 --- .../matter-thermostat/src/AttributeList.lua | 119 ++++++++++++++++++ .../matter-thermostat/src/init.lua | 15 ++- .../test/test_matter_thermo_featuremap.lua | 4 +- .../src/test/test_matter_thermostat.lua | 3 + 4 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 drivers/SmartThings/matter-thermostat/src/AttributeList.lua diff --git a/drivers/SmartThings/matter-thermostat/src/AttributeList.lua b/drivers/SmartThings/matter-thermostat/src/AttributeList.lua new file mode 100644 index 0000000000..9b8e48f7cb --- /dev/null +++ b/drivers/SmartThings/matter-thermostat/src/AttributeList.lua @@ -0,0 +1,119 @@ +-- Copyright 2022 SmartThings +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +-- DO NOT EDIT: this code is automatically generated by ZCL Advanced Platform generator. + + +--Note this file is present in the driver package in case it is not available in the lua libs on +-- the hub. It will be required for any API version <= 2. It will be removed by SmartThings once +-- all hub platforms running the driver support an API version greater than 2 +local cluster_base = require "st.matter.cluster_base" +local data_types = require "st.matter.data_types" +local TLVParser = require "st.matter.TLV.TLVParser" + +--- @class st.matter.clusters.Thermostat.AttributeList +--- @alias AttributeList +--- +--- @field public ID number 0xFFFB the ID of this attribute +--- @field public NAME string "AttributeList" the name of this attribute +--- @field public data_type st.matter.data_types.Array the data type of this attribute + +local AttributeList = { + ID = 0xFFFB, + NAME = "AttributeList", + base_type = data_types.Array, +} +--- Create a Array object of this attribute with any additional features provided for the attribute +--- This is also usable with the AttributeList(...) syntax +--- +--- @vararg vararg the values needed to construct a Array +--- @return st.matter.data_types.Array +function AttributeList:new_value(...) + local o = self.base_type(table.unpack({...})) + + return o +end + +--- Constructs an st.matter.interaction_model.InteractionRequest to read +--- this attribute from a device +--- @param device st.matter.Device +--- @param endpoint_id number|nil +--- @return st.matter.interaction_model.InteractionRequest containing an Interaction Request +function AttributeList:read(device, endpoint_id) + return cluster_base.read( + device, + endpoint_id, + self._cluster.ID, + self.ID, + nil --event_id + ) +end + + +--- Reporting policy: AttributeList => true => mandatory + +--- Sets up a Subscribe Interaction +--- +--- @param device any +--- @param endpoint_id number|nil +--- @return any +function AttributeList:subscribe(device, endpoint_id) + return cluster_base.subscribe( + device, + endpoint_id, + self._cluster.ID, + self.ID, + nil --event_id + ) +end + +function AttributeList:set_parent_cluster(cluster) + self._cluster = cluster + return self +end + +--- Builds an AttributeList test attribute reponse for the driver integration testing framework +--- +--- @param device st.matter.Device the device to build this message for +--- @param endpoint_id number|nil +--- @param value any +--- @param status string Interaction status associated with the path +--- @return st.matter.interaction_model.InteractionResponse of type REPORT_DATA +function AttributeList:build_test_report_data( + device, + endpoint_id, + value, + status +) + local data = data_types.validate_or_build_type(value, self.base_type) + + return cluster_base.build_test_report_data( + device, + endpoint_id, + self._cluster.ID, + self.ID, + data, + status + ) +end + +function AttributeList:deserialize(tlv_buf) + local data = TLVParser.decode_tlv(tlv_buf) + + return data +end + +setmetatable(AttributeList, {__call = AttributeList.new_value}) +return AttributeList + diff --git a/drivers/SmartThings/matter-thermostat/src/init.lua b/drivers/SmartThings/matter-thermostat/src/init.lua index 673e8b8d92..5e6a78ec41 100644 --- a/drivers/SmartThings/matter-thermostat/src/init.lua +++ b/drivers/SmartThings/matter-thermostat/src/init.lua @@ -15,10 +15,19 @@ local capabilities = require "st.capabilities" local log = require "log" local clusters = require "st.matter.clusters" - +local version = require "version" local MatterDriver = require "st.matter.driver" local utils = require "st.utils" +local ThermostatClusterAttributeList +if version.api < 3 then + ThermostatClusterAttributeList = require "AttributeList" + ThermostatClusterAttributeList:set_parent_cluster(clusters.Thermostat) +else + ThermostatClusterAttributeList = clusters.Thermostat.attributes.AttributeList +end + + local THERMOSTAT_MODE_MAP = { [clusters.Thermostat.types.ThermostatSystemMode.OFF] = capabilities.thermostatMode.thermostatMode.off, [clusters.Thermostat.types.ThermostatSystemMode.AUTO] = capabilities.thermostatMode.thermostatMode.auto, @@ -66,7 +75,7 @@ local function do_configure(driver, device) end device:set_field("profile_name", profile_name) - device:send(clusters.Thermostat.attributes.AttributeList:read(device, thermo_eps[1])) + device:send(ThermostatClusterAttributeList:read(device, thermo_eps[1])) log.info_with({hub_logs=true}, string.format("Updating device profile to %s.", profile_name)) device:try_update_metadata({profile = profile_name}) else @@ -246,7 +255,7 @@ local matter_driver_template = { [clusters.Thermostat.attributes.SystemMode.ID] = system_mode_handler, [clusters.Thermostat.attributes.ThermostatRunningState.ID] = running_state_handler, [clusters.Thermostat.attributes.ControlSequenceOfOperation.ID] = sequence_of_operation_handler, - [clusters.Thermostat.attributes.AttributeList.ID] = attr_list_handler + [ThermostatClusterAttributeList.ID] = attr_list_handler }, [clusters.FanControl.ID] = { [clusters.FanControl.attributes.FanModeSequence.ID] = fan_mode_sequence_handler, diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_featuremap.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_featuremap.lua index 7043f2954d..9ad6115d40 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_featuremap.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_featuremap.lua @@ -17,7 +17,9 @@ local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" local utils = require "st.utils" local Uint32 = require "st.matter.data_types".Uint32 - +--TODO remove this hack once "integration_test" has a mock for it +-- This is coming in Lua libs version 046x +function rpc_version() return 0 end local clusters = require "st.matter.clusters" local mock_device = test.mock_device.build_test_matter_device({ diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat.lua index 7f4ad9aa38..3ff65e9fcb 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat.lua @@ -13,6 +13,9 @@ -- limitations under the License. local test = require "integration_test" +--TODO remove this hack once "integration_test" has a mock for it +-- This is coming in Lua libs version 046x +function rpc_version() return 0 end local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" local utils = require "st.utils"