changed snmp timing to 100ms timeout

added control to fake pulse heartrate
disabled snmp check on display mode
This commit is contained in:
Lucas Pleß 2014-05-03 11:46:11 +02:00
parent ac48b496fb
commit 52e6847fc2
12 changed files with 357 additions and 81 deletions

View File

@ -125,6 +125,9 @@
<item class="de.psychose.StatsDisplay" icon="" removable="true" auto-create-binding="false" can-attach-label="false"> <item class="de.psychose.StatsDisplay" icon="" removable="true" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="0" /> <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="0" />
</item> </item>
<item class="de.psychose.PulseControl" icon="" removable="true" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="0" />
</item>
</group> </group>
</component> </component>
</project> </project>

View File

@ -63,7 +63,7 @@
<configuration> <configuration>
<archive> <archive>
<manifest> <manifest>
<mainClass>de.psychose.MainForm</mainClass> <mainClass>de.psychose.Main</mainClass>
</manifest> </manifest>
</archive> </archive>
<descriptorRefs> <descriptorRefs>

View File

@ -9,6 +9,7 @@ import java.awt.event.ActionEvent;
* @date: 14.04.14 21:44 * @date: 14.04.14 21:44
*/ */
public class ActorDisplay { public class ActorDisplay {
private final Timer timer;
private final static Color onColor = Color.WHITE; private final static Color onColor = Color.WHITE;
private final static Color offColor = Color.RED; private final static Color offColor = Color.RED;
private final static String offText = "no data"; private final static String offText = "no data";
@ -73,7 +74,7 @@ public class ActorDisplay {
} }
public ActorDisplay() { public ActorDisplay() {
final Timer timer = new Timer(100, new AbstractAction() { this.timer = new Timer(100, new AbstractAction() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
@ -127,8 +128,11 @@ public class ActorDisplay {
} }
} }
}); });
timer.setRepeats(true); this.timer.setRepeats(true);
timer.start(); }
public void startErrorTimer() {
this.timer.start();
} }
} }

View File

@ -40,6 +40,22 @@ public class ChaOSCclient {
return changeChaoscSubscription(true); return changeChaoscSubscription(true);
} }
public void sendPulse(String actor, int heartbeat, int pulse, int oxygen) {
try {
OSCMessage subscribeMessage = new OSCMessage("/" + actor + "/heartbeat");
subscribeMessage.addArgument(heartbeat);
subscribeMessage.addArgument(pulse);
subscribeMessage.addArgument(oxygen);
portOut.send(subscribeMessage);
} catch (IOException e) {
System.out.println("could not send pulse OSC Message");
e.printStackTrace();
}
}
private boolean changeChaoscSubscription(boolean subscribe) { private boolean changeChaoscSubscription(boolean subscribe) {
try { try {
OSCMessage subscribeMessage = new OSCMessage("/" + (subscribe ? "subscribe" : "unsubscribe")); OSCMessage subscribeMessage = new OSCMessage("/" + (subscribe ? "subscribe" : "unsubscribe"));
@ -50,8 +66,6 @@ public class ChaOSCclient {
portOut.send(subscribeMessage); portOut.send(subscribeMessage);
return true; return true;
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -70,6 +84,7 @@ public class ChaOSCclient {
InetAddress addr = a.nextElement(); InetAddress addr = a.nextElement();
if (addr.isSiteLocalAddress()) { if (addr.isSiteLocalAddress()) {
System.out.println("found address: " + addr.getHostAddress());
return addr; return addr;
} }
} }

View File

@ -0,0 +1,59 @@
package de.psychose;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.SocketException;
import java.net.UnknownHostException;
/**
* @author: lucas
* @date: 25.04.14 00:23
*/
public class Main {
public static void main(String[] args) {
final boolean showErrors = args.length > 0;
try
{
//UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
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");
frame.setContentPane(mainForm.getMainPanel());
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
chaOSCclient.stopReceiver();
super.windowClosing(e);
}
});
frame.setVisible(true);
new Streamer(8888, mainForm.getMainPanel()).run();
chaOSCclient.startReceiver();
} catch (UnknownHostException | SocketException e) {
e.printStackTrace();
}
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="de.psychose.MainForm"> <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="de.psychose.MainForm">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="4" column-count="6" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="5" column-count="6" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="5" bottom="5" right="5"/> <margin top="5" left="5" bottom="5" right="5"/>
<constraints> <constraints>
<xy x="20" y="20" width="720" height="576"/> <xy x="20" y="20" width="720" height="576"/>
@ -16,27 +16,27 @@
<children> <children>
<hspacer id="f912c"> <hspacer id="f912c">
<constraints> <constraints>
<grid row="1" column="5" row-span="2" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> <grid row="2" column="5" row-span="2" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
</hspacer> </hspacer>
<hspacer id="6a2b8"> <hspacer id="6a2b8">
<constraints> <constraints>
<grid row="1" column="1" row-span="2" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> <grid row="2" column="1" row-span="2" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
</hspacer> </hspacer>
<hspacer id="67192"> <hspacer id="67192">
<constraints> <constraints>
<grid row="1" column="3" row-span="2" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> <grid row="2" column="3" row-span="2" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
</hspacer> </hspacer>
<nested-form id="5519b" form-file="de/psychose/StatsDisplay.form" binding="statDisplay"> <nested-form id="5519b" form-file="de/psychose/StatsDisplay.form" binding="statDisplay">
<constraints> <constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/> <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
</nested-form> </nested-form>
<vspacer id="ad2ab"> <vspacer id="ad2ab">
<constraints> <constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
</vspacer> </vspacer>
<nested-form id="736bf" form-file="de/psychose/ActorDisplay.form" binding="actor2"> <nested-form id="736bf" form-file="de/psychose/ActorDisplay.form" binding="actor2">
@ -54,6 +54,21 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
</nested-form> </nested-form>
<nested-form id="5b53" form-file="de/psychose/PulseControl.form" binding="pulse1">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="4c934" form-file="de/psychose/PulseControl.form" binding="pulse2">
<constraints>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
<nested-form id="f9eb3" form-file="de/psychose/PulseControl.form" binding="pulse3">
<constraints>
<grid row="1" column="4" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
</children> </children>
</grid> </grid>
</form> </form>

View File

@ -5,25 +5,24 @@ import com.illposed.osc.OSCMessage;
import javax.swing.*; import javax.swing.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Date; import java.util.Date;
import java.util.Observable;
import java.util.Observer;
/** /**
* @author: lucas * @author: lucas
* @date: 14.04.14 21:43 * @date: 14.04.14 21:43
*/ */
public class MainForm { public class MainForm {
private ChaOSCclient osCclient; private final ChaOSCclient osCclient;
private SnmpStatClient snmpStatClient;
private JPanel mainPanel; private JPanel mainPanel;
private ActorDisplay actor1; private ActorDisplay actor1;
private ActorDisplay actor2; private ActorDisplay actor2;
private ActorDisplay actor3; private ActorDisplay actor3;
private StatsDisplay statDisplay; private StatsDisplay statDisplay;
private PulseControl pulse1;
private PulseControl pulse2;
private PulseControl pulse3;
private int totalMessageCount = 0; private int totalMessageCount = 0;
private int messagesTempCounter = 0; private int messagesTempCounter = 0;
@ -31,15 +30,17 @@ public class MainForm {
private long totalTraffic = 0; private long totalTraffic = 0;
private long lastTraffic = 0; private long lastTraffic = 0;
public MainForm(final ChaOSCclient chaOSCclient, final SnmpStatClient snmpStatClient) { public JPanel getMainPanel() {
return mainPanel;
}
public MainForm(final boolean showErrors, final ChaOSCclient chaOSCclient, final SnmpStatClient snmpStatClient) {
this.osCclient = chaOSCclient; this.osCclient = chaOSCclient;
this.snmpStatClient = snmpStatClient;
addActor("merle", "Proband 1", actor1); addActor("merle", "Körper 1", actor1, pulse1);
addActor("uwe", "Proband 2", actor2); addActor("uwe", "Körper 2", actor2, pulse2);
addActor("bjoern", "Proband 3", actor3); addActor("bjoern", "Körper 3", actor3, pulse3);
osCclient.startReceiver();
final Timer timer = new Timer(1000, new AbstractAction() { final Timer timer = new Timer(1000, new AbstractAction() {
@Override @Override
@ -55,18 +56,30 @@ public class MainForm {
final Timer snmpTimer = new Timer(5000, new AbstractAction() { final Timer snmpTimer = new Timer(5000, new AbstractAction() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
totalTraffic = snmpStatClient.getTrafficSum(); totalTraffic = snmpStatClient.getTrafficSum(); // in kB
statDisplay.setTotalTraffic(String.valueOf(totalTraffic / 1024)); statDisplay.setTotalTraffic(String.valueOf(totalTraffic));
statDisplay.setBandwidth(String.valueOf((totalTraffic - lastTraffic) / 1024 / 5)); statDisplay.setBandwidth(String.valueOf((totalTraffic - lastTraffic) / 5));
lastTraffic = totalTraffic; lastTraffic = totalTraffic;
} }
}); });
snmpTimer.setRepeats(true); snmpTimer.setRepeats(true);
if(showErrors) {
actor1.startErrorTimer();
actor2.startErrorTimer();
actor3.startErrorTimer();
snmpTimer.start(); snmpTimer.start();
} else {
pulse1.hide();
pulse2.hide();
pulse3.hide();
statDisplay.hide();
}
} }
private void addActor(final String actor, final String label, final ActorDisplay actorDisplay) { private void addActor(final String actor, final String label, final ActorDisplay actorDisplay, final PulseControl pulse) {
actorDisplay.setCaption(label); actorDisplay.setCaption(label);
osCclient.addListener("/" + actor.toLowerCase() + "/heartbeat", new OSCListener() { osCclient.addListener("/" + actor.toLowerCase() + "/heartbeat", new OSCListener() {
@Override @Override
@ -119,38 +132,18 @@ public class MainForm {
} }
} }
}); });
}
public static void main(String[] args) { pulse.addObserver(new Observer() {
final String host = args.length > 0 ? args[0] : "chaosc";
final int port = args.length > 1 ? Integer.parseInt(args[1]) : 7110;
try {
final ChaOSCclient chaOSCclient = new ChaOSCclient(host, port);
final SnmpStatClient snmp = new SnmpStatClient("switch/161");
final MainForm mainForm = new MainForm(chaOSCclient, snmp);
final JFrame frame = new JFrame("MainForm");
frame.setContentPane(mainForm.mainPanel);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.addWindowListener(new WindowAdapter() {
@Override @Override
public void windowClosing(WindowEvent e) { public void update(Observable o, Object arg) {
chaOSCclient.stopReceiver(); if(arg instanceof PulseData) {
super.windowClosing(e); final PulseData data = (PulseData)arg;
osCclient.sendPulse(actor, data.getHeartbeat(), data.getPulse(), data.getOxygen());
}
} }
}); });
frame.setVisible(true);
new Streamer(8888, mainForm.mainPanel).run();
} catch (UnknownHostException | SocketException e) {
e.printStackTrace();
}
} }
} }

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="de.psychose.PulseControl">
<grid id="27dc6" binding="pulsePanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="261" height="38"/>
</constraints>
<properties>
<background color="-16777216"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="a9565" class="javax.swing.JCheckBox" binding="enableCheckBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<foreground color="-1"/>
<selected value="false"/>
<text value="Enable"/>
</properties>
</component>
<component id="dadb" class="javax.swing.JSpinner" binding="spinner1" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
<minimum-size width="50" height="-1"/>
<preferred-size width="50" height="-1"/>
</grid>
</constraints>
<properties>
<background color="-16711423"/>
</properties>
</component>
<hspacer id="dec01">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</form>

View File

@ -0,0 +1,76 @@
package de.psychose;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Observable;
import java.util.Random;
/**
* @author: lucas
* @date: 03.05.14 10:10
*/
public class PulseControl extends Observable {
private final int PULSE_WOBBLE_WIDTH = 10;
private JCheckBox enableCheckBox;
private JSpinner spinner1;
private JPanel pulsePanel;
private Timer timer;
private Random random = new Random();
private int heartbeat = 0;
public PulseControl() {
enableCheckBox.setFocusable(false);
spinner1.setFocusable(false);
spinner1.setValue(110);
timer = new Timer(100, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
heartbeat = (heartbeat+1) % 2;
final int pulseWobbleCenter = (int)spinner1.getValue();
int pulse = pulseWobbleCenter - PULSE_WOBBLE_WIDTH / 2 + random.nextInt(PULSE_WOBBLE_WIDTH);
if(pulse < 60) pulse = 60;
if(pulse > 180) pulse = 180;
final PulseData data = new PulseData(heartbeat, pulse, 95 + random.nextInt(4));
setChanged();
notifyObservers(data);
final int delay = 60000 / pulse;
timer.setDelay(delay);
}
});
timer.setRepeats(true);
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()) {
System.out.println("starting pulsecontrol " + this);
timer.start();
}
} else {
if(timer.isRunning()) {
System.out.println("stopping pulsecontrol " + this);
timer.stop();
}
}
}
});
}
public void hide() {
this.pulsePanel.setVisible(false);
}
}

View File

@ -0,0 +1,55 @@
package de.psychose;
/**
* @author: lucas
* @date: 03.05.14 10:58
*/
public class PulseData {
private int heartbeat;
private int pulse;
private int oxygen;
public PulseData() {
}
public PulseData(int heartbeat, int pulse, int oxygen) {
this.heartbeat = heartbeat;
this.pulse = pulse;
this.oxygen = oxygen;
}
public int getHeartbeat() {
return heartbeat;
}
public void setHeartbeat(int heartbeat) {
this.heartbeat = heartbeat;
}
public int getPulse() {
return pulse;
}
public void setPulse(int pulse) {
this.pulse = pulse;
}
public int getOxygen() {
return oxygen;
}
public void setOxygen(int oxygen) {
this.oxygen = oxygen;
}
@Override
public String toString() {
return "PulseData{" +
"heartbeat=" + heartbeat +
", pulse=" + pulse +
", oxygen=" + oxygen +
"} ";
}
}

View File

@ -23,40 +23,52 @@ import java.util.List;
*/ */
public class SnmpStatClient { public class SnmpStatClient {
public static final String OID_COUNTER = "1.3.6.1.2.1.2.2.1.10"; public static final String OID_COUNTER = "1.3.6.1.2.1.2.2.1.10";
private final String host;
private HashMap<Integer, Long> lastPorts = new HashMap<>(); private HashMap<Integer, Long> lastPorts = new HashMap<>();
private HashMap<Integer, Long> sumPorts = new HashMap<>(); private HashMap<Integer, Long> sumPorts = new HashMap<>();
private Snmp snmp;
private CommunityTarget communityTarget;
private CommunityTarget getCommunityTarget() { private CommunityTarget getCommunityTarget(String host) {
CommunityTarget communityTarget = new CommunityTarget(); CommunityTarget communityTarget = new CommunityTarget();
communityTarget.setCommunity(new OctetString("public")); communityTarget.setCommunity(new OctetString("public"));
communityTarget.setVersion(SnmpConstants.version2c); communityTarget.setVersion(SnmpConstants.version2c);
communityTarget.setAddress(new UdpAddress(host)); communityTarget.setAddress(new UdpAddress(host));
communityTarget.setTimeout(500); communityTarget.setTimeout(100);
return communityTarget; return communityTarget;
} }
public SnmpStatClient(String host) { public SnmpStatClient(String host) {
this.host = host;
}
public long getTrafficSum() {
long sum = 0;
try { try {
final TransportMapping transportMapping = new DefaultUdpTransportMapping(); final TransportMapping transportMapping = new DefaultUdpTransportMapping();
transportMapping.listen(); transportMapping.listen();
final Snmp snmp = new Snmp(transportMapping); this.communityTarget = getCommunityTarget(host);
this.snmp = new Snmp(transportMapping);
} catch (IOException e) {
System.out.println("error: cannot get traffic from snmp target");
}
}
public long getTrafficSum() {
if (snmp == null || this.communityTarget == null) {
System.out.println("snmp error");
return 0;
}
long sum = 0;
try {
final TreeUtils treeUtils = new TreeUtils(snmp, new DefaultPDUFactory()); final TreeUtils treeUtils = new TreeUtils(snmp, new DefaultPDUFactory());
final List<TreeEvent> treeEventList = treeUtils.getSubtree(getCommunityTarget(), new OID(OID_COUNTER)); final List<TreeEvent> treeEventList = treeUtils.getSubtree(this.communityTarget, new OID(OID_COUNTER));
for (TreeEvent treeEvent : treeEventList) { for (TreeEvent treeEvent : treeEventList) {
if (treeEvent.getStatus() == TreeEvent.STATUS_OK) { if (treeEvent.getStatus() == TreeEvent.STATUS_OK) {
for (VariableBinding binding : treeEvent.getVariableBindings()) { for (VariableBinding binding : treeEvent.getVariableBindings()) {
int oid = binding.getOid().last(); int oid = binding.getOid().last();
long value = binding.getVariable().toLong(); long value = binding.getVariable().toLong() / 1024; // convert bytes down to kilobytes
long lastValue = 0; long lastValue = 0;
if (lastPorts.containsKey(oid)) lastValue = lastPorts.get(oid); if (lastPorts.containsKey(oid)) lastValue = lastPorts.get(oid);
long diff = value - lastValue; long diff = value - lastValue;
@ -67,10 +79,8 @@ public class SnmpStatClient {
} }
} }
} }
} catch (IllegalArgumentException e) {
snmp.close(); System.out.println("error: could not resolve address from snmp target");
} catch (IOException e) {
e.printStackTrace();
} }
for (long port : sumPorts.values()) { for (long port : sumPorts.values()) {

View File

@ -30,4 +30,8 @@ public class StatsDisplay {
lblBandwidth.setText(bandwidth); lblBandwidth.setText(bandwidth);
} }
public void hide() {
this.statPanel.setVisible(false);
}
} }