package org.wso2.carbon.device.mgt.iot.agent.kura.firealarm.core.utils.mqtt; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.wso2.carbon.device.mgt.iot.agent.kura.firealarm.core.communication .CommunicationHandlerException; import org.wso2.carbon.device.mgt.iot.agent.kura.firealarm.core.communication.mqtt .MQTTCommunicationHandler; import org.wso2.carbon.device.mgt.iot.agent.kura.firealarm.core.internal.AgentConstants; import org.wso2.carbon.device.mgt.iot.agent.kura.firealarm.core.internal.AgentCoreOperations; import org.wso2.carbon.device.mgt.iot.agent.kura.firealarm.core.internal.AgentManager; import java.nio.charset.StandardCharsets; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; public class MQTTCommunicationHandlerImpl extends MQTTCommunicationHandler { private static final Log log = LogFactory.getLog(MQTTCommunicationHandlerImpl.class); private static final AgentManager agentManager = AgentManager.getInstance(); private ScheduledExecutorService service = Executors.newScheduledThreadPool(2); private ScheduledFuture<?> dataPushServiceHandler; public MQTTCommunicationHandlerImpl(String deviceOwner, String deviceType, String mqttBrokerEndPoint, String subscribeTopic) { super(deviceOwner, deviceType, mqttBrokerEndPoint, subscribeTopic); } public MQTTCommunicationHandlerImpl(String deviceOwner, String deviceType, String mqttBrokerEndPoint, String subscribeTopic, int intervalInMillis) { super(deviceOwner, deviceType, mqttBrokerEndPoint, subscribeTopic, intervalInMillis); } public ScheduledFuture<?> getDataPushServiceHandler() { return dataPushServiceHandler; } @Override public void connect() { Runnable connector = new Runnable() { public void run() { while (!isConnected()) { try { connectToQueue(); subscribeToQueue(); publishDeviceData(agentManager.getAgentConfigs().getDataPushInterval()); } catch (CommunicationHandlerException e) { log.warn(AgentConstants.LOG_APPENDER + "Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed"); try { Thread.sleep(timeoutInterval); } catch (InterruptedException ex) { log.error(AgentConstants.LOG_APPENDER + "MQTT-Subscriber: Thread Sleep Interrupt Exception"); } } } } }; Thread connectorThread = new Thread(connector); connectorThread.setDaemon(true); connectorThread.start(); } @Override public void processIncomingMessage(MqttMessage message) { log.info(AgentConstants.LOG_APPENDER + "Message " + message.toString() + " was received"); String deviceOwner = agentManager.getAgentConfigs().getDeviceOwner(); String deviceID = agentManager.getAgentConfigs().getDeviceId(); String replyMessage; String[] controlSignal = message.toString().split(":"); // message- "<SIGNAL_TYPE>:<SIGNAL_MODE>" format.(ex: "BULB:ON", "TEMPERATURE", "HUMIDITY") switch (controlSignal[0].toUpperCase()) { case AgentConstants.BULB_CONTROL: AgentCoreOperations.changeBulbStatus(controlSignal[1].equals( AgentConstants.CONTROL_ON)); log.info(AgentConstants.LOG_APPENDER + "Bulb was switched to state: '" + controlSignal[1] + "'"); break; case AgentConstants.TEMPERATURE_CONTROL: double currentTemperature = agentManager.getTemperature(); String replyTemperature = "Current temperature was read as: '" + currentTemperature + "C'"; log.info(AgentConstants.LOG_APPENDER + replyTemperature); String tempPublishTopic = String.format( AgentConstants.MQTT_PUBLISH_TOPIC, deviceOwner, deviceID); replyMessage = AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature; try { publishToQueue(tempPublishTopic, replyMessage); } catch (CommunicationHandlerException e) { log.error(AgentConstants.LOG_APPENDER + "MQTT - Publishing, reply message to the MQTT Queue at: " + agentManager.getAgentConfigs().getMqttBrokerEndpoint() + "failed"); } break; case AgentConstants.HUMIDITY_CONTROL: double currentHumidity = agentManager.getHumidity(); String replyHumidity = "Current humidity was read as: '" + currentHumidity + "%'"; log.info(AgentConstants.LOG_APPENDER + replyHumidity); String humidPublishTopic = String.format( AgentConstants.MQTT_PUBLISH_TOPIC, deviceOwner, deviceID); replyMessage = AgentConstants.HUMIDITY_CONTROL + ":" + currentHumidity; try { publishToQueue(humidPublishTopic, replyMessage); } catch (CommunicationHandlerException e) { log.error(AgentConstants.LOG_APPENDER + "MQTT - Publishing, reply message to the MQTT Queue at: " + agentManager.getAgentConfigs().getMqttBrokerEndpoint() + "failed"); } break; default: log.warn(AgentConstants.LOG_APPENDER + "'" + controlSignal[0] + "' is invalid and not-supported for " + "this device-type"); break; } } @Override public void publishDeviceData(int publishInterval) { Runnable pushDataRunnable = new Runnable() { @Override public void run() { double currentTemperature = agentManager.getTemperature(); String payLoad = "PUBLISHER:" + AgentConstants.TEMPERATURE_CONTROL + ":" + currentTemperature; MqttMessage pushMessage = new MqttMessage(); pushMessage.setPayload(payLoad.getBytes(StandardCharsets.UTF_8)); pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE); pushMessage.setRetained(true); String topic = String.format(AgentConstants.MQTT_PUBLISH_TOPIC, agentManager.getAgentConfigs().getDeviceOwner(), agentManager.getAgentConfigs().getDeviceId()); try { publishToQueue(topic, pushMessage); log.info(AgentConstants.LOG_APPENDER + "Message: '" + pushMessage + "' published to MQTT Queue at [" + agentManager.getAgentConfigs().getMqttBrokerEndpoint() + "] under topic [" + topic + "]"); } catch (CommunicationHandlerException e) { log.warn(AgentConstants.LOG_APPENDER + "Data Publish attempt to topic - [" + AgentConstants.MQTT_PUBLISH_TOPIC + "] failed for payload [" + payLoad + "]"); } } }; dataPushServiceHandler = service.scheduleAtFixedRate(pushDataRunnable, publishInterval, publishInterval, TimeUnit.SECONDS); } @Override public void disconnect() { Runnable stopConnection = new Runnable() { public void run() { while (isConnected()) { try { dataPushServiceHandler.cancel(true); closeConnection(); } catch (MqttException e) { if (log.isDebugEnabled()) { log.warn(AgentConstants.LOG_APPENDER + "Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint); } try { Thread.sleep(timeoutInterval); } catch (InterruptedException e1) { log.error(AgentConstants.LOG_APPENDER + "MQTT-Terminator: Thread Sleep Interrupt Exception"); } } } } }; Thread terminatorThread = new Thread(stopConnection); terminatorThread.setDaemon(true); terminatorThread.start(); } @Override public void processIncomingMessage() { } }