Create working PoC of /sonos endpoint

This commit is contained in:
2020-07-07 21:18:38 +02:00
parent 160f4fea29
commit 01a19ccd02
5 changed files with 84 additions and 12 deletions

View File

@@ -12,21 +12,30 @@ class Request private constructor(
init {
val body = extractBody(request)
val pathParams = extractPathParams(matchingResult)
val pathParameters = extractPathParameters(matchingResult)
val queryVariables = extractQueryVariables(request)
luaTable.set("body", body)
luaTable.set("params", pathParams)
luaTable.set("query", queryVariables)
luaTable.set("path", pathParameters)
}
private fun extractPathParams(matchingResult: UriTemplate.MatchingResult) =
LuaValue.tableOf().also { params ->
private fun extractPathParameters(matchingResult: UriTemplate.MatchingResult) =
LuaValue.tableOf().also { table ->
matchingResult.variables
.map { LuaValue.valueOf(it.key) to LuaValue.valueOf(it.value) }
.forEach { params.set(it.first, it.second) }
.forEach { table.set(it.first, it.second) }
}
private fun extractQueryVariables(request: NanoHTTPD.IHTTPSession) =
LuaValue.tableOf().also { table ->
request.parms
.map { LuaValue.valueOf(it.key) to LuaValue.valueOf(it.value) }
.forEach { table.set(it.first, it.second) }
}
private fun extractBody(request: NanoHTTPD.IHTTPSession) =
mutableMapOf<String, String>().let {
request.parseBody(it)

View File

@@ -50,7 +50,9 @@ class ScriptsInitializer(private val context: Context, private val preferences:
private const val INITIALIZED_FLAG = "flag_initialized"
private val endpoints = mapOf(
"say.lua" to R.raw.say,
"file.lua" to R.raw.file
"file.lua" to R.raw.file,
"sonos.lua" to R.raw.sonos,
"cache.lua" to R.raw.cache
)
}
}

View File

@@ -0,0 +1,15 @@
return {
uri = "/cache/{filename}.{ext}",
method = Method.GET,
consumer = function(request)
local filename = string.format("%s.%s", request.path.filename, request.path.ext)
local file = cache.file(filename)
local mime = Mime[request.path.ext:upper()]
return {
mime = mime,
cached = true,
data = file
}
end
}

View File

@@ -1,17 +1,16 @@
return {
uri = "/{format}",
method = Method.POST,
accepts = Mime.JSON,
uri = "/tts.{ext}",
method = Method.GET,
consumer = function(request)
local body = json.decode(request.body)
local format = (request.params.format or "WAV"):upper()
local format = (request.path.ext or "wav"):upper()
local audioFormat = AudioFormat[format]
local mime = Mime[format]
local file = tts.sayToFile(body.text, body.language or "en", audioFormat)
local file = tts.sayToFile(request.query.phrase, request.query.lang or "en", audioFormat)
return {
mime = mime,
cached = false,
data = file
}
end

View File

@@ -0,0 +1,47 @@
local announcementUrl = "http://" .. server.address .. ":8080/cache"
local snapshot = nil
function prepareTTSFile(phrase, language)
local file = tts.sayToFile(phrase, language, AudioFormat.MP3)
return announcementUrl .. "/" .. file:getName()
end
function updateSnapshotIfFirst(device)
if(snapshot == nil) then
snapshot = device:snapshot()
end
end
function announce(device, data, url)
device:stop()
device:setVolume(data.volume)
device:playUri(url, "")
while(device:getPlayState():name() ~= "STOPPED") do
thread.sleep(500)
end
end
function restoreSnapshotIfLast(queueLength)
if(queueLength() == 0) then
if(snapshot ~= nil) then
snapshot:restore()
snapshot = nil
end
end
end
return {
uri = "/sonos",
method = Method.POST,
accepts = Mime.JSON,
queued = true,
consumer = function(request, queueLength)
local body = json.decode(request.body)
local zone = config.sonosDevices[body.zone]
local url = prepareTTSFile(body.text, body.language or "en")
updateSnapshotIfFirst(zone)
announce(zone, body, url)
restoreSnapshotIfLast(queueLength)
end
}