@@ -44,19 +44,12 @@ local SWITCH_LEVEL_LIGHTING_MIN = 1
44
44
local CURRENT_HUESAT_ATTR_MIN = 0
45
45
local CURRENT_HUESAT_ATTR_MAX = 254
46
46
47
- local SWITCH_INITIALIZED = " __switch_intialized"
48
- -- COMPONENT_TO_ENDPOINT_MAP is here only to preserve the endpoint mapping for
47
+ -- COMPONENT_TO_ENDPOINT_MAP is here to preserve the endpoint mapping for
49
48
-- devices that were joined to this driver as MCD devices before the transition
50
- -- to join all matter- switch devices as parent-child. This value will only exist
51
- -- in the device table for devices that joined prior to this transition, and it
52
- -- will not be set for new devices .
49
+ -- to join switch devices as parent-child. This value will exist in the device
50
+ -- table for devices that joined prior to this transition, and is also used for
51
+ -- button devices that require component mapping .
53
52
local COMPONENT_TO_ENDPOINT_MAP = " __component_to_endpoint_map"
54
- -- COMPONENT_TO_ENDPOINT_MAP_BUTTON is for devices with button endpoints, to
55
- -- preserve the MCD functionality for button devices from the matter-button
56
- -- driver after it was merged into the matter-switch driver. Note that devices
57
- -- containing both button endpoints and switch endpoints will use this field
58
- -- rather than COMPONENT_TO_ENDPOINT_MAP.
59
- local COMPONENT_TO_ENDPOINT_MAP_BUTTON = " __component_to_endpoint_map_button"
60
53
local ENERGY_MANAGEMENT_ENDPOINT = " __energy_management_endpoint"
61
54
local IS_PARENT_CHILD_DEVICE = " __is_parent_child_device"
62
55
local COLOR_TEMP_BOUND_RECEIVED_KELVIN = " __colorTemp_bound_received_kelvin"
@@ -67,6 +60,12 @@ local LEVEL_BOUND_RECEIVED = "__level_bound_received"
67
60
local LEVEL_MIN = " __level_min"
68
61
local LEVEL_MAX = " __level_max"
69
62
local COLOR_MODE = " __color_mode"
63
+
64
+ local updated_fields = {
65
+ { field_name = " __component_to_endpoint_map_button" , updated_field_name = COMPONENT_TO_ENDPOINT_MAP },
66
+ { field_name = " __switch_intialized" , updated_field_name = nil }
67
+ }
68
+
70
69
local HUE_SAT_COLOR_MODE = clusters .ColorControl .types .ColorMode .CURRENT_HUE_AND_CURRENT_SATURATION
71
70
local X_Y_COLOR_MODE = clusters .ColorControl .types .ColorMode .CURRENTX_AND_CURRENTY
72
71
@@ -292,8 +291,6 @@ local HELD_THRESHOLD = 1
292
291
-- this is the number of buttons for which we have a static profile already made
293
292
local STATIC_BUTTON_PROFILE_SUPPORTED = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 }
294
293
295
- local BUTTON_DEVICE_PROFILED = " __button_device_profiled"
296
-
297
294
-- Some switches will send a MultiPressComplete event as part of a long press sequence. Normally the driver will create a
298
295
-- button capability event on receipt of MultiPressComplete, but in this case that would result in an extra event because
299
296
-- the "held" capability event is generated when the LongPress event is received. The IGNORE_NEXT_MPC flag is used
@@ -456,15 +453,15 @@ local function find_default_endpoint(device)
456
453
end
457
454
458
455
local function component_to_endpoint (device , component )
459
- local map = device :get_field (COMPONENT_TO_ENDPOINT_MAP_BUTTON ) or device : get_field ( COMPONENT_TO_ENDPOINT_MAP ) or {}
456
+ local map = device :get_field (COMPONENT_TO_ENDPOINT_MAP ) or {}
460
457
if map [component ] then
461
458
return map [component ]
462
459
end
463
460
return find_default_endpoint (device )
464
461
end
465
462
466
463
local function endpoint_to_component (device , ep )
467
- local map = device :get_field (COMPONENT_TO_ENDPOINT_MAP_BUTTON ) or device : get_field ( COMPONENT_TO_ENDPOINT_MAP ) or {}
464
+ local map = device :get_field (COMPONENT_TO_ENDPOINT_MAP ) or {}
468
465
for component , endpoint in pairs (map ) do
469
466
if endpoint == ep then
470
467
return component
@@ -473,6 +470,17 @@ local function endpoint_to_component(device, ep)
473
470
return " main"
474
471
end
475
472
473
+ local function check_field_name_updates (device )
474
+ for _ , field in ipairs (updated_fields ) do
475
+ if device :get_field (field .field_name ) then
476
+ if field .updated_field_name ~= nil then
477
+ device :set_field (field .updated_field_name , device :get_field (field .field_name ), {persist = true })
478
+ end
479
+ device :set_field (field .field_name , nil )
480
+ end
481
+ end
482
+ end
483
+
476
484
local function assign_child_profile (device , child_ep )
477
485
local profile
478
486
@@ -512,41 +520,6 @@ local function assign_child_profile(device, child_ep)
512
520
return profile or " switch-binary"
513
521
end
514
522
515
- local function do_configure (driver , device )
516
- if device :get_field (BUTTON_DEVICE_PROFILED ) then
517
- return
518
- end
519
- local fan_eps = device :get_endpoints (clusters .FanControl .ID )
520
- local level_eps = device :get_endpoints (clusters .LevelControl .ID )
521
- local energy_eps = embedded_cluster_utils .get_endpoints (device , clusters .ElectricalEnergyMeasurement .ID )
522
- local power_eps = embedded_cluster_utils .get_endpoints (device , clusters .ElectricalPowerMeasurement .ID )
523
- local valve_eps = embedded_cluster_utils .get_endpoints (device , clusters .ValveConfigurationAndControl .ID )
524
- local profile_name = nil
525
- local level_support = " "
526
- if # level_eps > 0 then
527
- level_support = " -level"
528
- end
529
- if # energy_eps > 0 and # power_eps > 0 then
530
- profile_name = " plug" .. level_support .. " -power-energy-powerConsumption"
531
- elseif # energy_eps > 0 then
532
- profile_name = " plug" .. level_support .. " -energy-powerConsumption"
533
- elseif # power_eps > 0 then
534
- profile_name = " plug" .. level_support .. " -power"
535
- elseif # valve_eps > 0 then
536
- profile_name = " water-valve"
537
- if # embedded_cluster_utils .get_endpoints (device , clusters .ValveConfigurationAndControl .ID ,
538
- {feature_bitmap = clusters .ValveConfigurationAndControl .types .Feature .LEVEL }) > 0 then
539
- profile_name = profile_name .. " -level"
540
- end
541
- elseif # fan_eps > 0 then
542
- profile_name = " light-color-level-fan"
543
- end
544
-
545
- if profile_name then
546
- device :try_update_metadata ({ profile = profile_name })
547
- end
548
- end
549
-
550
523
local function configure_buttons (device )
551
524
if device .network_type == device_lib .NETWORK_TYPE_CHILD then
552
525
return
@@ -603,7 +576,7 @@ local function build_button_component_map(device, main_endpoint, button_eps)
603
576
component_map [button_component ] = ep
604
577
end
605
578
end
606
- device :set_field (COMPONENT_TO_ENDPOINT_MAP_BUTTON , component_map , {persist = true })
579
+ device :set_field (COMPONENT_TO_ENDPOINT_MAP , component_map , {persist = true })
607
580
end
608
581
609
582
local function build_button_profile (device , main_endpoint , num_button_eps )
@@ -619,7 +592,6 @@ local function build_button_profile(device, main_endpoint, num_button_eps)
619
592
else
620
593
device :try_update_metadata ({profile = profile_name })
621
594
end
622
- device :set_field (BUTTON_DEVICE_PROFILED , true )
623
595
end
624
596
625
597
local function build_child_switch_profiles (driver , device , main_endpoint )
@@ -683,13 +655,15 @@ local function handle_light_switch_with_onOff_server_clusters(device, main_endpo
683
655
end
684
656
685
657
local function initialize_buttons_and_switches (driver , device , main_endpoint )
658
+ local profile_found = false
686
659
local button_eps = device :get_endpoints (clusters .Switch .ID , {feature_bitmap = clusters .Switch .types .SwitchFeature .MOMENTARY_SWITCH })
687
660
if tbl_contains (STATIC_BUTTON_PROFILE_SUPPORTED , # button_eps ) then
688
661
build_button_profile (device , main_endpoint , # button_eps )
689
662
-- All button endpoints found will be added as additional components in the profile containing the main_endpoint.
690
- -- The resulting endpoint to component map is saved in the COMPONENT_TO_ENDPOINT_MAP_BUTTON field
663
+ -- The resulting endpoint to component map is saved in the COMPONENT_TO_ENDPOINT_MAP field
691
664
build_button_component_map (device , main_endpoint , button_eps )
692
665
configure_buttons (device )
666
+ profile_found = true
693
667
end
694
668
695
669
-- Without support for bindings, only clusters that are implemented as server are counted. This count is handled
@@ -701,9 +675,9 @@ local function initialize_buttons_and_switches(driver, device, main_endpoint)
701
675
-- Note: since their device type isn't supported, these devices join as a matter-thing.
702
676
if num_switch_server_eps > 0 and detect_matter_thing (device ) then
703
677
handle_light_switch_with_onOff_server_clusters (device , main_endpoint )
678
+ profile_found = true
704
679
end
705
-
706
- device :set_field (SWITCH_INITIALIZED , true , {persist = true })
680
+ return profile_found
707
681
end
708
682
709
683
local function detect_bridge (device )
@@ -721,20 +695,13 @@ local function device_init(driver, device)
721
695
if device .network_type ~= device_lib .NETWORK_TYPE_MATTER then
722
696
return
723
697
end
724
-
698
+ check_field_name_updates ( device )
725
699
device :set_component_to_endpoint_fn (component_to_endpoint )
726
700
device :set_endpoint_to_component_fn (endpoint_to_component )
727
-
728
- local main_endpoint = find_default_endpoint (device )
729
- if not device :get_field (COMPONENT_TO_ENDPOINT_MAP ) and -- this field is only set for old MCD devices. See comments in the field def.
730
- not device :get_field (SWITCH_INITIALIZED ) and
731
- not detect_bridge (device ) then
732
- -- initialize the main device card with buttons if applicable, and create child devices as needed for multi-switch devices.
733
- initialize_buttons_and_switches (driver , device , main_endpoint )
734
- end
735
701
if device :get_field (IS_PARENT_CHILD_DEVICE ) then
736
702
device :set_find_child (find_child )
737
703
end
704
+ local main_endpoint = find_default_endpoint (device )
738
705
-- ensure subscription to all endpoint attributes- including those mapped to child devices
739
706
for _ , ep in ipairs (device .endpoints ) do
740
707
if ep .endpoint_id ~= main_endpoint then
@@ -756,6 +723,50 @@ local function device_init(driver, device)
756
723
device :subscribe ()
757
724
end
758
725
726
+ local function do_configure (driver , device )
727
+ if detect_bridge (device ) then
728
+ return
729
+ end
730
+ local main_endpoint = find_default_endpoint (device )
731
+ -- initialize the main device card with buttons if applicable, and create child devices as needed for multi-switch devices.
732
+ local profile_found = initialize_buttons_and_switches (driver , device , main_endpoint )
733
+ if device :get_field (IS_PARENT_CHILD_DEVICE ) then
734
+ device :set_find_child (find_child )
735
+ end
736
+ if profile_found then
737
+ return
738
+ end
739
+
740
+ local fan_eps = device :get_endpoints (clusters .FanControl .ID )
741
+ local level_eps = device :get_endpoints (clusters .LevelControl .ID )
742
+ local energy_eps = embedded_cluster_utils .get_endpoints (device , clusters .ElectricalEnergyMeasurement .ID )
743
+ local power_eps = embedded_cluster_utils .get_endpoints (device , clusters .ElectricalPowerMeasurement .ID )
744
+ local valve_eps = embedded_cluster_utils .get_endpoints (device , clusters .ValveConfigurationAndControl .ID )
745
+ local profile_name = nil
746
+ local level_support = " "
747
+ if # level_eps > 0 then
748
+ level_support = " -level"
749
+ end
750
+ if # energy_eps > 0 and # power_eps > 0 then
751
+ profile_name = " plug" .. level_support .. " -power-energy-powerConsumption"
752
+ elseif # energy_eps > 0 then
753
+ profile_name = " plug" .. level_support .. " -energy-powerConsumption"
754
+ elseif # power_eps > 0 then
755
+ profile_name = " plug" .. level_support .. " -power"
756
+ elseif # valve_eps > 0 then
757
+ profile_name = " water-valve"
758
+ if # embedded_cluster_utils .get_endpoints (device , clusters .ValveConfigurationAndControl .ID ,
759
+ {feature_bitmap = clusters .ValveConfigurationAndControl .types .Feature .LEVEL }) > 0 then
760
+ profile_name = profile_name .. " -level"
761
+ end
762
+ elseif # fan_eps > 0 then
763
+ profile_name = " light-color-level-fan"
764
+ end
765
+ if profile_name then
766
+ device :try_update_metadata ({ profile = profile_name })
767
+ end
768
+ end
769
+
759
770
local function device_removed (driver , device )
760
771
log .info (" device removed" )
761
772
delete_import_poll_schedule (device )
0 commit comments