From a9d571b89d6c37c379bf5202ea1691cc327459a1 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Fri, 24 Oct 2025 09:56:18 +0100 Subject: [PATCH 01/18] no workspace files in repo --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c5bbdc6f99..cd6ab12173 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ tools/test_output/* tools/coverage_output/* .DS_Store .venv/ +drivers/SmartThings/zigbee-power-meter/zigbee-power-meter.code-workspace From 1f2ebee788a6b2bca03823c81a52e6b5f147ddb4 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Fri, 24 Oct 2025 15:45:09 +0100 Subject: [PATCH 02/18] start of using zigbee powerr meter as the main and then adding a sub driver for temperature, battery percentage --- .../zigbee-power-meter/fingerprints.yml | 7 +++++++ .../zigbee-power-meter/profiles/ct-clamp.yml | 0 .../zigbee-power-meter/src/chameleon/init.lua | 18 ++++++++++++++++++ .../zigbee-power-meter/src/init.lua | 1 + 4 files changed, 26 insertions(+) create mode 100644 drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml create mode 100644 drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua diff --git a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml index 37cf9df678..4a90af3f75 100644 --- a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml +++ b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml @@ -28,6 +28,11 @@ zigbeeManufacturer: manufacturer: ShinaSystem model: "PMM-300Z3" deviceProfileName: power-meter-consumption-report-sihas + - id: Chameleon/CT101xxxx + deviceLabel: Chameleon CT Clamp + manufacturer: Chameleon Technology + model: CT101xxxx + deviceProfileName: ct-clamp zigbeeGeneric: - id: "genericMeter" deviceLabel: Zigbee Meter @@ -35,3 +40,5 @@ zigbeeGeneric: server: - 0x0702 #Simple Metering deviceProfileName: power-meter + + diff --git a/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml b/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua new file mode 100644 index 0000000000..56537c15f1 --- /dev/null +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -0,0 +1,18 @@ +-- 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. + +-- sub driver of the Zigbee Power Meter +-- need to add the attribute battery percentage remaining (0x0021) from the Power Configuration Cluster (0x0001) +-- need to add the attribute power source (0x0007) from the Basic Cluster (0x0000) +-- need to add the attribute current temperature (0x0000) from the Temperature Configuration Cluster (0x002) \ No newline at end of file diff --git a/drivers/SmartThings/zigbee-power-meter/src/init.lua b/drivers/SmartThings/zigbee-power-meter/src/init.lua index ae98baca8b..016f1e7e42 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/init.lua @@ -67,6 +67,7 @@ local zigbee_power_meter_driver_template = { require("ezex"), require("frient"), require("shinasystems"), + require("chameleon"), }, lifecycle_handlers = { init = configurations.power_reconfig_wrapper(device_init), From 2112515659af38c9155a1f3abd89df00e9ec9d8a Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Mon, 27 Oct 2025 14:33:35 +0000 Subject: [PATCH 03/18] first pass, after help from gemini. battery seems to always be at 100% on both tested clamps, even throiugh one is as 98% --- .../zigbee-power-meter/profiles/ct-clamp.yml | 17 ++++ .../zigbee-power-meter/src/chameleon/init.lua | 99 ++++++++++++++++++- 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml b/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml index e69de29bb2..d8fc02d365 100644 --- a/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml +++ b/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml @@ -0,0 +1,17 @@ +name: ct-clamp +components: +- id: main + capabilities: + - id: powerMeter + version: 1 + - id: energyMeter + version: 1 + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + - id: battery # Add the battery capability + version: 1 + categories: + - name: CurbPowerMeter + diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua index 56537c15f1..9f4b456e4c 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -14,5 +14,100 @@ -- sub driver of the Zigbee Power Meter -- need to add the attribute battery percentage remaining (0x0021) from the Power Configuration Cluster (0x0001) --- need to add the attribute power source (0x0007) from the Basic Cluster (0x0000) --- need to add the attribute current temperature (0x0000) from the Temperature Configuration Cluster (0x002) \ No newline at end of file +-- need to add the attribute current temperature (0x0000) from the Temperature Configuration Cluster (0x002) + + +-- +-- SmartThings Edge Zigbee Subdriver for Battery Percentage (Power Configuration Cluster) +-- +-- This module provides the logic to configure and handle the Battery Percentage Remaining +-- attribute (0x0021) from the ZCL Power Configuration Cluster (0x0001). +-- +local capabilities = require "st.capabilities" +local zcl_clusters = require "st.zigbee.zcl.clusters" +local log = require "log" + +-- Constants for the Power Configuration Cluster +local POWER_CONFIG_CLUSTER_ID = zcl_clusters.PowerConfiguration.ID +local BATTERY_PERCENTAGE_REMAINING_ATTR = zcl_clusters.PowerConfiguration.attributes.BatteryPercentageRemaining.ID + +-- The attribute value is reported in 0.5% increments, so 200 is 100%. +local MAX_PERCENT_RAW = 200 + +-- Configuration: Report once every 6 hours (min/max interval) with a minimum change of 2% (4 in raw units) +local BATTERY_REPORTING_CONFIG = { + { + cluster = POWER_CONFIG_CLUSTER_ID, + attribute = BATTERY_PERCENTAGE_REMAINING_ATTR, + -- min_reporting_interval: 1 hour (3600 seconds) + minimum_reporting_interval = 3600, + -- max_reporting_interval: 6 hours (21600 seconds) + maximum_reporting_interval = 21600, + -- reportable_change: 2% (or 4 units, since 2 units = 1%) + reportable_change = 4, + } +} + +--- Function to handle the raw BatteryPercentageRemaining attribute report. +--- @param driver ZigbeeDriver +--- @param device ZigbeeDevice +--- @param cmd ZclAttributeReport or ZclReadAttributeResponse +local function handle_battery_percentage(driver, device, cmd) + -- The value is reported in units of 0.5% + local raw_value = cmd.body.attribute_value.value + local percentage = raw_value / 2 + + -- Clamp the value between 0 and 100 + local final_percentage = math.max(0, math.min(100, percentage)) + + driver:emit(device, capabilities.battery.battery(final_percentage)) + device:emit_event(capabilities.refresh.refresh()) -- Also refresh the device status + driver:log_debug(string.format( + "Received Battery Percentage Report for %s: Raw=%d, Final=%d%%", + device.label, raw_value, final_percentage + )) +end + +--- Function to set up the reporting configuration when the device is first configured or comes online. +--- @param driver ZigbeeDriver +--- @param device ZigbeeDevice +local function do_battery_config(driver, device) + driver:log_info(string.format("Configuring battery reporting for %s", device.label)) + + -- Send the configuration commands + for _, config in ipairs(BATTERY_REPORTING_CONFIG) do + local status, result = device:configure_reporting( + config.cluster, + config.attribute, + config.minimum_reporting_interval, + config.maximum_reporting_interval, + config.reportable_change + ) + end +end + +local battery_percentage_subdriver = { + -- Add a handler to configure battery reporting when the device is first configured. + -- You would typically call this from the 'added' or 'online' lifecycle event of your main driver. + lifecycle = { + added = do_battery_config, + online = do_battery_config, -- In case the device was previously configured + }, + + -- Add the handler for incoming attribute reports from the Power Configuration Cluster (0x0001) + -- and the specific Battery Percentage Remaining attribute (0x0021). + handlers = { + -- This uses the standard handler generator pattern + -- The third argument specifies the attribute ID (0x0021) + [zcl_clusters.PowerConfiguration.ID] = { + [BATTERY_PERCENTAGE_REMAINING_ATTR] = handle_battery_percentage, + } + }, + + -- Export the configuration function so it can be called manually if needed + -- or if you prefer to manage config flow externally. + do_battery_config = do_battery_config, +} +log.debug ("battery_percentage_subdriver") +return battery_percentage_subdriver + From cf02dcfc85fa7547ef1555e2ea65b32f457621b9 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Tue, 28 Oct 2025 16:35:35 +0000 Subject: [PATCH 04/18] Another attempt Now calling the ct clamp sub driver - have temperature,battery,power meter and energy meter on the screen, last two are correct values, first two are not as yet --- .../zigbee-power-meter/fingerprints.yml | 19 +++ .../zigbee-power-meter/profiles/ct-clamp.yml | 4 +- .../zigbee-power-meter/src/chameleon/init.lua | 161 ++++++++---------- 3 files changed, 90 insertions(+), 94 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml index 4a90af3f75..fab380ce6f 100644 --- a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml +++ b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml @@ -40,5 +40,24 @@ zigbeeGeneric: server: - 0x0702 #Simple Metering deviceProfileName: power-meter + - id: "ChameleonCTClamp" + deviceLabel: Zigbee CT + deviceIdentifiers: + - 0x000D + zigbeeProfiles: + - 0x0104 + clusters: + server: + - 0x0000 #Basic + - 0x0001 #Power Configuration + - 0x0002 #Device Temperature Configuration + - 0x0003 #Identify + - 0x0019 #Over the Air Bootloading + - 0x0020 #Poll Control + - 0x0702 #Simple Metering + - 0x0B04 #Electrical Measurement + client: + - 0x0003 #Identify + deviceProfileName: ct-clamp diff --git a/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml b/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml index d8fc02d365..e5ad44c8f3 100644 --- a/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml +++ b/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml @@ -10,7 +10,9 @@ components: version: 1 - id: refresh version: 1 - - id: battery # Add the battery capability + - id: battery + version: 1 + - id: temperatureMeasurement version: 1 categories: - name: CurbPowerMeter diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua index 9f4b456e4c..8f7d8aa1fc 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -1,113 +1,88 @@ --- 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. - --- sub driver of the Zigbee Power Meter --- need to add the attribute battery percentage remaining (0x0021) from the Power Configuration Cluster (0x0001) --- need to add the attribute current temperature (0x0000) from the Temperature Configuration Cluster (0x002) - - --- --- SmartThings Edge Zigbee Subdriver for Battery Percentage (Power Configuration Cluster) --- --- This module provides the logic to configure and handle the Battery Percentage Remaining --- attribute (0x0021) from the ZCL Power Configuration Cluster (0x0001). --- +local clusters = require "st.zigbee.zcl.clusters" +local cluster_base = require "st.zigbee.cluster_base" +local data_types = require "st.zigbee.data_types" local capabilities = require "st.capabilities" -local zcl_clusters = require "st.zigbee.zcl.clusters" local log = require "log" --- Constants for the Power Configuration Cluster -local POWER_CONFIG_CLUSTER_ID = zcl_clusters.PowerConfiguration.ID -local BATTERY_PERCENTAGE_REMAINING_ATTR = zcl_clusters.PowerConfiguration.attributes.BatteryPercentageRemaining.ID +local TemperatureMeasurement = clusters.DeviceTemperatureConfiguration +local PowerConfiguration = clusters.PowerConfiguration --- The attribute value is reported in 0.5% increments, so 200 is 100%. -local MAX_PERCENT_RAW = 200 +local ZIGBEE_FINGERPRINT = { + {model = "CT101xxxx" } +} --- Configuration: Report once every 6 hours (min/max interval) with a minimum change of 2% (4 in raw units) -local BATTERY_REPORTING_CONFIG = { +-- temperature: 0.5C, humidity: 2% +local configuration = { { - cluster = POWER_CONFIG_CLUSTER_ID, - attribute = BATTERY_PERCENTAGE_REMAINING_ATTR, - -- min_reporting_interval: 1 hour (3600 seconds) - minimum_reporting_interval = 3600, - -- max_reporting_interval: 6 hours (21600 seconds) - maximum_reporting_interval = 21600, - -- reportable_change: 2% (or 4 units, since 2 units = 1%) - reportable_change = 4, + cluster = TemperatureMeasurement.ID, + attribute = TemperatureMeasurement.attributes.CurrentTemperature.ID, + minimum_interval = 30, + maximum_interval = 3600, + data_type = TemperatureMeasurement.attributes.CurrentTemperature.base_type, + reportable_change = 50 + }, + { + cluster = PowerConfiguration.ID, + attribute = PowerConfiguration.attributes.BatteryPercentageRemaining.ID, + minimum_interval = 30, + maximum_interval = 3600, + data_type = PowerConfiguration.attributes.BatteryPercentageRemaining.base_type, + reportable_change = 1 } } ---- Function to handle the raw BatteryPercentageRemaining attribute report. ---- @param driver ZigbeeDriver ---- @param device ZigbeeDevice ---- @param cmd ZclAttributeReport or ZclReadAttributeResponse -local function handle_battery_percentage(driver, device, cmd) - -- The value is reported in units of 0.5% - local raw_value = cmd.body.attribute_value.value - local percentage = raw_value / 2 - - -- Clamp the value between 0 and 100 - local final_percentage = math.max(0, math.min(100, percentage)) +local is_chameleon_ct_clamp = function(opts, driver, device) + log.info("is_chameleon_ct_clamp") + for _, fingerprint in ipairs(ZIGBEE_FINGERPRINT) do + if device:get_model() == fingerprint.model then + log.info("Yes it is a ct clamp") + return true + end + end + log.info("No it isnt a ct clamp") + return false +end - driver:emit(device, capabilities.battery.battery(final_percentage)) - device:emit_event(capabilities.refresh.refresh()) -- Also refresh the device status - driver:log_debug(string.format( - "Received Battery Percentage Report for %s: Raw=%d, Final=%d%%", - device.label, raw_value, final_percentage - )) +local function battery_level_handler(driver, device, value, zb_rx) + log.info("battery_level_handler") + device:emit_event(capabilities.battery.battery(value.value)) end ---- Function to set up the reporting configuration when the device is first configured or comes online. ---- @param driver ZigbeeDriver ---- @param device ZigbeeDevice -local function do_battery_config(driver, device) - driver:log_info(string.format("Configuring battery reporting for %s", device.label)) - - -- Send the configuration commands - for _, config in ipairs(BATTERY_REPORTING_CONFIG) do - local status, result = device:configure_reporting( - config.cluster, - config.attribute, - config.minimum_reporting_interval, - config.maximum_reporting_interval, - config.reportable_change - ) +local function device_init(driver, device) + log.info("device_init") + if configuration ~= nil then + for _, attribute in ipairs(configuration) do + device:add_configured_attribute(attribute) + end + end + + local batt_level = device:get_latest_state("main", capabilities.battery.ID, capabilities.battery.battery + .NAME) or nil + if batt_level == nil then + device:emit_event(capabilities.battery.battery.normal()) end end -local battery_percentage_subdriver = { - -- Add a handler to configure battery reporting when the device is first configured. - -- You would typically call this from the 'added' or 'online' lifecycle event of your main driver. - lifecycle = { - added = do_battery_config, - online = do_battery_config, -- In case the device was previously configured - }, +local function added_handler(self, device) + log.info("added_handler") + device:emit_event(capabilities.temperatureMeasurement.temperature({ value = 0, unit = "C" })) + device:emit_event(capabilities.battery.battery({value = 0, unit = "%" })) +end - -- Add the handler for incoming attribute reports from the Power Configuration Cluster (0x0001) - -- and the specific Battery Percentage Remaining attribute (0x0021). - handlers = { - -- This uses the standard handler generator pattern - -- The third argument specifies the attribute ID (0x0021) - [zcl_clusters.PowerConfiguration.ID] = { - [BATTERY_PERCENTAGE_REMAINING_ATTR] = handle_battery_percentage, +local ct_clamp_battery_temperature_handler = { + NAME = "ct_clamp_battery_temperature_handler", + zigbee_handlers = { + attr = { + [PowerConfiguration.ID] = { + [PowerConfiguration.attributes.BatteryPercentageRemaining.ID] = battery_level_handler + } } }, - - -- Export the configuration function so it can be called manually if needed - -- or if you prefer to manage config flow externally. - do_battery_config = do_battery_config, + lifecycle_handlers = { + init = device_init, + added = added_handler + }, + can_handle = is_chameleon_ct_clamp } -log.debug ("battery_percentage_subdriver") -return battery_percentage_subdriver +return ct_clamp_battery_temperature_handler From 8546844874da2c73f19e47d8115a6314aa7e29f7 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Wed, 29 Oct 2025 09:40:33 +0000 Subject: [PATCH 05/18] first pass of what seems to be a fully working sub driver, packaged and deployed to the hub, using the standard smartthings zigbee power meter as the base and adding as a sub driver the temperature and battery level --- .../zigbee-power-meter/src/chameleon/init.lua | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua index 8f7d8aa1fc..61742d8ce7 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -32,20 +32,28 @@ local configuration = { } local is_chameleon_ct_clamp = function(opts, driver, device) - log.info("is_chameleon_ct_clamp") for _, fingerprint in ipairs(ZIGBEE_FINGERPRINT) do if device:get_model() == fingerprint.model then - log.info("Yes it is a ct clamp") return true end end - log.info("No it isnt a ct clamp") return false end -local function battery_level_handler(driver, device, value, zb_rx) +local function battery_level_handler(driver, device, value, _zb_rx) log.info("battery_level_handler") - device:emit_event(capabilities.battery.battery(value.value)) + local number = value.value/2 + local integer_result = math.floor(number) + device:emit_event(capabilities.battery.battery(integer_result)) +end + +local function temperature_handler(driver, device, value, _zb_rx) + log.info("temperature_handler") + if type(value.value) == "number" then + device:emit_event(capabilities.temperatureMeasurement.temperature({ value = value.value, unit = "C" })) + else + log.error("Invalid temperature value received: " .. tostring(value.value)) + end end local function device_init(driver, device) @@ -56,8 +64,7 @@ local function device_init(driver, device) end end - local batt_level = device:get_latest_state("main", capabilities.battery.ID, capabilities.battery.battery - .NAME) or nil + local batt_level = device:get_latest_state("main", capabilities.battery.ID, capabilities.battery.battery.NAME) or nil if batt_level == nil then device:emit_event(capabilities.battery.battery.normal()) end @@ -75,6 +82,9 @@ local ct_clamp_battery_temperature_handler = { attr = { [PowerConfiguration.ID] = { [PowerConfiguration.attributes.BatteryPercentageRemaining.ID] = battery_level_handler + }, + [TemperatureMeasurement.ID] = { + [TemperatureMeasurement.attributes.CurrentTemperature.ID] = temperature_handler } } }, From f7a9dab3295c5d36421dc9fa3ed35a94205e5222 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Thu, 13 Nov 2025 14:45:54 +0000 Subject: [PATCH 06/18] Changes to copied in values for temperature and battery percentage --- .../zigbee-power-meter/src/chameleon/init.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua index 61742d8ce7..e6245af14f 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -11,7 +11,7 @@ local ZIGBEE_FINGERPRINT = { {model = "CT101xxxx" } } --- temperature: 0.5C, humidity: 2% +-- temperature: 0.5C, battery level remaining: 1% local configuration = { { cluster = TemperatureMeasurement.ID, @@ -19,7 +19,7 @@ local configuration = { minimum_interval = 30, maximum_interval = 3600, data_type = TemperatureMeasurement.attributes.CurrentTemperature.base_type, - reportable_change = 50 + reportable_change = 1 }, { cluster = PowerConfiguration.ID, @@ -27,7 +27,7 @@ local configuration = { minimum_interval = 30, maximum_interval = 3600, data_type = PowerConfiguration.attributes.BatteryPercentageRemaining.base_type, - reportable_change = 1 + reportable_change = 2 } } @@ -41,14 +41,16 @@ local is_chameleon_ct_clamp = function(opts, driver, device) end local function battery_level_handler(driver, device, value, _zb_rx) - log.info("battery_level_handler") + if type(value.value) == "number" then local number = value.value/2 local integer_result = math.floor(number) device:emit_event(capabilities.battery.battery(integer_result)) + else + log.error("Invalid battery level value received: " .. tostring(value.value)) + end end local function temperature_handler(driver, device, value, _zb_rx) - log.info("temperature_handler") if type(value.value) == "number" then device:emit_event(capabilities.temperatureMeasurement.temperature({ value = value.value, unit = "C" })) else @@ -57,7 +59,6 @@ local function temperature_handler(driver, device, value, _zb_rx) end local function device_init(driver, device) - log.info("device_init") if configuration ~= nil then for _, attribute in ipairs(configuration) do device:add_configured_attribute(attribute) @@ -71,7 +72,6 @@ local function device_init(driver, device) end local function added_handler(self, device) - log.info("added_handler") device:emit_event(capabilities.temperatureMeasurement.temperature({ value = 0, unit = "C" })) device:emit_event(capabilities.battery.battery({value = 0, unit = "%" })) end From a5f9d4619050e0adbbac4d0d4078a34c23cac423 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Thu, 13 Nov 2025 14:46:52 +0000 Subject: [PATCH 07/18] remove reference to VS code workspace --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cd6ab12173..463facafbe 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ tools/test_output/* tools/coverage_output/* .DS_Store .venv/ -drivers/SmartThings/zigbee-power-meter/zigbee-power-meter.code-workspace + From 21e07f325c55920efcb8125188d70c84a0453128 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Thu, 13 Nov 2025 14:48:37 +0000 Subject: [PATCH 08/18] set back to origin code --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 463facafbe..cfd9fe533f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,4 @@ lua_libs-api_* tools/test_output/* tools/coverage_output/* .DS_Store -.venv/ - +.venv/ \ No newline at end of file From f101e5c46de45a7889eb89a1da5a1bce1ba03640 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Thu, 13 Nov 2025 14:50:58 +0000 Subject: [PATCH 09/18] no message --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cfd9fe533f..c5bbdc6f99 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ lua_libs-api_* tools/test_output/* tools/coverage_output/* .DS_Store -.venv/ \ No newline at end of file +.venv/ From a5d3c876e395e8e5d242abd631953c19e3fcc5bf Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Thu, 13 Nov 2025 14:52:54 +0000 Subject: [PATCH 10/18] cr lf --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c5bbdc6f99..463facafbe 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ tools/test_output/* tools/coverage_output/* .DS_Store .venv/ + From e04499ee318a0f34baec478acccf6fde51b44953 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Wed, 26 Nov 2025 10:01:45 +0000 Subject: [PATCH 11/18] WWSTCERT-9096 PR #2552 indent code under the statement to the right as per pull request comment --- .../SmartThings/zigbee-power-meter/src/chameleon/init.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua index e6245af14f..e1600c90a9 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -42,9 +42,9 @@ end local function battery_level_handler(driver, device, value, _zb_rx) if type(value.value) == "number" then - local number = value.value/2 - local integer_result = math.floor(number) - device:emit_event(capabilities.battery.battery(integer_result)) + local number = value.value/2 + local integer_result = math.floor(number) + device:emit_event(capabilities.battery.battery(integer_result)) else log.error("Invalid battery level value received: " .. tostring(value.value)) end From 777415833d80f7d521021d79938f9b8573d560df Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Wed, 3 Dec 2025 13:37:15 +0000 Subject: [PATCH 12/18] ct-clamp-driver-wwsm rename file from ct-clamp.yml to power-energy-battery-temperature.yml add copyright information --- drivers/SmartThings/zigbee-power-meter/fingerprints.yml | 2 +- .../{ct-clamp.yml => power-energy-battery-temperature.yml} | 0 drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua | 3 +++ 3 files changed, 4 insertions(+), 1 deletion(-) rename drivers/SmartThings/zigbee-power-meter/profiles/{ct-clamp.yml => power-energy-battery-temperature.yml} (100%) diff --git a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml index fab380ce6f..54d07f2997 100644 --- a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml +++ b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml @@ -32,7 +32,7 @@ zigbeeManufacturer: deviceLabel: Chameleon CT Clamp manufacturer: Chameleon Technology model: CT101xxxx - deviceProfileName: ct-clamp + deviceProfileName: power-energy-battery-temperature zigbeeGeneric: - id: "genericMeter" deviceLabel: Zigbee Meter diff --git a/drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml b/drivers/SmartThings/zigbee-power-meter/profiles/power-energy-battery-temperature.yml similarity index 100% rename from drivers/SmartThings/zigbee-power-meter/profiles/ct-clamp.yml rename to drivers/SmartThings/zigbee-power-meter/profiles/power-energy-battery-temperature.yml diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua index e1600c90a9..a5c34b762c 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -1,3 +1,6 @@ +-- Copyright 2025 SmartThings, Inc. +-- Licensed under the Apache License, Version 2.0 + local clusters = require "st.zigbee.zcl.clusters" local cluster_base = require "st.zigbee.cluster_base" local data_types = require "st.zigbee.data_types" From eeef59b7c64a2f86c5174ba2f9d5fa2dcc84464a Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Wed, 3 Dec 2025 13:44:11 +0000 Subject: [PATCH 13/18] ct_clamp-driver_wwsm removed unused variables cluster_base and data_types --- drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua index a5c34b762c..3184effa58 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -2,8 +2,6 @@ -- Licensed under the Apache License, Version 2.0 local clusters = require "st.zigbee.zcl.clusters" -local cluster_base = require "st.zigbee.cluster_base" -local data_types = require "st.zigbee.data_types" local capabilities = require "st.capabilities" local log = require "log" From 590dddd32906cc15c92a53392cd7968add11a6dc Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Wed, 3 Dec 2025 16:29:12 +0000 Subject: [PATCH 14/18] ct_clamp_river_wwsm add changed name into yaml file remove non manufacturer specific items --- .../zigbee-power-meter/fingerprints.yml | 20 +------------------ .../power-energy-battery-temperature.yml | 2 +- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml index 54d07f2997..9584159c9b 100644 --- a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml +++ b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml @@ -40,24 +40,6 @@ zigbeeGeneric: server: - 0x0702 #Simple Metering deviceProfileName: power-meter - - id: "ChameleonCTClamp" - deviceLabel: Zigbee CT - deviceIdentifiers: - - 0x000D - zigbeeProfiles: - - 0x0104 - clusters: - server: - - 0x0000 #Basic - - 0x0001 #Power Configuration - - 0x0002 #Device Temperature Configuration - - 0x0003 #Identify - - 0x0019 #Over the Air Bootloading - - 0x0020 #Poll Control - - 0x0702 #Simple Metering - - 0x0B04 #Electrical Measurement - client: - - 0x0003 #Identify - deviceProfileName: ct-clamp + diff --git a/drivers/SmartThings/zigbee-power-meter/profiles/power-energy-battery-temperature.yml b/drivers/SmartThings/zigbee-power-meter/profiles/power-energy-battery-temperature.yml index e5ad44c8f3..a47aef0114 100644 --- a/drivers/SmartThings/zigbee-power-meter/profiles/power-energy-battery-temperature.yml +++ b/drivers/SmartThings/zigbee-power-meter/profiles/power-energy-battery-temperature.yml @@ -1,4 +1,4 @@ -name: ct-clamp +name: power-energy-battery-temperature components: - id: main capabilities: From 3e2c2e59ac1882528481aa6c04b0842b96336c7c Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Mon, 8 Dec 2025 16:05:59 +0000 Subject: [PATCH 15/18] ct_clap_driver_wwsm Added longer copyright at top of our init.lua file removed comment about tempeature and battery removed battery level handler to main init.lua file under capabilities.battery, temperature syayed as its cluster 0x0402 not the normal temperature cluster and didn't update the temperature --- .../zigbee-power-meter/src/chameleon/init.lua | 22 ++++++++++++++----- .../zigbee-power-meter/src/init.lua | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua index 3184effa58..c09f7a4d36 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -1,5 +1,16 @@ --- Copyright 2025 SmartThings, Inc. --- Licensed under the Apache License, Version 2.0 +-- Copyright 2025 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. local clusters = require "st.zigbee.zcl.clusters" local capabilities = require "st.capabilities" @@ -12,7 +23,6 @@ local ZIGBEE_FINGERPRINT = { {model = "CT101xxxx" } } --- temperature: 0.5C, battery level remaining: 1% local configuration = { { cluster = TemperatureMeasurement.ID, @@ -81,9 +91,9 @@ local ct_clamp_battery_temperature_handler = { NAME = "ct_clamp_battery_temperature_handler", zigbee_handlers = { attr = { - [PowerConfiguration.ID] = { - [PowerConfiguration.attributes.BatteryPercentageRemaining.ID] = battery_level_handler - }, + --[PowerConfiguration.ID] = { + -- [PowerConfiguration.attributes.BatteryPercentageRemaining.ID] = battery_level_handler + --}, [TemperatureMeasurement.ID] = { [TemperatureMeasurement.attributes.CurrentTemperature.ID] = temperature_handler } diff --git a/drivers/SmartThings/zigbee-power-meter/src/init.lua b/drivers/SmartThings/zigbee-power-meter/src/init.lua index 016f1e7e42..0df18636d6 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/init.lua @@ -51,6 +51,7 @@ local zigbee_power_meter_driver_template = { capabilities.powerMeter, capabilities.energyMeter, capabilities.powerConsumptionReport, + capabilities.battery, }, zigbee_handlers = { global = { From 2209e1b61557bc6d1a5c93db33a4c0b0e9dd6aea Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Mon, 8 Dec 2025 16:40:17 +0000 Subject: [PATCH 16/18] removed as causing error in the HUB log --- .../SmartThings/zigbee-power-meter/src/chameleon/init.lua | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua index c09f7a4d36..e527936146 100644 --- a/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua +++ b/drivers/SmartThings/zigbee-power-meter/src/chameleon/init.lua @@ -75,11 +75,6 @@ local function device_init(driver, device) device:add_configured_attribute(attribute) end end - - local batt_level = device:get_latest_state("main", capabilities.battery.ID, capabilities.battery.battery.NAME) or nil - if batt_level == nil then - device:emit_event(capabilities.battery.battery.normal()) - end end local function added_handler(self, device) From e2b453f770ec34bbc824d0947c4e9837d4b99d3c Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Wed, 10 Dec 2025 10:50:51 +0000 Subject: [PATCH 17/18] ct_clamp_driver_wwsm removed 3 lines as requested in comments on the pull request --- drivers/SmartThings/zigbee-power-meter/fingerprints.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml index 9584159c9b..7807961214 100644 --- a/drivers/SmartThings/zigbee-power-meter/fingerprints.yml +++ b/drivers/SmartThings/zigbee-power-meter/fingerprints.yml @@ -39,7 +39,4 @@ zigbeeGeneric: clusters: server: - 0x0702 #Simple Metering - deviceProfileName: power-meter - - - + deviceProfileName: power-meter \ No newline at end of file From 766c49efee04c2823630ebf51432732881b56ff9 Mon Sep 17 00:00:00 2001 From: peter_wadsworth Date: Wed, 10 Dec 2025 10:53:59 +0000 Subject: [PATCH 18/18] ct_clamp_driver_wwsm remove unintentional extra line in .gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 463facafbe..cfd9fe533f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,4 @@ lua_libs-api_* tools/test_output/* tools/coverage_output/* .DS_Store -.venv/ - +.venv/ \ No newline at end of file