diff --git a/numass-control/msp/src/main/java/inr/numass/control/msp/MspDevice.java b/numass-control/msp/src/main/java/inr/numass/control/msp/MspDevice.java index 33cb2119..6e91ddd5 100644 --- a/numass-control/msp/src/main/java/inr/numass/control/msp/MspDevice.java +++ b/numass-control/msp/src/main/java/inr/numass/control/msp/MspDevice.java @@ -139,7 +139,7 @@ public class MspDevice extends Sensor implements PortHandler.PortControl } @Override - public String type() { + public String getType() { return "MKS E-Vision"; } diff --git a/numass-control/vac/src/main/java/inr/numass/control/readvac/CM32Device.java b/numass-control/vac/src/main/java/inr/numass/control/readvac/CM32Device.java index 107c8a94..2d1939e4 100644 --- a/numass-control/vac/src/main/java/inr/numass/control/readvac/CM32Device.java +++ b/numass-control/vac/src/main/java/inr/numass/control/readvac/CM32Device.java @@ -47,7 +47,7 @@ public class CM32Device extends PortSensor { } @Override - public String type() { + public String getType() { return meta().getString("type", "Leibold CM32"); } @@ -61,19 +61,19 @@ public class CM32Device extends PortSensor { String answer = sendAndWait(CM32_QUERY, timeout()); if (answer.isEmpty()) { - this.progressUpdate("No signal"); + this.updateMessage("No signal"); updateState(CONNECTED_STATE, false); return null; } else if (!answer.contains("PM1:mbar")) { - this.progressUpdate("Wrong answer: " + answer); + this.updateMessage("Wrong answer: " + answer); updateState(CONNECTED_STATE, false); return null; } else if (answer.substring(14, 17).equals("OFF")) { - this.progressUpdate("Off"); + this.updateMessage("Off"); updateState(CONNECTED_STATE, true); return null; } else { - this.progressUpdate("OK"); + this.updateMessage("OK"); updateState(CONNECTED_STATE, true); return Double.parseDouble(answer.substring(14, 17) + answer.substring(19, 23)); } diff --git a/numass-control/vac/src/main/java/inr/numass/control/readvac/MKSBaratronDevice.java b/numass-control/vac/src/main/java/inr/numass/control/readvac/MKSBaratronDevice.java index 304bbc41..01613efd 100644 --- a/numass-control/vac/src/main/java/inr/numass/control/readvac/MKSBaratronDevice.java +++ b/numass-control/vac/src/main/java/inr/numass/control/readvac/MKSBaratronDevice.java @@ -36,7 +36,7 @@ public class MKSBaratronDevice extends PortSensor { } @Override - public String type() { + public String getType() { return meta().getString("type", "MKS baratron"); } @@ -64,18 +64,18 @@ public class MKSBaratronDevice extends PortSensor { if (answer == null || answer.isEmpty()) { // invalidateState("connection"); updateState(CONNECTED_STATE, false); - this.progressUpdate("No connection"); + this.updateMessage("No connection"); return null; } else { updateState(CONNECTED_STATE, true); } double res = Double.parseDouble(answer); if (res <= 0) { - this.progressUpdate("Non positive"); + this.updateMessage("Non positive"); // invalidateState("power"); return null; } else { - this.progressUpdate("OK"); + this.updateMessage("OK"); return res; } } diff --git a/numass-control/vac/src/main/java/inr/numass/control/readvac/MKSVacDevice.java b/numass-control/vac/src/main/java/inr/numass/control/readvac/MKSVacDevice.java index affa5189..274ede98 100644 --- a/numass-control/vac/src/main/java/inr/numass/control/readvac/MKSVacDevice.java +++ b/numass-control/vac/src/main/java/inr/numass/control/readvac/MKSVacDevice.java @@ -138,7 +138,7 @@ public class MKSVacDevice extends PortSensor { } @Override - public String type() { + public String getType() { return meta().getString("type", "MKS vacuumeter"); } @@ -154,16 +154,16 @@ public class MKSVacDevice extends PortSensor { String answer = talk("PR" + getChannel() + "?"); if (answer == null || answer.isEmpty()) { updateState(CONNECTED_STATE, false); - this.progressUpdate("No connection"); + this.updateMessage("No connection"); return null; } double res = Double.parseDouble(answer); if (res <= 0) { - this.progressUpdate("No power"); + this.updateMessage("No power"); invalidateState("power"); return null; } else { - this.progressUpdate("OK"); + this.updateMessage("OK"); return res; } } diff --git a/numass-control/vac/src/main/java/inr/numass/control/readvac/MeradatVacDevice.java b/numass-control/vac/src/main/java/inr/numass/control/readvac/MeradatVacDevice.java index 900dede5..fabfb73c 100644 --- a/numass-control/vac/src/main/java/inr/numass/control/readvac/MeradatVacDevice.java +++ b/numass-control/vac/src/main/java/inr/numass/control/readvac/MeradatVacDevice.java @@ -51,7 +51,7 @@ public class MeradatVacDevice extends PortSensor { } @Override - public String type() { + public String getType() { return meta().getString("type", "Vit vacuumeter"); } @@ -93,7 +93,7 @@ public class MeradatVacDevice extends PortSensor { String answer = sendAndWait(query, timeout(), phrase -> phrase.startsWith(base)); if (answer.isEmpty()) { - this.progressUpdate("No signal"); + this.updateMessage("No signal"); updateState(CONNECTED_STATE, false); return null; } else { @@ -107,11 +107,11 @@ public class MeradatVacDevice extends PortSensor { } BigDecimal res = BigDecimal.valueOf(base * Math.pow(10, exp)); res = res.setScale(4, RoundingMode.CEILING); - this.progressUpdate("OK"); + this.updateMessage("OK"); updateState(CONNECTED_STATE, true); return res.doubleValue(); } else { - this.progressUpdate("Wrong answer: " + answer); + this.updateMessage("Wrong answer: " + answer); updateState(CONNECTED_STATE, false); return null; } diff --git a/numass-control/vac/src/main/java/inr/numass/control/readvac/VacCollectorDevice.java b/numass-control/vac/src/main/java/inr/numass/control/readvac/VacCollectorDevice.java index fed9c1de..306317fa 100644 --- a/numass-control/vac/src/main/java/inr/numass/control/readvac/VacCollectorDevice.java +++ b/numass-control/vac/src/main/java/inr/numass/control/readvac/VacCollectorDevice.java @@ -92,7 +92,7 @@ public class VacCollectorDevice extends Sensor { } @Override - public String type() { + public String getType() { return "Numass vacuum"; } diff --git a/numass-kserver/build.gradle b/numass-kserver/build.gradle index 900371e7..f06762f2 100644 --- a/numass-kserver/build.gradle +++ b/numass-kserver/build.gradle @@ -11,6 +11,7 @@ description = 'kodex/ktor based server' dependencies { compile "hep.dataforge:kodex-server" compile "hep.dataforge:dataforge-storage" + compile "hep.dataforge:dataforge-control" compile project(":numass-core") } diff --git a/numass-kserver/src/main/kotlin/inr/numass/server/Interceptors.kt b/numass-kserver/src/main/kotlin/inr/numass/server/Interceptors.kt index 23978564..0f6aa47e 100644 --- a/numass-kserver/src/main/kotlin/inr/numass/server/Interceptors.kt +++ b/numass-kserver/src/main/kotlin/inr/numass/server/Interceptors.kt @@ -1,7 +1,6 @@ package inr.numass.server -import hep.dataforge.context.Context -import hep.dataforge.meta.Meta +import hep.dataforge.control.DeviceManager import hep.dataforge.providers.Path import hep.dataforge.server.* import hep.dataforge.storage.api.TableLoader @@ -32,60 +31,99 @@ private suspend fun ApplicationCall.json(json: suspend JsonObjectBuilder.() -> U } } - -class StorageInterceptorBuilder : InterceptorBuilder { - override fun build(context: Context, meta: Meta): ServerInterceptor { - val storageManager = context.getFeature(StorageManager::class.java); - val storage = storageManager.buildStorage(meta); - return ServerInterceptor("storage") { - get("listStorage") { - val path = call.request.queryParameters["path"] ?: "" - val shelf = storage.optShelf(path) - if (shelf.isPresent) { - call.json { - val loaders = jsonArray(); - for (loader in StorageUtils.loaderStream(shelf.get())) { - loaders.add(jsonObject { - add("name", loader.name) - add("path", loader.path.toString()) - add("type", loader.type) - add("meta", loader.laminate.asJson()) - }) - } - add("loaders", loaders) +val storageInterceptor = InterceptorFactory { context, meta -> + val storageManager = context.getFeature(StorageManager::class.java); + val storage = storageManager.buildStorage(meta); + ServerInterceptor("storage") { + get("listStorage") { + val path = call.request.queryParameters["path"] ?: "" + val shelf = storage.optShelf(path) + if (shelf.isPresent) { + call.json { + val loaders = jsonArray(); + for (loader in StorageUtils.loaderStream(shelf.get())) { + loaders.add(jsonObject { + add("name", loader.name) + add("path", loader.path.toString()) + add("type", loader.type) + add("meta", loader.laminate.asJson()) + }) } - } else { - call.error("storage.shelfNotFound", "The shelf with path '$path' not found") + add("loaders", loaders) } + } else { + call.error("storage.shelfNotFound", "The shelf with path '$path' not found") } - get("getPlotData") { - val path = call.request.queryParameters["path"] - if (path == null) { - call.error("storage.missingParameter", "Missing request parameter 'path'") - } else { - val loaderObject = storage.provide(Path.of(path)) - if (loaderObject.isPresent) { - val loader = loaderObject.get(); - if (loader is TableLoader) { - val from = Value.of(call.request.queryParameters["from"] ?: "") - val to = Value.of(call.request.queryParameters["to"] ?: "") - val maxItems = (call.request.queryParameters.get("maxItems") ?: "1000").toInt() - call.json { - add("path", loader.path.toString()) - val data = jsonArray() - for (point in loader.index.pull(from, to, maxItems)) { - data.add(point.asJson()) - } + } + get("getPlotData") { + val path = call.request.queryParameters["path"] + if (path == null) { + call.error("storage.missingParameter", "Missing request parameter 'path'") + } else { + val loaderObject = storage.provide(Path.of(path)) + if (loaderObject.isPresent) { + val loader = loaderObject.get(); + if (loader is TableLoader) { + val from = Value.of(call.request.queryParameters["from"] ?: "") + val to = Value.of(call.request.queryParameters["to"] ?: "") + val maxItems = (call.request.queryParameters["maxItems"] ?: "1000").toInt() + call.json { + add("path", loader.path.toString()) + val data = jsonArray() + for (point in loader.index.pull(from, to, maxItems)) { + data.add(point.asJson()) } - } else { - call.error("storage.incorrectLoaderType", "Loader $path is not a TableLoader") } } else { - call.error("storage.loaderNotFound", "Can't find TableLoader with path = '$path'") + call.error("storage.incorrectLoaderType", "Loader $path is not a TableLoader") } + } else { + call.error("storage.loaderNotFound", "Can't find TableLoader with path = '$path'") } } } } +} + +val controlInterceptor = InterceptorFactory { context, meta -> + val deviceManager = context.getFeature(DeviceManager::class.java); + ServerInterceptor("devices") { + get("listDevices") { + call.json { + val devices = jsonArray(); + for (name in deviceManager.deviceNames()) { + val device = deviceManager.optDevice(name).get(); + devices.add(jsonObject { + add("name", name.toUnescaped()) + add("type", device.getType()) + add("meta", device.meta.asJson()) + }) + } + } + } + get("getDeviceState") { + val deviceName = call.request.queryParameters["name"] ?: ""; + if (deviceName.isEmpty()) { + call.error("devices.missingParameter", "Parameter 'name' is required") + } else { + val deviceOpt = deviceManager.optDevice(deviceName); + if (deviceOpt.isPresent) { + val device = deviceOpt.get(); + call.json { + add("name", deviceName) + add("type", device.type) + add("meta", device.meta.asJson()) + add("state", jsonObject { + for (state in device.listStates()) { + add(state, device.getState(state).toString()) + } + }) + } + } else { + call.error("devices.deviceNotFound", "Device with name: $deviceName not found in the system.") + } + } + } + } +} -} \ No newline at end of file diff --git a/numass-kserver/src/main/kotlin/inr/numass/server/KServerMain.kt b/numass-kserver/src/main/kotlin/inr/numass/server/KServerMain.kt new file mode 100644 index 00000000..0eafd9d0 --- /dev/null +++ b/numass-kserver/src/main/kotlin/inr/numass/server/KServerMain.kt @@ -0,0 +1,24 @@ +package inr.numass.server + +import hep.dataforge.context.Context +import hep.dataforge.context.Global +import hep.dataforge.control.DeviceManager +import hep.dataforge.meta.Meta +import hep.dataforge.server.KodexServer +import hep.dataforge.storage.commons.StorageManager + +fun main(args: Array) { + val meta = Meta.empty(); + val context = Context.build("SERVER", Global.instance(), meta) + val server = KodexServer(context, meta) + + context.optFeature(StorageManager::class.java).ifPresent{ + server.intercept(storageInterceptor) + } + + context.optFeature(DeviceManager::class.java).ifPresent{ + + } + + server.start() +} \ No newline at end of file