@@ -20,6 +20,13 @@ local CARBON_MONOXIDE_MEASUREMENT_UNIT = "CarbonMonoxideConcentrationMeasurement
20
20
local SMOKE_CO_ALARM_DEVICE_TYPE_ID = 0x0076
21
21
local PROFILE_MATCHED = " __profile_matched"
22
22
23
+ local HUE_MANUFACTURER_ID = 0x100B
24
+
25
+ local battery_support = {
26
+ NO_BATTERY = " NO_BATTERY" ,
27
+ BATTERY_PERCENTAGE = " BATTERY_PERCENTAGE"
28
+ }
29
+
23
30
local version = require " version"
24
31
if version .api < 10 then
25
32
clusters .SmokeCoAlarm = require " SmokeCoAlarm"
49
56
local supported_profiles =
50
57
{
51
58
" co" ,
59
+ " co-battery" ,
52
60
" co-comeas" ,
61
+ " co-comeas-battery" ,
53
62
" smoke" ,
63
+ " smoke-battey" ,
54
64
" smoke-co-comeas" ,
55
- " smoke-co-temp-humidity-comeas"
65
+ " smoke-co-comeas-battery" ,
66
+ " smoke-co-temp-humidity-comeas" ,
67
+ " smoke-co-temp-humidity-comeas-battery"
56
68
}
57
69
58
- local function match_profile (device )
70
+ local function match_profile (device , battery_supported )
59
71
local smoke_eps = embedded_cluster_utils .get_endpoints (device , clusters .SmokeCoAlarm .ID , {feature_bitmap = clusters .SmokeCoAlarm .types .Feature .SMOKE_ALARM })
60
72
local co_eps = embedded_cluster_utils .get_endpoints (device , clusters .SmokeCoAlarm .ID , {feature_bitmap = clusters .SmokeCoAlarm .types .Feature .CO_ALARM })
61
73
local temp_eps = embedded_cluster_utils .get_endpoints (device , clusters .TemperatureMeasurement .ID )
@@ -84,6 +96,9 @@ local function match_profile(device)
84
96
if # co_level_eps > 0 then
85
97
profile_name = profile_name .. " -colevel"
86
98
end
99
+ if battery_supported == battery_support .BATTERY_PERCENTAGE then
100
+ profile_name = profile_name .. " -battery"
101
+ end
87
102
88
103
-- remove leading "-"
89
104
profile_name = string.sub (profile_name , 2 )
108
123
109
124
local function device_init (driver , device )
110
125
if not device :get_field (PROFILE_MATCHED ) then
111
- match_profile (device )
126
+ local battery_feature_eps = device :get_endpoints (clusters .PowerSource .ID , {feature_bitmap = clusters .PowerSource .types .PowerSourceFeature .BATTERY })
127
+ -- Hue devices support the PowerSource cluster but don't support reporting battery percentage remaining
128
+ if # battery_feature_eps > 0 and device .manufacturer_info .vendor_id ~= HUE_MANUFACTURER_ID then
129
+ device :send (clusters .PowerSource .attributes .AttributeList :read ())
130
+ else
131
+ match_profile (device , battery_support .NO_BATTERY )
132
+ end
112
133
end
113
134
device :subscribe ()
114
135
end
@@ -201,6 +222,16 @@ local function battery_alert_attr_handler(driver, device, ib, response)
201
222
end
202
223
end
203
224
225
+ local function power_source_attribute_list_handler (driver , device , ib , response )
226
+ for _ , attr in ipairs (ib .data .elements ) do
227
+ -- Re-profile the device if BatPercentRemaining (Attribute ID 0x0C) is available
228
+ if attr .value == 0x0C then
229
+ match_profile (device , battery_support .BATTERY_PERCENTAGE )
230
+ return
231
+ end
232
+ end
233
+ end
234
+
204
235
local matter_smoke_co_alarm_handler = {
205
236
NAME = " matter-smoke-co-alarm" ,
206
237
lifecycle_handlers = {
@@ -219,7 +250,10 @@ local matter_smoke_co_alarm_handler = {
219
250
[clusters .CarbonMonoxideConcentrationMeasurement .ID ] = {
220
251
[clusters .CarbonMonoxideConcentrationMeasurement .attributes .MeasuredValue .ID ] = carbon_monoxide_attr_handler ,
221
252
[clusters .CarbonMonoxideConcentrationMeasurement .attributes .MeasurementUnit .ID ] = carbon_monoxide_unit_attr_handler ,
222
- }
253
+ },
254
+ [clusters .PowerSource .ID ] = {
255
+ [clusters .PowerSource .attributes .AttributeList .ID ] = power_source_attribute_list_handler ,
256
+ },
223
257
},
224
258
},
225
259
subscribed_attributes = {
@@ -246,6 +280,9 @@ local matter_smoke_co_alarm_handler = {
246
280
},
247
281
[capabilities .batteryLevel .ID ] = {
248
282
clusters .SmokeCoAlarm .attributes .BatteryAlert ,
283
+ },
284
+ [capabilities .batteryLevel .ID ] = {
285
+ clusters .PowerSource .attributes .BatPercentRemaining ,
249
286
}
250
287
},
251
288
can_handle = is_matter_smoke_co_alarm
0 commit comments