Updates to control using coroutines

This commit is contained in:
Alexander Nozik 2018-04-01 11:05:39 +03:00
parent 30f1805513
commit 5ada5e76bc
12 changed files with 100 additions and 151 deletions

View File

@ -21,7 +21,6 @@ import hep.dataforge.context.Context
import hep.dataforge.control.collectors.RegularPointCollector import hep.dataforge.control.collectors.RegularPointCollector
import hep.dataforge.control.connections.Roles import hep.dataforge.control.connections.Roles
import hep.dataforge.control.devices.PortSensor import hep.dataforge.control.devices.PortSensor
import hep.dataforge.control.devices.stringState
import hep.dataforge.control.ports.GenericPortController import hep.dataforge.control.ports.GenericPortController
import hep.dataforge.control.ports.Port import hep.dataforge.control.ports.Port
import hep.dataforge.control.ports.PortFactory import hep.dataforge.control.ports.PortFactory
@ -30,6 +29,7 @@ import hep.dataforge.exceptions.ControlException
import hep.dataforge.exceptions.StorageException import hep.dataforge.exceptions.StorageException
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.states.StateDef import hep.dataforge.states.StateDef
import hep.dataforge.states.valueState
import hep.dataforge.storage.api.TableLoader import hep.dataforge.storage.api.TableLoader
import hep.dataforge.storage.commons.LoaderFactory import hep.dataforge.storage.commons.LoaderFactory
import hep.dataforge.storage.commons.StorageConnection import hep.dataforge.storage.commons.StorageConnection
@ -79,11 +79,11 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor(context, meta) {
tableFormatBuilder.build() tableFormatBuilder.build()
} }
val sps: String by stringState(SPS) val sps: String by valueState(SPS).string
val pga: String by stringState(PGA) val pga: String by valueState(PGA).string
val abuf: String by stringState(ABUF) val abuf: String by valueState(ABUF).string
private val duration = Duration.parse(meta.getString("averagingDuration", "PT30S")) private val duration = Duration.parse(meta.getString("averagingDuration", "PT30S"))
@ -225,7 +225,7 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor(context, meta) {
} }
private val collector = RegularPointCollector(duration) { private val collector = RegularPointCollector(duration) {
notifyResult(produceResult(it)) notifyResult(it)
storageHelper?.push(it) storageHelper?.push(it)
} }
@ -245,7 +245,7 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor(context, meta) {
} }
} }
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) { override fun startMeasurement(oldMeta: Meta?, newMeta: Meta) {
if (oldMeta != null) { if (oldMeta != null) {
stopMeasurement() stopMeasurement()
} }
@ -257,7 +257,7 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor(context, meta) {
logger.info("Starting measurement") logger.info("Starting measurement")
connection?.also { connection.also {
it.onPhrase("[Ss]topped\\s*", this) { it.onPhrase("[Ss]topped\\s*", this) {
notifyMeasurementState(MeasurementState.STOPPED) notifyMeasurementState(MeasurementState.STOPPED)
} }
@ -289,8 +289,8 @@ class PKT8Device(context: Context, meta: Meta) : PortSensor(context, meta) {
} catch (ex: Exception) { } catch (ex: Exception) {
notifyError("Failed to stop measurement", ex) notifyError("Failed to stop measurement", ex)
} finally { } finally {
connection?.removeErrorListener(this) connection.removeErrorListener(this)
connection?.removePhraseListener(this) connection.removePhraseListener(this)
collector.stop() collector.stop()
logger.debug("Collector stopped") logger.debug("Collector stopped")
} }

View File

@ -22,8 +22,6 @@ import hep.dataforge.context.Context
import hep.dataforge.control.collectors.RegularPointCollector import hep.dataforge.control.collectors.RegularPointCollector
import hep.dataforge.control.connections.Roles import hep.dataforge.control.connections.Roles
import hep.dataforge.control.devices.PortSensor import hep.dataforge.control.devices.PortSensor
import hep.dataforge.control.devices.booleanState
import hep.dataforge.control.devices.doubleState
import hep.dataforge.control.ports.GenericPortController import hep.dataforge.control.ports.GenericPortController
import hep.dataforge.control.ports.Port import hep.dataforge.control.ports.Port
import hep.dataforge.control.ports.PortFactory import hep.dataforge.control.ports.PortFactory
@ -34,10 +32,10 @@ import hep.dataforge.exceptions.PortException
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.states.StateDef import hep.dataforge.states.StateDef
import hep.dataforge.states.StateDefs import hep.dataforge.states.StateDefs
import hep.dataforge.states.valueState
import hep.dataforge.storage.commons.StorageConnection import hep.dataforge.storage.commons.StorageConnection
import hep.dataforge.tables.TableFormatBuilder import hep.dataforge.tables.TableFormatBuilder
import hep.dataforge.tables.ValuesListener import hep.dataforge.tables.ValuesListener
import hep.dataforge.values.Value
import hep.dataforge.values.ValueType import hep.dataforge.values.ValueType
import inr.numass.control.DeviceView import inr.numass.control.DeviceView
import inr.numass.control.NumassStorageConnection import inr.numass.control.NumassStorageConnection
@ -64,20 +62,28 @@ class MspDevice(context: Context, meta: Meta) : PortSensor(context, meta) {
// private var measurementDelegate: Consumer<MspResponse>? = null // private var measurementDelegate: Consumer<MspResponse>? = null
val selected: Boolean by booleanState() val selected: Boolean by valueState("selected").boolean
var controlled: Boolean by booleanState() var controlled: Boolean by valueState("controlled") { _, value ->
control(value.booleanValue())
}.boolean
var filamentOn: Boolean by booleanState() var filament by valueState("filament") { old, value ->
selectFilament(value.intValue())
}
val peakJumpZero: Double by doubleState("peakJump.zero") var filamentOn: Boolean by valueState("filamentOn") { _, value ->
setFilamentOn(value.booleanValue())
}.boolean
var peakJumpZero: Double by valueState("peakJump.zero").double
private val averagingDuration: Duration = Duration.parse(meta.getString("averagingDuration", "PT30S")) private val averagingDuration: Duration = Duration.parse(meta.getString("averagingDuration", "PT30S"))
private var storageHelper: NumassStorageConnection? = null private var storageHelper: NumassStorageConnection? = null
private val collector = RegularPointCollector(averagingDuration) { res -> private val collector = RegularPointCollector(averagingDuration) { res ->
notifyResult(produceResult(res)) notifyResult(res)
forEachConnection(ValuesListener::class.java) { forEachConnection(ValuesListener::class.java) {
it.accept(res) it.accept(res)
} }
@ -109,27 +115,17 @@ class MspDevice(context: Context, meta: Meta) : PortSensor(context, meta) {
super.shutdown() super.shutdown()
} }
//TODO make actual request // //TODO make actual request
override fun computeState(stateName: String): Any = when (stateName) { // override fun computeState(stateName: String): Any = when (stateName) {
"controlled" -> false // "controlled" -> false
"filament" -> 1 // "filament" -> 1
"filamentOn" -> false//Always return false on first request // "filamentOn" -> false//Always return false on first request
"filamentStatus" -> "UNKNOWN" // "filamentStatus" -> "UNKNOWN"
else -> super.computeState(stateName) // else -> super.computeState(stateName)
} // }
override fun getType(): String = MSP_DEVICE_TYPE override fun getType(): String = MSP_DEVICE_TYPE
@Throws(ControlException::class)
override fun requestStateChange(stateName: String, value: Value) {
when (stateName) {
"controlled" -> control(value.booleanValue())
"filament" -> selectFilament(value.intValue())
"filamentOn" -> setFilamentOn(value.booleanValue())
else -> super.requestStateChange(stateName, value)
}
}
/** /**
* Startup MSP: get available sensors, select sensor and control. * Startup MSP: get available sensors, select sensor and control.
* *
@ -314,8 +310,8 @@ class MspDevice(context: Context, meta: Meta) : PortSensor(context, meta) {
} }
} }
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) { override fun startMeasurement(oldMeta: Meta?, newMeta: Meta) {
if(oldMeta!= null){ if (oldMeta != null) {
stopMeasurement() stopMeasurement()
} }
if (newMeta.getString("type", "peakJump") == "peakJump") { if (newMeta.getString("type", "peakJump") == "peakJump") {
@ -352,7 +348,7 @@ class MspDevice(context: Context, meta: Meta) : PortSensor(context, meta) {
throw ControlException("Can't create measurement for msp") throw ControlException("Can't create measurement for msp")
} }
storageHelper = NumassStorageConnection("msp"){builder.build()} storageHelper = NumassStorageConnection("msp") { builder.build() }
connect(storageHelper) connect(storageHelper)
connection.onAnyPhrase(this) { connection.onAnyPhrase(this) {
@ -400,7 +396,7 @@ class MspDevice(context: Context, meta: Meta) : PortSensor(context, meta) {
collector.stop() collector.stop()
val stop = commandAndWait("ScanStop").isOK val stop = commandAndWait("ScanStop").isOK
//Reset loaders in connections //Reset loaders in connections
storageHelper?.let { disconnect(it)} storageHelper?.let { disconnect(it) }
notifyMeasurementState(MeasurementState.STOPPED) notifyMeasurementState(MeasurementState.STOPPED)
} }

View File

@ -6,10 +6,11 @@ import hep.dataforge.control.devices.Device
import hep.dataforge.control.devices.DeviceListener import hep.dataforge.control.devices.DeviceListener
import hep.dataforge.control.devices.PortSensor import hep.dataforge.control.devices.PortSensor
import hep.dataforge.control.devices.Sensor import hep.dataforge.control.devices.Sensor
import hep.dataforge.exceptions.NameNotFoundException
import hep.dataforge.fx.bindWindow import hep.dataforge.fx.bindWindow
import hep.dataforge.meta.Meta import hep.dataforge.states.State
import hep.dataforge.states.ValueState
import hep.dataforge.values.Value import hep.dataforge.values.Value
import javafx.beans.binding.BooleanBinding
import javafx.beans.binding.ObjectBinding import javafx.beans.binding.ObjectBinding
import javafx.beans.property.BooleanProperty import javafx.beans.property.BooleanProperty
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
@ -48,8 +49,7 @@ fun Device.getDisplay(): DeviceDisplay<*> {
*/ */
abstract class DeviceDisplay<D : Device> : Component(), Connection, DeviceListener { abstract class DeviceDisplay<D : Device> : Component(), Connection, DeviceListener {
private val bindings = HashMap<String, ObjectBinding<Value>>() private val bindings = HashMap<String, ObjectBinding<*>>()
private val metaBindings = HashMap<String, ObjectBinding<Meta>>()
private val deviceProperty = SimpleObjectProperty<D>(this, "device", null) private val deviceProperty = SimpleObjectProperty<D>(this, "device", null)
val device: D by deviceProperty val device: D by deviceProperty
@ -81,76 +81,47 @@ abstract class DeviceDisplay<D : Device> : Component(), Connection, DeviceListen
abstract fun buildView(device: D): UIComponent?; abstract fun buildView(device: D): UIComponent?;
/** /**
* Get binding for a given device state * Create a binding for specific state and register it in update listener
* @param state
* *
* @return
*/ */
fun getStateBinding(state: String): ObjectBinding<Value> { private fun <T : Any> bindState(state: State<T>): ObjectBinding<T> {
return bindings.computeIfAbsent(state) { stateName -> val binding = object : ObjectBinding<T>() {
object : ObjectBinding<Value>() { override fun computeValue(): T {
override fun computeValue(): Value { return state.value
return if (isOpen) {
device.getState(stateName)
} else {
Value.NULL
}
}
} }
} }
bindings.putIfAbsent(state.name, binding)
return binding
} }
fun getMetaStateBinding(state: String): ObjectBinding<Meta> { fun getValueBinding(stateName: String): ObjectBinding<Value> {
return metaBindings.computeIfAbsent(state) { stateName -> val state: ValueState = device.states.filterIsInstance(ValueState::class.java).find { it.name == stateName }
object : ObjectBinding<Meta>() { ?: throw NameNotFoundException("State with name $stateName not found")
override fun computeValue(): Meta { return bindState(state)
return if (isOpen) {
device.getMetaState(stateName)
} else {
Meta.empty()
} }
}
}
}
}
fun getBooleanStateBinding(state: String): BooleanBinding =
getStateBinding(state).booleanBinding { it?.booleanValue() ?: false }
/** /**
* Bind existing boolean property to writable device state * Bind existing boolean property to writable device state
* @param state * @param state
* *
* @param property * @param property
*/ */
protected fun bindBooleanToState(state: String, property: BooleanProperty) { protected fun bindBooleanToState(state: String, property: BooleanProperty) {
getStateBinding(state).addListener { _, oldValue, newValue -> getValueBinding(state).addListener { _, oldValue, newValue ->
if (isOpen && oldValue !== newValue) { if (isOpen && oldValue != newValue) {
runLater { property.value = newValue.booleanValue() } runLater { property.value = newValue.booleanValue() }
} }
} }
property.addListener { _, oldValue, newValue -> property.addListener { _, oldValue, newValue ->
if (isOpen && oldValue != newValue) { if (isOpen && oldValue != newValue) {
runAsync { device.states[state] = newValue
if (!device.isInitialized) {
device.init()
}
device.setState(state, newValue)
}
} }
} }
} }
override fun notifyStateChanged(device: Device, name: String, state: Value) { override fun notifyStateChanged(device: Device, name: String, state: Any) {
bindings[name]?.invalidate() bindings[name]?.invalidate()
} }
override fun notifyMetaStateChanged(device: Device, name: String, state: Meta) {
metaBindings[name]?.invalidate()
}
open fun getBoardView(): Parent { open fun getBoardView(): Parent {
return HBox().apply { return HBox().apply {
alignment = Pos.CENTER_LEFT alignment = Pos.CENTER_LEFT

View File

@ -77,15 +77,13 @@ fun EventTarget.indicator(radius: Double = 10.0, op: (Indicator.() -> Unit) = {}
fun Indicator.bind(connection: DeviceDisplay<*>, state: String, transform: ((Value) -> Paint)? = null) { fun Indicator.bind(connection: DeviceDisplay<*>, state: String, transform: ((Value) -> Paint)? = null) {
tooltip(state) tooltip(state)
if (transform != null) { if (transform != null) {
bind(connection.getStateBinding(state), transform); bind(connection.getValueBinding(state), transform);
} else { } else {
bind(connection.getStateBinding(state)) { bind(connection.getValueBinding(state)) {
if (it.isNull) { when {
Color.GRAY it.isNull -> Color.GRAY
} else if (it.booleanValue()) { it.booleanValue() -> Color.GREEN
Color.GREEN; else -> Color.RED
} else {
Color.RED;
} }
} }
} }
@ -95,7 +93,7 @@ fun Indicator.bind(connection: DeviceDisplay<*>, state: String, transform: ((Val
* State name + indicator * State name + indicator
*/ */
fun EventTarget.deviceStateIndicator(connection: DeviceDisplay<*>, state: String, showName: Boolean = true, transform: ((Value) -> Paint)? = null) { fun EventTarget.deviceStateIndicator(connection: DeviceDisplay<*>, state: String, showName: Boolean = true, transform: ((Value) -> Paint)? = null) {
if (connection.device.hasState(state)) { if (connection.device.stateNames.contains(state)) {
if (showName) { if (showName) {
text("${state.toUpperCase()}: ") text("${state.toUpperCase()}: ")
} }
@ -112,16 +110,16 @@ fun EventTarget.deviceStateIndicator(connection: DeviceDisplay<*>, state: String
* A togglebutton + indicator for boolean state * A togglebutton + indicator for boolean state
*/ */
fun Node.deviceStateToggle(connection: DeviceDisplay<*>, state: String, title: String = state) { fun Node.deviceStateToggle(connection: DeviceDisplay<*>, state: String, title: String = state) {
if (connection.device.hasState(state)) { if (connection.device.stateNames.contains(state)) {
togglebutton(title) { togglebutton(title) {
isSelected = false isSelected = false
selectedProperty().addListener { _, oldValue, newValue -> selectedProperty().addListener { _, oldValue, newValue ->
if (oldValue != newValue) { if (oldValue != newValue) {
connection.device.setState(state, newValue) connection.device.states[state] = newValue
} }
} }
connection.getBooleanStateBinding(state).onChange { connection.getValueBinding(state).onChange {
isSelected = it isSelected = it?.booleanValue() ?: false
} }
} }
deviceStateIndicator(connection, state, false) deviceStateIndicator(connection, state, false)

View File

@ -20,7 +20,7 @@ class NumassStorageConnection(private val loaderName: String? = null, private va
@Synchronized @Synchronized
override fun accept(point: Values) { override fun accept(point: Values) {
if (device.optBooleanState("storing").nullable == true) { if (device.states.optBoolean("storing").nullable == true) {
val format = formatBuilder(device) val format = formatBuilder(device)
val suffix = DateTimeUtils.fileSuffix() val suffix = DateTimeUtils.fileSuffix()
val loaderName = "${loaderName ?: device.name}_$suffix" val loaderName = "${loaderName ?: device.name}_$suffix"

View File

@ -16,7 +16,7 @@ class StorageHelper(private val device: AbstractDevice, private val loaderFactor
private val loaderMap = HashMap<StorageConnection, TableLoader>() private val loaderMap = HashMap<StorageConnection, TableLoader>()
fun push(point: Values) { fun push(point: Values) {
if (device.optBooleanState("storing").nullable == true) { if (device.states.optBoolean("storing").nullable == true) {
device.forEachConnection("storage", StorageConnection::class.java) { connection -> device.forEachConnection("storage", StorageConnection::class.java) { connection ->
try { try {
val pl = loaderMap.computeIfAbsent(connection, loaderFactory) val pl = loaderMap.computeIfAbsent(connection, loaderFactory)

View File

@ -32,8 +32,8 @@ class CM32Device(context: Context, meta: Meta) : PortSensor(context, meta) {
} }
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) { override fun startMeasurement(oldMeta: Meta?, newMeta: Meta) {
startMeasurement { measurement {
doMeasure() doMeasure()
} }
} }

View File

@ -7,7 +7,6 @@ package inr.numass.control.readvac
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.control.devices.PortSensor import hep.dataforge.control.devices.PortSensor
import hep.dataforge.control.devices.intState
import hep.dataforge.control.ports.GenericPortController import hep.dataforge.control.ports.GenericPortController
import hep.dataforge.control.ports.Port import hep.dataforge.control.ports.Port
import hep.dataforge.control.ports.PortFactory import hep.dataforge.control.ports.PortFactory
@ -37,8 +36,8 @@ class MKSBaratronDevice(context: Context, meta: Meta) : PortSensor(context, meta
return GenericPortController(context, port) { it.endsWith("\r") } return GenericPortController(context, port) { it.endsWith("\r") }
} }
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) { override fun startMeasurement(oldMeta: Meta?, newMeta: Meta) {
startMeasurement { measurement {
doMeasure() doMeasure()
} }
} }

View File

@ -7,7 +7,6 @@ package inr.numass.control.readvac
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.control.devices.PortSensor import hep.dataforge.control.devices.PortSensor
import hep.dataforge.control.devices.booleanState
import hep.dataforge.control.ports.GenericPortController import hep.dataforge.control.ports.GenericPortController
import hep.dataforge.control.ports.Port import hep.dataforge.control.ports.Port
import hep.dataforge.control.ports.PortFactory import hep.dataforge.control.ports.PortFactory
@ -17,7 +16,7 @@ import hep.dataforge.exceptions.ControlException
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.states.StateDef import hep.dataforge.states.StateDef
import hep.dataforge.states.StateDefs import hep.dataforge.states.StateDefs
import hep.dataforge.values.Value import hep.dataforge.states.valueState
import hep.dataforge.values.ValueType.BOOLEAN import hep.dataforge.values.ValueType.BOOLEAN
import inr.numass.control.DeviceView import inr.numass.control.DeviceView
import java.lang.Double.parseDouble import java.lang.Double.parseDouble
@ -40,7 +39,11 @@ class MKSVacDevice(context: Context, meta: Meta) : PortSensor(context, meta) {
private val deviceAddress: String = meta.getString("address", "253") private val deviceAddress: String = meta.getString("address", "253")
var power: Boolean by booleanState("power") var power by valueState("power", getter = { talk("FP?") == "ON" }) { old, value ->
if (old != value) {
setPowerOn(value.booleanValue())
}
}.boolean
@Throws(ControlException::class) @Throws(ControlException::class)
@ -61,25 +64,11 @@ class MKSVacDevice(context: Context, meta: Meta) : PortSensor(context, meta) {
return GenericPortController(context, port) { it.endsWith(";FF") } return GenericPortController(context, port) { it.endsWith(";FF") }
} }
@Throws(ControlException::class)
override fun computeState(stateName: String): Any = when (stateName) {
"power" -> talk("FP?") == "ON"
else -> super.computeState(stateName)
}
@Throws(ControlException::class)
override fun requestStateChange(stateName: String, value: Value) {
when (stateName) {
"power" -> setPowerOn(value.booleanValue())
else -> super.requestStateChange(stateName, value)
}
}
@Throws(ControlException::class) @Throws(ControlException::class)
override fun shutdown() { override fun shutdown() {
if (connected) { if (connected) {
setState("power", false) power = false
} }
super.shutdown() super.shutdown()
} }
@ -110,27 +99,24 @@ class MKSVacDevice(context: Context, meta: Meta) : PortSensor(context, meta) {
override fun getType(): String = meta.getString("type", "numass.vac.mks") override fun getType(): String = meta.getString("type", "numass.vac.mks")
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) { override fun startMeasurement(oldMeta: Meta?, newMeta: Meta) {
startMeasurement { measurement {
doMeasure()
}
}
private fun doMeasure(): Meta {
// if (getState("power").booleanValue()) { // if (getState("power").booleanValue()) {
val channel = meta.getInt("channel", 5) val channel = meta.getInt("channel", 5)
val answer = talk("PR$channel?") val answer = talk("PR$channel?")
if (answer == null || answer.isEmpty()) { if (answer == null || answer.isEmpty()) {
updateState(PortSensor.CONNECTED_STATE, false) updateState(PortSensor.CONNECTED_STATE, false)
return produceError("No connection") notifyError("No connection")
} }
val res = parseDouble(answer) val res = parseDouble(answer)
return if (res <= 0) { if (res <= 0) {
updateState("power", false) updateState("power", false)
produceError("No power") notifyError("No power")
} else { } else {
this.updateMessage("OK") message = "OK"
produceResult(res) notifyResult(res)
} }
} }
}
} }

View File

@ -7,7 +7,6 @@ package inr.numass.control.readvac
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.control.devices.PortSensor import hep.dataforge.control.devices.PortSensor
import hep.dataforge.control.devices.intState
import hep.dataforge.control.ports.GenericPortController import hep.dataforge.control.ports.GenericPortController
import hep.dataforge.control.ports.Port import hep.dataforge.control.ports.Port
import hep.dataforge.control.ports.PortFactory import hep.dataforge.control.ports.PortFactory
@ -39,8 +38,8 @@ class MeradatVacDevice(context: Context, meta: Meta) : PortSensor(context, meta)
return meta.getString("type", "numass.vac.vit") return meta.getString("type", "numass.vac.vit")
} }
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) { override fun startMeasurement(oldMeta: Meta?, newMeta: Meta) {
startMeasurement{ measurement{
doMeasure() doMeasure()
} }
} }

View File

@ -124,7 +124,7 @@ class VacCollectorDevice(context: Context, meta: Meta, val sensors: Collection<S
} }
} }
override fun setMeasurement(oldMeta: Meta?, newMeta: Meta) { override fun startMeasurement(oldMeta: Meta?, newMeta: Meta) {
oldMeta?.let { oldMeta?.let {
stopMeasurement() stopMeasurement()
} }

View File

@ -114,8 +114,8 @@ val deviceInterceptor = InterceptorFactory { context, meta ->
add("type", device.type) add("type", device.type)
add("getMeta", device.meta.asJson()) add("getMeta", device.meta.asJson())
add("state", jsonObject { add("state", jsonObject {
for (state in device.listStates()) { device.states.forEach {
add(state, device.getState(state).toString()) add(it.name,it.toString())
} }
}) })
} }