sub init() m.top.setFocus(true) m.backend = m.top.findNode("backend") m.status = m.top.findNode("status") m.refreshTimer = m.top.findNode("refreshTimer") m.cameraPosters = [ m.top.findNode("poster1"), m.top.findNode("poster2"), m.top.findNode("poster3"), m.top.findNode("poster4") ] m.cameraNodes = [ m.top.findNode("cam1"), m.top.findNode("cam2"), m.top.findNode("cam3"), m.top.findNode("cam4") ] m.refreshToken = 0 loadConfig() end sub sub loadConfig() raw = ReadAsciiFile("pkg:/config/cameras.json") config = ParseJson(raw) if type(config) <> "roAssociativeArray" then m.status.text = "Unable to parse cameras.json" return end if m.config = config if config.doesExist("backend") and config.backend.doesExist("baseUrl") then m.backend.text = "Frigate snapshot source" end if if not config.doesExist("cameras") then m.status.text = "No cameras found in config" return end if if config.doesExist("backend") and config.backend.doesExist("refreshSeconds") then m.refreshTimer.duration = config.backend.refreshSeconds end if m.refreshTimer.observeField("fire", "onRefreshTimerFire") m.refreshTimer.control = "start" renderCameras() end sub sub renderCameras() if m.config = invalid or not m.config.doesExist("cameras") then return end if cameras = m.config.cameras m.status.text = cameras.count().toStr() + " cameras loaded, refreshing every " + m.refreshTimer.duration.toStr() + "s" for i = 0 to m.cameraNodes.count() - 1 poster = m.cameraPosters[i] node = m.cameraNodes[i] if i < cameras.count() then camera = cameras[i] poster.uri = addCacheBust(buildSnapshotUrl(m.config, camera)) node.text = camera.name else poster.uri = "" node.text = "Empty slot" end if end for end sub sub onRefreshTimerFire() m.refreshToken = m.refreshToken + 1 renderCameras() end sub function buildSnapshotUrl(config as Object, camera as Object) as String if not config.doesExist("backend") or not config.backend.doesExist("baseUrl") then return "" end if baseUrl = config.backend.baseUrl path = "" if camera.doesExist("snapshotPath") then path = camera.snapshotPath else if camera.doesExist("frigateCamera") then path = "/api/" + camera.frigateCamera + "/latest.jpg" else return "" end if if right(baseUrl, 1) = "/" and left(path, 1) = "/" then return left(baseUrl, len(baseUrl) - 1) + path else if right(baseUrl, 1) <> "/" and left(path, 1) <> "/" then return baseUrl + "/" + path end if return baseUrl + path end function function addCacheBust(url as String) as String token = m.refreshToken.toStr() if instr(1, url, "?") > 0 then return url + "&cb=" + token end if return url + "?cb=" + token end function