Skip to content

Commit d51954b

Browse files
authored
Merge pull request #2159 from SmartThingsCommunity/reconfigure-power-meter-zigbee
Add reconfiguration for zigbee power meter to reduce reporting
2 parents 3b7cb0e + cb3da21 commit d51954b

File tree

26 files changed

+360
-14
lines changed

26 files changed

+360
-14
lines changed

drivers/SmartThings/zigbee-switch/src/aqara/multi-switch/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ local device_lib = require "st.device"
22
local capabilities = require "st.capabilities"
33
local cluster_base = require "st.zigbee.cluster_base"
44
local data_types = require "st.zigbee.data_types"
5+
local configurations = require "configurations"
56

67
local PRIVATE_CLUSTER_ID = 0xFCC0
78
local PRIVATE_ATTRIBUTE_ID = 0x0009
@@ -100,7 +101,7 @@ end
100101
local aqara_multi_switch_handler = {
101102
NAME = "Aqara Multi Switch Handler",
102103
lifecycle_handlers = {
103-
init = device_init,
104+
init = configurations.power_reconfig_wrapper(device_init),
104105
added = device_added
105106
},
106107
can_handle = is_aqara_products

drivers/SmartThings/zigbee-switch/src/configurations.lua

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,15 @@
1414

1515
local clusters = require "st.zigbee.zcl.clusters"
1616
local constants = require "st.zigbee.constants"
17+
local capabilities = require "st.capabilities"
18+
local device_def = require "st.device"
1719

1820
local ColorControl = clusters.ColorControl
1921
local IASZone = clusters.IASZone
22+
local Status = require "st.zigbee.generated.types.ZclStatus"
23+
24+
local CONFIGURATION_VERSION_KEY = "_configuration_version"
25+
local CONFIGURATION_ATTEMPTED = "_reconfiguration_attempted"
2026

2127
local devices = {
2228
IKEA_RGB_BULB = {
@@ -60,8 +66,94 @@ local devices = {
6066
}
6167
}
6268

69+
6370
local configurations = {}
6471

72+
local active_power_configuration = {
73+
cluster = clusters.ElectricalMeasurement.ID,
74+
attribute = clusters.ElectricalMeasurement.attributes.ActivePower.ID,
75+
minimum_interval = 5,
76+
maximum_interval = 3600,
77+
data_type = clusters.ElectricalMeasurement.attributes.ActivePower.base_type,
78+
reportable_change = 5
79+
}
80+
81+
local instantaneous_demand_configuration = {
82+
cluster = clusters.SimpleMetering.ID,
83+
attribute = clusters.SimpleMetering.attributes.InstantaneousDemand.ID,
84+
minimum_interval = 5,
85+
maximum_interval = 3600,
86+
data_type = clusters.SimpleMetering.attributes.InstantaneousDemand.base_type,
87+
reportable_change = 5
88+
}
89+
90+
configurations.check_and_reconfig_devices = function(driver)
91+
for device_id, device in pairs(driver.device_cache) do
92+
local config_version = device:get_field(CONFIGURATION_VERSION_KEY)
93+
if config_version == nil or config_version < driver.current_config_version then
94+
if device:supports_capability(capabilities.powerMeter) then
95+
if device:supports_server_cluster(clusters.ElectricalMeasurement.ID) then
96+
-- Increase minimum reporting interval to 5 seconds
97+
device:send(clusters.ElectricalMeasurement.attributes.ActivePower:configure_reporting(device, 5, 600, 5))
98+
device:add_configured_attribute(active_power_configuration)
99+
end
100+
if device:supports_server_cluster(clusters.SimpleMetering.ID) then
101+
-- Increase minimum reporting interval to 5 seconds
102+
device:send(clusters.SimpleMetering.attributes.InstantaneousDemand:configure_reporting(device, 5, 600, 5))
103+
device:add_configured_attribute(instantaneous_demand_configuration)
104+
end
105+
end
106+
device:set_field(CONFIGURATION_ATTEMPTED, true, {persist = true})
107+
end
108+
end
109+
driver._reconfig_timer = nil
110+
end
111+
112+
configurations.handle_reporting_config_response = function(driver, device, zb_mess)
113+
local dev = device
114+
local find_child_fn = device:get_field(device_def.FIND_CHILD_KEY)
115+
if find_child_fn ~= nil then
116+
local child = find_child_fn(device, zb_mess.address_header.src_endpoint.value)
117+
if child ~= nil then
118+
dev = child
119+
end
120+
end
121+
if dev:get_field(CONFIGURATION_ATTEMPTED) == true then
122+
if zb_mess.body.zcl_body.global_status ~= nil and zb_mess.body.zcl_body.global_status.value == Status.SUCCESS then
123+
dev:set_field(CONFIGURATION_VERSION_KEY, driver.current_config_version, {persist = true})
124+
elseif zb_mess.body.zcl_body.config_records ~= nil then
125+
local config_records = zb_mess.body.zcl_body.config_records
126+
for _, record in ipairs(config_records) do
127+
if zb_mess.address_header.cluster.value == clusters.SimpleMetering.ID then
128+
if record.attr_id.value == clusters.SimpleMetering.attributes.InstantaneousDemand.ID
129+
and record.status.value == Status.SUCCESS then
130+
dev:set_field(CONFIGURATION_VERSION_KEY, driver.current_config_version, {persist = true})
131+
end
132+
elseif zb_mess.address_header.cluster.value == clusters.ElectricalMeasurement.ID then
133+
if record.attr_id.value == clusters.ElectricalMeasurement.attributes.ActivePower.ID
134+
and record.status.value == Status.SUCCESS then
135+
dev:set_field(CONFIGURATION_VERSION_KEY, driver.current_config_version, {persist = true})
136+
end
137+
end
138+
139+
end
140+
end
141+
end
142+
end
143+
144+
configurations.power_reconfig_wrapper = function(orig_function)
145+
local new_init = function(driver, device)
146+
local config_version = device:get_field(CONFIGURATION_VERSION_KEY)
147+
if config_version == nil or config_version < driver.current_config_version then
148+
if driver._reconfig_timer == nil then
149+
driver._reconfig_timer = driver:call_with_delay(5*60, configurations.check_and_reconfig_devices, "reconfig_power_devices")
150+
end
151+
end
152+
orig_function(driver, device)
153+
end
154+
return new_init
155+
end
156+
65157
configurations.get_device_configuration = function(zigbee_device)
66158
for _, device in pairs(devices) do
67159
for _, fingerprint in pairs(device.FINGERPRINTS) do

drivers/SmartThings/zigbee-switch/src/ezex/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
-- limitations under the License.
1414

1515
local zigbee_constants = require "st.zigbee.constants"
16+
local configurations = require "configurations"
1617

1718
local ZIGBEE_METERING_SWITCH_FINGERPRINTS = {
1819
{ model = "E240-KR116Z-HA" }
@@ -37,7 +38,7 @@ end
3738
local ezex_switch_handler = {
3839
NAME = "ezex switch handler",
3940
lifecycle_handlers = {
40-
init = do_init
41+
init = configurations.power_reconfig_wrapper(do_init)
4142
},
4243
can_handle = is_zigbee_ezex_switch
4344
}

drivers/SmartThings/zigbee-switch/src/hanssem/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
-- limitations under the License.
1414

1515
local stDevice = require "st.device"
16+
local configurations = require "configurations"
1617

1718
local FINGERPRINTS = {
1819
{ mfr = "Winners", model = "LSS1-101", children = 0 },
@@ -78,7 +79,7 @@ local HanssemSwitch = {
7879
NAME = "Zigbee Hanssem Switch",
7980
lifecycle_handlers = {
8081
added = device_added,
81-
init = device_init
82+
init = configurations.power_reconfig_wrapper(device_init)
8283
},
8384
can_handle = can_handle_hanssem_switch
8485
}

drivers/SmartThings/zigbee-switch/src/init.lua

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ local ZigbeeDriver = require "st.zigbee"
1717
local defaults = require "st.zigbee.defaults"
1818
local clusters = require "st.zigbee.zcl.clusters"
1919
local configurationMap = require "configurations"
20+
local zcl_global_commands = require "st.zigbee.zcl.global_commands"
2021
local SimpleMetering = clusters.SimpleMetering
22+
local ElectricalMeasurement = clusters.ElectricalMeasurement
2123
local preferences = require "preferences"
2224
local device_lib = require "st.device"
2325

@@ -127,6 +129,7 @@ local function device_added(driver, device, event)
127129
end
128130
end
129131

132+
130133
local zigbee_switch_driver_template = {
131134
supported_capabilities = {
132135
capabilities.switch,
@@ -164,8 +167,19 @@ local zigbee_switch_driver_template = {
164167
lazy_load_if_possible("laisiao"),
165168
lazy_load_if_possible("tuya-multi")
166169
},
170+
zigbee_handlers = {
171+
global = {
172+
[SimpleMetering.ID] = {
173+
[zcl_global_commands.CONFIGURE_REPORTING_RESPONSE_ID] = configurationMap.handle_reporting_config_response
174+
},
175+
[ElectricalMeasurement.ID] = {
176+
[zcl_global_commands.CONFIGURE_REPORTING_RESPONSE_ID] = configurationMap.handle_reporting_config_response
177+
}
178+
}
179+
},
180+
current_config_version = 1,
167181
lifecycle_handlers = {
168-
init = device_init,
182+
init = configurationMap.power_reconfig_wrapper(device_init),
169183
added = device_added,
170184
infoChanged = info_changed,
171185
doConfigure = do_configure

drivers/SmartThings/zigbee-switch/src/inovelli-vzm31-sn/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ local st_device = require "st.device"
1919
local data_types = require "st.zigbee.data_types"
2020
local capabilities = require "st.capabilities"
2121
local device_management = require "st.zigbee.device_management"
22+
local configurations = require "configurations"
2223

2324
local LATEST_CLOCK_SET_TIMESTAMP = "latest_clock_set_timestamp"
2425

@@ -358,7 +359,7 @@ local inovelli_vzm31_sn = {
358359
NAME = "inovelli vzm31-sn handler",
359360
lifecycle_handlers = {
360361
doConfigure = do_configure,
361-
init = device_init,
362+
init = configurations.power_reconfig_wrapper(device_init),
362363
infoChanged = info_changed
363364
},
364365
zigbee_handlers = {

drivers/SmartThings/zigbee-switch/src/laisiao/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
local capabilities = require "st.capabilities"
1616
local zcl_clusters = require "st.zigbee.zcl.clusters"
17+
local configurations = require "configurations"
1718

1819
local FINGERPRINTS = {
1920
{ mfr = "LAISIAO", model = "yuba" },
@@ -70,7 +71,7 @@ local laisiao_bath_heater = {
7071
capabilities.switch,
7172
},
7273
lifecycle_handlers = {
73-
init = device_init,
74+
init = configurations.power_reconfig_wrapper(device_init),
7475
},
7576
capability_handlers = {
7677
[capabilities.switch.ID] = {

drivers/SmartThings/zigbee-switch/src/multi-switch-no-master/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
-- limitations under the License.
1414
local st_device = require "st.device"
1515
local utils = require "st.utils"
16+
local configurations = require "configurations"
1617

1718
local MULTI_SWITCH_NO_MASTER_FINGERPRINTS = {
1819
{ mfr = "DAWON_DNS", model = "PM-S240-ZB", children = 1 },
@@ -113,7 +114,7 @@ end
113114
local multi_switch_no_master = {
114115
NAME = "multi switch no master",
115116
lifecycle_handlers = {
116-
init = device_init,
117+
init = configurations.power_reconfig_wrapper(device_init),
117118
added = device_added
118119
},
119120
can_handle = is_multi_switch_no_master

drivers/SmartThings/zigbee-switch/src/robb/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
local constants = require "st.zigbee.constants"
1616
local zcl_clusters = require "st.zigbee.zcl.clusters"
1717
local capabilities = require "st.capabilities"
18+
local configurations = require "configurations"
1819
local SimpleMetering = zcl_clusters.SimpleMetering
1920

2021
local ROBB_DIMMER_FINGERPRINTS = {
@@ -57,7 +58,7 @@ local robb_dimmer_handler = {
5758
}
5859
},
5960
lifecycle_handlers = {
60-
init = do_init
61+
init = configurations.power_reconfig_wrapper(do_init)
6162
},
6263
can_handle = is_robb_dimmer
6364
}

0 commit comments

Comments
 (0)