Allow changing the auto strategy

main
Clément FRÉVILLE 2 years ago
parent 659fb26862
commit 204d26a7e7

@ -14,7 +14,7 @@
<?import javafx.scene.control.TableColumn?> <?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TreeView?> <?import javafx.scene.control.TreeView?>
<?import javafx.scene.control.ChoiceBox?> <?import javafx.scene.control.ChoiceBox?>
<BorderPane xmlns:fx="http://javafx.com/fxml" prefHeight="400.0" prefWidth="600.0"> <BorderPane xmlns:fx="http://javafx.com/fxml" prefHeight="400.0" prefWidth="700.0">
<center> <center>
<SplitPane> <SplitPane>
<TreeView fx:id="sensorTree" /> <TreeView fx:id="sensorTree" />
@ -28,6 +28,9 @@
<left> <left>
<Button fx:id="changeBtn" onAction="#onChangeClick" visible="false">Change</Button> <Button fx:id="changeBtn" onAction="#onChangeClick" visible="false">Change</Button>
</left> </left>
<center>
<ChoiceBox fx:id="autoType" visible="false" />
</center>
<right> <right>
<Button fx:id="visualizeBtn" onAction="#onVisualizeClick">Visualize</Button> <Button fx:id="visualizeBtn" onAction="#onVisualizeClick">Visualize</Button>
</right> </right>

@ -11,15 +11,21 @@ import fr.uca.iut.clfreville2.gui.tree.SensorTreeCell;
import fr.uca.iut.clfreville2.gui.tree.SensorTreeItemBridge; import fr.uca.iut.clfreville2.gui.tree.SensorTreeItemBridge;
import fr.uca.iut.clfreville2.model.SensorRegistry; import fr.uca.iut.clfreville2.model.SensorRegistry;
import fr.uca.iut.clfreville2.model.binding.ToBooleanBinding; import fr.uca.iut.clfreville2.model.binding.ToBooleanBinding;
import fr.uca.iut.clfreville2.model.sensor.AutoSensor;
import fr.uca.iut.clfreville2.model.sensor.ManualSensor; import fr.uca.iut.clfreville2.model.sensor.ManualSensor;
import fr.uca.iut.clfreville2.model.sensor.Sensor; import fr.uca.iut.clfreville2.model.sensor.Sensor;
import fr.uca.iut.clfreville2.model.sensor.VirtualSensor; import fr.uca.iut.clfreville2.model.sensor.VirtualSensor;
import fr.uca.iut.clfreville2.model.sensor.auto.AutoUpdateStrategy;
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
import fr.uca.iut.clfreville2.model.sensor.auto.provider.StandardUpdateStrategyProvider;
import fr.uca.iut.clfreville2.model.sensor.provider.AutoSensorProvider; import fr.uca.iut.clfreville2.model.sensor.provider.AutoSensorProvider;
import fr.uca.iut.clfreville2.model.sensor.provider.ManualSensorProvider; import fr.uca.iut.clfreville2.model.sensor.provider.ManualSensorProvider;
import fr.uca.iut.clfreville2.model.sensor.provider.SensorProvider; import fr.uca.iut.clfreville2.model.sensor.provider.SensorProvider;
import fr.uca.iut.clfreville2.model.sensor.provider.VirtualSensorProvider; import fr.uca.iut.clfreville2.model.sensor.provider.VirtualSensorProvider;
import fr.uca.iut.clfreville2.persistence.StubSensorRegistryLoader; import fr.uca.iut.clfreville2.persistence.StubSensorRegistryLoader;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.Button; import javafx.scene.control.Button;
@ -57,6 +63,10 @@ public class MainWindows {
@FXML @FXML
private Button changeBtn; private Button changeBtn;
@FXML
private ChoiceBox<AutoUpdateStrategyProvider> autoType;
private final ChangeListener<AutoUpdateStrategy> autoUpdateChangeHandler = this::changedUpdateStrategy;
@FXML @FXML
private Button visualizeBtn; private Button visualizeBtn;
@ -150,10 +160,17 @@ public class MainWindows {
sensorName.textProperty().unbindBidirectional(oldValue.getValue().nameProperty()); sensorName.textProperty().unbindBidirectional(oldValue.getValue().nameProperty());
sourcesView.itemsProperty().unbind(); sourcesView.itemsProperty().unbind();
sourcesView.setItems(FXCollections.emptyObservableList()); sourcesView.setItems(FXCollections.emptyObservableList());
if (oldValue.getValue() instanceof AutoSensor auto) {
auto.updateStrategyProperty().removeListener(autoUpdateChangeHandler);
}
} }
if (newValue != null && newValue.getValue() != null) { if (newValue != null && newValue.getValue() != null) {
sensorId.textProperty().bind(newValue.getValue().displayNameExpression()); sensorId.textProperty().bind(newValue.getValue().displayNameExpression());
sensorName.textProperty().bindBidirectional(newValue.getValue().nameProperty()); sensorName.textProperty().bindBidirectional(newValue.getValue().nameProperty());
if (newValue.getValue() instanceof AutoSensor auto) {
auto.updateStrategyProperty().addListener(autoUpdateChangeHandler);
changedUpdateStrategy(null, null, auto.getUpdateStrategy());
}
if (newValue.getValue() instanceof VirtualSensor virtual) { if (newValue.getValue() instanceof VirtualSensor virtual) {
sourcesView.itemsProperty().bind(virtual.sourcesProperty()); sourcesView.itemsProperty().bind(virtual.sourcesProperty());
} }
@ -171,6 +188,10 @@ public class MainWindows {
treeItem -> treeItem != null && treeItem.getValue() instanceof ManualSensor treeItem -> treeItem != null && treeItem.getValue() instanceof ManualSensor
)); ));
visualizeBtn.visibleProperty().bind(sensorTree.getSelectionModel().selectedItemProperty().isNotNull()); visualizeBtn.visibleProperty().bind(sensorTree.getSelectionModel().selectedItemProperty().isNotNull());
autoType.visibleProperty().bind(new ToBooleanBinding<>(
sensorTree.getSelectionModel().selectedItemProperty(),
treeItem -> treeItem != null && treeItem.getValue() instanceof AutoSensor
));
} }
@FXML @FXML
@ -195,6 +216,16 @@ public class MainWindows {
@FXML @FXML
private void bindProvidable() { private void bindProvidable() {
autoType.getItems().addAll(StandardUpdateStrategyProvider.values());
autoType.setConverter(new NameableStringConverter<>(autoType.getItems()));
autoType.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
Sensor selected = getSelectedSensor();
if (!(selected instanceof AutoSensor sensor)) {
return;
}
sensor.setUpdateStrategy(newValue.create());
});
createType.getItems().addAll( createType.getItems().addAll(
new ManualSensorProvider(), new ManualSensorProvider(),
new AutoSensorProvider(), new AutoSensorProvider(),
@ -224,4 +255,8 @@ public class MainWindows {
} }
virtual.removeSource(source); virtual.removeSource(source);
} }
private void changedUpdateStrategy(ObservableValue<? extends AutoUpdateStrategy> ___, AutoUpdateStrategy o, AutoUpdateStrategy n) {
autoType.getSelectionModel().select(n.getType());
}
} }

@ -10,7 +10,7 @@ import javafx.beans.property.SimpleIntegerProperty;
public class Ticker extends Thread { public class Ticker extends Thread {
private final Tickable tickable; private final Tickable tickable;
private final IntegerProperty millisPerTick = new SimpleIntegerProperty(250); private final IntegerProperty millisPerTick = new SimpleIntegerProperty(500);
private final BooleanProperty running = new SimpleBooleanProperty(true); private final BooleanProperty running = new SimpleBooleanProperty(true);
public Ticker(Tickable tickable) { public Ticker(Tickable tickable) {

@ -2,9 +2,13 @@ package fr.uca.iut.clfreville2.model.sensor;
import fr.uca.iut.clfreville2.model.sensor.auto.AutoUpdateStrategy; import fr.uca.iut.clfreville2.model.sensor.auto.AutoUpdateStrategy;
import fr.uca.iut.clfreville2.model.shared.Tickable; import fr.uca.iut.clfreville2.model.shared.Tickable;
import javafx.beans.Observable;
import javafx.beans.property.DoubleProperty; import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyDoubleProperty; import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
@ -14,16 +18,16 @@ import static java.util.Objects.requireNonNull;
public class AutoSensor extends Sensor implements Tickable { public class AutoSensor extends Sensor implements Tickable {
private final DoubleProperty temperature = new SimpleDoubleProperty(); private final DoubleProperty temperature = new SimpleDoubleProperty();
private AutoUpdateStrategy updateStrategy; private final ObjectProperty<AutoUpdateStrategy> updateStrategy = new SimpleObjectProperty<>();
public AutoSensor(int id, String name, AutoUpdateStrategy updateStrategy) { public AutoSensor(int id, String name, AutoUpdateStrategy updateStrategy) {
super(id, name); super(id, name);
this.updateStrategy = requireNonNull(updateStrategy, "update strategy"); this.updateStrategy.set(requireNonNull(updateStrategy, "update strategy"));
} }
@Override @Override
public void tick() { public void tick() {
temperature.set(updateStrategy.nextValue(this)); temperature.set(updateStrategy.get().nextValue(this));
} }
@Override @Override
@ -32,10 +36,14 @@ public class AutoSensor extends Sensor implements Tickable {
} }
public AutoUpdateStrategy getUpdateStrategy() { public AutoUpdateStrategy getUpdateStrategy() {
return updateStrategy; return updateStrategy.get();
} }
public void setUpdateStrategy(AutoUpdateStrategy updateStrategy) { public void setUpdateStrategy(AutoUpdateStrategy updateStrategy) {
this.updateStrategy = requireNonNull(updateStrategy, "update strategy"); this.updateStrategy.set(requireNonNull(updateStrategy, "update strategy"));
}
public ReadOnlyObjectProperty<AutoUpdateStrategy> updateStrategyProperty() {
return updateStrategy;
} }
} }

@ -1,8 +1,8 @@
package fr.uca.iut.clfreville2.model.sensor.auto; package fr.uca.iut.clfreville2.model.sensor.auto;
import fr.uca.iut.clfreville2.model.sensor.AutoSensor; import fr.uca.iut.clfreville2.model.sensor.AutoSensor;
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
@FunctionalInterface
public interface AutoUpdateStrategy { public interface AutoUpdateStrategy {
/** /**
@ -12,4 +12,11 @@ public interface AutoUpdateStrategy {
* @return The next value of the sensor. * @return The next value of the sensor.
*/ */
double nextValue(AutoSensor currentState); double nextValue(AutoSensor currentState);
/**
* Gets the type of this strategy.
*
* @return The type of this strategy.
*/
AutoUpdateStrategyProvider getType();
} }

@ -0,0 +1,27 @@
package fr.uca.iut.clfreville2.model.sensor.auto;
import fr.uca.iut.clfreville2.model.sensor.AutoSensor;
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
import fr.uca.iut.clfreville2.model.sensor.auto.provider.StandardUpdateStrategyProvider;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class CpuUpdateStrategy implements AutoUpdateStrategy {
@Override
public double nextValue(AutoSensor currentState) {
try {
//return Integer.parseInt(Files.readString(Path.of("/sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon1/temp1_input")).trim()) / 1000D;
return Integer.parseInt(Files.readString(Path.of("/sys/class/thermal/thermal_zone0/temp")).trim()) / 1000D;
} catch (IOException e) {
return -1;
}
}
@Override
public AutoUpdateStrategyProvider getType() {
return StandardUpdateStrategyProvider.CPU;
}
}

@ -0,0 +1,34 @@
package fr.uca.iut.clfreville2.model.sensor.auto;
import fr.uca.iut.clfreville2.model.sensor.AutoSensor;
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
import fr.uca.iut.clfreville2.model.sensor.auto.provider.StandardUpdateStrategyProvider;
import java.util.Random;
public class RandomUpdateStrategy implements AutoUpdateStrategy {
private final Random random;
private final int min;
private final int max;
public RandomUpdateStrategy(int min, int max) {
this(new Random(), min, max);
}
public RandomUpdateStrategy(Random random, int min, int max) {
this.random = random;
this.min = min;
this.max = max;
}
@Override
public double nextValue(AutoSensor currentState) {
return random.nextDouble(min, max);
}
@Override
public AutoUpdateStrategyProvider getType() {
return StandardUpdateStrategyProvider.RANDOM_UPDATE;
}
}

@ -1,6 +1,8 @@
package fr.uca.iut.clfreville2.model.sensor.auto; package fr.uca.iut.clfreville2.model.sensor.auto;
import fr.uca.iut.clfreville2.model.sensor.AutoSensor; import fr.uca.iut.clfreville2.model.sensor.AutoSensor;
import fr.uca.iut.clfreville2.model.sensor.auto.provider.AutoUpdateStrategyProvider;
import fr.uca.iut.clfreville2.model.sensor.auto.provider.StandardUpdateStrategyProvider;
import java.util.Random; import java.util.Random;
@ -22,4 +24,9 @@ public class RandomVariationStrategy implements AutoUpdateStrategy {
public double nextValue(AutoSensor currentState) { public double nextValue(AutoSensor currentState) {
return currentState.getTemperature() + random.nextInt(maxVariation * 2) - maxVariation; return currentState.getTemperature() + random.nextInt(maxVariation * 2) - maxVariation;
} }
@Override
public AutoUpdateStrategyProvider getType() {
return StandardUpdateStrategyProvider.RANDOM_VARIATION;
}
} }

@ -0,0 +1,9 @@
package fr.uca.iut.clfreville2.model.sensor.auto.provider;
import fr.uca.iut.clfreville2.model.sensor.auto.AutoUpdateStrategy;
import fr.uca.iut.clfreville2.model.shared.Nameable;
public interface AutoUpdateStrategyProvider extends Nameable {
AutoUpdateStrategy create();
}

@ -0,0 +1,47 @@
package fr.uca.iut.clfreville2.model.sensor.auto.provider;
import fr.uca.iut.clfreville2.model.sensor.auto.AutoUpdateStrategy;
import fr.uca.iut.clfreville2.model.sensor.auto.CpuUpdateStrategy;
import fr.uca.iut.clfreville2.model.sensor.auto.RandomUpdateStrategy;
import fr.uca.iut.clfreville2.model.sensor.auto.RandomVariationStrategy;
/**
* Provide common update strategies.
* <p>
* This enum ensures that the same strategy is always returned with the same identity.
*/
public enum StandardUpdateStrategyProvider implements AutoUpdateStrategyProvider {
RANDOM_UPDATE {
@Override
public AutoUpdateStrategy create() {
return new RandomUpdateStrategy(-10, 40);
}
@Override
public String getName() {
return "Random";
}
},
RANDOM_VARIATION {
@Override
public AutoUpdateStrategy create() {
return new RandomVariationStrategy(5);
}
@Override
public String getName() {
return "Random variation";
}
},
CPU {
@Override
public AutoUpdateStrategy create() {
return new CpuUpdateStrategy();
}
@Override
public String getName() {
return "CPU";
}
}
}
Loading…
Cancel
Save