@Override
  public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
    try {
      String msgText = mqttMessage.toString();
      if (log.isDebugEnabled()) {
        log.debug(msgText);
      }
      PrivilegedCarbonContext.startTenantFlow();
      PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);

      if (log.isDebugEnabled()) {
        log.debug("Event received in MQTT Event Adapter - " + msgText);
      }

      if (contentValidator != null && contentTransformer != null) {
        ContentInfo contentInfo;
        Map<String, Object> dynamicProperties = new HashMap<>();
        dynamicProperties.put(MQTTEventAdapterConstants.TOPIC, topic);
        msgText = (String) contentTransformer.transform(msgText, dynamicProperties);
        contentInfo = contentValidator.validate(msgText, dynamicProperties);
        if (contentInfo != null && contentInfo.isValidContent()) {
          eventAdapterListener.onEvent(contentInfo.getMessage());
        }
      } else {
        eventAdapterListener.onEvent(msgText);
      }
    } finally {
      PrivilegedCarbonContext.endTenantFlow();
    }
  }
  @Override
  public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {

    if (MQTTMessageWrapper.isMyMessage(mqttMessage.toString())) return;

    String command = MQTTMessageWrapper.getCommand(mqttMessage.toString());
    switch (command) {
      case MQTTMessageWrapper.RcommandGetListDevice:
        // fine-tuning the GUI
        JSONObject jason = new JSONObject(mqttMessage.toString());

        JSONArray deviceList = jason.getJSONArray("devicesList");

        devices = new ArrayList<>();
        adapter.clear();

        for (int i = 0; i < deviceList.length(); i++) {
          JSONObject device = deviceList.getJSONObject(i);

          String friendlyName = (String) device.get("FriendlyName");
          // String index = new String(i + 1);

          devices.add(new Device(i + 1, friendlyName + " " + String.valueOf(i + 1), false, true));

          // Iterate through the elements of the array i.
          // Get thier value.
          // Get the value for the first element and the value for the last element.
        }

        //                String friendlyName = (String) jason.get("FriendlyName");

        // devices.add(new Device(1, "Z-Wave Light Bulb 1", false, true));
        // devices.add(new Device(1, "Z-Wave Light Bulb 2", false, true));

        ListView list = (ListView) findViewById(R.id.list);
        adapter = new Adapter(this, devices);
        list.setAdapter(adapter);

        break;
      case MQTTMessageWrapper.RcommandAddDevice:
        // Add new device
        break;
      default:
        break;
    }

    Log.d(TAG, "Received data from topic: " + topic + ", Mqtt message: " + mqttMessage.toString());
    if (adapter != null) {
      Device device = adapter.getItem(0);
      if (mqttMessage.toString().equals("on")) {
        device.setTurnOn(true);
      } else if (mqttMessage.toString().equals("off")) {
        device.setTurnOn(false);
      }
      adapter.notifyDataSetChanged();
    }
  }
  @Override
  public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
    try {
      String msgText = mqttMessage.toString();
      if (log.isDebugEnabled()) {
        log.debug(msgText);
      }
      PrivilegedCarbonContext.startTenantFlow();
      PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);

      if (log.isDebugEnabled()) {
        log.debug("Event received in MQTT Event Adaptor - " + msgText);
      }

      eventAdaptorListener.onEventCall(msgText);
    } catch (InputEventAdaptorEventProcessingException e) {
      throw new InputEventAdaptorEventProcessingException(e);
    } finally {
      PrivilegedCarbonContext.endTenantFlow();
    }
  }
  /**
   * Store an MQTT message
   *
   * @param clientHandle identifier for the client storing the message
   * @param topic The topic on which the message was published
   * @param message the arrived MQTT message
   * @return an identifier for the message, so that it can be removed when appropriate
   */
  @Override
  public String storeArrived(String clientHandle, String topic, MqttMessage message) {

    db = mqttDb.getWritableDatabase();

    traceHandler.traceDebug(
        TAG, "storeArrived{" + clientHandle + "}, {" + message.toString() + "}");

    byte[] payload = message.getPayload();
    int qos = message.getQos();
    boolean retained = message.isRetained();
    boolean duplicate = message.isDuplicate();

    ContentValues values = new ContentValues();
    String id = java.util.UUID.randomUUID().toString();
    values.put(MqttServiceConstants.MESSAGE_ID, id);
    values.put(MqttServiceConstants.CLIENT_HANDLE, clientHandle);
    values.put(MqttServiceConstants.DESTINATION_NAME, topic);
    values.put(MqttServiceConstants.PAYLOAD, payload);
    values.put(MqttServiceConstants.QOS, qos);
    values.put(MqttServiceConstants.RETAINED, retained);
    values.put(MqttServiceConstants.DUPLICATE, duplicate);
    values.put(MTIMESTAMP, System.currentTimeMillis());
    try {
      db.insertOrThrow(ARRIVED_MESSAGE_TABLE_NAME, null, values);
    } catch (SQLException e) {
      traceHandler.traceException(TAG, "onUpgrade", e);
      throw e;
    }
    int count = getArrivedRowCount(clientHandle);
    traceHandler.traceDebug(
        TAG,
        "storeArrived: inserted message with id of {"
            + id
            + "} - Number of messages in database for this clientHandle = "
            + count);
    return id;
  }
  /**
   * {@inheritDoc} VirtualFirealarm device-type specific implementation to process incoming
   * messages. This is the specific method signature of the overloaded "processIncomingMessage"
   * method that gets called from the messageArrived() callback of the "MQTTTransportHandler".
   */
  @Override
  public void processIncomingMessage(MqttMessage mqttMessage, String... messageParams) {
    if (messageParams.length != 0) {
      // owner and the deviceId are extracted from the MQTT topic to which the message was received.
      // <Topic> = [ServerName/Owner/DeviceType/DeviceId/"publisher"]
      String topic = messageParams[0];
      String[] topicParams = topic.split("/");
      String deviceId = topicParams[2];
      if (log.isDebugEnabled()) {
        log.debug("Received MQTT message for: [DEVICE.ID-" + deviceId + "]");
      }

      String actualMessage;
      try {
        // the hash-code of the deviceId is used as the alias for device certificates during SCEP
        // enrollment.
        // hence, the same is used here to fetch the device-specific-certificate from the key store.
        PublicKey clientPublicKey = VirtualFireAlarmServiceUtils.getDevicePublicKey(deviceId);
        PrivateKey serverPrivateKey = SecurityManager.getServerPrivateKey();

        // the MQTT-messages from VirtualFireAlarm devices are in the form {"Msg":<MESSAGE>,
        // "Sig":<SIGNATURE>}
        actualMessage =
            VirtualFireAlarmServiceUtils.extractMessageFromPayload(
                mqttMessage.toString(), serverPrivateKey, clientPublicKey);
        if (log.isDebugEnabled()) {
          log.debug("MQTT: Received Message [" + actualMessage + "] topic: [" + topic + "]");
        }

        if (actualMessage.contains("PUBLISHER")) {
          float temperature = Float.parseFloat(actualMessage.split(":")[2]);
          try {
            PrivilegedCarbonContext.startTenantFlow();
            PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
            DeviceManagementProviderService deviceManagementProviderService =
                (DeviceManagementProviderService)
                    ctx.getOSGiService(DeviceManagementProviderService.class, null);
            if (deviceManagementProviderService != null) {
              DeviceIdentifier identifier =
                  new DeviceIdentifier(deviceId, VirtualFireAlarmConstants.DEVICE_TYPE);
              Device device = deviceManagementProviderService.getDevice(identifier);
              if (device != null) {
                String owner = device.getEnrolmentInfo().getOwner();
                ctx.setTenantDomain(MultitenantUtils.getTenantDomain(owner), true);
                ctx.setUsername(owner);
                if (!VirtualFireAlarmServiceUtils.publishToDAS(deviceId, temperature)) {
                  log.error("MQTT Subscriber: Publishing data to DAS failed.");
                }
              }
            }
          } catch (DeviceManagementException e) {
            log.error(
                "Failed to retreive the device managment service for device type "
                    + VirtualFireAlarmConstants.DEVICE_TYPE,
                e);
          } finally {
            PrivilegedCarbonContext.endTenantFlow();
          }
          if (log.isDebugEnabled()) {
            log.debug("MQTT Subscriber: Published data to DAS successfully.");
          }

        } else if (actualMessage.contains("TEMPERATURE")) {
          String temperatureValue = actualMessage.split(":")[1];
        }
      } catch (VirtualFireAlarmException e) {
        String errorMsg =
            "CertificateManagementService failure oo Signature-Verification/Decryption was unsuccessful.";
        log.error(errorMsg, e);
      }
    } else {
      String errorMsg =
          "MQTT message ["
              + mqttMessage.toString()
              + "] was received without the topic information.";
      log.warn(errorMsg);
    }
  }
 @Override
 public void messageArrived(String arg0, MqttMessage arg1) throws Exception {
   log.info("MQTT Message received: " + arg1.toString());
 }
  public void logController(String topic, MqttMessage mqttMessage) {
    // get deviceId
    String[] split = topic.split("log/");
    String deviceId = split[1];

    // parse log
    try {
      JsonReader reader = Json.createReader(new StringReader(mqttMessage.toString()));
      JsonObject jsonMessage = reader.readObject();
      String logType = jsonMessage.getString("type");
      switch (logType) {
        case LOG_NORMAL:
          int temperature = 0;
          int timer = jsonMessage.getInt("time");
          try {
            temperature = jsonMessage.getInt("temperature");
          } catch (Exception se1) {
            // @todo: warning
            break;
          }
          JsonString subDeviceId = jsonMessage.getJsonString("subId");
          if (subDeviceId == null) sessionHandle.drawTemperature(deviceId, timer, temperature);
          else sessionHandle.drawTemperature(deviceId, timer, temperature, subDeviceId.toString());
          break;
        case LOG_WARNING:
          timer = jsonMessage.getInt("time");
          subDeviceId = jsonMessage.getJsonString("subId");
          int subdeviceNo = jsonMessage.getInt("number");
          String deviceState = jsonMessage.getString("value");
          String msg;
          switch (subdeviceNo) {
            case 1:
              msg = ("0".equals(deviceState)) ? "Button release" : "Button clicked";
              break;
            case 2:
              msg = ("0".equals(deviceState)) ? "Cửa cuốn được cuộn lên" : "Đang thả cửa cuốn";
              break;
            default:
              msg = DEFAULT_ALERT_MSG;
              break;
          }
          if (subDeviceId == null) sessionHandle.doAlert(deviceId, timer, msg);
          else sessionHandle.doAlert(deviceId, timer, msg, subDeviceId.toString());
          break;
        case LOG_CONTROL:
          String state = jsonMessage.getString("light");
          subdeviceNo = jsonMessage.getInt("no");
          sessionHandle.updateLightState(deviceId, subdeviceNo, state);
          break;
        case LOG_ACK:
          subdeviceNo = jsonMessage.getInt("number");
          deviceState = jsonMessage.getString("value");
          state = ("0".equals(deviceState)) ? "off" : "on";
          sessionHandle.ackLightState(deviceId, subdeviceNo, state);
          break;
        case LOG_DEVICE_STATUS:
          JsonArray lstDevice = jsonMessage.getJsonArray("status");
          System.out.println("Update status:");
          for (int i = 0; i < lstDevice.size(); i++) {
            JsonObject device = (JsonObject) lstDevice.get(i);
            System.out.println(device.toString());
            subdeviceNo = device.getInt("no");
            int intState = device.getInt("value");
            state = (intState == 0) ? "off" : "on";
            sessionHandle.updateLightState(deviceId, subdeviceNo, state);
          }
          sessionHandle.finishUpdateDeviceStatus();
          break;
        default:
      }

    } catch (Exception ex) {
      System.out.println("Parse error");
      System.out.println(topic);
      System.out.println(mqttMessage);
      System.out.println(ex.getMessage());
    }
  }