diff --git a/hassio/plugin.toml b/hassio/plugin.toml index bd73a65..4287a90 100644 --- a/hassio/plugin.toml +++ b/hassio/plugin.toml @@ -1,6 +1,6 @@ id = "pozzoo/hassio" name = "Home Assistant" -version = "2.0.1" +version = "2.0.2" plugin_api = 4 author = "Pozzoo" license = "MIT" diff --git a/hassio/service_sse.luau b/hassio/service_sse.luau index ec94d10..992b3ba 100644 --- a/hassio/service_sse.luau +++ b/hassio/service_sse.luau @@ -39,6 +39,7 @@ local retryCount = 0 local maxRetriesNotified = false local suspended = false local connectionRequestInFlight = false +local connectingSince = nil local function getCleanToken() if type(haToken) ~= "string" then return "" end @@ -214,8 +215,10 @@ end local function fetchInitialStates() if not isConfigured() or suspended or connectionRequestInFlight then return end connectionRequestInFlight = true + connectingSince = os.clock() local launched = haRequest("/api/states", "GET", nil, function(res) connectionRequestInFlight = false + connectingSince = nil if not res.body or res.body == "" then noctalia.log("Empty response body from /api/states") @@ -287,6 +290,7 @@ local function fetchInitialStates() if not launched then connectionRequestInFlight = false + connectingSince = nil status = "disconnected" noctalia.state.set("connection_status", status) syncUpdateInterval() @@ -396,6 +400,14 @@ function update() return end + if status == "connecting" and connectingSince and (os.clock() - connectingSince) > 15 then + connectionRequestInFlight = false + connectingSince = nil + status = "disconnected" + noctalia.state.set("connection_status", status) + syncUpdateInterval() + end + if status == "disconnected" then retryCount = retryCount + 1 if retryCount >= MAX_RECONNECT_RETRIES then diff --git a/hassio/shortcut.luau b/hassio/shortcut.luau index 664bb48..9fcd3f7 100644 --- a/hassio/shortcut.luau +++ b/hassio/shortcut.luau @@ -14,6 +14,11 @@ local pendingTimerSeq = 0 local PENDING_TIMEOUT_SECONDS = 8 local render +local function getCleanUrl() + if type(haUrl) ~= "string" then return "" end + return (haUrl:gsub("/$", "")) +end + local function getCleanToken() if type(haToken) ~= "string" then return "" end return haToken:gsub("^%s+", ""):gsub("%s+$", "") @@ -116,7 +121,7 @@ function onClick() local entity = getEntity() local cleanToken = getCleanToken() - if not entity or not haUrl or haUrl == "" or cleanToken == "" then return end + if not entity or getCleanUrl() == "" or cleanToken == "" then return end local eid = entity.entity_id if pendingToggle[eid] then return end @@ -128,7 +133,7 @@ function onClick() local encoded = noctalia.json.encode({ entity_id = eid }) noctalia.http({ - url = haUrl .. "/api/services/" .. entity.domain .. "/toggle", + url = getCleanUrl() .. "/api/services/" .. entity.domain .. "/toggle", method = "POST", headers = { "Authorization: Bearer " .. cleanToken, diff --git a/hassio/shortcut_2.luau b/hassio/shortcut_2.luau index 3e27b2f..65fb0b7 100644 --- a/hassio/shortcut_2.luau +++ b/hassio/shortcut_2.luau @@ -14,6 +14,11 @@ local pendingTimerSeq = 0 local PENDING_TIMEOUT_SECONDS = 8 local render +local function getCleanUrl() + if type(haUrl) ~= "string" then return "" end + return (haUrl:gsub("/$", "")) +end + local function getCleanToken() if type(haToken) ~= "string" then return "" end return haToken:gsub("^%s+", ""):gsub("%s+$", "") @@ -116,7 +121,7 @@ function onClick() local entity = getEntity() local cleanToken = getCleanToken() - if not entity or not haUrl or haUrl == "" or cleanToken == "" then return end + if not entity or getCleanUrl() == "" or cleanToken == "" then return end local eid = entity.entity_id if pendingToggle[eid] then return end @@ -128,7 +133,7 @@ function onClick() local encoded = noctalia.json.encode({ entity_id = eid }) noctalia.http({ - url = haUrl .. "/api/services/" .. entity.domain .. "/toggle", + url = getCleanUrl() .. "/api/services/" .. entity.domain .. "/toggle", method = "POST", headers = { "Authorization: Bearer " .. cleanToken, diff --git a/hassio/shortcut_3.luau b/hassio/shortcut_3.luau index cf25cfe..935444b 100644 --- a/hassio/shortcut_3.luau +++ b/hassio/shortcut_3.luau @@ -14,6 +14,11 @@ local pendingTimerSeq = 0 local PENDING_TIMEOUT_SECONDS = 8 local render +local function getCleanUrl() + if type(haUrl) ~= "string" then return "" end + return (haUrl:gsub("/$", "")) +end + local function getCleanToken() if type(haToken) ~= "string" then return "" end return haToken:gsub("^%s+", ""):gsub("%s+$", "") @@ -116,7 +121,7 @@ function onClick() local entity = getEntity() local cleanToken = getCleanToken() - if not entity or not haUrl or haUrl == "" or cleanToken == "" then return end + if not entity or getCleanUrl() == "" or cleanToken == "" then return end local eid = entity.entity_id if pendingToggle[eid] then return end @@ -128,7 +133,7 @@ function onClick() local encoded = noctalia.json.encode({ entity_id = eid }) noctalia.http({ - url = haUrl .. "/api/services/" .. entity.domain .. "/toggle", + url = getCleanUrl() .. "/api/services/" .. entity.domain .. "/toggle", method = "POST", headers = { "Authorization: Bearer " .. cleanToken, diff --git a/hassio/shortcut_4.luau b/hassio/shortcut_4.luau index 369bed1..769536f 100644 --- a/hassio/shortcut_4.luau +++ b/hassio/shortcut_4.luau @@ -14,6 +14,11 @@ local pendingTimerSeq = 0 local PENDING_TIMEOUT_SECONDS = 8 local render +local function getCleanUrl() + if type(haUrl) ~= "string" then return "" end + return (haUrl:gsub("/$", "")) +end + local function getCleanToken() if type(haToken) ~= "string" then return "" end return haToken:gsub("^%s+", ""):gsub("%s+$", "") @@ -116,7 +121,7 @@ function onClick() local entity = getEntity() local cleanToken = getCleanToken() - if not entity or not haUrl or haUrl == "" or cleanToken == "" then return end + if not entity or getCleanUrl() == "" or cleanToken == "" then return end local eid = entity.entity_id if pendingToggle[eid] then return end @@ -128,7 +133,7 @@ function onClick() local encoded = noctalia.json.encode({ entity_id = eid }) noctalia.http({ - url = haUrl .. "/api/services/" .. entity.domain .. "/toggle", + url = getCleanUrl() .. "/api/services/" .. entity.domain .. "/toggle", method = "POST", headers = { "Authorization: Bearer " .. cleanToken,