Skip to content

Commit 754f2a7

Browse files
authored
Merge pull request #2389 from SmartThingsCommunity/bugfix/hue_pro_migration_device_create
philips-hue: Split mapping of hue resource IDs by bridge
2 parents faa3ea8 + 856f35f commit 754f2a7

File tree

11 files changed

+85
-35
lines changed

11 files changed

+85
-35
lines changed

drivers/SmartThings/philips-hue/src/disco/init.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,13 @@ function HueDiscovery.handle_discovered_child_device(driver, bridge_network_id,
334334
end
335335

336336
for _, svc_info in ipairs(primary_services[primary_service_type]) do
337+
if driver:get_device_by_dni(v1_dni) then
338+
return
339+
end
337340
local v2_resource_id = svc_info.rid or ""
338-
if driver:get_device_by_dni(v1_dni) or driver.hue_identifier_to_device_record[v2_resource_id] then return end
341+
if (driver.hue_identifier_to_device_record_by_bridge[bridge_network_id] or {})[v2_resource_id] then
342+
return
343+
end
339344
end
340345

341346
local api_instance =

drivers/SmartThings/philips-hue/src/handlers/lifecycle_handlers/button.lua

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ function ButtonLifecycleHandlers.added(driver, device, parent_device_id, resourc
5252
end
5353

5454
local button_rid_to_index_map = {}
55+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device) or {}
5556
if button_info.button then
56-
driver.hue_identifier_to_device_record[button_info.id] = device
57+
hue_id_to_device[button_info.id] = device
5758
button_rid_to_index_map[button_info.id] = 1
5859
end
5960

@@ -65,7 +66,7 @@ function ButtonLifecycleHandlers.added(driver, device, parent_device_id, resourc
6566
local button_id = button_info[button_id_key]
6667

6768
if button and button_id then
68-
driver.hue_identifier_to_device_record[button_id] = device
69+
hue_id_to_device[button_id] = device
6970
button_rid_to_index_map[button_id] = var
7071

7172
local supported_button_values = utils.get_supported_button_values(button.event_values)
@@ -86,7 +87,7 @@ function ButtonLifecycleHandlers.added(driver, device, parent_device_id, resourc
8687
end
8788

8889
if button_info.power_id then
89-
driver.hue_identifier_to_device_record[button_info.power_id] = device
90+
hue_id_to_device[button_info.power_id] = device
9091
end
9192

9293
log.debug(st_utils.stringify_table(button_rid_to_index_map, "button index map", true))
@@ -98,7 +99,7 @@ function ButtonLifecycleHandlers.added(driver, device, parent_device_id, resourc
9899
device:set_field(Fields._ADDED, true, { persist = true })
99100
device:set_field(Fields._REFRESH_AFTER_INIT, true, { persist = true })
100101

101-
driver.hue_identifier_to_device_record[device_button_resource_id] = device
102+
hue_id_to_device[device_button_resource_id] = device
102103
end
103104

104105
---@param driver HueDriver
@@ -114,8 +115,9 @@ function ButtonLifecycleHandlers.init(driver, device)
114115
log.debug("resource id " .. tostring(device_button_resource_id))
115116

116117
local hue_device_id = device:get_field(Fields.HUE_DEVICE_ID)
117-
if not driver.hue_identifier_to_device_record[device_button_resource_id] then
118-
driver.hue_identifier_to_device_record[device_button_resource_id] = device
118+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device) or {}
119+
if not hue_id_to_device[device_button_resource_id] then
120+
hue_id_to_device[device_button_resource_id] = device
119121
end
120122
local button_info, err
121123
button_info = Discovery.device_state_disco_cache[device_button_resource_id]

drivers/SmartThings/philips-hue/src/handlers/lifecycle_handlers/contact.lua

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ function ContactLifecycleHandlers.added(driver, device, parent_device_id, resour
5151
return
5252
end
5353

54-
driver.hue_identifier_to_device_record[sensor_info.power_id] = device
55-
driver.hue_identifier_to_device_record[sensor_info.tamper_id] = device
54+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device) or {}
55+
hue_id_to_device[sensor_info.power_id] = device
56+
hue_id_to_device[sensor_info.tamper_id] = device
5657

5758
device:set_field(Fields.DEVICE_TYPE, HueDeviceTypes.CONTACT, { persist = true })
5859
device:set_field(Fields.HUE_DEVICE_ID, sensor_info.hue_device_id, { persist = true })
@@ -61,7 +62,7 @@ function ContactLifecycleHandlers.added(driver, device, parent_device_id, resour
6162
device:set_field(Fields._ADDED, true, { persist = true })
6263
device:set_field(Fields._REFRESH_AFTER_INIT, true, { persist = true })
6364

64-
driver.hue_identifier_to_device_record[device_sensor_resource_id] = device
65+
hue_id_to_device[device_sensor_resource_id] = device
6566
end
6667

6768
---@param driver HueDriver
@@ -77,8 +78,9 @@ function ContactLifecycleHandlers.init(driver, device)
7778
log.debug("resource id " .. tostring(device_sensor_resource_id))
7879

7980
local hue_device_id = device:get_field(Fields.HUE_DEVICE_ID)
80-
if not driver.hue_identifier_to_device_record[device_sensor_resource_id] then
81-
driver.hue_identifier_to_device_record[device_sensor_resource_id] = device
81+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device) or {}
82+
if not hue_id_to_device[device_sensor_resource_id] then
83+
hue_id_to_device[device_sensor_resource_id] = device
8284
end
8385
local sensor_info, err
8486
sensor_info = Discovery.device_state_disco_cache[device_sensor_resource_id]

drivers/SmartThings/philips-hue/src/handlers/lifecycle_handlers/init.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ function LifecycleHandlers.device_added(driver, device, ...)
9393
if device_type ~= HueDeviceTypes.BRIDGE then
9494
---@cast device HueChildDevice
9595
local resource_id = utils.get_hue_rid(device)
96+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device) or {}
9697
if resource_id then
97-
driver.hue_identifier_to_device_record[resource_id] = device
98+
hue_id_to_device[resource_id] = device
9899
end
99100

100101
local resource_state_known = (Discovery.device_state_disco_cache[resource_id] ~= nil)

drivers/SmartThings/philips-hue/src/handlers/lifecycle_handlers/light.lua

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ function LightLifecycleHandlers.added(driver, device, parent_device_id, resource
190190
device:set_field(Fields._ADDED, true, { persist = true })
191191
device:set_field(Fields._REFRESH_AFTER_INIT, true, { persist = true })
192192

193-
driver.hue_identifier_to_device_record[device_light_resource_id] = device
193+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device) or {}
194+
hue_id_to_device[device_light_resource_id] = device
194195

195196
-- the refresh handler adds lights that don't have a fully initialized bridge to a queue.
196197
driver:inject_capability_command(device, {
@@ -218,8 +219,9 @@ function LightLifecycleHandlers.init(driver, device)
218219
device.device_network_id
219220

220221
local hue_device_id = device:get_field(Fields.HUE_DEVICE_ID)
221-
if not driver.hue_identifier_to_device_record[device_light_resource_id] then
222-
driver.hue_identifier_to_device_record[device_light_resource_id] = device
222+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device) or {}
223+
if not hue_id_to_device[device_light_resource_id] then
224+
hue_id_to_device[device_light_resource_id] = device
223225
end
224226
local svc_rids_for_device = driver.services_for_device_rid[hue_device_id] or {}
225227
if not svc_rids_for_device[device_light_resource_id] then

drivers/SmartThings/philips-hue/src/handlers/lifecycle_handlers/motion.lua

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ function MotionLifecycleHandlers.added(driver, device, parent_device_id, resourc
5050
})
5151
return
5252
end
53+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device) or {}
5354

54-
driver.hue_identifier_to_device_record[sensor_info.power_id] = device
55-
driver.hue_identifier_to_device_record[sensor_info.temperature_id] = device
56-
driver.hue_identifier_to_device_record[sensor_info.light_level_id] = device
55+
hue_id_to_device[sensor_info.power_id] = device
56+
hue_id_to_device[sensor_info.temperature_id] = device
57+
hue_id_to_device[sensor_info.light_level_id] = device
5758

5859
device:set_field(Fields.DEVICE_TYPE, HueDeviceTypes.MOTION, { persist = true })
5960
device:set_field(Fields.HUE_DEVICE_ID, sensor_info.hue_device_id, { persist = true })
@@ -62,7 +63,7 @@ function MotionLifecycleHandlers.added(driver, device, parent_device_id, resourc
6263
device:set_field(Fields._ADDED, true, { persist = true })
6364
device:set_field(Fields._REFRESH_AFTER_INIT, true, { persist = true })
6465

65-
driver.hue_identifier_to_device_record[device_sensor_resource_id] = device
66+
hue_id_to_device[device_sensor_resource_id] = device
6667
end
6768

6869
---@param driver HueDriver
@@ -78,8 +79,9 @@ function MotionLifecycleHandlers.init(driver, device)
7879
log.debug("resource id " .. tostring(device_sensor_resource_id))
7980

8081
local hue_device_id = device:get_field(Fields.HUE_DEVICE_ID)
81-
if not driver.hue_identifier_to_device_record[device_sensor_resource_id] then
82-
driver.hue_identifier_to_device_record[device_sensor_resource_id] = device
82+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device) or {}
83+
if not hue_id_to_device[device_sensor_resource_id] then
84+
hue_id_to_device[device_sensor_resource_id] = device
8385
end
8486
local sensor_info, err
8587
sensor_info = Discovery.device_state_disco_cache[device_sensor_resource_id]

drivers/SmartThings/philips-hue/src/hue_driver_template.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ local set_color_temp_handler = utils.safe_wrap_handler(command_handlers.set_colo
7070
--- @class HueDriver:Driver
7171
--- @field public ignored_bridges table<string,boolean>
7272
--- @field public joined_bridges table<string,boolean>
73-
--- @field public hue_identifier_to_device_record table<string,HueChildDevice>
73+
--- @field public hue_identifier_to_device_record_by_bridge table<string, table<string,HueChildDevice>>
7474
--- @field public services_for_device_rid table<string,table<string,string>> Map the device resource ID to another map that goes from service rid to service rtype
7575
--- @field public waiting_grandchildren table<string,{ waiting_resource_info: HueResourceInfo, join_callback: fun(driver: HueDriver, waiting_resource_info: HueResourceInfo, parent_device: HueChildDevice)}[]>?
7676
--- @field public stray_device_tx table cosock channel
@@ -113,7 +113,7 @@ function HueDriver.new_driver_template(dbg_config)
113113

114114
ignored_bridges = {},
115115
joined_bridges = {},
116-
hue_identifier_to_device_record = {},
116+
hue_identifier_to_device_record_by_bridge = {},
117117
services_for_device_rid = {},
118118
-- the only real way we have to know which bridge a bulb wants to use at migration time
119119
-- is by looking at the stored api key so we will make a map to look up bridge IDs with

drivers/SmartThings/philips-hue/src/utils/grouped_utils.lua

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
local log = require "log"
22
local Fields = require "fields"
33
local cosock = require "cosock"
4+
local utils = require "utils"
45

56
--- Room or zone with the children translated from their hue device id or light resource id to
67
--- their SmartThings represented device object. The grouped light resource id is also moved into
@@ -100,10 +101,11 @@ end
100101
---@param group_kind string room or zone
101102
---@param driver HueDriver
102103
---@param hue_id_to_device table
104+
---@param light_id_to_device table
103105
---@param resp table?
104106
---@param err any?
105107
---@return HueLightGroup[]?
106-
local function handle_group_scan_response(group_kind, driver, hue_id_to_device, resp, err)
108+
local function handle_group_scan_response(group_kind, driver, hue_id_to_device, light_id_to_device, resp, err)
107109
if err or not resp then
108110
log.error(string.format("Failed to scan for %s: %s", group_kind, err or "unknown error"))
109111
return nil
@@ -121,7 +123,7 @@ local function handle_group_scan_response(group_kind, driver, hue_id_to_device,
121123

122124
log.info(string.format("Successfully got %d %s", #resp.data, group_kind))
123125
for _, group in ipairs(resp.data) do
124-
build_hue_light_group(group, hue_id_to_device, driver.hue_identifier_to_device_record)
126+
build_hue_light_group(group, hue_id_to_device, light_id_to_device)
125127
log.info(string.format("Found light group %s with %d device records", group.id, #group.devices))
126128
end
127129

@@ -134,12 +136,14 @@ end
134136
--- @param hue_id_to_device table
135137
function grouped_utils.scan_groups(driver, bridge_device, api, hue_id_to_device)
136138
local rooms, zones
137-
while not (rooms and zones) do -- TODO: Should this be one and done? Timeout?
139+
-- These are the hue light/other service ids rather than the hue device ids
140+
local light_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, bridge_device) or {}
141+
while not (rooms and zones) do
138142
if not rooms then
139-
rooms = handle_group_scan_response("rooms", driver, hue_id_to_device, api:get_rooms())
143+
rooms = handle_group_scan_response("rooms", driver, hue_id_to_device, light_id_to_device, api:get_rooms())
140144
end
141145
if not zones then
142-
zones = handle_group_scan_response("zones", driver, hue_id_to_device, api:get_zones())
146+
zones = handle_group_scan_response("zones", driver, hue_id_to_device, light_id_to_device, api:get_zones())
143147
end
144148
end
145149
-- Combine rooms and zones.
@@ -204,7 +208,10 @@ function grouped_utils.group_update(driver, bridge_device, to_update)
204208
if to_update.children then
205209
local devices =
206210
build_group_device_table(
207-
to_update, build_hue_id_to_device_map(bridge_device), driver.hue_identifier_to_device_record
211+
to_update,
212+
build_hue_id_to_device_map(bridge_device),
213+
-- These are the hue light/other service ids rather than the hue device ids
214+
utils.get_hue_id_to_device_table_by_bridge(driver, bridge_device) or {}
208215
)
209216
-- check if number of children has changed and if we need to move it
210217
update_index = #devices ~= #group.devices
@@ -241,7 +248,10 @@ function grouped_utils.group_add(driver, bridge_device, to_add)
241248
end
242249
local hue_light_group =
243250
build_hue_light_group(
244-
to_add, build_hue_id_to_device_map(bridge_device), driver.hue_identifier_to_device_record
251+
to_add,
252+
build_hue_id_to_device_map(bridge_device),
253+
-- These are the hue light/other service ids rather than the hue device ids
254+
utils.get_hue_id_to_device_table_by_bridge(driver, bridge_device) or {}
245255
)
246256
insert(groups, hue_light_group)
247257
log.info(string.format("Adding group %s, %d devices",

drivers/SmartThings/philips-hue/src/utils/hue_bridge_utils.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ function hue_bridge_utils.do_bridge_network_init(driver, bridge_device, bridge_u
4040
{ [HueApi.APPLICATION_KEY_HEADER] = api_key },
4141
nil
4242
)
43+
local hue_identifier_to_device_record = utils.get_hue_id_to_device_table_by_bridge(driver, bridge_device) or {}
4344

4445
eventsource.onopen = function(msg)
4546
log.info_with({ hub_logs = true },
@@ -171,7 +172,7 @@ function hue_bridge_utils.do_bridge_network_init(driver, bridge_device, bridge_u
171172
local resource_ids = {}
172173
if update_data.type == "zigbee_connectivity" and update_data.owner ~= nil then
173174
for rid, rtype in pairs(driver.services_for_device_rid[update_data.owner.rid] or {}) do
174-
if driver.hue_identifier_to_device_record[rid] then
175+
if hue_identifier_to_device_record[rid] then
175176
log.debug(string.format("Adding RID %s to resource_ids", rid))
176177
table.insert(resource_ids, rid)
177178
end
@@ -186,7 +187,7 @@ function hue_bridge_utils.do_bridge_network_init(driver, bridge_device, bridge_u
186187
end
187188
for _, resource_id in ipairs(resource_ids) do
188189
log.debug(string.format("Looking for device record for %s", resource_id))
189-
local child_device = driver.hue_identifier_to_device_record[resource_id]
190+
local child_device = hue_identifier_to_device_record[resource_id]
190191
if child_device ~= nil and child_device.id ~= nil then
191192
if update_data.type == "zigbee_connectivity" then
192193
log.debug("emitting event for zigbee connectivity")
@@ -203,7 +204,7 @@ function hue_bridge_utils.do_bridge_network_init(driver, bridge_device, bridge_u
203204
for _, delete_data in ipairs(event.data) do
204205
if HueDeviceTypes.can_join_device_for_service(delete_data.type) then
205206
local resource_id = delete_data.id
206-
local child_device = driver.hue_identifier_to_device_record[resource_id]
207+
local child_device = hue_identifier_to_device_record[resource_id]
207208
if child_device ~= nil and child_device.id ~= nil then
208209
log.info(
209210
string.format(

drivers/SmartThings/philips-hue/src/utils/hue_multi_service_device_utils/sensor.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
local utils = require "utils"
2+
13
local SensorMultiServiceHelper = {}
24
function SensorMultiServiceHelper.update_multi_service_device_maps(driver, device, hue_device_id, sensor_info)
35
local svc_rids_for_device = driver.services_for_device_rid[hue_device_id] or {}
@@ -15,8 +17,9 @@ function SensorMultiServiceHelper.update_multi_service_device_maps(driver, devic
1517
end
1618

1719
driver.services_for_device_rid[hue_device_id] = svc_rids_for_device
20+
local hue_id_to_device = utils.get_hue_id_to_device_table_by_bridge(driver, device)
1821
for rid, _ in pairs(driver.services_for_device_rid[hue_device_id]) do
19-
driver.hue_identifier_to_device_record[rid] = device
22+
hue_id_to_device[rid] = device
2023
end
2124
end
2225

0 commit comments

Comments
 (0)