Changes due to new requirements
This commit is contained in:
commit
5b072329d3
40
nbactions.xml
Normal file
40
nbactions.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<actions>
|
||||
<action>
|
||||
<actionName>run</actionName>
|
||||
<packagings>
|
||||
<packaging>jar</packaging>
|
||||
</packagings>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
<goal>javafx:run</goal>
|
||||
</goals>
|
||||
</action>
|
||||
<action>
|
||||
<actionName>debug</actionName>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
<goal>javafx:run@ide-debug</goal>
|
||||
</goals>
|
||||
<properties>
|
||||
<jpda.listen>true</jpda.listen>
|
||||
</properties>
|
||||
</action>
|
||||
<action>
|
||||
<actionName>profile</actionName>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
<goal>javafx:run@ide-profile</goal>
|
||||
</goals>
|
||||
</action>
|
||||
<action>
|
||||
<actionName>CUSTOM-jlink</actionName>
|
||||
<displayName>jlink</displayName>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
<!-- compile not needed with javafx-maven-plugin v0.0.5 -->
|
||||
<goal>compile</goal>
|
||||
<goal>javafx:jlink</goal>
|
||||
</goals>
|
||||
</action>
|
||||
</actions>
|
||||
106
pom.xml
Normal file
106
pom.xml
Normal file
@ -0,0 +1,106 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>efi.projekt</groupId>
|
||||
<artifactId>Virtueller_Gesundheitsassistent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
|
||||
<version>1.2.5</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-web</artifactId>
|
||||
<version>21.0.9</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>21.0.9</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.websocket</groupId>
|
||||
<artifactId>jakarta.websocket-client-api</artifactId>
|
||||
<version>2.2.0</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openpnp</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.12.0</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<release>21</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>0.0.4</version>
|
||||
<configuration>
|
||||
<mainClass>efi.projekt.virtueller_gesundheitsassistent.App</mainClass>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<!-- Default configuration for running -->
|
||||
<!-- Usage: mvn clean javafx:run -->
|
||||
<id>default-cli</id>
|
||||
</execution>
|
||||
<execution>
|
||||
<!-- Configuration for manual attach debugging -->
|
||||
<!-- Usage: mvn clean javafx:run@debug -->
|
||||
<id>debug</id>
|
||||
<configuration>
|
||||
<options>
|
||||
<option>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:8000</option>
|
||||
</options>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<!-- Configuration for automatic IDE debugging -->
|
||||
<id>ide-debug</id>
|
||||
<configuration>
|
||||
<options>
|
||||
<option>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address}</option>
|
||||
</options>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<!-- Configuration for automatic IDE profiling -->
|
||||
<id>ide-profile</id>
|
||||
<configuration>
|
||||
<options>
|
||||
<option>${profiler.jvmargs.arg1}</option>
|
||||
<option>${profiler.jvmargs.arg2}</option>
|
||||
<option>${profiler.jvmargs.arg3}</option>
|
||||
<option>${profiler.jvmargs.arg4}</option>
|
||||
<option>${profiler.jvmargs.arg5}</option>
|
||||
</options>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@ -0,0 +1,44 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent;
|
||||
|
||||
import java.io.IOException;
|
||||
import javafx.application.Application;
|
||||
import static javafx.application.Application.launch;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
|
||||
/**
|
||||
* JavaFX App
|
||||
* @author naumueller
|
||||
*/
|
||||
public class App extends Application {
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws IOException {
|
||||
// Lade FXML
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/efi/projekt/virtueller_gesundheitsassistent/view/FxView.fxml"));
|
||||
Parent root = loader.load();
|
||||
|
||||
// Erzeuge Model & ViewModel
|
||||
|
||||
Scene scene = new Scene(root, 1280, 720);
|
||||
|
||||
primaryStage.setTitle("Virtueller Gesundheitsassistent");
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
private static Parent loadFXML(String fxml) throws IOException {
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(
|
||||
App.class.getResource("/efi/projekt/virtueller_gesundheitsassistent/view/" + fxml + ".fxml")
|
||||
);
|
||||
return fxmlLoader.load();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent;
|
||||
|
||||
public class SystemInfo {
|
||||
|
||||
public static String javaVersion() {
|
||||
return System.getProperty("java.version");
|
||||
}
|
||||
|
||||
public static String javafxVersion() {
|
||||
return System.getProperty("javafx.version");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.controller;
|
||||
|
||||
import efi.projekt.virtueller_gesundheitsassistent.service.CameraService;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public class CameraController {
|
||||
|
||||
@FXML private ImageView cameraView;
|
||||
|
||||
private final CameraService cameraService = new CameraService();
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
start();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void start() {
|
||||
cameraService.start(image ->
|
||||
Platform.runLater(() -> cameraView.setImage(image))
|
||||
);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void stopCamera() {
|
||||
cameraService.stop();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.model;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public class AssistantState {
|
||||
|
||||
private final ObjectProperty<ClassificationType> classification =
|
||||
new SimpleObjectProperty<>(ClassificationType.NORMAL);
|
||||
|
||||
private final BooleanProperty speaking =
|
||||
new SimpleBooleanProperty(false);
|
||||
|
||||
private final BooleanProperty monitoring =
|
||||
new SimpleBooleanProperty(true);
|
||||
|
||||
public ObjectProperty<ClassificationType> classificationProperty() {
|
||||
return classification;
|
||||
}
|
||||
|
||||
public BooleanProperty speakingProperty() {
|
||||
return speaking;
|
||||
}
|
||||
|
||||
public BooleanProperty monitoringProperty() {
|
||||
return monitoring;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.model;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public record Classification (
|
||||
String label,
|
||||
String text,
|
||||
String mqttValue
|
||||
) {}
|
||||
@ -0,0 +1,13 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.model;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public enum ClassificationType {
|
||||
NORMAL,
|
||||
MUEDIGKEIT,
|
||||
ABLENKUNG,
|
||||
STRESS,
|
||||
REAKTION
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.service;
|
||||
|
||||
import efi.projekt.virtueller_gesundheitsassistent.util.Logger;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javafx.scene.image.Image;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.videoio.VideoCapture;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public class CameraService {
|
||||
|
||||
static {
|
||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||
}
|
||||
|
||||
private VideoCapture capture;
|
||||
private ScheduledExecutorService timer;
|
||||
|
||||
public void start(java.util.function.Consumer<Image> frameConsumer) {
|
||||
if (capture != null && capture.isOpened()) {
|
||||
return;
|
||||
}
|
||||
|
||||
capture = new VideoCapture(0);
|
||||
|
||||
if (!capture.isOpened()) {
|
||||
Logger.error("CAMERA", "Kamera konnte nicht geoeffnet werden");
|
||||
return;
|
||||
}
|
||||
|
||||
Runnable frameGrabber = () -> {
|
||||
Mat frame = new Mat();
|
||||
if (capture.read(frame)) {
|
||||
Image image = matToImage(frame);
|
||||
frameConsumer.accept(image);
|
||||
}
|
||||
};
|
||||
|
||||
timer = Executors.newSingleThreadScheduledExecutor();
|
||||
timer.scheduleAtFixedRate(frameGrabber, 0, 33, TimeUnit.MILLISECONDS);
|
||||
|
||||
Logger.info("CAMERA", "Kamera gestartet");
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (timer != null && !timer.isShutdown()) {
|
||||
timer.shutdown();
|
||||
}
|
||||
if (capture != null && capture.isOpened()) {
|
||||
capture.release();
|
||||
}
|
||||
Logger.info("CAMERA", "Kamera gestoppt");
|
||||
}
|
||||
|
||||
private Image matToImage(Mat frame) {
|
||||
MatOfByte buffer = new MatOfByte();
|
||||
Imgcodecs.imencode(".png", frame, buffer);
|
||||
return new Image(new ByteArrayInputStream(buffer.toArray()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.service;
|
||||
|
||||
import efi.projekt.virtueller_gesundheitsassistent.model.ClassificationType;
|
||||
import efi.projekt.virtueller_gesundheitsassistent.util.Logger;
|
||||
import javafx.application.Platform;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public class ClassificationService {
|
||||
|
||||
private static final String TOPIC = "Text";
|
||||
|
||||
public ClassificationService(MqttClientService mqtt) {
|
||||
|
||||
mqtt.subscribe(TOPIC, payload -> {
|
||||
|
||||
ClassificationType type = switch (payload) {
|
||||
case "0" -> ClassificationType.NORMAL;
|
||||
case "1" -> ClassificationType.MUEDIGKEIT;
|
||||
case "2" -> ClassificationType.ABLENKUNG;
|
||||
case "3" -> ClassificationType.REAKTION;
|
||||
case "4" -> ClassificationType.STRESS;
|
||||
default -> ClassificationType.NORMAL;
|
||||
};
|
||||
|
||||
Logger.info("STATE", "Neue Klassifizierung: " + type);
|
||||
|
||||
Platform.runLater(() ->
|
||||
StateService.getState()
|
||||
.classificationProperty()
|
||||
.set(type)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,121 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.service;
|
||||
|
||||
import efi.projekt.virtueller_gesundheitsassistent.util.Logger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import org.eclipse.paho.client.mqttv3.*;
|
||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public class MqttClientService implements MqttCallback {
|
||||
|
||||
private static final String BROKER_URL = "tcp://localhost:1883";
|
||||
private static final String CLIENT_ID = "JavaClientPublisherSubscriber";
|
||||
|
||||
private final Map<String, Consumer<String>> topicListeners =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
private MqttClient client;
|
||||
|
||||
public MqttClientService() {
|
||||
try {
|
||||
client = new MqttClient(
|
||||
BROKER_URL,
|
||||
CLIENT_ID,
|
||||
new MemoryPersistence()
|
||||
);
|
||||
client.setCallback(this);
|
||||
|
||||
MqttConnectOptions options = new MqttConnectOptions();
|
||||
options.setCleanSession(true);
|
||||
options.setAutomaticReconnect(true);
|
||||
|
||||
Logger.info("MQTT", "Verbinde mit Broker " + BROKER_URL);
|
||||
client.connect(options);
|
||||
Logger.info("MQTT", "Verbindung hergestellt");
|
||||
|
||||
} catch (MqttException e) {
|
||||
Logger.error("MQTT", "Fehler beim Verbinden", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
try {
|
||||
if (client != null && client.isConnected()) {
|
||||
client.disconnect();
|
||||
Logger.info("MQTT", "Verbindung getrennt");
|
||||
}
|
||||
} catch (MqttException e) {
|
||||
Logger.error("MQTT", "Fehler beim Trennen", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void subscribe(String topic, Consumer<String> listener) {
|
||||
topicListeners.put(topic, listener);
|
||||
try {
|
||||
client.subscribe(topic);
|
||||
Logger.info("MQTT", "Topic abonniert: " + topic);
|
||||
} catch (MqttException e) {
|
||||
Logger.error("MQTT", "Subscribe fehlgeschlagen: " + topic, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void publish(String topic, String message, int qos) {
|
||||
try {
|
||||
MqttMessage mqttMessage =
|
||||
new MqttMessage(message.getBytes(StandardCharsets.UTF_8));
|
||||
mqttMessage.setQos(qos);
|
||||
|
||||
client.publish(topic, mqttMessage);
|
||||
|
||||
Logger.debug(
|
||||
"MQTT",
|
||||
"Publish -> Topic=" + topic + ", QoS=" + qos + ", Payload=" + message
|
||||
);
|
||||
} catch (MqttException e) {
|
||||
Logger.error("MQTT", "Publish fehlgeschlagen", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionLost(Throwable cause) {
|
||||
Logger.warn(
|
||||
"MQTT",
|
||||
"Verbindung verloren: " + cause.getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageArrived(String topic, MqttMessage message) throws Exception {
|
||||
String payload =
|
||||
new String(message.getPayload(), StandardCharsets.UTF_8);
|
||||
|
||||
Logger.debug(
|
||||
"MQTT",
|
||||
"Nachricht empfangen -> Topic=" + topic + ", Payload=" + payload
|
||||
);
|
||||
|
||||
Consumer<String> listener = topicListeners.get(topic);
|
||||
if (listener != null) {
|
||||
listener.accept(payload);
|
||||
} else {
|
||||
Logger.warn(
|
||||
"MQTT",
|
||||
"Keine Listener für Topic: " + topic
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deliveryComplete(IMqttDeliveryToken token) {
|
||||
Logger.debug(
|
||||
"MQTT",
|
||||
"Delivery complete, MessageId=" + token.getMessageId()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.service;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.web.WebView;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public class PixelStreamingService {
|
||||
private final WebView webView;
|
||||
|
||||
public PixelStreamingService(String url) {
|
||||
webView = new WebView();
|
||||
webView.getEngine().load(url);
|
||||
}
|
||||
|
||||
public Node getView() {
|
||||
return webView;
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
webView.getEngine().reload();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
webView.setVisible(false);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
webView.setVisible(true);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.service;
|
||||
|
||||
import efi.projekt.virtueller_gesundheitsassistent.model.AssistantState;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public class StateService {
|
||||
|
||||
private static final AssistantState STATE = new AssistantState();
|
||||
|
||||
private StateService() {}
|
||||
|
||||
public static AssistantState getState() {
|
||||
return STATE;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.service;
|
||||
|
||||
import efi.projekt.virtueller_gesundheitsassistent.util.Logger;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import jakarta.websocket.*;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
@ClientEndpoint
|
||||
public class UnrealWebSocketService {
|
||||
|
||||
private Session session;
|
||||
private final URI serverUri;
|
||||
private final AtomicBoolean connected = new AtomicBoolean(false);
|
||||
|
||||
|
||||
public UnrealWebSocketService(String serverUrl) {
|
||||
this.serverUri = URI.create(serverUrl);
|
||||
connect();
|
||||
}
|
||||
|
||||
private void connect() {
|
||||
try {
|
||||
WebSocketContainer container =
|
||||
ContainerProvider.getWebSocketContainer();
|
||||
|
||||
Logger.info("UNREAL", "Verbinde zu " + serverUri);
|
||||
container.connectToServer(this, serverUri);
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error("UNREAL", "WebSocket-Verbindung fehlgeschlagen", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return connected.get();
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
try {
|
||||
if (session != null && session.isOpen()) {
|
||||
session.close();
|
||||
Logger.info("UNREAL", "WebSocket-Verbindung geschlossen");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error("UNREAL", "Fehler beim Schließen der Verbindung", e);
|
||||
}
|
||||
}
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session) {
|
||||
this.session = session;
|
||||
connected.set(true);
|
||||
Logger.info("UNREAL", "WebSocket verbunden");
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(Session session, CloseReason reason) {
|
||||
connected.set(false);
|
||||
Logger.warn("UNREAL", "WebSocket geschlossen: " + reason.getReasonPhrase());
|
||||
}
|
||||
|
||||
@OnError
|
||||
public void onError(Session session, Throwable throwable) {
|
||||
connected.set(false);
|
||||
Logger.error("UNREAL", "WebSocket-Fehler", throwable);
|
||||
}
|
||||
|
||||
@OnMessage
|
||||
public void onMessage(String message) {
|
||||
Logger.debug("UNREAL", "Nachricht empfangen: " + message);
|
||||
}
|
||||
|
||||
public void speak(String text) {
|
||||
if (!connected.get()) {
|
||||
Logger.warn("UNREAL", "Nicht verbunden! Text wird nicht gesendet!");
|
||||
return;
|
||||
}
|
||||
|
||||
String json = buildSpeakMessage(text);
|
||||
|
||||
session.getAsyncRemote().sendText(json);
|
||||
Logger.info("UNREAL", "Sende Speak-Command: " + text);
|
||||
}
|
||||
|
||||
public String buildSpeakMessage(String text) {
|
||||
return "{"
|
||||
+ "\"type\":\"speak\","
|
||||
+ "\"text\":\"" + escape(text) + "\""
|
||||
+ "}";
|
||||
}
|
||||
|
||||
public String escape(String text) {
|
||||
return text.replace("\"", "\\\"");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package efi.projekt.virtueller_gesundheitsassistent.util;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author naumueller
|
||||
*/
|
||||
public class Logger {
|
||||
public enum Level {
|
||||
DEBUG,
|
||||
INFO,
|
||||
WARN,
|
||||
ERROR
|
||||
}
|
||||
|
||||
private static Level currentLevel = Level.DEBUG;
|
||||
|
||||
private static final DateTimeFormatter FORMATTER =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private Logger() {
|
||||
// Verhindert Instanziierung
|
||||
}
|
||||
|
||||
public static void setLevel(Level level) {
|
||||
currentLevel = level;
|
||||
}
|
||||
|
||||
public static void debug(String source, String message) {
|
||||
log(Level.DEBUG, source, message, null);
|
||||
}
|
||||
|
||||
public static void info(String source, String message) {
|
||||
log(Level.INFO, source, message, null);
|
||||
}
|
||||
|
||||
public static void warn(String source, String message) {
|
||||
log(Level.WARN, source, message, null);
|
||||
}
|
||||
|
||||
public static void error(String source, String message) {
|
||||
log(Level.ERROR, source, message, null);
|
||||
}
|
||||
|
||||
public static void error(String source, String message, Throwable throwable) {
|
||||
log(Level.ERROR, source, message, throwable);
|
||||
}
|
||||
|
||||
public static synchronized void log(
|
||||
Level level,
|
||||
String source,
|
||||
String message,
|
||||
Throwable throwable
|
||||
) {
|
||||
// Log-Level filtern
|
||||
if (level.ordinal() < currentLevel.ordinal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String timestamp = LocalDateTime.now().format(FORMATTER);
|
||||
|
||||
String logLine = String.format(
|
||||
"[%s] [%s] [%s] %s",
|
||||
timestamp,
|
||||
level,
|
||||
source,
|
||||
message
|
||||
);
|
||||
|
||||
if (level == Level.ERROR) {
|
||||
System.err.println(logLine);
|
||||
if (throwable != null) {
|
||||
throwable.printStackTrace(System.err);
|
||||
}
|
||||
} else {
|
||||
System.out.println(logLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Tab?>
|
||||
<?import javafx.scene.control.TabPane?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
|
||||
|
||||
<TabPane xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<tabs>
|
||||
<Tab text="Minimal">
|
||||
<fx:include source="designs/MinimalView.fxml"/>
|
||||
</Tab>
|
||||
<Tab text="Immersive">
|
||||
<fx:include source="designs/ImmersiveView.fxml"/>
|
||||
</Tab>
|
||||
<Tab text="Compact">
|
||||
<fx:include source="designs/CompactView.fxml"/>
|
||||
</Tab>
|
||||
<Tab text="Dashboard">
|
||||
<fx:include source="designs/DashboardView.fxml"/>
|
||||
</Tab>
|
||||
</tabs>
|
||||
</TabPane>
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import java.util.*?>
|
||||
<?import javafx.scene.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1">
|
||||
|
||||
</AnchorPane>
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
|
||||
|
||||
<StackPane xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="efi.projekt.virtueller_gesundheitsassistent.controller.CameraController">
|
||||
<children>
|
||||
<ImageView fx:id="cameraView" fitHeight="240.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
|
||||
</children>
|
||||
</StackPane>
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import java.util.*?>
|
||||
<?import javafx.scene.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1">
|
||||
|
||||
</AnchorPane>
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import java.util.*?>
|
||||
<?import javafx.scene.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1">
|
||||
|
||||
</AnchorPane>
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import java.util.*?>
|
||||
<?import javafx.scene.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1">
|
||||
|
||||
</AnchorPane>
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import java.util.*?>
|
||||
<?import javafx.scene.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1">
|
||||
|
||||
</AnchorPane>
|
||||
14
src/main/java/module-info.java
Normal file
14
src/main/java/module-info.java
Normal file
@ -0,0 +1,14 @@
|
||||
module efi.projekt.virtueller_gesundheitsassistent {
|
||||
requires javafx.controls;
|
||||
requires javafx.fxml;
|
||||
requires java.base;
|
||||
requires org.eclipse.paho.client.mqttv3;
|
||||
requires javafx.web;
|
||||
requires jakarta.websocket.client;
|
||||
requires opencv;
|
||||
|
||||
|
||||
opens efi.projekt.virtueller_gesundheitsassistent to javafx.fxml;
|
||||
|
||||
exports efi.projekt.virtueller_gesundheitsassistent;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user