Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly trigger Actuator Target Events #31

Merged
merged 6 commits into from
Nov 3, 2023
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 @@ -48,9 +48,7 @@ class VSSPropertiesViewModel : ViewModel() {
private set

val valueTypes: List<ValueCase> = ValueCase.values().toList()
val fieldTypes: List<Field> = Field.values().toList()
.filterNot { it.toString().contains(EXCLUDED_FIELD_TYPES) }
.minus(listOf(Field.FIELD_UNSPECIFIED, Field.UNRECOGNIZED)) // Not relevant field types
val fieldTypes: List<Field> = listOf(Field.FIELD_VALUE, Field.FIELD_ACTUATOR_TARGET)

val datapoint: Datapoint
get() = vssProperties.valueType.createDatapoint(vssProperties.value)
Expand All @@ -62,16 +60,12 @@ class VSSPropertiesViewModel : ViewModel() {
fun updateVssProperties(vssProperties: VSSProperties = VSSProperties()) {
this.vssProperties = vssProperties
}

companion object {
const val EXCLUDED_FIELD_TYPES = "METADATA"
}
}

@Immutable
data class VSSProperties(
val vssPath: String = "Vehicle.Speed",
val valueType: ValueCase = ValueCase.VALUE_NOT_SET,
val value: String = "130",
val fieldType: Field = Field.FIELD_UNSPECIFIED,
val fieldType: Field = Field.FIELD_VALUE,
)
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/detekt.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ tasks.withType<Detekt>().configureEach {
parallel = true
setSource(projectDir)
include("**/*.kt", "**/*.kts")
exclude("**/resources/**", "**/build/**")
exclude("**/resources/**", "**/build/**", "**/node_modules/**")
config.setFrom(project.file("$rootDir/config/detekt/config.yml"))
baseline.set(baselineFile)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse
import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse
import org.eclipse.kuksa.proto.v1.Types
import org.eclipse.kuksa.proto.v1.Types.Datapoint
import org.eclipse.kuksa.proto.v1.Types.Field
import org.eclipse.kuksa.subscription.DataBrokerSubscriber
import org.eclipse.kuksa.vsscore.model.VssProperty
import org.eclipse.kuksa.vsscore.model.VssSpecification
Expand Down Expand Up @@ -117,7 +118,7 @@ class DataBrokerConnection internal constructor(
@JvmOverloads
fun <T : VssSpecification> subscribe(
specification: T,
fields: List<Types.Field> = listOf(Types.Field.FIELD_VALUE),
fields: List<Field> = listOf(Field.FIELD_VALUE),
listener: VssSpecificationListener<T>,
) {
fields.forEach { field ->
Expand All @@ -130,7 +131,7 @@ class DataBrokerConnection internal constructor(
*/
fun <T : VssSpecification> unsubscribe(
specification: T,
fields: List<Types.Field> = listOf(Types.Field.FIELD_VALUE),
fields: List<Field> = listOf(Field.FIELD_VALUE),
listener: VssSpecificationListener<T>,
) {
fields.forEach { field ->
Expand Down Expand Up @@ -160,7 +161,7 @@ class DataBrokerConnection internal constructor(
@JvmOverloads
suspend fun <T : VssSpecification> fetch(
specification: T,
fields: List<Types.Field> = listOf(Types.Field.FIELD_VALUE),
fields: Collection<Field> = listOf(Field.FIELD_VALUE),
): T {
return withContext(dispatcher) {
try {
Expand Down Expand Up @@ -204,18 +205,22 @@ class DataBrokerConnection internal constructor(

/**
* Only a [VssProperty] can be updated because they have an actual value. When provided with any parent
* [VssSpecification] then this [update] method will find all [VssProperty] children and updates them instead.
* [VssSpecification] then this [update] method will find all [VssProperty] children and updates their corresponding
* [fields] instead.
* Compared to [update] with only one [Property] and [Datapoint], here multiple [SetResponse] will be returned
* because a [VssSpecification] may consists of multiple values which may need to be updated.
*
* @throws DataBrokerException in case the connection to the DataBroker is no longer active
* @throws IllegalArgumentException if the [VssProperty] could not be converted to a [Datapoint].
*/
suspend fun update(vssSpecification: VssSpecification): List<SetResponse> {
suspend fun update(
vssSpecification: VssSpecification,
fields: List<Field> = listOf(Field.FIELD_VALUE),
wba2hi marked this conversation as resolved.
Show resolved Hide resolved
): List<SetResponse> {
val responses = mutableListOf<SetResponse>()

vssSpecification.vssProperties.forEach { vssProperty ->
val property = Property(vssProperty.vssPath)
val property = Property(vssProperty.vssPath, fields)
val response = update(property, vssProperty.datapoint)
responses.add(response)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import io.grpc.stub.StreamObserver
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.eclipse.kuksa.extension.TAG
import org.eclipse.kuksa.extension.applyDatapoint
import org.eclipse.kuksa.proto.v1.KuksaValV1
import org.eclipse.kuksa.proto.v1.KuksaValV1.SubscribeResponse
import org.eclipse.kuksa.proto.v1.Types
Expand Down Expand Up @@ -94,16 +96,21 @@ internal class DataBrokerTransporter(
): KuksaValV1.SetResponse {
return withContext(defaultDispatcher) {
val blockingStub = VALGrpc.newBlockingStub(managedChannel)
val dataEntry = Types.DataEntry.newBuilder()
.setPath(vssPath)
.setValue(updatedDatapoint)
.build()
val entryUpdate = KuksaValV1.EntryUpdate.newBuilder()
.setEntry(dataEntry)
.addAllFields(fields)
.build()

val entryUpdates = fields.map { field ->
val dataEntry = Types.DataEntry.newBuilder()
.setPath(vssPath)
.applyDatapoint(updatedDatapoint, field)
.build()

KuksaValV1.EntryUpdate.newBuilder()
.setEntry(dataEntry)
.addFields(field)
.build()
}

val request = KuksaValV1.SetRequest.newBuilder()
.addUpdates(entryUpdate)
.addAllUpdates(entryUpdates)
.build()

return@withContext try {
Expand Down Expand Up @@ -162,7 +169,7 @@ internal class DataBrokerTransporter(
}

override fun onCompleted() {
Log.d("TAG", "onCompleted() called")
Log.d(TAG, "onCompleted() called")
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2023 Contributors to the Eclipse Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*
*/

package org.eclipse.kuksa.extension

import org.eclipse.kuksa.proto.v1.Types
import org.eclipse.kuksa.proto.v1.Types.Field

/**
* Applies the given [datapoint] to the given [Types.DataEntry.Builder]. If the [field] is set to
* [Field.FIELD_ACTUATOR_TARGET] it will set the datapoint using [Types.DataEntry.Builder.setActuatorTarget],
* otherwise it it will set the datapoint using [Types.DataEntry.Builder.setValue].
*/
fun Types.DataEntry.Builder.applyDatapoint(
datapoint: Types.Datapoint,
field: Field,
): Types.DataEntry.Builder {
when (field) {
Field.FIELD_ACTUATOR_TARGET -> {
this.actuatorTarget = datapoint
}

else -> {
this.value = datapoint
}
}

return this
}