@@ -357,94 +357,136 @@ local function create_level_measurement_profile(device)
357357 return meas_name , level_name
358358end
359359
360- local function do_configure (driver , device )
361- local heat_eps = device :get_endpoints (clusters .Thermostat .ID , {feature_bitmap = clusters .Thermostat .types .ThermostatFeature .HEATING })
362- local cool_eps = device :get_endpoints (clusters .Thermostat .ID , {feature_bitmap = clusters .Thermostat .types .ThermostatFeature .COOLING })
363- local thermo_eps = device :get_endpoints (clusters .Thermostat .ID )
360+ local function create_air_quality_sensor_profile (device )
361+ local aqs_eps = embedded_cluster_utils .get_endpoints (device , clusters .AirQuality .ID )
362+ local profile_name = " "
363+ if # aqs_eps > 0 then
364+ profile_name = profile_name .. " -aqs"
365+ end
366+ local meas_name , level_name = create_level_measurement_profile (device )
367+ if meas_name ~= " " then
368+ profile_name = profile_name .. meas_name .. " -meas"
369+ end
370+ if level_name ~= " " then
371+ profile_name = profile_name .. level_name .. " -level"
372+ end
373+ return profile_name
374+ end
375+
376+ local function create_fan_profile (device )
364377 local fan_eps = device :get_endpoints (clusters .FanControl .ID )
365378 local wind_eps = device :get_endpoints (clusters .FanControl .ID , {feature_bitmap = clusters .FanControl .types .FanControlFeature .WIND })
366379 local rock_eps = device :get_endpoints (clusters .FanControl .ID , {feature_bitmap = clusters .FanControl .types .Feature .ROCKING })
367- local humidity_eps = device :get_endpoints (clusters .RelativeHumidityMeasurement .ID )
368- local battery_eps = device :get_endpoints (clusters .PowerSource .ID , {feature_bitmap = clusters .PowerSource .types .PowerSourceFeature .BATTERY })
369- -- use get_endpoints for embedded clusters
380+ local profile_name = " "
381+ if # fan_eps > 0 then
382+ profile_name = profile_name .. " -fan"
383+ end
384+ if # rock_eps > 0 then
385+ profile_name = profile_name .. " -rock"
386+ end
387+ if # wind_eps > 0 then
388+ profile_name = profile_name .. " -wind"
389+ end
390+ return profile_name
391+ end
392+
393+ local function create_air_purifier_profile (device )
370394 local hepa_filter_eps = embedded_cluster_utils .get_endpoints (device , clusters .HepaFilterMonitoring .ID )
371395 local ac_filter_eps = embedded_cluster_utils .get_endpoints (device , clusters .ActivatedCarbonFilterMonitoring .ID )
372- local aqs_eps = embedded_cluster_utils .get_endpoints (device , clusters .AirQuality .ID )
396+ local fan_eps_seen = false
397+ local profile_name = " air-purifier"
398+ if # hepa_filter_eps > 0 then
399+ profile_name = profile_name .. " -hepa"
400+ end
401+ if # ac_filter_eps > 0 then
402+ profile_name = profile_name .. " -ac"
403+ end
404+
405+ -- air purifier profiles include -fan later in the name for historical reasons.
406+ -- save this information for use at that point.
407+ local fan_profile = create_fan_profile (device )
408+ if fan_profile ~= " " then
409+ fan_eps_seen = true
410+ end
411+ fan_profile = string.gsub (fan_profile , " -fan" , " " )
412+ profile_name = profile_name .. fan_profile
413+
414+ return profile_name , fan_eps_seen
415+ end
416+
417+ local function create_thermostat_modes_profile (device )
418+ local heat_eps = device :get_endpoints (clusters .Thermostat .ID , {feature_bitmap = clusters .Thermostat .types .ThermostatFeature .HEATING })
419+ local cool_eps = device :get_endpoints (clusters .Thermostat .ID , {feature_bitmap = clusters .Thermostat .types .ThermostatFeature .COOLING })
420+
421+ local thermostat_modes = " "
422+ if # heat_eps == 0 and # cool_eps == 0 then
423+ device .log .warn_with ({hub_logs = true }, " Device does not support either heating or cooling. No matching profile" )
424+ return " No Heating nor Cooling Support"
425+ elseif # heat_eps > 0 and # cool_eps == 0 then
426+ thermostat_modes = thermostat_modes .. " -heating-only"
427+ elseif # cool_eps > 0 and # heat_eps == 0 then
428+ thermostat_modes = thermostat_modes .. " -cooling-only"
429+ end
430+ return thermostat_modes
431+ end
432+
433+ local function do_configure (driver , device )
434+ local thermostat_eps = device :get_endpoints (clusters .Thermostat .ID )
435+ local humidity_eps = device :get_endpoints (clusters .RelativeHumidityMeasurement .ID )
436+ local battery_eps = device :get_endpoints (clusters .PowerSource .ID , {feature_bitmap = clusters .PowerSource .types .PowerSourceFeature .BATTERY })
373437 local device_type = get_device_type (driver , device )
374- local profile_name = " thermostat "
438+ local profile_name
375439 if device_type == RAC_DEVICE_TYPE_ID then
376440 profile_name = " room-air-conditioner"
377441
378442 if # humidity_eps > 0 then
379443 profile_name = profile_name .. " -humidity"
380444 end
381- if # fan_eps > 0 then
382- profile_name = profile_name .. " -fan"
383- if # wind_eps > 0 then
384- profile_name = profile_name .. " -wind"
385- end
386- end
387445
388- if # heat_eps > 0 and # cool_eps > 0 then
446+ -- Room AC does not support the rocking feature of FanControl.
447+ local fan_name = create_fan_profile (device )
448+ fan_name = string.gsub (fan_name , " -rock" , " " )
449+ profile_name = profile_name .. fan_name
450+
451+ local thermostat_modes = create_thermostat_modes_profile (device )
452+ if thermostat_modes == " " then
389453 profile_name = profile_name .. " -heating-cooling"
390454 else
391- device .log .warn_with ({hub_logs = true }, " Room AC does not support both heating and cooling. No matching profile" )
455+ device .log .warn_with ({hub_logs = true }, " Device does not support both heating and cooling. No matching profile" )
392456 return
393457 end
394458
395459 if profile_name == " room-air-conditioner-humidity-fan-wind-heating-cooling" then
396460 profile_name = " room-air-conditioner"
397461 end
398462
399- device .log .info_with ({hub_logs = true }, string.format (" Updating device profile to %s." , profile_name ))
400- device :try_update_metadata ({profile = profile_name })
401463 elseif device_type == FAN_DEVICE_TYPE_ID then
402- profile_name = " fan"
403- if # rock_eps > 0 then
404- profile_name = profile_name .. " -rock"
405- end
406- if # wind_eps > 0 then
407- profile_name = profile_name .. " -wind"
408- end
464+ profile_name = create_fan_profile (device )
465+ -- remove leading "-"
466+ profile_name = string.sub (profile_name , 2 )
409467 if profile_name == " fan" then
410468 profile_name = " fan-generic"
411469 end
412470
413- device .log .info_with ({hub_logs = true }, string.format (" Updating device profile to %s." , profile_name ))
414- device :try_update_metadata ({profile = profile_name })
415471 elseif device_type == AP_DEVICE_TYPE_ID then
416- profile_name = " air-purifier"
417- if # hepa_filter_eps > 0 and # ac_filter_eps > 0 then
418- profile_name = profile_name .. " -hepa" .. " -ac"
419- elseif # hepa_filter_eps > 0 then
420- profile_name = profile_name .. " -hepa"
421- elseif # ac_filter_eps > 0 then
422- profile_name = profile_name .. " -ac"
423- end
424- if # rock_eps > 0 then
425- profile_name = profile_name .. " -rock"
426- end
427- if # wind_eps > 0 then
428- profile_name = profile_name .. " -wind"
429- end
430-
431- if # thermo_eps > 0 then
472+ local fan_eps_found
473+ profile_name , fan_eps_found = create_air_purifier_profile (device )
474+ if # thermostat_eps > 0 then
432475 profile_name = profile_name .. " -thermostat"
433- if # humidity_eps > 0 and # fan_eps > 0 then
434- profile_name = profile_name .. " -humidity" .. " -fan"
435- elseif # humidity_eps > 0 then
476+
477+ if # humidity_eps > 0 then
436478 profile_name = profile_name .. " -humidity"
437- elseif # fan_eps > 0 then
479+ end
480+
481+ if fan_eps_found then
438482 profile_name = profile_name .. " -fan"
439483 end
440484
441- if # heat_eps == 0 and # cool_eps == 0 then
442- device . log . warn_with ({ hub_logs = true }, " Thermostat does not support heating or cooling. No matching profile " )
485+ local thermostat_modes = create_thermostat_modes_profile ( device )
486+ if thermostat_modes == " No Heating nor Cooling Support " then
443487 return
444- elseif # heat_eps > 0 and # cool_eps == 0 then
445- profile_name = profile_name .. " -heating-only"
446- elseif # cool_eps > 0 and # heat_eps == 0 then
447- profile_name = profile_name .. " -cooling-only"
488+ else
489+ profile_name = profile_name .. thermostat_modes
448490 end
449491
450492 profile_name = profile_name .. " -nostate"
@@ -453,39 +495,26 @@ local function do_configure(driver, device)
453495 profile_name = profile_name .. " -nobattery"
454496 end
455497 end
498+ profile_name = profile_name .. create_air_quality_sensor_profile (device )
456499
457- if # aqs_eps > 0 then
458- profile_name = profile_name .. " -aqs"
459- end
460-
461- local meas_name , level_name = create_level_measurement_profile (device )
462-
463- if meas_name ~= " " then
464- profile_name = profile_name .. meas_name .. " -meas"
465- end
500+ elseif # thermostat_eps > 0 then
501+ profile_name = " thermostat"
466502
467- if level_name ~= " " then
468- profile_name = profile_name .. level_name .. " -level "
503+ if # humidity_eps > 0 then
504+ profile_name = profile_name .. " -humidity "
469505 end
470506
471- device .log .info_with ({hub_logs = true }, string.format (" Updating device profile to %s." , profile_name ))
472- device :try_update_metadata ({profile = profile_name })
473- elseif # thermo_eps == 1 then
474- if # humidity_eps > 0 and # fan_eps > 0 then
475- profile_name = profile_name .. " -humidity" .. " -fan"
476- elseif # humidity_eps > 0 then
477- profile_name = profile_name .. " -humidity"
478- elseif # fan_eps > 0 then
507+ -- thermostat profiles support neither wind nor rocking FanControl attributes
508+ local fan_name = create_fan_profile (device )
509+ if fan_name ~= " " then
479510 profile_name = profile_name .. " -fan"
480511 end
481512
482- if # heat_eps == 0 and # cool_eps == 0 then
483- device . log . warn_with ({ hub_logs = true }, " Thermostat does not support heating or cooling. No matching profile " )
513+ local thermostat_modes = create_thermostat_modes_profile ( device )
514+ if thermostat_modes == " No Heating nor Cooling Support " then
484515 return
485- elseif # heat_eps > 0 and # cool_eps == 0 then
486- profile_name = profile_name .. " -heating-only"
487- elseif # cool_eps > 0 and # heat_eps == 0 then
488- profile_name = profile_name .. " -cooling-only"
516+ else
517+ profile_name = profile_name .. thermostat_modes
489518 end
490519
491520 -- TODO remove this in favor of reading Thermostat clusters AttributeList attribute
@@ -496,15 +525,14 @@ local function do_configure(driver, device)
496525 if # battery_eps == 0 then
497526 profile_name = profile_name .. " -nobattery"
498527 end
528+ else
529+ device .log .warn_with ({hub_logs = true }, " Device type is not supported in thermostat driver" )
530+ return
531+ end
499532
533+ if profile_name then
500534 device .log .info_with ({hub_logs = true }, string.format (" Updating device profile to %s." , profile_name ))
501535 device :try_update_metadata ({profile = profile_name })
502- elseif # fan_eps == 1 then
503- profile_name = " fan"
504- device .log .info_with ({hub_logs = true }, string.format (" Updating device profile to %s." , profile_name ))
505- device :try_update_metadata ({profile = profile_name })
506- else
507- device .log .warn_with ({hub_logs = true }, " Device does not support thermostat cluster" )
508536 end
509537end
510538
0 commit comments