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 * A hub that could locate multiple devices and redirect actions to them
*/ */
public interface DeviceHub : Provider { public interface DeviceHub : Provider {
public val deviceName: String
public val devices: Map<NameToken, Device> public val devices: Map<NameToken, Device>
override val defaultTarget: String get() = Device.DEVICE_TARGET 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<*>) -> private val propertyChanges = device.propertyFlow.map { (propertyName: String, value: MetaItem<*>) ->
PropertyChangedMessage( PropertyChangedMessage(
sourceDevice = deviceName, sourceDevice = deviceName,
key = propertyName, property = propertyName,
value = value, value = value,
) )
} }
@ -69,7 +69,7 @@ public class DeviceController(
when (request) { when (request) {
is PropertyGetMessage -> { is PropertyGetMessage -> {
PropertyChangedMessage( PropertyChangedMessage(
key = request.property, property = request.property,
value = device.getProperty(request.property), value = device.getProperty(request.property),
sourceDevice = deviceTarget, sourceDevice = deviceTarget,
targetDevice = request.sourceDevice targetDevice = request.sourceDevice
@ -83,7 +83,7 @@ public class DeviceController(
device.setProperty(request.property, request.value) device.setProperty(request.property, request.value)
} }
PropertyChangedMessage( PropertyChangedMessage(
key = request.property, property = request.property,
value = device.getProperty(request.property), value = device.getProperty(request.property),
sourceDevice = deviceTarget, sourceDevice = deviceTarget,
targetDevice = request.sourceDevice 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") val device = this[targetName] ?: error("The device with name $targetName not found in $this")
DeviceController.respondMessage(device, targetName.toString(), request) DeviceController.respondMessage(device, targetName.toString(), request)
} catch (ex: Exception) { } 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.control.api.DeviceHub
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.get
import hep.dataforge.meta.string
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.NameToken import hep.dataforge.names.NameToken
import kotlin.properties.ReadOnlyProperty import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass 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 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 tag: PluginTag = PluginTag("devices", group = PluginTag.DATAFORGE_GROUP)
override val type: KClass<out DeviceManager> = DeviceManager::class 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") val device = hub[targetName] ?: error("The device with name $targetName not found in $hub")
DeviceController.respondMessage(device, targetName.toString(), message) DeviceController.respondMessage(device, targetName.toString(), message)
} catch (ex: Exception) { } 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 { // override suspend fun respond(request: Envelope): Envelope = try {

View File

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

View File

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