Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion drivers/SmartThings/sonos/src/api/event_handlers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function CapEventHandlers.handle_group_update(device, group_info)
end

function CapEventHandlers.handle_audio_clip_status(device, clips)
for _, clip in ipairs(clips) do
for _, clip in ipairs(clips or {}) do
if clip.status == "ACTIVE" then
log.debug(st_utils.stringify_table(clip, "Playing Audio Clip: ", false))
elseif clip.status == "DONE" then
Expand Down
17 changes: 10 additions & 7 deletions drivers/SmartThings/sonos/src/api/sonos_connection.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ local _update_subscriptions_helper = function(
command,
reply_tx
)
for _, namespace in ipairs(namespaces) do
for _, namespace in ipairs(namespaces or {}) do
local wss_msg_header = {
namespace = namespace,
command = command,
Expand Down Expand Up @@ -259,7 +259,9 @@ local function _oauth_reconnect_task(sonos_conn)

if unauthorized then
sonos_conn.driver:alert_unauthorized()
local token, channel_error = token_receive_handle:receive()
local token, channel_error =
(token_receive_handle and token_receive_handle:receive()) or nil,
"no token receive handle"
if not token then
log.warn(string.format("Error requesting token: %s", channel_error))
local _, get_token_err = sonos_conn.driver:get_oauth_token()
Expand Down Expand Up @@ -405,7 +407,7 @@ function SonosConnection.new(driver, device)
)
return
end
local group = household.groups[header.groupId] or { playerIds = {} }
local group = household.groups[header.groupId] or { player_ids = {} }
for _, player_id in ipairs(group.player_ids) do
local device_for_player = self.driver:device_for_player(header.householdId, player_id)
--- we've seen situations where these messages can be processed while a device
Expand All @@ -429,7 +431,7 @@ function SonosConnection.new(driver, device)
)
return
end
local group = household.groups[header.groupId] or { playerIds = {} }
local group = household.groups[header.groupId] or { player_ids = {} }
for _, player_id in ipairs(group.player_ids) do
local device_for_player = self.driver:device_for_player(header.householdId, player_id)
--- we've seen situations where these messages can be processed while a device
Expand All @@ -452,7 +454,7 @@ function SonosConnection.new(driver, device)
)
return
end
local group = household.groups[header.groupId] or { playerIds = {} }
local group = household.groups[header.groupId] or { player_ids = {} }
for _, player_id in ipairs(group.player_ids) do
local device_for_player = self.driver:device_for_player(header.householdId, player_id)
--- we've seen situations where these messages can be processed while a device
Expand All @@ -467,9 +469,10 @@ function SonosConnection.new(driver, device)
if body.version ~= favorites_version then
favorites_version = body.version

local household = self.driver.sonos:get_household(header.householdId) or { groups = {} }
local household = self.driver.sonos:get_household(header.householdId)
or self.driver.sonos.EMPTY_HOUSEHOLD

for group_id, group in pairs(household.groups) do
for group_id, group in pairs(household.groups or {}) do
local coordinator_id =
self.driver.sonos:get_coordinator_for_group(header.householdId, group_id)
local coordinator_player = household.players[coordinator_id]
Expand Down
8 changes: 4 additions & 4 deletions drivers/SmartThings/sonos/src/api/sonos_ssdp_discovery.lua
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function SpeakerDiscoveryInfo.new(ssdp_info, discovery_info)
ret.rest_path = rest_path
end

for k, v in pairs(SpeakerDiscoveryInfo) do
for k, v in pairs(SpeakerDiscoveryInfo or {}) do
rawset(ret, k, v)
end

Expand Down Expand Up @@ -227,7 +227,7 @@ local function make_persistent_task_impl(
log.warn(string.format("Select error: %s", select_err))
end

for _, receiver in ipairs(recv_ready) do
for _, receiver in ipairs(recv_ready or {}) do
if receiver == interval_timer then
interval_timer:handled()
ssdp_search_handle:multicast_m_search()
Expand Down Expand Up @@ -331,7 +331,7 @@ function SonosPersistentSsdpTask:get_all_known()
-- make a shallow copy of the table so it doesn't get clobbered
-- the player info itself is a read-only proxy table as well
local known = {}
for id, info in pairs(self.player_info_by_sonos_ids) do
for id, info in pairs(self.player_info_by_sonos_ids or {}) do
known[id] = info
end
return known
Expand Down Expand Up @@ -454,7 +454,7 @@ function sonos_ssdp.spawn_persistent_ssdp_task()
log.debug(
st_utils.stringify_table(waiting_handles, "waiting for unique keys and mac addresses", true)
)
for _, reply_tx in ipairs(waiting_handles) do
for _, reply_tx in ipairs(waiting_handles or {}) do
reply_tx:send(speaker_info)
end

Expand Down
16 changes: 8 additions & 8 deletions drivers/SmartThings/sonos/src/api/sonos_websocket_router.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ local pending_close = {}

cosock.spawn(function()
while true do
for _, unique_key in ipairs(pending_close) do -- close any sockets pending close before selecting/receiving on them
for _, unique_key in ipairs(pending_close or {}) do -- close any sockets pending close before selecting/receiving on them
local wss = websockets[unique_key]
if wss ~= nil then
log.trace(string.format("Closing websocket for player %s", unique_key))
Expand All @@ -60,7 +60,7 @@ cosock.spawn(function()
pending_close = {}

local socks = { control_rx }
for _, wss in pairs(websockets) do
for _, wss in pairs(websockets or {}) do
table.insert(socks, wss)
end
local receivers, _, err = socket.select(socks, nil, 10)
Expand All @@ -71,7 +71,7 @@ cosock.spawn(function()
log.error("Error in Websocket Router event loop: " .. err)
end
else
for _, recv in ipairs(receivers) do
for _, recv in ipairs(receivers or {}) do
if recv.link and recv.link.queue and #recv.link.queue == 0 then -- workaround a bug in receiving
log.warn("attempting to receive on empty channel")
goto continue
Expand All @@ -93,7 +93,7 @@ cosock.spawn(function()
elseif err == "closed" and recv.id then -- closed websocket
log.trace(string.format("Websocket %s closed", tostring(recv.id)))
local still_open_sockets = {}
for unique_key, wss in pairs(websockets) do
for unique_key, wss in pairs(websockets or {}) do
if wss.id ~= recv.id then
still_open_sockets[unique_key] = wss
end
Expand Down Expand Up @@ -207,7 +207,7 @@ local function _make_websocket(url_table, api_key)

local headers = SonosApi.make_headers(api_key)
local config = LustreConfig.default():protocol("v1.api.smartspeaker.audio")
for k, v in pairs(headers) do
for k, v in pairs(headers or {}) do
config = config:header(k, v)
end

Expand Down Expand Up @@ -313,7 +313,7 @@ end
function SonosWebSocketRouter.cleanup_unused_sockets(driver)
log.trace("Begin cleanup of unused websockets")
local should_keep = {}
for unique_key, _ in pairs(websockets) do
for unique_key, _ in pairs(websockets or {}) do
local household_id, player_id = unique_key:match("(.*)/(.*)")
local is_joined = driver.sonos:get_device_id_for_player(household_id, player_id) ~= nil
log.debug(string.format("Is Player %s joined? %s", player_id, is_joined))
Expand All @@ -322,7 +322,7 @@ function SonosWebSocketRouter.cleanup_unused_sockets(driver)

local known_devices = driver:get_devices()

for _, device in ipairs(known_devices) do
for _, device in ipairs(known_devices or {}) do
local household_id, coordinator_id = driver.sonos:get_coordinator_for_device(device)
local coordinator_unique_key, bad_key_part =
utils.sonos_unique_key(household_id, coordinator_id)
Expand All @@ -340,7 +340,7 @@ function SonosWebSocketRouter.cleanup_unused_sockets(driver)
end
end

for unique_key, keep in pairs(should_keep) do
for unique_key, keep in pairs(should_keep or {}) do
if not keep then
SonosWebSocketRouter.close_socket_for_player(unique_key)
end
Expand Down
4 changes: 2 additions & 2 deletions drivers/SmartThings/sonos/src/cosock/bus.lua
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ end
function __sender_mt:close()
self._bus_inner.closed = true
local existing_links = self._bus_inner.receiver_links
for _, link in pairs(existing_links) do
for _, link in pairs(existing_links or {}) do
if link.waker then
link.waker()
end
Expand All @@ -176,7 +176,7 @@ end
function __sender_mt:send(msg)
if not self._bus_inner.closed then
-- wapping in table allows `nil` to be sent as a message
for _, link in pairs(self._bus_inner.receiver_links) do
for _, link in pairs(self._bus_inner.receiver_links or {}) do
table.insert(link.queue, { msg = msg })
if link.waker then
link.waker()
Expand Down
12 changes: 6 additions & 6 deletions drivers/SmartThings/sonos/src/sonos_driver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function SonosDriver:oauth_info_event_subscribe()
end

function SonosDriver:update_after_startup_state_received()
for k, v in pairs(self.hub_augmented_driver_data) do
for k, v in pairs(self.hub_augmented_driver_data or {}) do
local decode_success, decoded = pcall(json.decode, v)
if decode_success then
self:handle_augmented_data_change(k, decoded)
Expand Down Expand Up @@ -212,7 +212,7 @@ function SonosDriver:handle_startup_state_received()
token_refresher.spawn_token_refresher(self)
end
self.startup_state_received = true
for _, device in pairs(self.devices_waiting_for_startup_state) do
for _, device in pairs(self.devices_waiting_for_startup_state or {}) do
SonosDriverLifecycleHandlers.initialize_device(self, device)
end
self.devices_waiting_for_startup_state = {}
Expand Down Expand Up @@ -291,7 +291,7 @@ function SonosDriver:check_auth(info_or_device)
end

local unauthorized = false
for _, api_key in pairs(SonosApi.api_keys) do
for _, api_key in pairs(SonosApi.api_keys or {}) do
local headers = SonosApi.make_headers(api_key, maybe_token and maybe_token.accessToken)
local response, response_err = SonosApi.RestApi.get_groups_info(rest_url, household_id, headers)

Expand Down Expand Up @@ -422,13 +422,13 @@ local function make_ssdp_event_handler(
local recv_ready, _, select_err = cosock.socket.select(receivers, nil, nil)

if recv_ready then
for _, receiver in ipairs(recv_ready) do
for _, receiver in ipairs(recv_ready or {}) do
if oauth_token_subscription ~= nil and receiver == oauth_token_subscription then
local token_evt, receive_err = oauth_token_subscription:receive()
if not token_evt then
log.warn(string.format("Error on token event bus receive: %s", receive_err))
else
for _, event in pairs(unauthorized) do
for _, event in pairs(unauthorized or {}) do
-- shouldn't need a nil check on the ssdp_task here since this whole function
-- won't get called unless the task is successfully spawned.
driver.ssdp_task:publish(event)
Expand Down Expand Up @@ -696,7 +696,7 @@ function SonosDriver.new_driver_template()
},
}

for k, v in pairs(SonosDriver) do
for k, v in pairs(SonosDriver or {}) do
template[k] = v
end

Expand Down
11 changes: 6 additions & 5 deletions drivers/SmartThings/sonos/src/sonos_state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ local _STATE = {
--- @class SonosState
local SonosState = {}
SonosState.__index = SonosState
SonosState.EMPTY_HOUSEHOLD = _STATE.households:get_or_init("__EMPTY")

---@param device SonosDevice
---@param info SpeakerDiscoveryInfo
Expand Down Expand Up @@ -361,26 +362,26 @@ function SonosState:update_household_info(id, groups_event, driver)

local groups, players = groups_event.groups, groups_event.players

for _, group in ipairs(groups) do
for _, group in ipairs(groups or {}) do
household.groups[group.id] =
{ id = group.id, coordinator_id = group.coordinatorId, player_ids = group.playerIds }
for _, playerId in ipairs(group.playerIds) do
for _, playerId in ipairs(group.playerIds or {}) do
household.player_to_group[playerId] = group.id
end
end

-- Iterate through the players and track all the devices associated with them
-- for bonded set tracking.
local log_devices_error = false
for _, player in ipairs(players) do
for _, player in ipairs(players or {}) do
-- Prefer devices because deviceIds is deprecated but all we care about is
-- the ID so either way is fine.
if type(player.devices) == "table" then
for _, device in ipairs(player.devices) do
for _, device in ipairs(player.devices or {}) do
update_device_info(driver, player, household, known_bonded_players, device.id)
end
elseif type(player.deviceIds) == "table" then
for _, device_id in ipairs(player.deviceIds) do
for _, device_id in ipairs(player.deviceIds or {}) do
update_device_info(driver, player, household, known_bonded_players, device_id)
end
else
Expand Down
6 changes: 3 additions & 3 deletions drivers/SmartThings/sonos/src/ssdp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ end
---@diagnostic disable-next-line: inject-field
function Ssdp.check_headers_contain(headers, keys_to_check)
local missing = {}
for _, header_key in ipairs(keys_to_check) do
for _, header_key in ipairs(keys_to_check or {}) do
if headers:get_one(header_key) == nil then
table.insert(missing, header_key)
end
Expand Down Expand Up @@ -197,7 +197,7 @@ end
--- the search end time will be pushed out based on the `mx` parameter, extending the amount of
--- time that `receive_m_search_response` will return results with a timeout.
function _ssdp_mt:multicast_m_search()
for term, _ in pairs(self.search_terms) do
for term, _ in pairs(self.search_terms or {}) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we may want to crash here if this is nil, since it would mean potentially not discovering devices when we should be.

local multicast_msg = table.concat({
"M-SEARCH * HTTP/1.1",
"HOST: 239.255.255.250:1900",
Expand Down Expand Up @@ -284,7 +284,7 @@ function _ssdp_mt:next_msearch_response()
)
end

for _, location in ipairs(location_candidates) do
for _, location in ipairs(location_candidates or {}) do
local location_host_match = location:match("http://([^,/]+):[^/]+/.+%.xml")
if location_host_match ~= nil then
possible_locations[location_host_match] = location
Expand Down
4 changes: 2 additions & 2 deletions drivers/SmartThings/sonos/src/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ function utils.deep_table_eq(tbl1, tbl2)
if tbl1 == tbl2 then
return true
elseif type(tbl1) == "table" and type(tbl2) == "table" then
for key1, value1 in pairs(tbl1) do
for key1, value1 in pairs(tbl1 or {}) do
local value2 = tbl2[key1]

if value2 == nil then
Expand All @@ -337,7 +337,7 @@ function utils.deep_table_eq(tbl1, tbl2)
end

-- check for missing keys in tbl1
for key2, _ in pairs(tbl2) do
for key2, _ in pairs(tbl2 or {}) do
if tbl1[key2] == nil then
return false
end
Expand Down
Loading