Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,8 @@ class Topics(vararg val topics: String) {
/** MQTT topic string for the "ChangePersonMetadataValueMapi" command. */
val CHANGE_PERSON_METADATA_VALUE = "xs3/1/cmd/ChangePersonMetadataValueMapi"

/** MQTT topic string for the "ChangeZoneMetadataValueMapi" command. */
val CHANGE_ZONE_METADATA_VALUE = "xs3/1/cmd/ChangeZoneMetadataValueMapi"
/** MQTT topic string for the "ChangeInstallationPointMetadataValueMapi" command. */
val CHANGE_INSTALLATION_POINT_METADATA_VALUE =
"xs3/1/cmd/ChangeInstallationPointMetadataValueMapi"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,35 @@ suspend fun XesarConnect.removeInstallationPointFromZoneAsync(
)
}

/**
* Changes the value of custom data field of a zone.
*
* @param id The ID of the zone.
* @param metadataId The metadataID of the data field.
* @param value The new value of the field.
* @param requestConfig The request configuration (optional).
*/
suspend fun XesarConnect.changeZoneMetadataValueAsync(
id: UUID,
metadataId: UUID,
value: String,
requestConfig: XesarConnect.RequestConfig = buildRequestConfig(),
): SingleEventResult<ZoneChanged> {
return sendCommandAsync<ChangeZoneMetadataValueMapi, ZoneChanged>(
Topics.Command.CHANGE_ZONE_METADATA_VALUE,
Topics.Event.ZONE_CHANGED,
true,
ChangeZoneMetadataValueMapi(
config.uuidGenerator.generateId(),
id,
metadataId,
value,
token,
),
requestConfig,
)
}

/**
* Retrieves a cold stream of [Zone] objects, fetching them incrementally in smaller,more manageable
* chunks rather than retrieving the entire dataset at once. Use [Query.Params.pageLimit] to choose
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.open200.xesar.connect.messages.command

import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents a command POJO to change a custom data field value for a zone.
*
* @param commandId The id of the command.
* @param id The id of the zone.
* @param metadataId The id of the custom data field.
* @param value The new value of the custom data field.
* @param token The token of the command.
*/
@Serializable
data class ChangeZoneMetadataValueMapi(
override val commandId: @Serializable(with = UUIDSerializer::class) UUID,
val id: @Serializable(with = UUIDSerializer::class) UUID,
val metadataId: @Serializable(with = UUIDSerializer::class) UUID,
val value: String,
val token: String,
) : Command
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.open200.xesar.connect.messages.event

import com.open200.xesar.connect.messages.EntityMetadata
import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable
Expand All @@ -10,10 +11,12 @@ import kotlinx.serialization.Serializable
* @param name The name of the zone.
* @param description The description of the zone.
* @param id The id of the zone.
* @param entityMetadata Contains the information for all defined custom data fields for the zone.
*/
@Serializable
data class ZoneChanged(
val name: String,
val description: String,
@Serializable(with = UUIDSerializer::class) val id: UUID,
val entityMetadata: List<EntityMetadata>? = null,
) : Event
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
package com.open200.xesar.connect.messages.query

import com.open200.xesar.connect.messages.EntityMetadata
import com.open200.xesar.connect.utils.UUIDSerializer
import java.util.*
import kotlinx.serialization.Serializable

/**
* Represents a zone.
*
* @param installationPoints The list of installation points of the zone (optional).
* @param partitionId The partition identifier of the zone.
* @param installationPointCount The installationPointCount of the zone (optional).
* @param name The name of the zone.
* @param description The description of the zone (optional).
* @param id The id of the zone.
* @param entityMetadata Contains the information for all defined custom data fields for the zone
* (optional).
*/
@Serializable
data class Zone(
val installationPoints: List<@Serializable(with = UUIDSerializer::class) UUID> = emptyList(),
Expand All @@ -12,6 +25,7 @@ data class Zone(
val name: String,
val description: String? = null,
@Serializable(with = UUIDSerializer::class) val id: UUID,
val entityMetadata: List<EntityMetadata>? = null,
) : QueryListResource, QueryElementResource {

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ZoneElementTest :
)

val zoneString =
"{\"requestId\":\"d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6\",\"response\":{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"497f6eca-6276-4993-bfeb-53cbbbba6f08\"}}"
"{\"requestId\":\"d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6\",\"response\":{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"497f6eca-6276-4993-bfeb-53cbbbba6f08\",\"entityMetadata\":[{\"id\":\"123e4567-e89b-12d3-a456-426614174000\",\"name\":\"type\",\"value\":\"floor\"},{\"id\":\"0f8fad5b-d9cb-469f-a165-70867728950e\",\"name\":\"city\",\"value\":null}]}}"

Comment thread
PaulWinter91 marked this conversation as resolved.
test("encoding QueryElement for a zone") {
val zoneEncoded = encodeQueryElement(zone)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ZoneListTest :
)

val zoneString =
"{\"requestId\":\"00000000-1281-40ae-89d7-5c541d77a757\",\"response\":{\"data\":[{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"497f6eca-6276-4993-bfeb-53cbbbba6f08\"},{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\",\"f6a5bdf2-7c7d-11ee-b962-0242ac120002\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"a4c838a8-f6be-49e0-abee-c1d3b2897279\"}],\"totalCount\":2,\"filterCount\":2}}"
"{\"requestId\":\"00000000-1281-40ae-89d7-5c541d77a757\",\"response\":{\"data\":[{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"497f6eca-6276-4993-bfeb-53cbbbba6f08\",\"entityMetadata\":[{\"id\":\"123e4567-e89b-12d3-a456-426614174000\",\"name\":\"type\",\"value\":\"floor\"},{\"id\":\"0f8fad5b-d9cb-469f-a165-70867728950e\",\"name\":\"city\",\"value\":null}]},{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\",\"f6a5bdf2-7c7d-11ee-b962-0242ac120002\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"a4c838a8-f6be-49e0-abee-c1d3b2897279\",\"entityMetadata\":[{\"id\":\"123e4567-e89b-12d3-a456-426614174000\",\"name\":\"type\",\"value\":\"floor\"},{\"id\":\"0f8fad5b-d9cb-469f-a165-70867728950e\",\"name\":\"city\",\"value\":null}]}],\"totalCount\":2,\"filterCount\":2}}"

Comment thread
PaulWinter91 marked this conversation as resolved.
test("encoding QueryList for a list of zones") {
val zoneEncoded = encodeQueryList(zoneList)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package com.open200.xesar.connect.it.command

import com.open200.xesar.connect.Topics
import com.open200.xesar.connect.XesarConnect
import com.open200.xesar.connect.XesarMqttClient
import com.open200.xesar.connect.extension.changeZoneMetadataValueAsync
import com.open200.xesar.connect.it.MosquittoContainer
import com.open200.xesar.connect.messages.EntityMetadata
import com.open200.xesar.connect.messages.event.ApiEvent
import com.open200.xesar.connect.messages.event.ZoneChanged
import com.open200.xesar.connect.messages.event.encodeEvent
import io.kotest.common.runBlocking
import io.kotest.core.spec.style.FunSpec
import io.kotest.extensions.testcontainers.perProject
import io.kotest.matchers.equals.shouldBeEqual
import io.mockk.coEvery
import java.util.*
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.launch

class ChangeZoneMetadataValueTest :
FunSpec({
val container = MosquittoContainer.container()
val config = MosquittoContainer.config(container)
listener(container.perProject())

test("change zone metadata value") {
coEvery { config.uuidGenerator.generateId() }
.returns(UUID.fromString("00000000-1281-40ae-89d7-5c541d77a757"))

val zoneId = UUID.fromString("11111111-2222-3333-4444-555555555555")
val metadataId = UUID.fromString("aaaaaaaa-0000-0000-0000-000000000001")

runBlocking {
val simulatedBackendReady = CompletableDeferred<Unit>()
val commandReceived = CompletableDeferred<String>()

launch {
XesarMqttClient.connectAsync(config).await().use { client ->
client.subscribeAsync(arrayOf(Topics.ALL_TOPICS)).await()

client.onMessage = { topic, payload ->
when (topic) {
Topics.Command.CHANGE_ZONE_METADATA_VALUE -> {
commandReceived.complete(payload.decodeToString())
}
}
}

simulatedBackendReady.complete(Unit)

val commandContent = commandReceived.await()

commandContent.shouldBeEqual(
"{\"commandId\":\"00000000-1281-40ae-89d7-5c541d77a757\",\"id\":\"11111111-2222-3333-4444-555555555555\",\"metadataId\":\"aaaaaaaa-0000-0000-0000-000000000001\",\"value\":\"Top Secret\",\"token\":\"JDJhJDEwJDFSNEljZ2FaRUNXUXBTQ25XN05KbE9qRzFHQ1VjMzkvWTBVcFpZb1M4Vmt0dnJYZ0tJVFBx\"}"
)

val apiEvent =
ApiEvent(
UUID.fromString("00000000-1281-40ae-89d7-5c541d77a757"),
ZoneChanged(
name = "Test Zone",
description = "Test Description",
id = zoneId,
entityMetadata =
listOf(
EntityMetadata(
id = metadataId,
name = "security clearance required",
value = "Top Secret",
)
),
),
)

client
.publishAsync(Topics.Event.ZONE_CHANGED, encodeEvent(apiEvent))
.await()
}
}

launch {
simulatedBackendReady.await()

val api = XesarConnect.connectAndLoginAsync(config).await()
api.subscribeAsync(Topics(Topics.Event.ZONE_CHANGED)).await()

val result =
api.changeZoneMetadataValueAsync(
id = zoneId,
metadataId = metadataId,
value = "Top Secret",
)
.await()

result.id.shouldBeEqual(zoneId)
result.entityMetadata!!
.single { it.id == metadataId }
.value
?.shouldBeEqual("Top Secret")
}
}
}
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.open200.xesar.connect.util.fixture

import com.open200.xesar.connect.messages.EntityMetadata
import com.open200.xesar.connect.messages.query.Zone
import java.util.*

Expand All @@ -13,5 +14,18 @@ object ZoneFixture {
description = "zone description",
id = UUID.fromString("497f6eca-6276-4993-bfeb-53cbbbba6f08"),
installationPoints = listOf(UUID.fromString("7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a")),
entityMetadata =
listOf(
EntityMetadata(
id = UUID.fromString("123e4567-e89b-12d3-a456-426614174000"),
name = "type",
value = "floor",
),
EntityMetadata(
id = UUID.fromString("0f8fad5b-d9cb-469f-a165-70867728950e"),
name = "city",
value = null,
),
),
)
}
Loading