HomeNative/app/src/main/java/dev/coffeeco/homenative/data/HomeClient.kt
2024-09-03 12:25:13 +02:00

95 lines
3.3 KiB
Kotlin

package dev.coffeeco.homenative.data
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.plugins.DefaultRequest
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.websocket.DefaultClientWebSocketSession
import io.ktor.client.plugins.websocket.WebSockets
import io.ktor.client.plugins.websocket.receiveDeserialized
import io.ktor.client.plugins.websocket.sendSerialized
import io.ktor.client.plugins.websocket.webSocket
import io.ktor.client.plugins.websocket.webSocketSession
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.client.statement.HttpResponse
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.contentType
import io.ktor.serialization.kotlinx.KotlinxWebsocketSerializationConverter
import io.ktor.serialization.kotlinx.json.json
import io.ktor.utils.io.InternalAPI
import io.ktor.websocket.DefaultWebSocketSession
import io.ktor.websocket.FrameType
import io.ktor.websocket.send
import io.ktor.websocket.serialization.receiveDeserializedBase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import java.util.EventListener
class HomeClient(private val baseUrl: String, private val accessToken: String) {
val jsonConfig = Json { // isLenient = true
// useArrayPolymorphism = true
allowStructuredMapKeys = true
ignoreUnknownKeys = true // explicitNulls = false
// namingStrategy = JsonNamingStrategy.SnakeCase
encodeDefaults = true // IMPORTANT
}
private val client: HttpClient = HttpClient(OkHttp) {
install(WebSockets) {
contentConverter = KotlinxWebsocketSerializationConverter(Json)
}
install(ContentNegotiation) {
json(jsonConfig)
}
install(DefaultRequest) {
header(HttpHeaders.Authorization, "Bearer $accessToken")
}
}
val wsClient = WSClient(GlobalScope, baseUrl, accessToken, client)
suspend fun apiStatus(): HttpResponse {
val res = client.get("$baseUrl/api/")
return res
}
private suspend fun getState(): List<StatesResItem> {
val res = client.get("$baseUrl/api/states")
val body = res.body<List<StatesResItem>>()
return body
}
suspend fun getUsefulState(): List<StatesResItem> {
val all = getState()
val filtered = all.filter { i -> i.entityId.startsWith("switch.") }
return filtered
}
private suspend fun updateService(
entityId: String, domain: String, service: String
): HttpResponse {
return client.post("$baseUrl/api/services/$domain/$service") {
contentType(ContentType.Application.Json)
setBody(PostServiceBody(entityId))
}
}
suspend fun updateSwitch(entityId: String, service: String) {
if (service !in switchServices) {
throw Exception("Illegal/unknown service was specified")
}
val res = updateService(entityId, "switch", service)
}
}
val switchServices = listOf("turn_off", "turn_on", "toggle")