Skip to content

Commit

Permalink
CHAD-12259 zigbee motion: high battery usage
Browse files Browse the repository at this point in the history
Users reported higher battery consumption with edge drivers and a disparity was noted between DTH and driver cluster configurations. A forthcoming change in the lua libraries will change the defaults, but this change should significantly improve the situation for most users in the meantime with a simple refresh. Changes the IAS Zone reporting configuration to use the device defaults and changes temperature reporting to a max interval of 10 minutes with a 1 degree celsius reporting threshold.

add change for zigbee contact as well
  • Loading branch information
greens committed Jan 30, 2024
1 parent 36fa288 commit 352d768
Show file tree
Hide file tree
Showing 19 changed files with 213 additions and 138 deletions.
27 changes: 0 additions & 27 deletions drivers/SmartThings/zigbee-contact/src/battery-overrides/init.lua

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ local CONTACT_TEMPERATURE_SENSOR_FINGERPRINTS = {
{ mfr = "CentraLite", model = "3323-G" },
{ mfr = "CentraLite", model = "Contact Sensor-A" },
{ mfr = "Visonic", model = "MCT-340 E" },
{ mfr = "Visonic", model = "MCT-340 SMA" },
{ mfr = "Ecolink", model = "4655BC0-R" },
{ mfr = "Ecolink", model = "DWZB1-ECO" },
{ mfr = "iMagic by GreatStar", model = "1116-S" },
Expand Down
1 change: 0 additions & 1 deletion drivers/SmartThings/zigbee-contact/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ local zigbee_contact_driver_template = {
},
sub_drivers = {
require("aqara"),
require("battery-overrides"),
require("aurora-contact-sensor"),
require("contact-temperature-sensor"),
require("multi-sensor"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ local battery_defaults = require "st.zigbee.defaults.battery_defaults"
local multi_utils = require "multi-sensor/multi_utils"
local capabilities = require "st.capabilities"
local data_types = require "st.zigbee.data_types"
local zcl_clusters = require "st.zigbee.zcl.clusters"

local TARGET_DEV_MAJOR = 1
local TARGET_DEV_MINOR = 15
Expand All @@ -24,6 +25,8 @@ local TARGET_DEV_BUILD = 7
local CENTRALITE_MFG = 0x104E

local init_handler = function(self, device)
device:remove_configured_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
device:remove_monitored_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
local firmware_full_version = device.data.firmwareFullVersion or "0000"
local dev_major = tonumber(firmware_full_version:sub(1,1), 16)
local dev_minor = tonumber(firmware_full_version:sub(2,2), 16)
Expand Down
8 changes: 7 additions & 1 deletion drivers/SmartThings/zigbee-contact/src/multi-sensor/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ local function zone_status_handler(driver, device, zone_status, zb_rx)
end
end

local function do_init(driver, device)
device:remove_configured_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
device:remove_monitored_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
end

local function added_handler(self, device)
device:emit_event(capabilities.accelerationSensor.acceleration.inactive())
device:refresh()
Expand All @@ -72,7 +77,8 @@ end
local multi_sensor = {
NAME = "Zigbee Multi Sensor",
lifecycle_handlers = {
added = added_handler
added = added_handler,
init = do_init
},
zigbee_handlers = {
global = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ local zcl_commands = require "st.zigbee.zcl.global_commands"
local multi_utils = require "multi-sensor/multi_utils"
local capabilities = require "st.capabilities"
local data_types = require "st.zigbee.data_types"
local zcl_clusters = require "st.zigbee.zcl.clusters"

local SMARTTHINGS_MFG = 0x110A

Expand Down Expand Up @@ -55,6 +56,8 @@ end

local function init_handler(driver, device)
battery_defaults.enable_battery_voltage_table(device, battery_table)
device:remove_configured_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
device:remove_monitored_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
end

local function do_configure(self, device)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,14 +242,6 @@ test.register_coroutine_test(
mock_device.id,
TemperatureMeasurement.attributes.MeasuredValue:configure_reporting(mock_device, 30, 300, 16)
})
test.socket.zigbee:__expect_send({
mock_device.id,
zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, IASZone.ID)
})
test.socket.zigbee:__expect_send({
mock_device.id,
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 30, 300, 1)
})
test.socket.zigbee:__expect_send({
mock_device.id,
IASCIEAddress:write(mock_device, zigbee_test_utils.mock_hub_eui)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,6 @@ test.register_coroutine_test(
mock_device.id,
TemperatureMeasurement.attributes.MeasuredValue:configure_reporting(mock_device, 30, 300, 16)
})
test.socket.zigbee:__expect_send({
mock_device.id,
zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, IASZone.ID)
})
test.socket.zigbee:__expect_send({
mock_device.id,
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 30, 300, 1)
})
test.socket.zigbee:__expect_send({
mock_device.id,
IASCIEAddress:write(mock_device, zigbee_test_utils.mock_hub_eui)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,14 +296,6 @@ test.register_coroutine_test(
mock_device.id,
TemperatureMeasurement.attributes.MeasuredValue:configure_reporting(mock_device, 30, 300, 16)
})
test.socket.zigbee:__expect_send({
mock_device.id,
zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, IASZone.ID)
})
test.socket.zigbee:__expect_send({
mock_device.id,
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 30, 300, 1)
})
test.socket.zigbee:__expect_send({
mock_device.id,
IASCIEAddress:write(mock_device, zigbee_test_utils.mock_hub_eui)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@
-- limitations under the License.

local battery_defaults = require "st.zigbee.defaults.battery_defaults"
local zcl_clusters = require "st.zigbee.zcl.clusters"

local TARGET_DEV_MAJOR = 1
local TARGET_DEV_MINOR = 15
local TARGET_DEV_BUILD = 7

local init_handler = function(self, device)
-- TODO: the IAS Zone changes should be replaced after supporting functions are included in the lua libs
device:remove_monitored_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
device:remove_configured_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)

local firmware_full_version = device.data.firmwareFullVersion or "0000"
local dev_major = tonumber(firmware_full_version:sub(1,1), 16)
local dev_minor = tonumber(firmware_full_version:sub(2,2), 16)
Expand Down
26 changes: 26 additions & 0 deletions drivers/SmartThings/zigbee-motion-sensor/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@ local capabilities = require "st.capabilities"
local ZigbeeDriver = require "st.zigbee"
local defaults = require "st.zigbee.defaults"
local constants = require "st.zigbee.constants"
local zcl_clusters = require "st.zigbee.zcl.clusters"

local HAS_RECONFIGURED = "_has_reconfigured"

-- TODO: Remove when available in lua libs
-- This is a temporary method to lower battery consumption in several devices.
-- Disparities were noted between DTH implementations and driver defaults. -sg
local do_refresh = function(driver, device, command)
device:refresh()

if device:get_field(HAS_RECONFIGURED) == nil then
if device:supports_capability_by_id(capabilities.temperatureMeasurement.ID) and device:supports_server_cluster(zcl_clusters.TemperatureMeasurement.ID) then
device:send(zcl_clusters.TemperatureMeasurement.attributes.MeasuredValue:configure_reporting(device, 30, 600, 100))
end

if device:supports_capability_by_id(capabilities.motionSensor.ID) and device:supports_server_cluster(zcl_clusters.IASZone.ID) then
device:send(zcl_clusters.IASZone.attributes.ZoneStatus:configure_reporting(device, 0xFFFF, 0x0000, 0)) -- reset to default
end
device:set_field(HAS_RECONFIGURED, true)
end
end

local zigbee_motion_driver = {
supported_capabilities = {
Expand All @@ -26,6 +47,11 @@ local zigbee_motion_driver = {
capabilities.presenceSensor,
capabilities.contactSensor
},
capability_handlers = {
[capabilities.refresh.ID] = {
[capabilities.refresh.commands.refresh.NAME] = do_refresh,
}
},
sub_drivers = {
require("aqara"),
require("aurora"),
Expand Down
10 changes: 9 additions & 1 deletion drivers/SmartThings/zigbee-motion-sensor/src/iris/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.

local zcl_clusters = require "st.zigbee.zcl.clusters"
local battery_defaults = require "st.zigbee.defaults.battery_defaults"

local ZIGBEE_IRIS_MOTION_SENSOR_FINGERPRINTS = {
{ mfr = "iMagic by GreatStar", model = "1117-S" }
}

-- TODO: the IAS Zone changes should be replaced after supporting functions are included in the lua libs
local do_init = function(driver, device)
battery_defaults.build_linear_voltage_init(2.4, 2.7)(driver, device)
device:remove_monitored_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
device:remove_configured_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
end

local is_zigbee_iris_motion_sensor = function(opts, driver, device)
for _, fingerprint in ipairs(ZIGBEE_IRIS_MOTION_SENSOR_FINGERPRINTS) do
if device:get_manufacturer() == fingerprint.mfr and device:get_model() == fingerprint.model then
Expand All @@ -30,7 +38,7 @@ end
local iris_motion_handler = {
NAME = "Iris Motion Handler",
lifecycle_handlers = {
init = battery_defaults.build_linear_voltage_init(2.4, 2.7)
init = do_init
},
can_handle = is_zigbee_iris_motion_sensor
}
Expand Down
9 changes: 9 additions & 0 deletions drivers/SmartThings/zigbee-motion-sensor/src/samjin/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ local capabilities = require "st.capabilities"

local utils = require "st.utils"

-- TODO: the IAS Zone changes should be replaced after supporting functions are included in the lua libs
local do_init = function(driver, device)
device:remove_monitored_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
device:remove_configured_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
end

local function samjin_battery_percentage_handler(driver, device, raw_value, zb_rx)
local raw_percentage = raw_value.value - (200 - raw_value.value) / 2
local percentage = utils.clamp_value(utils.round(raw_percentage / 2), 0, 100)
Expand All @@ -28,6 +34,9 @@ end

local samjin_driver = {
NAME = "Samjin Sensor",
lifecycle_handlers = {
init = do_init
},
zigbee_handlers = {
attr = {
[PowerConfiguration.ID] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.

local zcl_clusters = require "st.zigbee.zcl.clusters"
local battery_defaults = require "st.zigbee.defaults.battery_defaults"

local battery_table = {
Expand All @@ -33,6 +34,9 @@ local battery_table = {

local function init_handler(driver, device)
battery_defaults.enable_battery_voltage_table(device, battery_table)
-- TODO: the IAS Zone changes should be replaced after supporting functions are included in the lua libs
device:remove_monitored_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
device:remove_configured_attribute(zcl_clusters.IASZone.ID, zcl_clusters.IASZone.attributes.ZoneStatus.ID)
end

local smartthings_motion = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ test.register_coroutine_test(
mock_device.id,
TemperatureMeasurement.attributes.MeasuredValue:configure_reporting(mock_device, 30, 300, 0x10)
})
test.socket.zigbee:__expect_send({
mock_device.id,
TemperatureMeasurement.attributes.MeasuredValue:configure_reporting(mock_device, 30, 600, 100)
})
test.socket.zigbee:__expect_send({
mock_device.id,
zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, TemperatureMeasurement.ID)
Expand Down Expand Up @@ -228,6 +232,10 @@ test.register_coroutine_test(
mock_device.id,
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 30, 300, 0)
})
test.socket.zigbee:__expect_send({
mock_device.id,
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 0xFFFF, 0x0000, 0)
})
test.socket.zigbee:__expect_send({
mock_device.id,
zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, IASZone.ID)
Expand Down Expand Up @@ -285,6 +293,22 @@ test.register_message_test(
IASZone.attributes.ZoneStatus:read(mock_device)
}
},
{
channel = "zigbee",
direction = "send",
message = {
mock_device.id,
TemperatureMeasurement.attributes.MeasuredValue:configure_reporting(mock_device, 30, 600, 100)
}
},
{
channel = "zigbee",
direction = "send",
message = {
mock_device.id,
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 0xFFFF, 0x0000, 0)
}
},
},
{
inner_block_ordering = "relaxed"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ test.register_coroutine_test(
mock_device.id,
zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, IASZone.ID)
})
test.socket.zigbee:__expect_send({
mock_device.id,
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 0xFFFF, 0x0000, 0)
})

mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
end
Expand Down Expand Up @@ -170,6 +174,14 @@ test.register_message_test(
IASZone.attributes.ZoneStatus:read(mock_device)
}
},
{
channel = "zigbee",
direction = "send",
message = {
mock_device.id,
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 0xFFFF, 0x0000, 0)
}
},
},
{
inner_block_ordering = "relaxed"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ test.register_coroutine_test(
mock_device.id,
TemperatureMeasurement.attributes.MeasuredValue:configure_reporting(mock_device, 30, 300, 16)
})
test.socket.zigbee:__expect_send({
mock_device.id,
TemperatureMeasurement.attributes.MeasuredValue:configure_reporting(mock_device, 30, 600, 100)
})
test.socket.zigbee:__expect_send({
mock_device.id,
zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, TemperatureMeasurement.ID)
Expand All @@ -88,14 +92,18 @@ test.register_coroutine_test(
mock_device.id,
IASZone.attributes.ZoneStatus:read(mock_device)
})
-- test.socket.zigbee:__expect_send({
-- mock_device.id,
-- IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 30, 300, 0)
-- })
test.socket.zigbee:__expect_send({
mock_device.id,
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 30, 300, 0)
})
test.socket.zigbee:__expect_send({
mock_device.id,
zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, IASZone.ID)
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 0xFFFF, 0x0000, 0)
})
-- test.socket.zigbee:__expect_send({
-- mock_device.id,
-- zigbee_test_utils.build_bind_request(mock_device, zigbee_test_utils.mock_hub_eui, IASZone.ID)
-- })
mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
end
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ test.register_coroutine_test(
test.socket.capability:__queue_receive({ mock_device.id, { capability = "refresh", component = "main", command = "refresh", args = {} } })
test.socket.zigbee:__expect_send({ mock_device.id, IASZone.attributes.ZoneStatus:read(mock_device) })
test.socket.zigbee:__expect_send({ mock_device.id, PowerConfiguration.attributes.BatteryVoltage:read(mock_device) })
test.socket.zigbee:__expect_send({ mock_device.id, IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 0xFFFF, 0x0000, 0) })
end
)

Expand Down Expand Up @@ -79,6 +80,7 @@ test.register_coroutine_test(
IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 30, 3600, 1)
}
)
test.socket.zigbee:__expect_send({ mock_device.id, IASZone.attributes.ZoneStatus:configure_reporting(mock_device, 0xFFFF, 0x0000, 0) })
test.socket.zigbee:__expect_send(
{
mock_device.id,
Expand Down
Loading

0 comments on commit 352d768

Please sign in to comment.