/**
   * Publish / send a message to an MQTT server
   *
   * @param topicName the name of the topic to publish to
   * @param qos the quality of service to delivery the message at (0,1,2)
   * @param payload the set of bytes to send to the MQTT server
   * @throws MqttException
   */
  public void publish(String topicName, int qos, byte[] payload) throws MqttException {

    // Connect to the MQTT server
    // issue a non-blocking connect and then use the token to wait until the
    // connect completes. An exception is thrown if connect fails.
    log("Connecting to " + brokerUrl + " with client ID " + client.getClientId());
    IMqttToken conToken = client.connect(conOpt, null, null);
    conToken.waitForCompletion();
    log("Connected");

    String time = new Timestamp(System.currentTimeMillis()).toString();
    log("Publishing at: " + time + " to topic \"" + topicName + "\" qos " + qos);

    // Construct the message to send
    MqttMessage message = new MqttMessage(payload);
    message.setQos(qos);

    // Send the message to the server, control is returned as soon
    // as the MQTT client has accepted to deliver the message.
    // Use the delivery token to wait until the message has been
    // delivered
    IMqttDeliveryToken pubToken = client.publish(topicName, message, null, null);
    pubToken.waitForCompletion();
    log("Published");

    // Disconnect the client
    // Issue the disconnect and then use a token to wait until
    // the disconnect completes.
    log("Disconnecting");
    IMqttToken discToken = client.disconnect(null, null);
    discToken.waitForCompletion();
    log("Disconnected");
  }
  /**
   * Constructs an instance of the sample client wrapper
   *
   * @param brokerUrl the url to connect to
   * @param clientId the client id to connect with
   * @param cleanSession clear state at end of connection or not (durable or non-durable
   *     subscriptions)
   * @param quietMode whether debug should be printed to standard out
   * @param userName the username to connect with
   * @param password the password for the user
   * @throws MqttException
   */
  public SampleAsyncWait(
      String brokerUrl,
      String clientId,
      boolean cleanSession,
      boolean quietMode,
      String userName,
      String password)
      throws MqttException {
    this.brokerUrl = brokerUrl;
    this.quietMode = quietMode;
    this.clean = cleanSession;
    this.userName = userName;
    this.password = password;
    // This sample stores in a temporary directory... where messages temporarily
    // stored until the message has been delivered to the server.
    // ..a real application ought to store them somewhere
    // where they are not likely to get deleted or tampered with
    String tmpDir = System.getProperty("java.io.tmpdir");
    MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(tmpDir);

    try {
      // Construct the connection options object that contains connection parameters
      // such as cleanSession and LWT
      conOpt = new MqttConnectOptions();
      conOpt.setCleanSession(clean);
      if (password != null) {
        conOpt.setPassword(this.password.toCharArray());
      }
      if (userName != null) {
        conOpt.setUserName(this.userName);
      }

      // Construct a non-blocking MQTT client instance
      client = new MqttAsyncClient(this.brokerUrl, clientId, dataStore);

      // Set this wrapper as the callback handler
      client.setCallback(this);

    } catch (MqttException e) {
      e.printStackTrace();
      log("Unable to set up client: " + e.toString());
      System.exit(1);
    }
  }
  public static void main(String[] args) {
    clearConsolidation();

    try {
      final MqttAsyncClient mqttClient =
          new MqttAsyncClient(BROKER_URI, MqttClient.generateClientId(), new MemoryPersistence());

      mqttClient.setCallback(
          new MqttCallback() {

            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {

              try {
                // TODO retrieve sensor value and sensor name
                double sensorValue = 0;
                // sensorValue = ...
                String sensorName = null;
                // sensorName = ...

                ConsolidatedValues conso = consolidation.get(sensorName);
                if (conso == null) {
                  conso = new ConsolidatedValues();
                  consolidation.put(sensorName, conso);
                }

                conso.addSample(sensorValue);

                // end of the minute?
                if (System.currentTimeMillis() > nextMinuteTimestamp) {
                  System.out.println("PUBLISH CONSOLIDATION");

                  // TODO publish computed average value

                  clearConsolidation();
                }
              } catch (RuntimeException e) {
                e.printStackTrace();
              }
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {
              // not used
            }

            @Override
            public void connectionLost(Throwable cause) {
              System.out.println("Connection lost: " + cause.getLocalizedMessage());
            }
          });
      mqttClient.connect(
          null,
          new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {

              // TODO subscribe to live data
            }

            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
              exception.printStackTrace();
            }
          });
    } catch (MqttException e) {
      e.printStackTrace();
    }
  }
  public static void main(String[] args) throws JSONException, MqttException {

    final MqttAsyncClient mqtt = MqttAsyncClient.createMqttClient("52fcc04c4dc903d66d6f8f92");
    //		System.out.println(getCid());

  }
  /**
   * Subscribe to a topic on an MQTT server Once subscribed this method waits for the messages to
   * arrive from the server that match the subscription. It continues listening for messages until
   * the enter key is pressed.
   *
   * @param topicName to subscribe to (can be wild carded)
   * @param qos the maximum quality of service to receive messages at for this subscription
   * @throws MqttException
   */
  public void subscribe(String topicName, int qos) throws MqttException {

    // Connect to the MQTT server
    // issue a non-blocking connect and then use the token to wait until the
    // connect completes. An exception is thrown if connect fails.
    log("Connecting to " + brokerUrl + " with client ID " + client.getClientId());
    IMqttToken conToken = client.connect(conOpt, null, null);
    conToken.waitForCompletion();
    log("Connected");

    // Subscribe to the requested topic.
    // Control is returned as soon client has accepted to deliver the subscription.
    // Use a token to wait until the subscription is in place.
    log("Subscribing to topic \"" + topicName + "\" qos " + qos);

    IMqttToken subToken = client.subscribe(topicName, qos, null, null);
    subToken.waitForCompletion();
    log("Subscribed to topic \"" + topicName);

    // Continue waiting for messages until the Enter is pressed
    log("Press <Enter> to exit");
    try {
      System.in.read();
    } catch (IOException e) {
      // If we can't read we'll just exit
    }

    // Disconnect the client
    // Issue the disconnect and then use the token to wait until
    // the disconnect completes.
    log("Disconnecting");
    IMqttToken discToken = client.disconnect(null, null);
    discToken.waitForCompletion();
    log("Disconnected");
  }