Updating control

This commit is contained in:
Alexander Nozik 2018-04-06 10:02:28 +03:00
parent 68fa5c715b
commit 794929890a
6 changed files with 145 additions and 147 deletions

View File

@ -12,14 +12,20 @@ import hep.dataforge.meta.Meta
import hep.dataforge.names.Name
import hep.dataforge.states.StateDef
import hep.dataforge.values.ValueType
import inr.numass.control.DeviceDisplayFX
import inr.numass.control.DeviceView
import inr.numass.control.getDisplay
import javafx.scene.Parent
import tornadofx.*
import java.util.*
import java.util.stream.Stream
import kotlin.collections.ArrayList
@StateDef(value = ValueDef(name = "address", type = arrayOf(ValueType.NUMBER), info = "Current active magnet"))
@DeviceView(LambdaHubDisplay::class)
class LambdaHub(context: Context, meta: Meta) : DeviceHub, AbstractDevice(context, meta) {
private val magnets = ArrayList<LambdaMagnet>();
val magnets = ArrayList<LambdaMagnet>();
private val port: Port = buildPort()
private val controller = LambdaPortController(context, port)
@ -61,3 +67,16 @@ class LambdaHub(context: Context, meta: Meta) : DeviceHub, AbstractDevice(contex
override val deviceNames: Stream<Name>
get() = magnets.stream().map { Name.ofSingle(it.name) }
}
class LambdaHubDisplay: DeviceDisplayFX<LambdaHub>() {
override fun buildView(device: LambdaHub): UIComponent? {
return object: View() {
override val root: Parent = vbox {
device.magnets.forEach {
this.add(it.getDisplay().view!!)
}
}
}
}
}

View File

@ -29,6 +29,8 @@ import hep.dataforge.states.StateDefs
import hep.dataforge.states.valueState
import hep.dataforge.utils.DateTimeUtils
import hep.dataforge.values.ValueType.*
import inr.numass.control.DeviceView
import inr.numass.control.magnet.fx.MagnetDisplay
import kotlinx.coroutines.experimental.runBlocking
import java.time.Instant
import java.time.temporal.ChronoUnit
@ -50,8 +52,9 @@ import java.util.concurrent.TimeUnit
StateDef(value = ValueDef(name = "updating", type = arrayOf(BOOLEAN), def = "false", info = "Shows if current ramping in progress"), writable = true),
StateDef(value = ValueDef(name = "monitoring", type = arrayOf(BOOLEAN), def = "false", info = "Shows if monitoring task is running"), writable = true),
StateDef(value = ValueDef(name = "speed", type = arrayOf(NUMBER), info = "Current change speed in Ampere per minute"), writable = true),
StateDef(ValueDef(name = "state", type = [STRING], def = "INIT", enumeration = LambdaMagnet.MagnetState::class, info = "Current state of magnet operation"))
StateDef(ValueDef(name = "status", type = [STRING], def = "INIT", enumeration = LambdaMagnet.MagnetStatus::class, info = "Current state of magnet operation"))
)
@DeviceView(MagnetDisplay::class)
class LambdaMagnet(private val controller: LambdaPortController, meta: Meta) : AbstractDevice(controller.context, meta) {
private var closePortOnShutDown = false
@ -100,7 +103,7 @@ class LambdaMagnet(private val controller: LambdaPortController, meta: Meta) : A
val output = valueState("output", getter = { controller.talk(address, "OUT?") == "OK" }) { _, value ->
setOutputMode(value.booleanValue())
if (!value.booleanValue()) {
state = MagnetState.OFF
status = MagnetStatus.OFF
}
}
@ -134,7 +137,7 @@ class LambdaMagnet(private val controller: LambdaPortController, meta: Meta) : A
var speed by valueState("speed").doubleDelegate
var state by valueState("state").enumDelegate<MagnetState>()
var status by valueState("status").enumDelegate<MagnetStatus>()
private set
/**
@ -211,9 +214,9 @@ class LambdaMagnet(private val controller: LambdaPortController, meta: Meta) : A
val nextI = nextI(measuredI, targetI)
if (bound(nextI)) {
outCurrent = nextI
state = MagnetState.OK
status = MagnetStatus.OK
} else {
state = MagnetState.BOUND
status = MagnetStatus.BOUND
}
} else {
stopUpdateTask()
@ -313,7 +316,7 @@ class LambdaMagnet(private val controller: LambdaPortController, meta: Meta) : A
controller.bound = { i -> Math.abs(this.current.doubleValue - i) <= difference }
}
enum class MagnetState {
enum class MagnetStatus {
INIT, // no information
OFF, // Magnet output is off
OK, // Magnet ouput is on

View File

@ -20,13 +20,10 @@ import inr.numass.control.DeviceDisplayFX
import inr.numass.control.magnet.LambdaMagnet
import javafx.application.Platform
import javafx.beans.value.ObservableValue
import javafx.fxml.Initializable
import javafx.scene.control.*
import javafx.scene.layout.AnchorPane
import javafx.scene.paint.Color
import tornadofx.*
import java.net.URL
import java.util.*
/**
* FXML Controller class
@ -38,42 +35,34 @@ class MagnetDisplay : DeviceDisplayFX<LambdaMagnet>() {
return MagnetControllerComponent(device)
}
val current by lazy { valueBinding(device.voltage) }
val voltage by lazy { valueBinding(device.current) }
var target by device.target.doubleDelegate
var output by device.output.booleanDelegate
var monitoring by device.monitoring.booleanDelegate
var updating by device.updating.booleanDelegate
inner class MagnetControllerComponent(val device: LambdaMagnet) : Fragment(), Initializable {
inner class MagnetControllerComponent(val device: LambdaMagnet) : Fragment() {
override val root: AnchorPane by fxml("/fxml/SingleMagnet.fxml")
private var showConfirmation = true
var showConfirmation = true
val labelI: Label by fxml()
val labelU: Label by fxml()
val targetIField: TextField by fxml()
val magnetName: Label by fxml()
val monitorButton: ToggleButton by fxml()
val statusLabel: Label by fxml()
val setButton: ToggleButton by fxml()
val magnetSpeedField: TextField by fxml()
/**
* Initializes the controller class.
*
* @param url
* @param rb
*/
override fun initialize(url: URL, rb: ResourceBundle) {
val current = valueBinding(device.voltage)
val voltage = valueBinding(device.current)
var target by device.target.doubleDelegate
var output by device.output.booleanDelegate
var monitoring by device.monitoring.booleanDelegate
var updating by device.updating.booleanDelegate
//TODO add status
val labelI: Label by fxid()
val labelU: Label by fxid()
val targetIField: TextField by fxid()
val magnetName: Label by fxid()
val monitorButton: ToggleButton by fxid()
val statusLabel: Label by fxid()
val setButton: ToggleButton by fxid()
val magnetSpeedField: TextField by fxid()
init{
targetIField.textProperty().addListener { observable: ObservableValue<out String>, oldValue: String, newValue: String ->
if (!newValue.matches("\\d*(\\.)?\\d*".toRegex())) {
targetIField.text = oldValue
@ -129,7 +118,7 @@ class MagnetDisplay : DeviceDisplayFX<LambdaMagnet>() {
setButton.selectedProperty().onChange {
try {
setOutput(it)
setOutputOn(it)
} catch (ex: PortException) {
displayError(this.device.name, null, ex)
}
@ -145,12 +134,10 @@ class MagnetDisplay : DeviceDisplayFX<LambdaMagnet>() {
}
}
fun setShowConfirmation(showConfirmation: Boolean) {
this.showConfirmation = showConfirmation
}
@Throws(PortException::class)
private fun setOutput(outputOn: Boolean) {
private fun setOutputOn(outputOn: Boolean) {
if (outputOn) {
if (showConfirmation) {
val alert = Alert(Alert.AlertType.WARNING)

View File

@ -16,110 +16,98 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<?import javafx.scene.text.*?>
<?import javafx.scene.shape.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<fx:root id="SingleMagnetPanel" minHeight="-Infinity" minWidth="-Infinity" prefHeight="175.0" prefWidth="280.0" type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<VBox prefHeight="175.0" prefWidth="270.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<?import javafx.scene.text.*?>
<AnchorPane id="SingleMagnetPanel" minHeight="-Infinity" minWidth="-Infinity" prefHeight="175.0" prefWidth="280.0"
xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<VBox prefHeight="175.0" prefWidth="270.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<padding>
<Insets bottom="1.0" left="1.0" right="1.0" top="1.0"/>
</padding>
<HBox alignment="CENTER" style="-fx-background-color: LIGHTGREEN;">
<children>
<Label fx:id="magnetName" alignment="CENTER" contentDisplay="CENTER" layoutX="74.0" prefHeight="28.0" prefWidth="167.0" text="Name">
<Label fx:id="magnetName" alignment="CENTER" contentDisplay="CENTER" layoutX="74.0" prefHeight="28.0"
prefWidth="167.0" text="Name">
<font>
<Font name="System Bold" size="18.0" />
<Font name="System Bold" size="18.0"/>
</font>
</Label>
</children>
</HBox>
<Separator prefWidth="200.0" />
<Separator prefWidth="200.0"/>
<Pane prefHeight="35.0" prefWidth="250.0">
<children>
<Label layoutX="14.0" layoutY="8.0" text="Status:">
<font>
<Font size="14.0" />
<Font size="14.0"/>
</font>
</Label>
<Label fx:id="statusLabel" alignment="CENTER" layoutX="67.0" layoutY="4.0" prefHeight="27.0" prefWidth="80.0" text="INIT" textFill="GRAY">
<Label fx:id="statusLabel" alignment="CENTER" layoutX="67.0" layoutY="4.0" prefHeight="27.0"
prefWidth="80.0" text="INIT" textFill="GRAY">
<font>
<Font name="System Bold" size="18.0" />
<Font name="System Bold" size="18.0"/>
</font>
</Label>
<TextField fx:id="magnetSpeedField" layoutX="173.0" layoutY="4.0" prefHeight="26.0" prefWidth="49.0" />
<Label layoutX="230.0" layoutY="9.0" text="A/min" />
</children>
<TextField fx:id="magnetSpeedField" layoutX="173.0" layoutY="4.0" prefHeight="26.0" prefWidth="49.0"/>
<Label layoutX="230.0" layoutY="9.0" text="A/min"/>
</Pane>
<Separator prefWidth="200.0" />
<Separator prefWidth="200.0"/>
<HBox prefHeight="50.0" prefWidth="250.0">
<children>
<Pane prefHeight="50.0" prefWidth="135.0" style="-fx-border-color: RED; -fx-border-radius: 6;">
<children>
<HBox.margin>
<Insets/>
</HBox.margin>
<Label layoutX="14.0" layoutY="13.0" text="I">
<font>
<Font name="System Bold" size="16.0" />
<Font name="System Bold" size="16.0"/>
</font>
</Label>
<Label fx:id="labelI" alignment="CENTER_RIGHT" layoutX="40.0" layoutY="13.0" prefHeight="25.0" prefWidth="80.0" text="?" textFill="RED">
<Label fx:id="labelI" alignment="CENTER_RIGHT" layoutX="40.0" layoutY="13.0" prefHeight="25.0"
prefWidth="80.0" text="?" textFill="RED">
<font>
<Font name="System Bold" size="16.0" />
<Font name="System Bold" size="16.0"/>
</font>
</Label>
</children>
<HBox.margin>
<Insets />
</HBox.margin>
</Pane>
<Separator orientation="VERTICAL" prefHeight="200.0">
<padding>
<Insets right="1.0" />
<Insets right="1.0"/>
</padding>
</Separator>
<Pane layoutX="10.0" layoutY="10.0" prefHeight="50.0" prefWidth="135.0" style="-fx-border-color: BLUE; -fx-border-radius: 6;">
<children>
<Pane layoutX="10.0" layoutY="10.0" prefHeight="50.0" prefWidth="135.0"
style="-fx-border-color: BLUE; -fx-border-radius: 6;">
<HBox.margin>
<Insets/>
</HBox.margin>
<Label layoutX="14.0" layoutY="13.0" text="U">
<font>
<Font name="System Bold" size="16.0" />
<Font name="System Bold" size="16.0"/>
</font>
</Label>
<Label fx:id="labelU" alignment="CENTER_RIGHT" layoutX="40.0" layoutY="13.0" prefHeight="25.0" prefWidth="80.0" text="?" textAlignment="JUSTIFY" textFill="BLUE">
<Label fx:id="labelU" alignment="CENTER_RIGHT" layoutX="40.0" layoutY="13.0" prefHeight="25.0"
prefWidth="80.0" text="?" textAlignment="JUSTIFY" textFill="BLUE">
<font>
<Font name="System Bold" size="16.0" />
<Font name="System Bold" size="16.0"/>
</font>
</Label>
</children>
<HBox.margin>
<Insets />
</HBox.margin>
</Pane>
</children>
</HBox>
<Separator prefWidth="200.0" />
<Separator prefWidth="200.0"/>
<Pane prefHeight="50.0" prefWidth="250.0" style="-fx-border-color: GREEN; -fx-border-radius: 6;">
<children>
<VBox.margin>
<Insets/>
</VBox.margin>
<Label layoutX="9.0" layoutY="15.0" text="I target">
<font>
<Font name="System Bold" size="16.0" />
<Font name="System Bold" size="16.0"/>
</font>
</Label>
<TextField fx:id="targetIField" layoutX="83.0" layoutY="13.0" prefHeight="25.0" prefWidth="55.0" text="0.0" />
<ToggleButton fx:id="setButton" layoutX="160.0" layoutY="13.0" mnemonicParsing="false" onAction="#onOutToggle" text="Set" />
<ToggleButton fx:id="monitorButton" contentDisplay="RIGHT" layoutX="199.0" layoutY="13.0" mnemonicParsing="false" onAction="#onMonitorToggle" prefHeight="26.0" prefWidth="70.0" text="Monitor" />
</children>
<VBox.margin>
<Insets />
</VBox.margin>
<TextField fx:id="targetIField" layoutX="83.0" layoutY="13.0" prefHeight="25.0" prefWidth="55.0"
text="0.0"/>
<ToggleButton fx:id="setButton" layoutX="160.0" layoutY="13.0" mnemonicParsing="false" text="Set"/>
<ToggleButton fx:id="monitorButton" contentDisplay="RIGHT" layoutX="199.0" layoutY="13.0"
mnemonicParsing="false" prefHeight="26.0" prefWidth="70.0" text="Monitor"/>
</Pane>
<Separator prefWidth="250.0" />
</children>
<padding>
<Insets bottom="1.0" left="1.0" right="1.0" top="1.0" />
</padding>
<Separator prefWidth="250.0"/>
</VBox>
</children>
</fx:root>
</AnchorPane>

View File

@ -72,6 +72,7 @@ abstract class NumassControlApplication<in D : Device> : App() {
try {
device?.shutdown()
} catch (ex: Exception) {
device?.context?.close()
LoggerFactory.getLogger(javaClass).error("Failed to shutdown application", ex);
} finally {
super.stop()

View File

@ -22,7 +22,7 @@ import java.nio.file.Paths
/**
* Created by darksnake on 08-May-17.
*/
val DEFAULT_CONFIG_LOCATION = "./numass-control.xml"
const val DEFAULT_CONFIG_LOCATION = "./numass-control.xml"
//val STORING_STATE = "storing"
//val dfIcon: Image = Image(Global::class.java.getResourceAsStream("/img/df.png"))