001package var.mom.mqtt.smarthome;
002
003import java.awt.Color;
004import java.awt.Frame;
005import java.awt.Graphics;
006import java.awt.event.WindowAdapter;
007import java.awt.event.WindowEvent;
008import java.util.HashMap;
009import java.util.Map;
010
011import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
012import org.eclipse.paho.client.mqttv3.MqttCallback;
013import org.eclipse.paho.client.mqttv3.MqttClient;
014import org.eclipse.paho.client.mqttv3.MqttException;
015import org.eclipse.paho.client.mqttv3.MqttMessage;
016
017/**
018 * client for the Smart Home application: plots graphically sensor observations
019 *
020 * @author Sandro Leuchter
021 *
022 */
023class FloorPlotter extends Frame {
024        /**
025         *
026         */
027        private static final long serialVersionUID = 8554414803806269611L;
028        private static FloorPlotter plot;
029        private static final int MAXX = 1000;
030        private static final int MAXY = 600;
031        private static Map<String, Color> topicColors = new HashMap<>();
032        private static Color[] colors = { Color.red, Color.blue, Color.black, Color.cyan };
033        private static int lastColor = 0;
034        private static Color[][] plotdata = new Color[MAXX][MAXY];
035        private static long start = System.currentTimeMillis();
036        private static String sensorType;
037        private static String floor;
038
039        /**
040         * main routine and starting point of program. subscribes to all messages
041         * (sensor observations) on topic <tt>Conf.TOPICSTART/args[0]/+/args[1]</tt>
042         * i.e. all observations from a certain sensor type in all rooms on a certain
043         * floor.
044         *
045         * @param args[0] floor where sensor is located
046         * @param args[1] type of sensor
047         * @throws MqttException Paho library exceptions that have something to do with
048         *                       MQTT
049         * 
050         */
051        public static void main(String[] args) throws MqttException {
052                floor = args[0];
053                sensorType = args[1];
054                String topic = Conf.TOPICSTART + "/" + floor + "/+/" + sensorType;
055
056                plot = new FloorPlotter();
057                plot.setTitle("Floor Plot: " + floor);
058                plot.setSize(MAXX, MAXY);
059                plot.setVisible(true);
060
061                MqttClient client = new MqttClient(Conf.BROKER, MqttClient.generateClientId());
062                client.setCallback(new MqttCallback() {
063
064                        @Override
065                        public void connectionLost(Throwable arg0) {
066                        }
067
068                        @Override
069                        public void deliveryComplete(IMqttDeliveryToken arg0) {
070                        }
071
072                        @Override
073                        public void messageArrived(String topic, MqttMessage m) throws Exception {
074                                int x = (int) ((System.currentTimeMillis() - start) / 1000.0);
075                                try {
076                                        double messwert = Double.valueOf(m.toString());
077                                        int y = (int) Math.round(100.0 + (messwert * 10.0));
078                                        String[] topicLevels = topic.split("/");
079                                        String etage = topicLevels[1];
080                                        String raum = topicLevels[2];
081                                        if (!topicColors.containsKey(raum)) {
082                                                topicColors.put(raum, colors[lastColor++]);
083                                                System.out
084                                                                .println("Dem Plot der Etage " + etage + " wurde der " + sensorType + "-Sensor im Raum "
085                                                                                + raum + " in der Farbe " + topicColors.get(raum).toString() + " hinzugefügt.");
086                                        }
087                                        // System.out.format("(%3d, %3d) <- %2.2f, %s\n", x, y,
088                                        // Double.valueOf(m.toString()), raum);
089                                        plotdata[x][y] = topicColors.get(raum);
090                                        plot.repaint();
091                                } catch (NumberFormatException e) {
092                                        System.out.println(m); // message is not an observation:
093                                                                                        // will be printed out instead
094                                }
095                        }
096                });
097                client.connect();
098                client.subscribe(topic);
099                try {
100                        while (true) {
101                                Thread.sleep(1000);
102                        }
103                } catch (InterruptedException e) {
104                        System.err.println(e.getMessage());
105                } finally {
106                        try {
107                                client.disconnect();
108                        } catch (MqttException e) {
109                                // unrecoverable
110                        }
111                }
112        }
113
114        /**
115         * constructor. initializes window and adds WindowListener for close event
116         */
117        public FloorPlotter() {
118                addWindowListener(new WindowAdapter() {
119                        @Override
120                        public void windowClosing(WindowEvent ev) {
121                                dispose();
122                                System.exit(0);
123                        }
124                });
125        }
126
127        /**
128         * @see java.awt.Frame#paint(Graphics)
129         */
130        @Override
131        public void paint(Graphics g) {
132                for (int x = 0; x < MAXX; x++) {
133                        for (int y = 0; y < MAXY; y++) {
134                                if (plotdata[x][y] != null) {
135                                        g.setColor(plotdata[x][y]);
136                                        g.fillOval(x, y, 3, 3);
137                                }
138                        }
139                }
140        }
141}