From aff3fcad87d061650cf016ab0a2338e311ad31f7 Mon Sep 17 00:00:00 2001 From: nifi Date: Tue, 14 Sep 2010 10:38:12 +0000 Subject: [PATCH] Fixed to sort nodes by id. Added charts for packets received last 5 minutes and last/average hops to sink --- .../sics/contiki/collect/CollectServer.java | 97 ++++++++++++++----- .../src/se/sics/contiki/collect/Node.java | 8 +- .../contiki/collect/gui/NodeInfoPanel.java | 8 +- .../contiki/collect/gui/TimeChartPanel.java | 8 +- 4 files changed, 87 insertions(+), 34 deletions(-) diff --git a/examples/sky-shell/src/se/sics/contiki/collect/CollectServer.java b/examples/sky-shell/src/se/sics/contiki/collect/CollectServer.java index 6ca315e9e..02e3f199c 100644 --- a/examples/sky-shell/src/se/sics/contiki/collect/CollectServer.java +++ b/examples/sky-shell/src/se/sics/contiki/collect/CollectServer.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * 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 * Created : 3 jul 2008 - * Updated : $Date: 2010/09/08 12:39:40 $ - * $Revision: 1.12 $ + * Updated : $Date: 2010/09/14 10:38:12 $ + * $Revision: 1.13 $ */ package se.sics.contiki.collect; @@ -59,6 +59,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.Hashtable; import java.util.Properties; import javax.swing.BorderFactory; @@ -66,6 +67,7 @@ import javax.swing.DefaultListModel; import javax.swing.JCheckBoxMenuItem; import javax.swing.JFileChooser; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenu; import javax.swing.JMenuBar; @@ -73,6 +75,7 @@ import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; +import javax.swing.ListCellRenderer; import javax.swing.SwingUtilities; import javax.swing.event.ListSelectionEvent; 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 FIRMWARE_FILE = "sky-shell.ihex"; + private static final Comparator NODE_COMPARATOR = new Comparator() { + + 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 String configFile; @@ -162,7 +179,7 @@ public class CollectServer { nodeModel = new DefaultListModel(); nodeList = new JList(nodeModel); - nodeList.setPrototypeCellValue("Node 88888"); + nodeList.setPrototypeCellValue("888.888"); nodeList.addListSelectionListener(new ListSelectionListener() { @Override @@ -193,6 +210,10 @@ public class CollectServer { }}); 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); mainPanel = new JTabbedPane(); @@ -208,7 +229,8 @@ public class CollectServer { final int defaultMaxItemCount = 250; visualizers = new Visualizer[] { 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" }) { { ValueAxis axis = chart.getCategoryPlot().getRangeAxis(); @@ -225,7 +247,8 @@ public class CollectServer { 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" }) { { ValueAxis axis = chart.getCategoryPlot().getRangeAxis(); @@ -249,7 +272,7 @@ public class CollectServer { return data.getAveragePower(); } }, - new BarChartPanel(this, "Average Temperature", "Temperature", null, "Celsius", + new BarChartPanel(this, "Average Temperature", "Temperature", "Nodes", "Celsius", new String[] { "Celsius" }) { { chart.getCategoryPlot().getRangeAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits()); @@ -323,7 +346,7 @@ public class CollectServer { 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(); axis.setLowerBound(0.0); @@ -335,13 +358,14 @@ public class CollectServer { return data.getValue(SensorData.HOPS); } }, - new BarChartPanel(this, "Network Hops", "Network Hops", null, "Hops", - new String[] { "Hops" }) { + new BarChartPanel(this, "Network Hops (Per Node)", "Network Hops", "Nodes", "Hops", + new String[] { "Last Hop", "Average Hops" }, false) { { chart.getCategoryPlot().getRangeAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits()); } protected void addSensorData(SensorData data) { 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") { @@ -352,7 +376,45 @@ public class CollectServer { 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 NodeInfoPanel(), serialConsole @@ -706,7 +768,7 @@ public class CollectServer { public synchronized Node[] getNodes() { if (nodeCache == null) { Node[] tmp = nodeTable.values().toArray(new Node[nodeTable.size()]); - Arrays.sort(tmp); + Arrays.sort(tmp, NODE_COMPARATOR); nodeCache = tmp; } return nodeCache; @@ -731,18 +793,9 @@ public class CollectServer { final Node newNode = node; SwingUtilities.invokeLater(new Runnable() { public void run() { - // Insert the node sorted by id - String nodeID = newNode.getID(); boolean added = false; for (int i = 0, n = nodeModel.size(); i < n; i++) { - String id = ((Node) nodeModel.get(i)).getID(); - 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(); - } + int cmp = NODE_COMPARATOR.compare(newNode, ((Node) nodeModel.get(i))); if (cmp < 0) { nodeModel.insertElementAt(newNode, i); added = true; diff --git a/examples/sky-shell/src/se/sics/contiki/collect/Node.java b/examples/sky-shell/src/se/sics/contiki/collect/Node.java index ad959759e..55230ed6b 100644 --- a/examples/sky-shell/src/se/sics/contiki/collect/Node.java +++ b/examples/sky-shell/src/se/sics/contiki/collect/Node.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * 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 * Created : 3 jul 2008 - * Updated : $Date: 2008/08/29 10:00:23 $ - * $Revision: 1.3 $ + * Updated : $Date: 2010/09/14 10:38:12 $ + * $Revision: 1.4 $ */ package se.sics.contiki.collect; @@ -62,7 +62,7 @@ public class Node implements Comparable { public Node(String nodeID) { this.id = nodeID; - this.name = "Node " + nodeID; + this.name = nodeID; sensorDataAggregator = new SensorDataAggregator(this); } diff --git a/examples/sky-shell/src/se/sics/contiki/collect/gui/NodeInfoPanel.java b/examples/sky-shell/src/se/sics/contiki/collect/gui/NodeInfoPanel.java index 3fb6cc066..36ae72d63 100644 --- a/examples/sky-shell/src/se/sics/contiki/collect/gui/NodeInfoPanel.java +++ b/examples/sky-shell/src/se/sics/contiki/collect/gui/NodeInfoPanel.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * 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 * Created : 6 sep 2010 - * Updated : $Date: 2010/09/08 12:40:18 $ - * $Revision: 1.2 $ + * Updated : $Date: 2010/09/14 10:38:12 $ + * $Revision: 1.3 $ */ package se.sics.contiki.collect.gui; @@ -123,7 +123,7 @@ public class NodeInfoPanel extends JPanel implements Visualizer { for(Node node : selectedNodes) { SensorDataAggregator sda = node.getSensorDataAggregator(); long longest = sda.getLongestPeriod(); - sb.append(node.getName() + '\n' + sb.append("Node " + node.getName() + '\n' + " Packets Received: \t" + sda.getPacketCount() + '\n' + " Duplicates: \t" + sda.getDuplicateCount() + '\n'); if (longest > 0) { diff --git a/examples/sky-shell/src/se/sics/contiki/collect/gui/TimeChartPanel.java b/examples/sky-shell/src/se/sics/contiki/collect/gui/TimeChartPanel.java index 9ccff7bf8..3f8d084f5 100644 --- a/examples/sky-shell/src/se/sics/contiki/collect/gui/TimeChartPanel.java +++ b/examples/sky-shell/src/se/sics/contiki/collect/gui/TimeChartPanel.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * 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 * Created : 3 jul 2008 - * Updated : $Date: 2010/08/31 13:05:40 $ - * $Revision: 1.4 $ + * Updated : $Date: 2010/09/14 10:38:12 $ + * $Revision: 1.5 $ */ package se.sics.contiki.collect.gui; @@ -169,7 +169,7 @@ public abstract class TimeChartPanel extends JPanel implements Visualizer { timeSeries.removeAllSeries(); if (this.selectedNodes != null) { 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 int groupSize = getGroupSize(node); if (groupSize > 1) {