/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.persistence.mqtt.internal; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.openhab.core.items.Item; import org.openhab.core.persistence.PersistenceService; import org.openhab.io.transport.mqtt.MqttService; import org.osgi.framework.BundleContext; import org.osgi.service.cm.ConfigurationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This is a {@link PersistenceService} implementation using MQTT. * * It can be used to persist item states through MQTT messages. The service only * supports sending of data, not receiving. * * Which items are persisted and when they are persisted can be configured in * the mqtt.persist file in the configurations/persistence folder. The * mqtt.persist file follows the standard openHAB persistence definitions. * * The broker to which the messages are sent is defined by the * mqtt-persistence:broker property in the openhab.cfg file. * * The topic to which messages are sent is defined by the mqtt-persistence:topic * property. * * The message payload is created from a template string, which you can define * in the property mqtt-persistence:message. * * For both the topic and message, the following parameter replacements are made * using String.format: * * <pre> * %1 item name * %2 alias (as defined in mqtt.persist) * %3 item state * %4 current timestamp * </pre> * * @author Davy Vanherbergen * @since 1.3.0 */ public class MqttPersistenceService implements PersistenceService { private static Logger logger = LoggerFactory.getLogger(MqttPersistenceService.class); private MqttService mqttService; private String brokerName; private String topic; private String messageTemplate; private MqttPersistencePublisher publisher; private boolean configured; /** * Start the persistence service. */ public void activate(final BundleContext bundleContext, final Map<String, Object> properties) { deactivate(0); brokerName = getProperty(properties, "broker"); topic = getProperty(properties, "topic"); messageTemplate = getProperty(properties, "message"); configured = true; logger.debug("Configuration updated for MQTT Persistence."); if (StringUtils.isBlank(brokerName)) { logger.debug("Configuration incomplete. Cannot start yet."); return; } logger.debug("Activating MQTT Persistence"); // create a new message publisher and register it publisher = new MqttPersistencePublisher(topic, messageTemplate); mqttService.registerMessageProducer(brokerName, publisher); } /** * Shut down the persistence service. */ public void deactivate(final int reason) { logger.debug("Deactivating MQTT Persistence"); if (StringUtils.isNotBlank(brokerName) && publisher != null) { mqttService.unregisterMessageProducer(brokerName, publisher); } } /** * Get a value from the given properties. * * @param properties * dictionary to load property from. * @param name * of the property * @return property value * @throws ConfigurationException * if the property is empty */ private String getProperty(Map<String, Object> properties, String name) { String value = (String) properties.get(name); if (StringUtils.isNotBlank(value)) { return value.trim(); } else { logger.warn("mqtt-persistence:" + name, "Missing or invalid property '" + name + "'"); return null; } } @Override public String getName() { return "mqtt"; } @Override public void store(Item item) { store(item, null); } @Override public void store(Item item, String alias) { if (!configured) { logger.trace("MQTT Persistence not configured yet. Cannot store item state for {}", item.getName()); return; } try { publisher.publish(item, alias); logger.debug("Published item state '{}' for item '{}'", item.getState(), item.getName()); } catch (Exception e) { logger.error("Error sending persistency message for item '{}' : {}", item.getName(), e); } } /** * Set MQTT Service from DS. * * @param mqttService * to set. */ public void setMqttService(MqttService mqttService) { this.mqttService = mqttService; } /** * Unset MQTT Service from DS. * * @param mqttService * to remove. */ public void unsetMqttService(MqttService mqttService) { this.mqttService = null; } }