@@ -164,130 +164,101 @@ local supported_profiles =
164164 " aqs-temp-humidity-tvoc-level-pm25-meas" ,
165165}
166166
167- local function configure (driver , device )
168- -- we have to read the unit before reports of values will do anything
169- for _ , cluster in ipairs (units_required ) do
170- device :send (cluster .attributes .MeasurementUnit :read (device ))
167+ local AIR_QUALITY_MAP = {
168+ {capabilities .carbonMonoxideMeasurement .ID , " -co" , clusters .CarbonMonoxideConcentrationMeasurement },
169+ {capabilities .carbonMonoxideHealthConcern .ID , " -co" , clusters .CarbonMonoxideConcentrationMeasurement },
170+ {capabilities .carbonDioxideMeasurement .ID , " -co2" , clusters .CarbonDioxideConcentrationMeasurement },
171+ {capabilities .carbonDioxideHealthConcern .ID , " -co2" , clusters .CarbonDioxideConcentrationMeasurement },
172+ {capabilities .nitrogenDioxideHealthConcern .ID , " -no2" , clusters .NitrogenDioxideConcentrationMeasurement },
173+ {capabilities .nitrogenDioxideMeasurement .ID , " -no2" , clusters .NitrogenDioxideConcentrationMeasurement },
174+ {capabilities .ozoneHealthConcern .ID , " -ozone" , clusters .OzoneConcentrationMeasurement },
175+ {capabilities .ozoneMeasurement .ID , " -ozone" , clusters .OzoneConcentrationMeasurement },
176+ {capabilities .formaldehydeMeasurement .ID , " -ch2o" , clusters .FormaldehydeConcentrationMeasurement },
177+ {capabilities .formaldehydeHealthConcern .ID , " -ch2o" , clusters .FormaldehydeConcentrationMeasurement },
178+ {capabilities .veryFineDustHealthConcern .ID , " -pm1" , clusters .Pm1ConcentrationMeasurement },
179+ {capabilities .veryFineDustSensor .ID , " -pm1" , clusters .Pm1ConcentrationMeasurement },
180+ {capabilities .fineDustSensor .ID , " -pm25" , clusters .Pm25ConcentrationMeasurement },
181+ {capabilities .fineDustHealthConcern .ID , " -pm25" , clusters .Pm25ConcentrationMeasurement },
182+ {capabilities .dustSensor .ID , " -pm10" , clusters .Pm10ConcentrationMeasurement },
183+ {capabilities .dustHealthConcern .ID , " -pm10" , clusters .Pm10ConcentrationMeasurement },
184+ {capabilities .radonHealthConcern .ID , " -radon" , clusters .RadonConcentrationMeasurement },
185+ {capabilities .radonMeasurement .ID , " -radon" , clusters .RadonConcentrationMeasurement },
186+ {capabilities .tvocHealthConcern .ID , " -tvoc" , clusters .TotalVolatileOrganicCompoundsConcentrationMeasurement },
187+ {capabilities .tvocMeasurement .ID , " -tvoc" , clusters .TotalVolatileOrganicCompoundsConcentrationMeasurement },
188+ }
189+
190+ local function create_level_measurement_profile (device )
191+ local meas_name , level_name = " " , " "
192+ for _ , details in ipairs (AIR_QUALITY_MAP ) do
193+ local cap_id = details [1 ]
194+ local cluster = details [3 ]
195+ -- capability describes either a HealthConcern or Measurement/Sensor
196+ if (cap_id :match (" HealthConcern$" )) then
197+ local attr_eps = embedded_cluster_utils .get_endpoints (device , cluster .ID , { feature_bitmap = cluster .types .Feature .LEVEL_INDICATION })
198+ if # attr_eps > 0 then
199+ level_name = level_name .. details [2 ]
200+ end
201+ elseif (cap_id :match (" Measurement$" ) or cap_id :match (" Sensor$" )) then
202+ local attr_eps = embedded_cluster_utils .get_endpoints (device , cluster .ID , { feature_bitmap = cluster .types .Feature .NUMERIC_MEASUREMENT })
203+ if # attr_eps > 0 then
204+ meas_name = meas_name .. details [2 ]
205+ end
206+ end
171207 end
208+ return meas_name , level_name
209+ end
172210
173- -- check to see if device can switch to a more limited profile based on cluster support
211+ local function do_configure ( driver , device )
174212 local temp_eps = embedded_cluster_utils .get_endpoints (device , clusters .TemperatureMeasurement .ID )
175213 local humidity_eps = embedded_cluster_utils .get_endpoints (device , clusters .RelativeHumidityMeasurement .ID )
176- local co_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .CarbonMonoxideConcentrationMeasurement .ID , {feature_bitmap = clusters .CarbonMonoxideConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
177- local co_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .CarbonMonoxideConcentrationMeasurement .ID , {feature_bitmap = clusters .CarbonMonoxideConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
178- local co2_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .CarbonDioxideConcentrationMeasurement .ID , {feature_bitmap = clusters .CarbonDioxideConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
179- local co2_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .CarbonDioxideConcentrationMeasurement .ID , {feature_bitmap = clusters .CarbonDioxideConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
180- local no2_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .NitrogenDioxideConcentrationMeasurement .ID , {feature_bitmap = clusters .NitrogenDioxideConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
181- local no2_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .NitrogenDioxideConcentrationMeasurement .ID , {feature_bitmap = clusters .NitrogenDioxideConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
182- local ozone_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .OzoneConcentrationMeasurement .ID , {feature_bitmap = clusters .OzoneConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
183- local ozone_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .OzoneConcentrationMeasurement .ID , {feature_bitmap = clusters .OzoneConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
184- local formaldehyde_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .FormaldehydeConcentrationMeasurement .ID , {feature_bitmap = clusters .FormaldehydeConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
185- local formaldehyde_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .FormaldehydeConcentrationMeasurement .ID , {feature_bitmap = clusters .FormaldehydeConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
186- local pm1_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .Pm1ConcentrationMeasurement .ID , {feature_bitmap = clusters .Pm1ConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
187- local pm1_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .Pm1ConcentrationMeasurement .ID , {feature_bitmap = clusters .Pm1ConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
188- local pm2_5_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .Pm25ConcentrationMeasurement .ID , {feature_bitmap = clusters .Pm25ConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
189- local pm2_5_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .Pm25ConcentrationMeasurement .ID , {feature_bitmap = clusters .Pm25ConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
190- local pm10_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .Pm10ConcentrationMeasurement .ID , {feature_bitmap = clusters .Pm10ConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
191- local pm10_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .Pm10ConcentrationMeasurement .ID , {feature_bitmap = clusters .Pm10ConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
192- local radon_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .RadonConcentrationMeasurement .ID , {feature_bitmap = clusters .RadonConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
193- local radon_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .RadonConcentrationMeasurement .ID , {feature_bitmap = clusters .RadonConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
194- local tvoc_level_eps = embedded_cluster_utils .get_endpoints (device , clusters .TotalVolatileOrganicCompoundsConcentrationMeasurement .ID , {feature_bitmap = clusters .TotalVolatileOrganicCompoundsConcentrationMeasurement .types .Feature .LEVEL_INDICATION })
195- local tvoc_meas_eps = embedded_cluster_utils .get_endpoints (device , clusters .TotalVolatileOrganicCompoundsConcentrationMeasurement .ID , {feature_bitmap = clusters .TotalVolatileOrganicCompoundsConcentrationMeasurement .types .Feature .NUMERIC_MEASUREMENT })
214+
215+ -- we have to read the unit before reports of values will do anything
216+ for _ , cluster in ipairs (units_required ) do
217+ device :send (cluster .attributes .MeasurementUnit :read (device ))
218+ end
196219
197220 local profile_name = " aqs"
198- local level_indication_support = " "
199- local numeric_measurement_support = " "
200221
201222 if # temp_eps > 0 then
202223 profile_name = profile_name .. " -temp"
203224 end
204225 if # humidity_eps > 0 then
205226 profile_name = profile_name .. " -humidity"
206227 end
207- if # co_level_eps > 0 then
208- level_indication_support = level_indication_support .. " -co"
209- end
210- if # co2_level_eps > 0 then
211- level_indication_support = level_indication_support .. " -co2"
212- end
213- if # no2_level_eps > 0 then
214- level_indication_support = level_indication_support .. " -no2"
215- end
216- if # ozone_level_eps > 0 then
217- level_indication_support = level_indication_support .. " -ozone"
218- end
219- if # formaldehyde_level_eps > 0 then
220- level_indication_support = level_indication_support .. " -formaldehyde"
221- end
222- if # pm1_level_eps > 0 then
223- level_indication_support = level_indication_support .. " -pm1"
224- end
225- if # pm2_5_level_eps > 0 then
226- level_indication_support = level_indication_support .. " -pm25"
227- end
228- if # pm10_level_eps > 0 then
229- level_indication_support = level_indication_support .. " -pm10"
230- end
231- if # radon_level_eps > 0 then
232- level_indication_support = level_indication_support .. " -radon"
233- end
234- if # tvoc_level_eps > 0 then
235- level_indication_support = level_indication_support .. " -tvoc"
236- end
228+
229+ local meas_name , level_name = create_level_measurement_profile (device )
230+
237231 -- If all endpoints are supported, use '-all' in the profile name so that it
238232 -- remains under the profile name character limit
239- if level_indication_support == " -co-co2-no2-ozone-formaldehyde -pm1-pm25-pm10-radon-tvoc" then
240- level_indication_support = " -all"
233+ if level_name == " -co-co2-no2-ozone-ch2o -pm1-pm25-pm10-radon-tvoc" then
234+ level_name = " -all"
241235 end
242- if level_indication_support ~= " " then
243- profile_name = profile_name .. level_indication_support .. " -level"
236+ if level_name ~= " " then
237+ profile_name = profile_name .. level_name .. " -level"
244238 end
245239
246- if # co_meas_eps > 0 then
247- numeric_measurement_support = numeric_measurement_support .. " -co"
248- end
249- if # co2_meas_eps > 0 then
250- numeric_measurement_support = numeric_measurement_support .. " -co2"
251- end
252- if # no2_meas_eps > 0 then
253- numeric_measurement_support = numeric_measurement_support .. " -no2"
254- end
255- if # ozone_meas_eps > 0 then
256- numeric_measurement_support = numeric_measurement_support .. " -ozone"
257- end
258- if # formaldehyde_meas_eps > 0 then
259- numeric_measurement_support = numeric_measurement_support .. " -formaldehyde"
260- end
261- if # pm1_meas_eps > 0 then
262- numeric_measurement_support = numeric_measurement_support .. " -pm1"
263- end
264- if # pm2_5_meas_eps > 0 then
265- numeric_measurement_support = numeric_measurement_support .. " -pm25"
266- end
267- if # pm10_meas_eps > 0 then
268- numeric_measurement_support = numeric_measurement_support .. " -pm10"
269- end
270- if # radon_meas_eps > 0 then
271- numeric_measurement_support = numeric_measurement_support .. " -radon"
272- end
273- if # tvoc_meas_eps > 0 then
274- numeric_measurement_support = numeric_measurement_support .. " -tvoc"
275- end
276240 -- If all endpoints are supported, use '-all' in the profile name so that it
277241 -- remains under the profile name character limit
278- if numeric_measurement_support == " -co-co2-no2-ozone-formaldehyde -pm1-pm25-pm10-radon-tvoc" then
279- numeric_measurement_support = " -all"
242+ if meas_name == " -co-co2-no2-ozone-ch2o -pm1-pm25-pm10-radon-tvoc" then
243+ meas_name = " -all"
280244 end
281- if numeric_measurement_support ~= " " then
282- profile_name = profile_name .. numeric_measurement_support .. " -meas"
245+ if meas_name ~= " " then
246+ profile_name = profile_name .. meas_name .. " -meas"
283247 end
284248
285249 if not tbl_contains (supported_profiles , profile_name ) then
286250 device .log .warn_with ({hub_logs = true }, string.format (" No matching profile for device. Tried to use profile %s" , profile_name ))
287- if # co_meas_eps > 0 or # no2_meas_eps > 0 or # ozone_meas_eps > 0 or # formaldehyde_meas_eps > 0 or
288- # pm1_meas_eps > 0 or # pm10_meas_eps > 0 or # radon_meas_eps > 0 then
251+
252+ local function meas_find (sub_name )
253+ return string.match (meas_name , sub_name ) ~= nil
254+ end
255+
256+ -- try to best match to existing profiles
257+ -- these checks, meas_find("co%-") and meas_find("co$"), match the string to co and NOT co2.
258+ if meas_find (" co%-" ) or meas_find (" co$" ) or meas_find (" no2" ) or meas_find (" ozone" ) or meas_find (" ch2o" ) or
259+ meas_find (" pm1" ) or meas_find (" pm10" ) or meas_find (" radon" ) then
289260 profile_name = " aqs-temp-humidity-all-meas"
290- elseif # humidity_eps > 0 or # temp_eps > 0 or # co2_meas_eps > 0 or # pm2_5_meas_eps > 0 or # tvoc_meas_eps > 0 then
261+ elseif # humidity_eps > 0 or # temp_eps > 0 or meas_find ( " co2 " ) or meas_find ( " pm25 " ) or meas_find ( " tvoc " ) then
291262 profile_name = " aqs-temp-humidity-co2-pm25-tvoc-meas"
292263 else
293264 -- device only supports air quality at this point
@@ -445,7 +416,7 @@ local matter_air_quality_sensor_handler = {
445416 NAME = " matter-air-quality-sensor" ,
446417 lifecycle_handlers = {
447418 init = device_init ,
448- doConfigure = configure
419+ doConfigure = do_configure
449420 },
450421 matter_handlers = {
451422 attr = {
0 commit comments