Skip to content

Commit

Permalink
Merge pull request #74 from efirestone/firestone/serialization-fix
Browse files Browse the repository at this point in the history
fix: Fix serialization of commands
  • Loading branch information
efirestone authored Oct 18, 2023
2 parents 1345761 + 28db83e commit 021f907
Show file tree
Hide file tree
Showing 8 changed files with 596 additions and 27 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

![GitHub Actions status](https://github.com/efirestone/hassle/workflows/Latest%20push/badge.svg)
![LINE](https://img.shields.io/badge/line--coverage-32.63%25-red.svg)
![LINE](https://img.shields.io/badge/line--coverage-46.07%25-orange.svg)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.codellyrandom.hassle/hassle/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.codellyrandom.hassle/hassle)

# Hassle
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ kotlin {
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("reflect"))
}
}
val jvmMain by getting {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import kotlinx.atomicfu.atomic
import kotlinx.coroutines.CoroutineScope
import kotlin.collections.set
import kotlin.reflect.KType
import kotlin.reflect.typeOf
import kotlinx.serialization.json.Json as SerializationJson

internal typealias SensorsByApiName = MutableMap<EntityId, Sensor<*>>
Expand Down Expand Up @@ -170,7 +171,7 @@ internal class HomeAssistantApiClientImpl(
}

override suspend fun <C : Command, T : Any> await(command: C, commandType: KType, resultType: KType): T {
val id = send(command)
val id = send(command, commandType)
return session!!.consumeSingleMessage(id, resultType)
}

Expand All @@ -184,10 +185,14 @@ internal class HomeAssistantApiClientImpl(
* @param command the command to send
* @return The ID of the command that was sent.
*/
internal suspend fun <C : Command> send(command: C): Int {
internal suspend inline fun <reified C : Command> send(command: C): Int {
return send(command, typeOf<C>())
}

internal suspend fun <C : Command> send(command: C, commandType: KType): Int {
val id = commandId.incrementAndGet()
val commandWithId = command.copy(id) // has to be called within single thread to prevent race conditions
mapper.toJson(commandWithId).let { serializedCommand ->
mapper.toJson(commandWithId, commandType).let { serializedCommand ->
// TODO: Reconnect if session is missing
session!!.callWebSocketApi(serializedCommand)
.also { logger.i { "Called hass api with message: $serializedCommand" } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,28 @@ internal class SubscribeEventsCommand(
override var id: Int? = null,
@SerialName("event_type")
val eventType: EventType,
val type: String = "subscribe_events",
) : CommandImpl(id) {
override fun copy(id: Int?) = SubscribeEventsCommand(id = id, eventType = eventType, type = type)
val type: String = "subscribe_events"

override fun copy(id: Int?) = SubscribeEventsCommand(id = id, eventType = eventType)
}

@Serializable
internal class GetStatesCommand(
override var id: Int? = null,
val type: String = "get_states",
) : CommandImpl(id) {
override fun copy(id: Int?) = GetStatesCommand(id = id, type = type)
val type: String = "get_states"

override fun copy(id: Int?) = GetStatesCommand(id = id)
}

@Serializable
internal class GetServicesCommand(
override var id: Int? = null,
val type: String = "get_services",
) : CommandImpl(id) {
override fun copy(id: Int?) = GetServicesCommand(id = id, type = type)
val type: String = "get_services"

override fun copy(id: Int?) = GetServicesCommand(id = id)
}

// - Service Command
Expand All @@ -63,8 +66,9 @@ internal sealed class ServiceCommand(
override var id: Int? = null,
var domain: Domain,
var service: Service,
val type: String = "call_service",
) : CommandImpl(id) {
val type: String = "call_service"

@Serializable
class Target(
@SerialName("entity_id")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ data class ServicesResponse(
val id: Int,
val type: String,
val success: Boolean,
val result: Map<String, JsonObject>,
val result: Map<String, JsonObject> = mapOf(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ class StatesResponse(
val id: Int,
val type: String,
val success: Boolean,
val result: Array<JsonObject>,
val result: Array<JsonObject> = arrayOf(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ suspend fun HomeAssistantApiClient.requestLocationUpdate(vararg devices: Device)

@Serializable
class MobileNotificationData {
lateinit var subtitle: String
private val push: PushData = PushData()
var apnsHeaders: ApnsHeaders? = null
var presentationOptions: List<PresentationOptions>? = null
Expand Down
Loading

0 comments on commit 021f907

Please sign in to comment.