Fixed to sort nodes by id. Added charts for packets received last 5 minutes and last/average hops to sink

This commit is contained in:
nifi 2010-09-14 10:38:12 +00:00
parent a226286351
commit aff3fcad87
4 changed files with 87 additions and 34 deletions

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: CollectServer.java,v 1.12 2010/09/08 12:39:40 nifi Exp $ * $Id: CollectServer.java,v 1.13 2010/09/14 10:38:12 nifi Exp $
* *
* ----------------------------------------------------------------- * -----------------------------------------------------------------
* *
@ -34,8 +34,8 @@
* *
* Authors : Joakim Eriksson, Niclas Finne * Authors : Joakim Eriksson, Niclas Finne
* Created : 3 jul 2008 * Created : 3 jul 2008
* Updated : $Date: 2010/09/08 12:39:40 $ * Updated : $Date: 2010/09/14 10:38:12 $
* $Revision: 1.12 $ * $Revision: 1.13 $
*/ */
package se.sics.contiki.collect; package se.sics.contiki.collect;
@ -59,6 +59,7 @@ import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Properties; import java.util.Properties;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
@ -66,6 +67,7 @@ import javax.swing.DefaultListModel;
import javax.swing.JCheckBoxMenuItem; import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JMenu; import javax.swing.JMenu;
import javax.swing.JMenuBar; import javax.swing.JMenuBar;
@ -73,6 +75,7 @@ import javax.swing.JMenuItem;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTabbedPane; import javax.swing.JTabbedPane;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
@ -98,6 +101,20 @@ public class CollectServer {
public static final String INIT_SCRIPT = "collect-init.script"; public static final String INIT_SCRIPT = "collect-init.script";
public static final String FIRMWARE_FILE = "sky-shell.ihex"; public static final String FIRMWARE_FILE = "sky-shell.ihex";
private static final Comparator<Node> NODE_COMPARATOR = new Comparator<Node>() {
public int compare(Node o1, Node o2) {
String i1 = o1.getID();
String i2 = o2.getID();
// Shorter id first (4.0 before 10.0)
if (i1.length() == i2.length()) {
return i1.compareTo(i2);
}
return i1.length() - i2.length();
}
};
private Properties config = new Properties(); private Properties config = new Properties();
private String configFile; private String configFile;
@ -162,7 +179,7 @@ public class CollectServer {
nodeModel = new DefaultListModel(); nodeModel = new DefaultListModel();
nodeList = new JList(nodeModel); nodeList = new JList(nodeModel);
nodeList.setPrototypeCellValue("Node 88888"); nodeList.setPrototypeCellValue("888.888");
nodeList.addListSelectionListener(new ListSelectionListener() { nodeList.addListSelectionListener(new ListSelectionListener() {
@Override @Override
@ -193,6 +210,10 @@ public class CollectServer {
}}); }});
nodeList.setBorder(BorderFactory.createTitledBorder("Nodes")); nodeList.setBorder(BorderFactory.createTitledBorder("Nodes"));
ListCellRenderer renderer = nodeList.getCellRenderer();
if (renderer instanceof JLabel) {
((JLabel)renderer).setHorizontalAlignment(JLabel.RIGHT);
}
window.getContentPane().add(new JScrollPane(nodeList), BorderLayout.WEST); window.getContentPane().add(new JScrollPane(nodeList), BorderLayout.WEST);
mainPanel = new JTabbedPane(); mainPanel = new JTabbedPane();
@ -208,7 +229,8 @@ public class CollectServer {
final int defaultMaxItemCount = 250; final int defaultMaxItemCount = 250;
visualizers = new Visualizer[] { visualizers = new Visualizer[] {
mapPanel, mapPanel,
new BarChartPanel(this, "Average Power", "Average Power Consumption", null, "Power (mW)", new BarChartPanel(this, "Average Power", "Average Power Consumption",
"Nodes", "Power (mW)",
new String[] { "LPM", "CPU", "Radio listen", "Radio transmit" }) { new String[] { "LPM", "CPU", "Radio listen", "Radio transmit" }) {
{ {
ValueAxis axis = chart.getCategoryPlot().getRangeAxis(); ValueAxis axis = chart.getCategoryPlot().getRangeAxis();
@ -225,7 +247,8 @@ public class CollectServer {
dataset.addValue(aggregator.getTransmitPower(), categories[3], nodeName); dataset.addValue(aggregator.getTransmitPower(), categories[3], nodeName);
} }
}, },
new BarChartPanel(this, "Instantaneous Power", "Instantaneous Power Consumption", null, "Power (mW)", new BarChartPanel(this, "Instantaneous Power",
"Instantaneous Power Consumption", "Nodes", "Power (mW)",
new String[] { "LPM", "CPU", "Radio listen", "Radio transmit" }) { new String[] { "LPM", "CPU", "Radio listen", "Radio transmit" }) {
{ {
ValueAxis axis = chart.getCategoryPlot().getRangeAxis(); ValueAxis axis = chart.getCategoryPlot().getRangeAxis();
@ -249,7 +272,7 @@ public class CollectServer {
return data.getAveragePower(); return data.getAveragePower();
} }
}, },
new BarChartPanel(this, "Average Temperature", "Temperature", null, "Celsius", new BarChartPanel(this, "Average Temperature", "Temperature", "Nodes", "Celsius",
new String[] { "Celsius" }) { new String[] { "Celsius" }) {
{ {
chart.getCategoryPlot().getRangeAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits()); chart.getCategoryPlot().getRangeAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits());
@ -323,7 +346,7 @@ public class CollectServer {
return data.getLight2(); return data.getLight2();
} }
}, },
new TimeChartPanel(this, "Network Hops", "Network Hops", "Time", "Hops") { new TimeChartPanel(this, "Network Hops (Over Time)", "Network Hops", "Time", "Hops") {
{ {
ValueAxis axis = chart.getXYPlot().getRangeAxis(); ValueAxis axis = chart.getXYPlot().getRangeAxis();
axis.setLowerBound(0.0); axis.setLowerBound(0.0);
@ -335,13 +358,14 @@ public class CollectServer {
return data.getValue(SensorData.HOPS); return data.getValue(SensorData.HOPS);
} }
}, },
new BarChartPanel(this, "Network Hops", "Network Hops", null, "Hops", new BarChartPanel(this, "Network Hops (Per Node)", "Network Hops", "Nodes", "Hops",
new String[] { "Hops" }) { new String[] { "Last Hop", "Average Hops" }, false) {
{ {
chart.getCategoryPlot().getRangeAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits()); chart.getCategoryPlot().getRangeAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits());
} }
protected void addSensorData(SensorData data) { protected void addSensorData(SensorData data) {
dataset.addValue(data.getValue(SensorData.HOPS), categories[0], data.getNode().getName()); dataset.addValue(data.getValue(SensorData.HOPS), categories[0], data.getNode().getName());
dataset.addValue(data.getNode().getSensorDataAggregator().getAverageValue(SensorData.HOPS), categories[1], data.getNode().getName());
} }
}, },
new TimeChartPanel(this, "Latency", "Latency", "Time", "Seconds") { new TimeChartPanel(this, "Latency", "Latency", "Time", "Seconds") {
@ -352,7 +376,45 @@ public class CollectServer {
return data.getLatency(); return data.getLatency();
} }
}, },
new PacketChartPanel(this, "Received Packets", "Time", "Received Packets"), new PacketChartPanel(this, "Received (Over Time)", "Time", "Received Packets"),
new BarChartPanel(this, "Received (Per Node)", "Received Packets Per Node", "Nodes", "Packets",
new String[] { "Packets", "Duplicates" }) {
{
chart.getCategoryPlot().getRangeAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits());
}
protected void addSensorData(SensorData data) {
Node node = data.getNode();
SensorDataAggregator sda = node.getSensorDataAggregator();
dataset.addValue(sda.getDataCount(), categories[0], node.getName());
dataset.addValue(sda.getDuplicateCount(), categories[1], node.getName());
}
},
new BarChartPanel(this, "Received (5 min)", "Received Packets (last 5 min)", "Nodes", "Packets",
new String[] { "Packets", "Duplicates" }) {
{
chart.getCategoryPlot().getRangeAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits());
}
protected void addSensorData(SensorData data) {
Node node = data.getNode();
int dataCount = node.getSensorDataCount();
int packetCount = 0;
int duplicateCount = 0;
long earliestData = System.currentTimeMillis() - (5 * 60 * 60 * 1000);
for(int index = dataCount - 1; index >= 0; index--) {
SensorData sd = node.getSensorData(index);
if (sd.getSystemTime() < earliestData) {
break;
}
if (sd.isDuplicate()) {
duplicateCount++;
} else {
packetCount++;
}
}
dataset.addValue(packetCount, categories[0], node.getName());
dataset.addValue(duplicateCount, categories[1], node.getName());
}
},
// new SeqnoChartPanel(this, "Received Packets", "Received Packets", "Seqno", "Received Packets"), // new SeqnoChartPanel(this, "Received Packets", "Received Packets", "Seqno", "Received Packets"),
new NodeInfoPanel(), new NodeInfoPanel(),
serialConsole serialConsole
@ -706,7 +768,7 @@ public class CollectServer {
public synchronized Node[] getNodes() { public synchronized Node[] getNodes() {
if (nodeCache == null) { if (nodeCache == null) {
Node[] tmp = nodeTable.values().toArray(new Node[nodeTable.size()]); Node[] tmp = nodeTable.values().toArray(new Node[nodeTable.size()]);
Arrays.sort(tmp); Arrays.sort(tmp, NODE_COMPARATOR);
nodeCache = tmp; nodeCache = tmp;
} }
return nodeCache; return nodeCache;
@ -731,18 +793,9 @@ public class CollectServer {
final Node newNode = node; final Node newNode = node;
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
// Insert the node sorted by id
String nodeID = newNode.getID();
boolean added = false; boolean added = false;
for (int i = 0, n = nodeModel.size(); i < n; i++) { for (int i = 0, n = nodeModel.size(); i < n; i++) {
String id = ((Node) nodeModel.get(i)).getID(); int cmp = NODE_COMPARATOR.compare(newNode, ((Node) nodeModel.get(i)));
int cmp;
// Shorter id first (4.0 before 10.0)
if (nodeID.length() == id.length()) {
cmp = nodeID.compareTo(id);
} else {
cmp = nodeID.length() - id.length();
}
if (cmp < 0) { if (cmp < 0) {
nodeModel.insertElementAt(newNode, i); nodeModel.insertElementAt(newNode, i);
added = true; added = true;

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: Node.java,v 1.3 2008/08/29 10:00:23 nifi Exp $ * $Id: Node.java,v 1.4 2010/09/14 10:38:12 nifi Exp $
* *
* ----------------------------------------------------------------- * -----------------------------------------------------------------
* *
@ -34,8 +34,8 @@
* *
* Authors : Joakim Eriksson, Niclas Finne * Authors : Joakim Eriksson, Niclas Finne
* Created : 3 jul 2008 * Created : 3 jul 2008
* Updated : $Date: 2008/08/29 10:00:23 $ * Updated : $Date: 2010/09/14 10:38:12 $
* $Revision: 1.3 $ * $Revision: 1.4 $
*/ */
package se.sics.contiki.collect; package se.sics.contiki.collect;
@ -62,7 +62,7 @@ public class Node implements Comparable<Node> {
public Node(String nodeID) { public Node(String nodeID) {
this.id = nodeID; this.id = nodeID;
this.name = "Node " + nodeID; this.name = nodeID;
sensorDataAggregator = new SensorDataAggregator(this); sensorDataAggregator = new SensorDataAggregator(this);
} }

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: NodeInfoPanel.java,v 1.2 2010/09/08 12:40:18 nifi Exp $ * $Id: NodeInfoPanel.java,v 1.3 2010/09/14 10:38:12 nifi Exp $
* *
* ----------------------------------------------------------------- * -----------------------------------------------------------------
* *
@ -34,8 +34,8 @@
* *
* Authors : Joakim Eriksson, Niclas Finne * Authors : Joakim Eriksson, Niclas Finne
* Created : 6 sep 2010 * Created : 6 sep 2010
* Updated : $Date: 2010/09/08 12:40:18 $ * Updated : $Date: 2010/09/14 10:38:12 $
* $Revision: 1.2 $ * $Revision: 1.3 $
*/ */
package se.sics.contiki.collect.gui; package se.sics.contiki.collect.gui;
@ -123,7 +123,7 @@ public class NodeInfoPanel extends JPanel implements Visualizer {
for(Node node : selectedNodes) { for(Node node : selectedNodes) {
SensorDataAggregator sda = node.getSensorDataAggregator(); SensorDataAggregator sda = node.getSensorDataAggregator();
long longest = sda.getLongestPeriod(); long longest = sda.getLongestPeriod();
sb.append(node.getName() + '\n' sb.append("Node " + node.getName() + '\n'
+ " Packets Received: \t" + sda.getPacketCount() + '\n' + " Packets Received: \t" + sda.getPacketCount() + '\n'
+ " Duplicates: \t" + sda.getDuplicateCount() + '\n'); + " Duplicates: \t" + sda.getDuplicateCount() + '\n');
if (longest > 0) { if (longest > 0) {

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: TimeChartPanel.java,v 1.4 2010/08/31 13:05:40 nifi Exp $ * $Id: TimeChartPanel.java,v 1.5 2010/09/14 10:38:12 nifi Exp $
* *
* ----------------------------------------------------------------- * -----------------------------------------------------------------
* *
@ -34,8 +34,8 @@
* *
* Authors : Joakim Eriksson, Niclas Finne * Authors : Joakim Eriksson, Niclas Finne
* Created : 3 jul 2008 * Created : 3 jul 2008
* Updated : $Date: 2010/08/31 13:05:40 $ * Updated : $Date: 2010/09/14 10:38:12 $
* $Revision: 1.4 $ * $Revision: 1.5 $
*/ */
package se.sics.contiki.collect.gui; package se.sics.contiki.collect.gui;
@ -169,7 +169,7 @@ public abstract class TimeChartPanel extends JPanel implements Visualizer {
timeSeries.removeAllSeries(); timeSeries.removeAllSeries();
if (this.selectedNodes != null) { if (this.selectedNodes != null) {
for(Node node: this.selectedNodes) { for(Node node: this.selectedNodes) {
TimeSeries series = new TimeSeries(node.getName(), Second.class); TimeSeries series = new TimeSeries("Node " + node.getName(), Second.class);
// Reduce the number of items by grouping them and use the average for each group // Reduce the number of items by grouping them and use the average for each group
int groupSize = getGroupSize(node); int groupSize = getGroupSize(node);
if (groupSize > 1) { if (groupSize > 1) {