diff --git a/healthdisplay/.idea/uiDesigner.xml b/healthdisplay/.idea/uiDesigner.xml
index c47fa82..709fd23 100644
--- a/healthdisplay/.idea/uiDesigner.xml
+++ b/healthdisplay/.idea/uiDesigner.xml
@@ -119,16 +119,18 @@
-
- -
-
-
-
-
+ -
+
+
+ -
+
+
-
-
+
\ No newline at end of file
diff --git a/healthdisplay/healthdisplay.iml b/healthdisplay/healthdisplay.iml
index d987de2..efc4c55 100644
--- a/healthdisplay/healthdisplay.iml
+++ b/healthdisplay/healthdisplay.iml
@@ -5,20 +5,19 @@
+
+
+
-
-
-
-
-
+
\ No newline at end of file
diff --git a/healthdisplay/pom.xml b/healthdisplay/pom.xml
index cd5c36f..8fc0fba 100644
--- a/healthdisplay/pom.xml
+++ b/healthdisplay/pom.xml
@@ -15,21 +15,22 @@
0.2
-
- org.jboss.netty
- netty
- 3.2.7.Final
-
+
+
+
+
+
com.intellij
forms_rt
7.0.3
+ compile
-
- org.snmp4j
- snmp4j
- 1.9.1f
-
+
+
+
+
+
diff --git a/healthdisplay/src/main/java/de/psychose/ActorData.java b/healthdisplay/src/main/java/de/psychose/ActorData.java
new file mode 100644
index 0000000..db0374b
--- /dev/null
+++ b/healthdisplay/src/main/java/de/psychose/ActorData.java
@@ -0,0 +1,103 @@
+package de.psychose;
+
+/**
+ * @author: lucas
+ * @date: 17.11.14 21:07
+ */
+public class ActorData {
+
+ private PulseData pulseData = new PulseData();
+ private int airflow;
+ private int ekg;
+ private int emg;
+ private float temperature;
+ private boolean tommyHeartbeat;
+
+ private long timestampPulse = 0;
+ private long timestampTommyPulse = 0;
+ private long timestampEkg = 0;
+ private long timestampEmg = 0;
+ private long timestampTemperature = 0;
+ private long timestampBreath = 0;
+
+ // TODO: hier die timestamps setzen wann letztes mal geändert,
+ // dann kann ich in ActorDisplay im Timer einfach prüfen ob differenz > timeout, dann rot setzen
+
+
+ public void setTimestampPulse() {
+ this.timestampPulse = System.currentTimeMillis();
+ }
+ public PulseData getPulseData() {
+ return pulseData;
+ }
+
+ public void setPulseData(PulseData pulseData) {
+ this.pulseData = pulseData;
+ this.timestampPulse = System.currentTimeMillis();
+ }
+
+ public int getAirflow() {
+ return airflow;
+ }
+
+ public void setAirflow(int airflow) {
+ this.airflow = airflow;
+ this.timestampBreath = System.currentTimeMillis();
+ }
+
+ public int getEkg() {
+ return ekg;
+ }
+
+ public void setEkg(int ekg) {
+ this.ekg = ekg;
+ this.timestampEkg = System.currentTimeMillis();
+ }
+
+ public int getEmg() {
+ return emg;
+ }
+
+ public void setEmg(int emg) {
+ this.emg = emg;
+ this.timestampEmg = System.currentTimeMillis();
+ }
+
+ public float getTemperature() {
+ return temperature;
+ }
+
+ public void setTemperature(float temperature) {
+ this.temperature = temperature;
+ this.timestampTemperature = System.currentTimeMillis();
+ }
+
+ public boolean getTommyHeartbeat() {
+ return tommyHeartbeat;
+ }
+
+ public void setTommyHeartbeat(boolean tommyHeartbeat) {
+ this.tommyHeartbeat = tommyHeartbeat;
+ this.timestampTommyPulse = System.currentTimeMillis();
+ }
+
+ public long getTimestampPulse() {
+ return timestampPulse;
+ }
+
+ public long getTimestampEkg() {
+ return timestampEkg;
+ }
+
+ public long getTimestampEmg() {
+ return timestampEmg;
+ }
+
+ public long getTimestampTemperature() {
+ return timestampTemperature;
+ }
+
+ public long getTimestampBreath() {
+ return timestampBreath;
+ }
+}
diff --git a/healthdisplay/src/main/java/de/psychose/ActorDisplay.java b/healthdisplay/src/main/java/de/psychose/ActorDisplay.java
index e2f0531..a6c9313 100644
--- a/healthdisplay/src/main/java/de/psychose/ActorDisplay.java
+++ b/healthdisplay/src/main/java/de/psychose/ActorDisplay.java
@@ -3,6 +3,7 @@ package de.psychose;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
+import java.text.DecimalFormat;
/**
* @author: lucas
@@ -14,7 +15,6 @@ public class ActorDisplay {
private final static Color offColor = Color.RED;
private final static String offText = "no data";
- private JPanel actorPanel;
private JLabel lblCaption;
private JLabel lblHeartbeat;
private JLabel lblPulse;
@@ -23,54 +23,32 @@ public class ActorDisplay {
private JLabel lblEmg;
private JLabel lblTemperature;
private JLabel lblBreath;
+ private JPanel actorPanel;
+ private ActorData actorData;
+ private boolean showErrors = false;
+ private DecimalFormat df = new DecimalFormat("#.0");
- private int counterHeartbeat = 0;
- private int counterPulse = 0;
- private int counterOxy = 0;
- private int counterEkg = 0;
- private int counterEmg = 0;
- private int counterTemperature = 0;
- private int counterBreath = 0;
+ //TODO: die einzelnen Setter wegmachen, dafür eine setData() bauen die die daten en bloc nimmt
+ // die darin enthaltenen timestamps dann für rotfärbung nehmen
- private int timeout = 20; // 20 * 100ms
+ public void setActorData(ActorData actorData) {
+ this.actorData = actorData;
+ }
public void setCaption(String caption) {
lblCaption.setText(caption);
}
- public void setBreath(String breath) {
- lblBreath.setText(breath);
- counterBreath = 0;
- }
+ public void update() {
+ lblBreath.setText(String.valueOf(actorData.getAirflow()));
- public void setTemperature(String temperature) {
- lblTemperature.setText(temperature);
- counterTemperature = 0;
- }
+ lblTemperature.setText(df.format(actorData.getTemperature()));
+ lblEkg.setText(String.valueOf(actorData.getEkg()));
+ lblPulse.setText(actorData.getPulseData().getHeartbeat() == 0 ? "systole" : "diastole");
+ lblEmg.setText(String.valueOf(actorData.getEmg()));
+ lblOxy.setText(String.valueOf(actorData.getPulseData().getOxygen()));
+ lblHeartbeat.setText(String.valueOf(actorData.getPulseData().getPulse()));
- public void setEkg(String value) {
- lblEkg.setText(value);
- counterEkg = 0;
- }
-
- public void setPulse(String pulse) {
- lblPulse.setText(pulse);
- counterPulse = 0;
- }
-
- public void setEmg(String emg) {
- lblEmg.setText(emg);
- counterEmg = 0;
- }
-
- public void setOxy(String oxy) {
- lblOxy.setText(oxy);
- counterOxy = 0;
- }
-
- public void setHeartbeat(String heartbeat) {
- lblHeartbeat.setText(heartbeat);
- counterHeartbeat = 0;
}
public ActorDisplay() {
@@ -78,62 +56,65 @@ public class ActorDisplay {
@Override
public void actionPerformed(ActionEvent e) {
- if (++counterTemperature > timeout) {
- lblTemperature.setForeground(offColor);
- lblTemperature.setText(offText);
- } else {
- lblTemperature.setForeground(onColor);
- }
+ if (actorData == null)
+ return;
- if (++counterPulse > timeout) {
- lblPulse.setForeground(offColor);
- lblPulse.setText(offText);
- } else {
- lblPulse.setForeground(onColor);
- }
+ update();
- if (++counterOxy > timeout) {
- lblOxy.setForeground(offColor);
- lblOxy.setText(offText);
- } else {
- lblOxy.setForeground(onColor);
- }
+ if (showErrors) {
- if (++counterEkg > timeout) {
- lblEkg.setForeground(offColor);
- lblEkg.setText(offText);
- } else {
- lblEkg.setForeground(onColor);
- }
+ long timeout = System.currentTimeMillis() - 1000;
- if (++counterEmg > timeout) {
- lblEmg.setForeground(offColor);
- lblEmg.setText(offText);
- } else {
- lblEmg.setForeground(onColor);
- }
+ if (actorData.getTimestampTemperature() < timeout) {
+ lblTemperature.setForeground(offColor);
+ lblTemperature.setText(offText);
+ } else {
+ lblTemperature.setForeground(onColor);
+ }
- if (++counterHeartbeat > timeout) {
- lblHeartbeat.setForeground(offColor);
- lblHeartbeat.setText(offText);
- } else {
- lblHeartbeat.setForeground(onColor);
- }
+ if (actorData.getTimestampPulse() < timeout) {
+ lblPulse.setForeground(offColor);
+ lblPulse.setText(offText);
+ lblOxy.setForeground(offColor);
+ lblOxy.setText(offText);
+ lblHeartbeat.setForeground(offColor);
+ lblHeartbeat.setText(offText);
+ } else {
+ lblPulse.setForeground(onColor);
+ lblOxy.setForeground(onColor);
+ lblHeartbeat.setForeground(onColor);
+ }
- if (++counterBreath > timeout) {
- lblBreath.setForeground(offColor);
- lblBreath.setText(offText);
- } else {
- lblBreath.setForeground(onColor);
+ if (actorData.getTimestampEkg() < timeout) {
+ lblEkg.setForeground(offColor);
+ lblEkg.setText(offText);
+ } else {
+ lblEkg.setForeground(onColor);
+ }
+
+ if (actorData.getTimestampEmg() < timeout) {
+ lblEmg.setForeground(offColor);
+ lblEmg.setText(offText);
+ } else {
+ lblEmg.setForeground(onColor);
+ }
+
+ if (actorData.getTimestampBreath() < timeout) {
+ lblBreath.setForeground(offColor);
+ lblBreath.setText(offText);
+ } else {
+ lblBreath.setForeground(onColor);
+ }
}
}
});
- this.timer.setRepeats(true);
+
+ timer.setRepeats(true);
+ timer.start();
}
- public void startErrorTimer() {
- this.timer.start();
+ public void setShowErrors(boolean showErrors) {
+ this.showErrors = showErrors;
}
-
}
diff --git a/healthdisplay/src/main/java/de/psychose/ActorHeart.form b/healthdisplay/src/main/java/de/psychose/ActorHeart.form
new file mode 100644
index 0000000..86b3aa2
--- /dev/null
+++ b/healthdisplay/src/main/java/de/psychose/ActorHeart.form
@@ -0,0 +1,18 @@
+
+
diff --git a/healthdisplay/src/main/java/de/psychose/ActorHeart.java b/healthdisplay/src/main/java/de/psychose/ActorHeart.java
new file mode 100644
index 0000000..2dfeef4
--- /dev/null
+++ b/healthdisplay/src/main/java/de/psychose/ActorHeart.java
@@ -0,0 +1,67 @@
+package de.psychose;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+/**
+ * @author: lucas
+ * @date: 15.11.14 21:36
+ */
+public class ActorHeart {
+ private JPanel heartPanel;
+ private ActorData actorData1;
+ private ActorData actorData2;
+ private ActorData actorData3;
+ private ImagePanel imagePanel;
+ private Timer timer;
+
+ public ActorHeart() {
+ imagePanel = new ImagePanel("/de/psychose/heart1_klein_inv.jpg", "/de/psychose/heart2_klein_inv.jpg");
+ heartPanel.add(imagePanel);
+
+ timer = new Timer(100, new AbstractAction() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(actorData1 != null && actorData2 != null && actorData3 != null) {
+ imagePanel.repaint();
+ }
+ }
+ });
+ timer.setRepeats(true);
+ timer.start();
+ }
+
+ public void setActorData(final ActorData actorData1, final ActorData actorData2, final ActorData actorData3) {
+ this.actorData1 = actorData1;
+ this.actorData2 = actorData2;
+ this.actorData3 = actorData3;
+ }
+
+ private class ImagePanel extends JPanel {
+ private BufferedImage image1;
+ private BufferedImage image2;
+
+ public ImagePanel(String imageA, String imageB) {
+ try {
+ image1 = ImageIO.read(getClass().getResourceAsStream(imageA));
+ image2 = ImageIO.read(getClass().getResourceAsStream(imageB));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ if(actorData1 != null && actorData2 != null && actorData3 != null) {
+ g.drawImage(ActorHeart.this.actorData1.getTommyHeartbeat() ? image1 : image2, 0, 0, null, null);
+ g.drawImage(ActorHeart.this.actorData2.getTommyHeartbeat() ? image1 : image2, 263, 0, null, null);
+ g.drawImage(ActorHeart.this.actorData3.getTommyHeartbeat() ? image1 : image2, 526, 0, null, null);
+ }
+ }
+ }
+}
diff --git a/healthdisplay/src/main/java/de/psychose/ChaOSCclient.java b/healthdisplay/src/main/java/de/psychose/ChaOSCclient.java
index 9674dfa..a795850 100644
--- a/healthdisplay/src/main/java/de/psychose/ChaOSCclient.java
+++ b/healthdisplay/src/main/java/de/psychose/ChaOSCclient.java
@@ -23,7 +23,12 @@ public class ChaOSCclient {
public ChaOSCclient(String host, int port) throws UnknownHostException, SocketException {
portOut = new OSCPortOut(InetAddress.getByName(host), port);
- portIn = new OSCPortIn(OSC_CLIENT_PORT);
+ try {
+ portIn = new OSCPortIn(OSC_CLIENT_PORT);
+ } catch (SocketException se) {
+ System.out.println("Port " + OSC_CLIENT_PORT + " already in use. Trying " + OSC_CLIENT_PORT + 1);
+ portIn = new OSCPortIn(OSC_CLIENT_PORT + 1);
+ }
}
public void addListener(String address, OSCListener listener) {
diff --git a/healthdisplay/src/main/java/de/psychose/ControlForm.form b/healthdisplay/src/main/java/de/psychose/ControlForm.form
new file mode 100644
index 0000000..1a0130d
--- /dev/null
+++ b/healthdisplay/src/main/java/de/psychose/ControlForm.form
@@ -0,0 +1,43 @@
+
+
diff --git a/healthdisplay/src/main/java/de/psychose/ControlForm.java b/healthdisplay/src/main/java/de/psychose/ControlForm.java
new file mode 100644
index 0000000..4bec000
--- /dev/null
+++ b/healthdisplay/src/main/java/de/psychose/ControlForm.java
@@ -0,0 +1,54 @@
+package de.psychose;
+
+import javax.swing.*;
+import java.util.Observable;
+import java.util.Observer;
+
+/**
+ * @author: lucas
+ * @date: 15.11.14 22:23
+ */
+public class ControlForm {
+ private PulseControl pulse1;
+ private PulseControl pulse2;
+ private PulseControl pulse3;
+ private JPanel mainPanel;
+ private ActorDisplay actor1;
+ private ActorDisplay actor2;
+ private ActorDisplay actor3;
+
+ private final ChaOSCclient osCclient;
+
+ public JPanel getMainPanel() {
+ return mainPanel;
+ }
+
+
+ public ControlForm(ChaOSCclient chaOSCclient, final ActorData actorData1, final ActorData actorData2, final ActorData actorData3) {
+ this.osCclient = chaOSCclient;
+
+ addActor("merle", pulse1, actor1, actorData1);
+ addActor("uwe", pulse2, actor2, actorData2);
+ addActor("bjoern", pulse3, actor3, actorData3);
+
+ actor1.setShowErrors(true);
+ actor2.setShowErrors(true);
+ actor3.setShowErrors(true);
+
+ }
+
+ private void addActor(final String actor, PulseControl pulse, ActorDisplay display, ActorData actorData) {
+ pulse.addObserver(new Observer() {
+ @Override
+ public void update(Observable o, Object arg) {
+ if(arg instanceof PulseData) {
+ final PulseData data = (PulseData)arg;
+ osCclient.sendPulse(actor, data.getHeartbeat(), data.getPulse(), data.getOxygen());
+ }
+ }
+ });
+ display.setCaption(actor);
+ display.setActorData(actorData);
+ }
+
+}
diff --git a/healthdisplay/src/main/java/de/psychose/Main.java b/healthdisplay/src/main/java/de/psychose/Main.java
index b5a43b6..3bcfa59 100644
--- a/healthdisplay/src/main/java/de/psychose/Main.java
+++ b/healthdisplay/src/main/java/de/psychose/Main.java
@@ -1,60 +1,192 @@
package de.psychose;
+import com.illposed.osc.OSCListener;
+import com.illposed.osc.OSCMessage;
+
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.SocketException;
import java.net.UnknownHostException;
+import java.util.Date;
/**
* @author: lucas
* @date: 25.04.14 00:23
*/
public class Main {
+ private ChaOSCclient chaOSCclient;
+ private ControlForm controlForm;
+ private MainForm mainForm;
+
+ private int totalMessageCount = 0;
+ private int messagesTempCounter = 0;
+
+ private long totalTraffic = 0;
+ private long lastTraffic = 0;
+
+ private final ActorData actorData1 = new ActorData();
+ private final ActorData actorData2 = new ActorData();
+ private final ActorData actorData3 = new ActorData();
public static void main(String[] args) {
+ new Main();
+ }
- final boolean showErrors = args.length > 0;
-
- try
- {
- //UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
- UIManager.setLookAndFeel( "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" );
- }
- catch ( Exception e )
- {
+ public Main() {
+ try {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
+ } catch (Exception e) {
e.printStackTrace();
}
try {
- final ChaOSCclient chaOSCclient = new ChaOSCclient("chaosc", 7110);
- final SnmpStatClient snmp = new SnmpStatClient("switch/161");
- final MainForm mainForm = new MainForm(showErrors, chaOSCclient, snmp);
- final JFrame frame = new JFrame("MainForm");
+ this.chaOSCclient = new ChaOSCclient("chaosc", 7110);
+ this.controlForm = new ControlForm(chaOSCclient, actorData1, actorData2, actorData3);
+
+ final JFrame cframe = new JFrame("HD Control");
+ cframe.setContentPane(controlForm.getMainPanel());
+ cframe.setResizable(false);
+ cframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ cframe.pack();
+
+
+ this.mainForm = new MainForm(actorData1, actorData2, actorData3);
+ final JFrame frame = new JFrame("HD Main");
frame.setContentPane(mainForm.getMainPanel());
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+// frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
+ frame.setUndecorated(true);
frame.pack();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
chaOSCclient.stopReceiver();
- snmp.stopRunning();
+// snmp.stopRunning();
super.windowClosing(e);
}
});
- frame.setVisible(true);
- new Streamer(8888, mainForm.getMainPanel()).run();
+ addActor("merle", actorData1);
+ addActor("uwe", actorData2);
+ addActor("bjoern", actorData3);
+
+ cframe.setVisible(true);
+ frame.setVisible(true);
chaOSCclient.startReceiver();
} catch (UnknownHostException | SocketException e) {
e.printStackTrace();
}
+
}
+ private void addActor(final String actor, final ActorData actorData) {
+
+ chaOSCclient.addListener("/" + actor.toLowerCase() + "/heartbeat", new OSCListener() {
+ @Override
+ public void acceptMessage(Date time, OSCMessage message) {
+ if (message.getArguments().length == 3) {
+ totalMessageCount++;
+
+ if (message.getArguments()[1] instanceof Integer) {
+ int pulse = (int) (message.getArguments()[1]);
+
+ if (pulse > 60) { // try to skip the invalid pulserate from device
+
+ // set the heartrate
+ actorData.getPulseData().setPulse((int) (message.getArguments()[1]));
+
+ // set the beat ( 0 or 1 )
+ if (message.getArguments()[0] instanceof Integer) {
+ actorData.getPulseData().setHeartbeat((int) (message.getArguments()[0]));
+ }
+
+ //TODO: remove this, its for testing without tommy only
+ actorData.setTommyHeartbeat(((int) message.getArguments()[0]) == 1);
+
+ // set the oxy level
+ if (message.getArguments()[2] instanceof Integer) {
+ actorData.getPulseData().setOxygen((int) (message.getArguments()[2]));
+ }
+
+ actorData.setTimestampPulse();
+ }
+ }
+ }
+ }
+ });
+
+ chaOSCclient.addListener("/" + actor.toLowerCase() + "/ekg", new OSCListener() {
+ @Override
+ public void acceptMessage(Date time, OSCMessage message) {
+ if (message.getArguments().length == 1) {
+ totalMessageCount++;
+
+ if (message.getArguments()[0] instanceof Integer) {
+ actorData.setEkg((int) (message.getArguments()[0]));
+ }
+ }
+ }
+ });
+
+ chaOSCclient.addListener("/" + actor.toLowerCase() + "/emg", new OSCListener() {
+ @Override
+ public void acceptMessage(Date time, OSCMessage message) {
+ if (message.getArguments().length == 1) {
+ totalMessageCount++;
+
+ if (message.getArguments()[0] instanceof Integer) {
+ actorData.setEmg((int) (message.getArguments()[0]));
+ }
+ }
+ }
+ });
+
+ chaOSCclient.addListener("/" + actor.toLowerCase() + "/temperatur", new OSCListener() {
+ @Override
+ public void acceptMessage(Date time, OSCMessage message) {
+ if (message.getArguments().length == 1) {
+ totalMessageCount++;
+
+ if (message.getArguments()[0] instanceof Float) {
+ actorData.setTemperature((float) (message.getArguments()[0]));
+ }
+ }
+ }
+ });
+
+ chaOSCclient.addListener("/" + actor.toLowerCase() + "/airFlow", new OSCListener() {
+ @Override
+ public void acceptMessage(Date time, OSCMessage message) {
+ if (message.getArguments().length == 1) {
+ totalMessageCount++;
+
+ if (message.getArguments()[0] instanceof Integer) {
+ actorData.setAirflow((int) (message.getArguments()[0]));
+ }
+ }
+ }
+ });
+
+ chaOSCclient.addListener("/" + actor.toLowerCase() + "/tommypuls", new OSCListener() {
+ @Override
+ public void acceptMessage(Date time, OSCMessage message) {
+ if (message.getArguments().length == 1) {
+ totalMessageCount++;
+
+ if (message.getArguments()[0] instanceof Integer) {
+ actorData.setTommyHeartbeat((boolean) (message.getArguments()[0]));
+ }
+ //TODO: evtl muss das oben hier noch anders
+ }
+ }
+ });
+
+ }
}
diff --git a/healthdisplay/src/main/java/de/psychose/MainForm.form b/healthdisplay/src/main/java/de/psychose/MainForm.form
index 7a2b026..75ac05b 100644
--- a/healthdisplay/src/main/java/de/psychose/MainForm.form
+++ b/healthdisplay/src/main/java/de/psychose/MainForm.form
@@ -1,74 +1,52 @@
diff --git a/healthdisplay/src/main/java/de/psychose/MainForm.java b/healthdisplay/src/main/java/de/psychose/MainForm.java
index 6f46532..9178b32 100644
--- a/healthdisplay/src/main/java/de/psychose/MainForm.java
+++ b/healthdisplay/src/main/java/de/psychose/MainForm.java
@@ -1,152 +1,48 @@
package de.psychose;
-import com.illposed.osc.OSCListener;
-import com.illposed.osc.OSCMessage;
-
import javax.swing.*;
import java.awt.event.ActionEvent;
-import java.util.Date;
-import java.util.Observable;
-import java.util.Observer;
+import java.text.DecimalFormat;
/**
* @author: lucas
* @date: 14.04.14 21:43
*/
public class MainForm {
- private final ChaOSCclient osCclient;
private JPanel mainPanel;
+ private ActorHeart heart1;
private ActorDisplay actor1;
private ActorDisplay actor2;
private ActorDisplay actor3;
- private StatsDisplay statDisplay;
- private PulseControl pulse1;
- private PulseControl pulse2;
- private PulseControl pulse3;
-
- private int totalMessageCount = 0;
- private int messagesTempCounter = 0;
-
- private long totalTraffic = 0;
- private long lastTraffic = 0;
+ private JLabel breath;
+ private final DecimalFormat df = new DecimalFormat("#.0");
public JPanel getMainPanel() {
return mainPanel;
}
- public MainForm(final boolean showErrors, final ChaOSCclient chaOSCclient, final SnmpStatClient snmpStatClient) {
- this.osCclient = chaOSCclient;
+ public MainForm(final ActorData actorData1, final ActorData actorData2, final ActorData actorData3) {
- addActor("merle", "Körper 1", actor1, pulse1);
- addActor("uwe", "Körper 2", actor2, pulse2);
- addActor("bjoern", "Körper 3", actor3, pulse3);
+ actor1.setCaption("Körper 1");
+ actor2.setCaption("Körper 2");
+ actor3.setCaption("Körper 3");
+ actor1.setActorData(actorData1);
+ actor2.setActorData(actorData2);
+ actor3.setActorData(actorData3);
+ heart1.setActorData(actorData1, actorData2, actorData3);
-
- final Timer timer = new Timer(1000, new AbstractAction() {
+ final Timer timer = new Timer(100, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
- statDisplay.setMessagesPerSec(String.valueOf(totalMessageCount - messagesTempCounter));
- statDisplay.setMessageCount(String.valueOf(totalMessageCount));
- messagesTempCounter = totalMessageCount;
+ breath.setText(String.valueOf(actorData1.getAirflow()));
}
});
timer.setRepeats(true);
timer.start();
- final Timer snmpTimer = new Timer(5000, new AbstractAction() {
- @Override
- public void actionPerformed(ActionEvent e) {
- totalTraffic = snmpStatClient.getTrafficSum(); // in kB
- statDisplay.setTotalTraffic(String.valueOf(totalTraffic));
- statDisplay.setBandwidth(String.valueOf((totalTraffic - lastTraffic) / 5));
- lastTraffic = totalTraffic;
- }
- });
- snmpTimer.setRepeats(true);
- snmpStatClient.start();
-
-
- if(showErrors) {
- actor1.startErrorTimer();
- actor2.startErrorTimer();
- actor3.startErrorTimer();
- snmpTimer.start();
- } else {
- pulse1.hide();
- pulse2.hide();
- pulse3.hide();
- statDisplay.hide();
- }
-
-
}
- private void addActor(final String actor, final String label, final ActorDisplay actorDisplay, final PulseControl pulse) {
- actorDisplay.setCaption(label);
- osCclient.addListener("/" + actor.toLowerCase() + "/heartbeat", new OSCListener() {
- @Override
- public void acceptMessage(Date time, OSCMessage message) {
- if (message.getArguments().length == 3) {
- totalMessageCount++;
- actorDisplay.setHeartbeat(message.getArguments()[0].toString().equals("0") ? "Systole" : "Diastole");
- actorDisplay.setPulse(message.getArguments()[1].toString());
- actorDisplay.setOxy(message.getArguments()[2].toString());
- }
- }
- });
-
- osCclient.addListener("/" + actor.toLowerCase() + "/ekg", new OSCListener() {
- @Override
- public void acceptMessage(Date time, OSCMessage message) {
- if (message.getArguments().length == 1) {
- totalMessageCount++;
- actorDisplay.setEkg(message.getArguments()[0].toString());
- }
- }
- });
-
- osCclient.addListener("/" + actor.toLowerCase() + "/emg", new OSCListener() {
- @Override
- public void acceptMessage(Date time, OSCMessage message) {
- if (message.getArguments().length == 1) {
- totalMessageCount++;
- actorDisplay.setEmg(message.getArguments()[0].toString());
- }
- }
- });
-
- osCclient.addListener("/" + actor.toLowerCase() + "/temperatur", new OSCListener() {
- @Override
- public void acceptMessage(Date time, OSCMessage message) {
- if (message.getArguments().length == 1) {
- totalMessageCount++;
- actorDisplay.setTemperature(message.getArguments()[0].toString());
- }
- }
- });
-
- osCclient.addListener("/" + actor.toLowerCase() + "/airFlow", new OSCListener() {
- @Override
- public void acceptMessage(Date time, OSCMessage message) {
- if (message.getArguments().length == 1) {
- totalMessageCount++;
- actorDisplay.setBreath(message.getArguments()[0].toString());
- }
- }
- });
-
- pulse.addObserver(new Observer() {
- @Override
- public void update(Observable o, Object arg) {
- if(arg instanceof PulseData) {
- final PulseData data = (PulseData)arg;
- osCclient.sendPulse(actor, data.getHeartbeat(), data.getPulse(), data.getOxygen());
- }
- }
- });
- }
-
diff --git a/healthdisplay/src/main/java/de/psychose/PulseControl.form b/healthdisplay/src/main/java/de/psychose/PulseControl.form
index 9e77e02..a27987b 100644
--- a/healthdisplay/src/main/java/de/psychose/PulseControl.form
+++ b/healthdisplay/src/main/java/de/psychose/PulseControl.form
@@ -6,7 +6,6 @@
-
@@ -16,7 +15,6 @@
-
diff --git a/healthdisplay/src/main/java/de/psychose/PulseControl.java b/healthdisplay/src/main/java/de/psychose/PulseControl.java
index 915518e..191d0a2 100644
--- a/healthdisplay/src/main/java/de/psychose/PulseControl.java
+++ b/healthdisplay/src/main/java/de/psychose/PulseControl.java
@@ -35,7 +35,7 @@ public class PulseControl extends Observable {
int pulse = pulseWobbleCenter - PULSE_WOBBLE_WIDTH / 2 + random.nextInt(PULSE_WOBBLE_WIDTH);
if(pulse < 60) pulse = 60;
- if(pulse > 180) pulse = 180;
+ if(pulse > 230) pulse = 230;
final PulseData data = new PulseData(heartbeat, pulse, 95 + random.nextInt(4));
setChanged();
@@ -51,7 +51,6 @@ public class PulseControl extends Observable {
enableCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
- System.out.println("item state changed");
JCheckBox checkBox = (JCheckBox)e.getSource();
if(checkBox.isSelected()) {
if(!timer.isRunning()) {
@@ -69,8 +68,4 @@ public class PulseControl extends Observable {
});
}
- public void hide() {
- this.pulsePanel.setVisible(false);
- }
-
}
diff --git a/healthdisplay/src/main/java/de/psychose/SnmpStatClient.java b/healthdisplay/src/main/java/de/psychose/SnmpStatClient.java
deleted file mode 100644
index a76ba09..0000000
--- a/healthdisplay/src/main/java/de/psychose/SnmpStatClient.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package de.psychose;
-
-import org.snmp4j.CommunityTarget;
-import org.snmp4j.Snmp;
-import org.snmp4j.TransportMapping;
-import org.snmp4j.mp.SnmpConstants;
-import org.snmp4j.smi.OID;
-import org.snmp4j.smi.OctetString;
-import org.snmp4j.smi.UdpAddress;
-import org.snmp4j.smi.VariableBinding;
-import org.snmp4j.transport.DefaultUdpTransportMapping;
-import org.snmp4j.util.DefaultPDUFactory;
-import org.snmp4j.util.TreeEvent;
-import org.snmp4j.util.TreeUtils;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * @author: lucas
- * @date: 18.04.14 12:10
- */
-public class SnmpStatClient extends Thread {
- private final int napTime = 5000;
- public static final String OID_COUNTER = "1.3.6.1.2.1.2.2.1.10";
- private HashMap lastPorts = new HashMap<>();
- private HashMap sumPorts = new HashMap<>();
- private Snmp snmp;
- private CommunityTarget communityTarget;
- private long currentTrafficSum = 0;
- private Boolean doRun = true;
-
- private CommunityTarget getCommunityTarget(String host) {
- CommunityTarget communityTarget = new CommunityTarget();
- communityTarget.setCommunity(new OctetString("public"));
- communityTarget.setVersion(SnmpConstants.version2c);
- communityTarget.setAddress(new UdpAddress(host));
- communityTarget.setTimeout(300);
- return communityTarget;
- }
-
- public SnmpStatClient(String host) {
- try {
- final TransportMapping transportMapping = new DefaultUdpTransportMapping();
- transportMapping.listen();
-
- this.communityTarget = getCommunityTarget(host);
- this.snmp = new Snmp(transportMapping);
-
- } catch (IOException e) {
- e.printStackTrace();
- System.out.println("error: cannot get traffic from snmp target");
- }
- }
-
- public void stopRunning() {
- doRun = false;
- }
-
- @Override
- public void run() {
- if (snmp == null || this.communityTarget == null) {
- System.out.println("snmp error");
- doRun = false;
- }
-
- while (doRun && !Thread.interrupted()) {
- long sleepTill = System.currentTimeMillis() + napTime;
-
- getSNMPValues();
-
- try {
- long remainingTime = sleepTill - System.currentTimeMillis();
- if (remainingTime > 0)
- Thread.sleep(remainingTime);
- } catch (InterruptedException e) {
- return;
- }
-
- }
-
- }
-
- private void getSNMPValues() {
- if (snmp == null || this.communityTarget == null) {
- System.out.println("snmp error");
- doRun = false;
- return;
- }
-
- long sum = 0;
-
- try {
-
- final TreeUtils treeUtils = new TreeUtils(snmp, new DefaultPDUFactory());
- final List treeEventList = treeUtils.getSubtree(this.communityTarget, new OID(OID_COUNTER));
-
- for (TreeEvent treeEvent : treeEventList) {
- if (treeEvent.getStatus() == TreeEvent.STATUS_OK) {
- for (VariableBinding binding : treeEvent.getVariableBindings()) {
- int oid = binding.getOid().last();
- long value = binding.getVariable().toLong() / 1024; // convert bytes down to kilobytes
- long lastValue = 0;
- if (lastPorts.containsKey(oid)) lastValue = lastPorts.get(oid);
- long diff = value - lastValue;
-
- if (diff > 0) {
- sumPorts.put(oid, lastValue + diff);
- }
- }
- }
- }
- } catch (IllegalArgumentException e) {
- System.out.println("error: could not resolve address from snmp target");
- }
-
- for (long port : sumPorts.values()) {
- sum += port;
- }
-
- currentTrafficSum = sum;
- }
-
- public long getTrafficSum() {
- return currentTrafficSum;
- }
-
-}
diff --git a/healthdisplay/src/main/java/de/psychose/StatsDisplay.form b/healthdisplay/src/main/java/de/psychose/StatsDisplay.form
deleted file mode 100644
index 0ea389a..0000000
--- a/healthdisplay/src/main/java/de/psychose/StatsDisplay.form
+++ /dev/null
@@ -1,112 +0,0 @@
-
-
diff --git a/healthdisplay/src/main/java/de/psychose/StatsDisplay.java b/healthdisplay/src/main/java/de/psychose/StatsDisplay.java
deleted file mode 100644
index d0a002d..0000000
--- a/healthdisplay/src/main/java/de/psychose/StatsDisplay.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package de.psychose;
-
-import javax.swing.*;
-
-/**
- * @author: lucas
- * @date: 18.04.14 02:19
- */
-public class StatsDisplay {
- private JLabel lblCaption;
- private JLabel lblMessageCount;
- private JLabel lblMessagesPerSec;
- private JPanel statPanel;
- private JLabel lblTraffic;
- private JLabel lblBandwidth;
-
- public void setMessageCount(String count) {
- lblMessageCount.setText(count);
- }
-
- public void setMessagesPerSec(String messagesPerSec) {
- lblMessagesPerSec.setText(messagesPerSec);
- }
-
- public void setTotalTraffic(String totalTraffic) {
- lblTraffic.setText(totalTraffic);
- }
-
- public void setBandwidth(String bandwidth) {
- lblBandwidth.setText(bandwidth);
- }
-
- public void hide() {
- this.statPanel.setVisible(false);
- }
-
-}
diff --git a/healthdisplay/src/main/java/de/psychose/Streamer.java b/healthdisplay/src/main/java/de/psychose/Streamer.java
deleted file mode 100644
index deea16a..0000000
--- a/healthdisplay/src/main/java/de/psychose/Streamer.java
+++ /dev/null
@@ -1,256 +0,0 @@
-package de.psychose;
-
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.*;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.netty.handler.codec.frame.TooLongFrameException;
-import org.jboss.netty.handler.codec.http.*;
-import org.jboss.netty.handler.stream.ChunkedInput;
-import org.jboss.netty.handler.stream.ChunkedWriteHandler;
-import org.jboss.netty.util.CharsetUtil;
-
-import javax.imageio.ImageIO;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.channels.ClosedChannelException;
-import java.util.concurrent.Executors;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
-import static org.jboss.netty.handler.codec.http.HttpMethod.GET;
-import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
-import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
-
-/**
- * @author Maurus Cuelenaere
- * taken from http://blog.maurus.be/2012/05/09/netty-mjpeg-streamer/
- */
-public class Streamer {
- private final int port;
- private final Component view;
- private final ViewRenderer renderer;
-
- private class ViewRenderer implements Runnable {
- private final BufferedImage image;
- private final AtomicReference currentBuffer;
- private final AtomicInteger listenerCount;
- private final int napTime;
- private final ByteArrayOutputStream outputStream;
-
- public ViewRenderer() {
- this(10);
- }
-
- public ViewRenderer(int fps) {
- this.napTime = 1000 / fps;
- this.listenerCount = new AtomicInteger();
- this.currentBuffer = new AtomicReference();
- this.image = new BufferedImage(view.getWidth(), view.getHeight(), BufferedImage.TYPE_INT_RGB);
- this.outputStream = new ByteArrayOutputStream();
- }
-
- @Override
- public void run() {
- while (!Thread.interrupted()) {
- long sleepTill = System.currentTimeMillis() + napTime;
-
- if (listenerCount.get() > 0) {
- Graphics g = image.createGraphics();
- view.paint(g);
- g.dispose();
-
- byte[] newData = null;
- try {
- ImageIO.write(image, "jpg", outputStream);
- newData = outputStream.toByteArray();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- outputStream.reset();
- }
-
- if (newData != null) {
- currentBuffer.set(newData);
- synchronized (currentBuffer) {
- currentBuffer.notifyAll();
- }
- }
- }
-
- try {
- long remainingTime = sleepTill - System.currentTimeMillis();
- if (remainingTime > 0)
- Thread.sleep(remainingTime);
- } catch (InterruptedException e) {
- return;
- }
- }
- }
-
- public void registerListener() {
- listenerCount.incrementAndGet();
- }
-
- public void unregisterListener() {
- listenerCount.decrementAndGet();
- }
-
- public void waitForData() throws InterruptedException {
- synchronized (currentBuffer) {
- currentBuffer.wait();
- }
- }
-
- public byte[] getData() {
- return currentBuffer.get();
- }
- }
-
- private class HttpMultipartReplaceStream implements ChunkedInput {
- private final byte[] header;
- private boolean closed;
-
- public HttpMultipartReplaceStream(String boundary) {
- this.header = ("--" + boundary + "\r\nContent-Type: image/jpeg\r\n\r\n").getBytes();
-
- renderer.registerListener();
- }
-
- @Override
- public void close() throws Exception {
- if (closed)
- return;
-
- closed = true;
- renderer.unregisterListener();
- }
-
- @Override
- public boolean hasNextChunk() throws Exception {
- return !closed;
- }
-
- @Override
- public boolean isEndOfInput() throws Exception {
- return closed;
- }
-
- @Override
- public Object nextChunk() throws Exception {
- if (closed)
- return null;
-
- renderer.waitForData();
- byte[] body = renderer.getData();
-
- return ChannelBuffers.wrappedBuffer(header, body);
- }
- }
-
- private class HttpStreamerHandler extends SimpleChannelUpstreamHandler {
- @Override
- public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
- HttpRequest request = (HttpRequest) e.getMessage();
- if (request.getMethod() != GET) {
- sendError(ctx, METHOD_NOT_ALLOWED);
- return;
- } else if (!"/stream".equals(request.getUri())) {
- sendError(ctx, NOT_FOUND);
- return;
- }
-
- final String boundary = "thisisourmagicboundary";
- HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
- HttpHeaders.setHeader(response, "Connection", "close");
- HttpHeaders.setHeader(response, "Content-Type", "multipart/x-mixed-replace;boundary=" + boundary);
- HttpHeaders.setHeader(response, "Cache-control", "no-cache");
- HttpHeaders.setHeader(response, "Pragma", "no-cache");
- HttpHeaders.setHeader(response, "Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
-
- Channel ch = e.getChannel();
-
- final HttpMultipartReplaceStream replaceStream = new HttpMultipartReplaceStream(boundary);
- ch.getCloseFuture().addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(ChannelFuture future) throws Exception {
- // Stop the stream when the channel is closed
- replaceStream.close();
- }
- });
-
- // Write the initial line and the headers
- ch.write(response);
-
- // Write the content
- ChannelFuture writeFuture = ch.write(replaceStream);
-
- // Close the connection when the whole content is written out
- writeFuture.addListener(ChannelFutureListener.CLOSE);
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
- Channel ch = e.getChannel();
- Throwable cause = e.getCause();
- if (cause instanceof TooLongFrameException) {
- sendError(ctx, BAD_REQUEST);
- return;
- } else if (cause instanceof ClosedChannelException) {
- ch.close();
- return;
- }
-
- cause.printStackTrace();
- if (ch.isConnected())
- sendError(ctx, INTERNAL_SERVER_ERROR);
- }
-
- private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
- HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status);
- response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
- response.setContent(ChannelBuffers.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8));
-
- // Close the connection as soon as the error message is sent.
- ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);
- }
- }
-
- public Streamer(int port, Component view) {
- this.port = port;
- this.view = view;
- this.renderer = new ViewRenderer();
- }
-
- public void run() {
- // Configure the server.
- ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
-
- // Set up the event pipeline factory.
- bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
- @Override
- public ChannelPipeline getPipeline() throws Exception {
- // Create a default pipeline implementation.
- ChannelPipeline pipeline = Channels.pipeline();
-
- pipeline.addLast("decoder", new HttpRequestDecoder());
- pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
- pipeline.addLast("encoder", new HttpResponseEncoder());
- pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
- pipeline.addLast("handler", new HttpStreamerHandler());
-
- return pipeline;
- }
- });
-
- // Bind and start to accept incoming connections.
- bootstrap.bind(new InetSocketAddress(port));
-
- // Start the renderer
- new Thread(renderer, "Image renderer").start();
- }
-}
\ No newline at end of file
diff --git a/healthdisplay/src/main/java/de/psychose/Test.java b/healthdisplay/src/main/java/de/psychose/Test.java
deleted file mode 100644
index 6a1e54c..0000000
--- a/healthdisplay/src/main/java/de/psychose/Test.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package de.psychose;
-
-import javax.sound.midi.*;
-import java.io.File;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-
-public class Test {
- public static final int NOTE_ON = 0x90;
- public static final int NOTE_OFF = 0x80;
- public static final String[] NOTE_NAMES = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "H"};
-
- private static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
- System.out.printf("Display name: %s%n", netint.getDisplayName());
- System.out.printf("Name: %s%n", netint.getName());
- Enumeration inetAddresses = netint.getInetAddresses();
-
- for (InetAddress inetAddress : Collections.list(inetAddresses)) {
- System.out.printf("InetAddress: %s%n", inetAddress);
- }
- System.out.printf("%n");
- }
-
- public static void main(String[] args) throws Exception {
-
- SnmpStatClient snmpStatClient = new SnmpStatClient("switch/161");
-
- System.out.println(snmpStatClient.getTrafficSum() / 1024 / 1024 + "MB");
-
-
- if(true) return;
-
- Enumeration nets = NetworkInterface.getNetworkInterfaces();
- for (NetworkInterface netint : Collections.list(nets)) {
- displayInterfaceInformation(netint);
- }
-
-
- if(true) return;
-
- Sequence sequence = MidiSystem.getSequence(new File("/home/lucas/jake-avril_14th.mid"));
-
- HashSet notes = new HashSet();
-
- int trackNumber = 0;
- for (Track track : sequence.getTracks()) {
- trackNumber++;
- System.out.println("Track " + trackNumber + ": size = " + track.size());
- System.out.println();
- for (int i = 0; i < track.size(); i++) {
- MidiEvent event = track.get(i);
- System.out.print("@" + event.getTick() + " ");
- MidiMessage message = event.getMessage();
- if (message instanceof ShortMessage) {
- ShortMessage sm = (ShortMessage) message;
- System.out.print("Channel: " + sm.getChannel() + " ");
- if (sm.getCommand() == NOTE_ON) {
- int key = sm.getData1();
- int octave = (key / 12) - 1;
- int note = key % 12;
- String noteName = NOTE_NAMES[note];
- int velocity = sm.getData2();
- System.out.println("Note on, " + noteName + octave + " key=" + key + " velocity: " + velocity);
-
- notes.add(noteName + octave);
-
- } else if (sm.getCommand() == NOTE_OFF) {
- int key = sm.getData1();
- int octave = (key / 12) - 1;
- int note = key % 12;
- String noteName = NOTE_NAMES[note];
- int velocity = sm.getData2();
- System.out.println("Note off, " + noteName + octave + " key=" + key + " velocity: " + velocity);
- } else {
- System.out.println("Command:" + sm.getCommand());
- }
- } else {
- System.out.println("Other message: " + message.getClass());
- }
- }
-
- System.out.println();
-
-
- }
-
-
- System.out.println(notes);
- }
-}
\ No newline at end of file
diff --git a/healthdisplay/src/main/resources/de/psychose/heart1_klein.jpg b/healthdisplay/src/main/resources/de/psychose/heart1_klein.jpg
new file mode 100644
index 0000000..b6d2260
Binary files /dev/null and b/healthdisplay/src/main/resources/de/psychose/heart1_klein.jpg differ
diff --git a/healthdisplay/src/main/resources/de/psychose/heart1_klein_inv.jpg b/healthdisplay/src/main/resources/de/psychose/heart1_klein_inv.jpg
new file mode 100644
index 0000000..842f27e
Binary files /dev/null and b/healthdisplay/src/main/resources/de/psychose/heart1_klein_inv.jpg differ
diff --git a/healthdisplay/src/main/resources/de/psychose/heart2_klein.jpg b/healthdisplay/src/main/resources/de/psychose/heart2_klein.jpg
new file mode 100644
index 0000000..0c06048
Binary files /dev/null and b/healthdisplay/src/main/resources/de/psychose/heart2_klein.jpg differ
diff --git a/healthdisplay/src/main/resources/de/psychose/heart2_klein_inv.jpg b/healthdisplay/src/main/resources/de/psychose/heart2_klein_inv.jpg
new file mode 100644
index 0000000..4d1d6d5
Binary files /dev/null and b/healthdisplay/src/main/resources/de/psychose/heart2_klein_inv.jpg differ