message refactoring

This commit is contained in:
Alexander Nozik 2021-01-10 20:50:45 +03:00
parent d716eac07f
commit b883bece48
6 changed files with 41 additions and 14 deletions

View File

@ -8,6 +8,8 @@ import hep.dataforge.provider.Provider
* A hub that could locate multiple devices and redirect actions to them
*/
public interface DeviceHub : Provider {
public val deviceName: String
public val devices: Map<NameToken, Device>
override val defaultTarget: String get() = Device.DEVICE_TARGET

View File

@ -24,7 +24,7 @@ public class DeviceController(
private val propertyChanges = device.propertyFlow.map { (propertyName: String, value: MetaItem<*>) ->
PropertyChangedMessage(
sourceDevice = deviceName,
key = propertyName,
property = propertyName,
value = value,
)
}
@ -69,7 +69,7 @@ public class DeviceController(
when (request) {
is PropertyGetMessage -> {
PropertyChangedMessage(
key = request.property,
property = request.property,
value = device.getProperty(request.property),
sourceDevice = deviceTarget,
targetDevice = request.sourceDevice
@ -83,7 +83,7 @@ public class DeviceController(
device.setProperty(request.property, request.value)
}
PropertyChangedMessage(
key = request.property,
property = request.property,
value = device.getProperty(request.property),
sourceDevice = deviceTarget,
targetDevice = request.sourceDevice
@ -149,6 +149,6 @@ public suspend fun DeviceHub.respondMessage(request: DeviceMessage): DeviceMessa
val device = this[targetName] ?: error("The device with name $targetName not found in $this")
DeviceController.respondMessage(device, targetName.toString(), request)
} catch (ex: Exception) {
DeviceMessage.error(ex, sourceDevice = request.targetDevice, targetDevice = request.sourceDevice)
DeviceMessage.error(ex, sourceDevice = deviceName, targetDevice = request.sourceDevice)
}
}

View File

@ -5,12 +5,14 @@ import hep.dataforge.control.api.Device
import hep.dataforge.control.api.DeviceHub
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.get
import hep.dataforge.meta.string
import hep.dataforge.names.Name
import hep.dataforge.names.NameToken
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
public class DeviceManager : AbstractPlugin(), DeviceHub {
public class DeviceManager(override val deviceName: String = "") : AbstractPlugin(), DeviceHub {
override val tag: PluginTag get() = Companion.tag
/**
@ -33,7 +35,8 @@ public class DeviceManager : AbstractPlugin(), DeviceHub {
override val tag: PluginTag = PluginTag("devices", group = PluginTag.DATAFORGE_GROUP)
override val type: KClass<out DeviceManager> = DeviceManager::class
override fun invoke(meta: Meta, context: Context): DeviceManager = DeviceManager()
override fun invoke(meta: Meta, context: Context): DeviceManager =
DeviceManager(meta["deviceName"].string ?: "")
}
}

View File

@ -54,7 +54,7 @@ public class HubController(
val device = hub[targetName] ?: error("The device with name $targetName not found in $hub")
DeviceController.respondMessage(device, targetName.toString(), message)
} catch (ex: Exception) {
DeviceMessage.error(ex, sourceDevice = null, targetDevice = message.sourceDevice)
DeviceMessage.error(ex, sourceDevice = hub.deviceName, targetDevice = message.sourceDevice)
}
//
// override suspend fun respond(request: Envelope): Envelope = try {

View File

@ -18,28 +18,39 @@ public sealed class DeviceMessage {
public companion object {
public fun error(
cause: Throwable,
sourceDevice: String?,
sourceDevice: String,
targetDevice: String? = null,
): DeviceErrorMessage = DeviceErrorMessage(
errorMessage = cause.message,
errorType = cause::class.simpleName,
errorStackTrace = cause.stackTraceToString()
errorStackTrace = cause.stackTraceToString(),
sourceDevice = sourceDevice,
targetDevice = targetDevice
)
public fun fromMeta(meta: Meta): DeviceMessage = Json.decodeFromJsonElement(meta.toJson())
}
}
/**
* Notify that property is changed. [sourceDevice] is mandatory.
* [property] corresponds to property name.
* [value] could be null if the property is invalidated.
*
*/
@Serializable
@SerialName("property.changed")
public data class PropertyChangedMessage(
public val key: String,
public val property: String,
public val value: MetaItem<*>?,
override val sourceDevice: String,
override val targetDevice: String? = null,
override val comment: String? = null,
) : DeviceMessage()
/**
* A command to set or invalidate property. [targetDevice] is mandatory.
*/
@Serializable
@SerialName("property.set")
public data class PropertySetMessage(
@ -50,6 +61,10 @@ public data class PropertySetMessage(
override val comment: String? = null,
) : DeviceMessage()
/**
* A command to request property value asynchronously. [targetDevice] is mandatory.
* The property value should be returned asynchronously via [PropertyChangedMessage].
*/
@Serializable
@SerialName("property.get")
public data class PropertyGetMessage(
@ -60,7 +75,7 @@ public data class PropertyGetMessage(
) : DeviceMessage()
/**
* Request device description
* Request device description. The result is returned in form of [DescriptionMessage]
*/
@Serializable
@SerialName("description.get")
@ -82,22 +97,28 @@ public data class DescriptionMessage(
override val comment: String? = null,
) : DeviceMessage()
/**
* A request to execute an action. [targetDevice] is mandatory
*/
@Serializable
@SerialName("action.execute")
public data class ActionExecuteMessage(
public val action: String,
public val argument: MetaItem<*>?,
override val sourceDevice: String? = null,
override val targetDevice: String? = null,
override val targetDevice: String,
override val comment: String? = null,
) : DeviceMessage()
/**
* Asynchronous action result. [sourceDevice] is mandatory
*/
@Serializable
@SerialName("action.result")
public data class ActionResultMessage(
public val action: String,
public val result: MetaItem<*>?,
override val sourceDevice: String? = null,
override val sourceDevice: String,
override val targetDevice: String? = null,
override val comment: String? = null,
) : DeviceMessage()
@ -148,7 +169,7 @@ public data class DeviceErrorMessage(
public val errorMessage: String?,
public val errorType: String? = null,
public val errorStackTrace: String? = null,
override val sourceDevice: String? = null,
override val sourceDevice: String,
override val targetDevice: String? = null,
override val comment: String? = null,
) : DeviceMessage()

View File

@ -22,6 +22,7 @@ import kotlin.time.Duration
class PiMotionMasterDevice(
context: Context,
override val deviceName: String = "PiMotionMaster",
private val portFactory: PortFactory = KtorTcpPort,
) : DeviceBase(context), DeviceHub {