From 3473de3617b68ec54ca764f5eb1dc0d76df89f41 Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Tue, 9 Apr 2019 10:40:07 +0200
Subject: [PATCH] Reworked binding to openHAB version 2.4.0.

- Changed connection to	mqtt broker to old way using MqttService
- Changed processing of	numbers	to double instead of float
---
 META-INF/MANIFEST.MF                          |   1 -
 .../handler/AbstractMqttHandler.java          | 133 +++++++++++-------
 .../handler/AbstractSmartWatchHandler.java    |  22 +--
 .../handler/AbstractSmartphoneHandler.java    |  22 ++-
 .../binding/openlicht/handler/MqttUtils.java  |   2 +-
 .../handler/SkyWriterHATHandler.java          |   6 -
 .../internal/OpenLichtHandlerFactory.java     |   4 +-
 7 files changed, 105 insertions(+), 85 deletions(-)

diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
index 35ea27a..f6ff8e1 100644
--- a/META-INF/MANIFEST.MF
+++ b/META-INF/MANIFEST.MF
@@ -18,7 +18,6 @@ Import-Package:
  org.eclipse.smarthome.core.thing.type,
  org.eclipse.smarthome.core.types,
  org.eclipse.smarthome.io.transport.mqtt,
- org.openhab.binding.mqtt.handler,
  org.osgi.framework,
  org.osgi.service.component,
  org.slf4j
diff --git a/src/main/java/org/openhab/binding/openlicht/handler/AbstractMqttHandler.java b/src/main/java/org/openhab/binding/openlicht/handler/AbstractMqttHandler.java
index d941bd4..1751245 100644
--- a/src/main/java/org/openhab/binding/openlicht/handler/AbstractMqttHandler.java
+++ b/src/main/java/org/openhab/binding/openlicht/handler/AbstractMqttHandler.java
@@ -3,7 +3,7 @@ package org.openhab.binding.openlicht.handler;
 import static org.openhab.binding.openlicht.BindingConstants.*;
 
 import java.math.BigDecimal;
-import java.nio.ByteBuffer;
+import java.util.Map.Entry;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ScheduledExecutorService;
@@ -12,26 +12,27 @@ import java.util.concurrent.locks.ReentrantLock;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.smarthome.core.common.registry.RegistryChangeListener;
 import org.eclipse.smarthome.core.thing.Thing;
-import org.eclipse.smarthome.core.thing.ThingRegistry;
 import org.eclipse.smarthome.core.thing.ThingStatus;
 import org.eclipse.smarthome.core.thing.ThingStatusDetail;
 import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
-import org.eclipse.smarthome.core.thing.binding.ThingHandler;
+//import org.openhab.binding.mqtt.handler.AbstractBrokerHandler;
+//import org.openhab.binding.openlicht.internal.ConfigurationHolder;
 import org.eclipse.smarthome.io.transport.mqtt.MqttBrokerConnection;
 import org.eclipse.smarthome.io.transport.mqtt.MqttMessageSubscriber;
-import org.openhab.binding.mqtt.handler.AbstractBrokerHandler;
+import org.eclipse.smarthome.io.transport.mqtt.MqttService;
+import org.eclipse.smarthome.io.transport.mqtt.MqttServiceObserver;
 import org.openhab.binding.openlicht.internal.ConfigurationHolder;
 import org.osgi.framework.Version;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public abstract class AbstractMqttHandler extends BaseThingHandler
-        implements MqttMessageSubscriber, RegistryChangeListener<Thing> {
+        implements MqttMessageSubscriber, MqttServiceObserver/* , RegistryChangeListener<Thing> */ {
 
     protected final @NonNull Logger logger = LoggerFactory.getLogger(AbstractMqttHandler.class);
-    private @Nullable ThingRegistry thingRegistry;
+    // private @Nullable ThingRegistry thingRegistry;
+    private @Nullable MqttService mqttService;
     private int usedTopicLength = 0;
     private MqttBrokerConnection currentBrokerConnection = null;
     private boolean warnNoBrokerConnection = true;
@@ -43,50 +44,70 @@ public abstract class AbstractMqttHandler extends BaseThingHandler
 
     public AbstractMqttHandler(Thing thing, ConfigurationHolder configurationHolder) {
         super(thing);
-        this.thingRegistry = configurationHolder.getThingRegistry();
-        this.thingRegistry.addRegistryChangeListener(this);
+        // this.thingRegistry = configurationHolder.getThingRegistry();
+        // this.thingRegistry.addRegistryChangeListener(this);
+        this.mqttService = configurationHolder.getMqttService();
+        if (this.mqttService != null) {
+            this.mqttService.addBrokersListener(this);
+        }
         this.executor = configurationHolder.getExecutor();
         this.version = configurationHolder.getVersion();
         this.configUpdateLock = new ReentrantLock();
+        logger.info("Started handler " + this.getClass().getSimpleName() + " in version " + version);
     }
 
-    @Override
-    public void added(Thing element) {
-        if (thingIsMyMqttBroker(element)) {
-            addConnectionOf(element);
-        }
-    }
+    // @Override
+    // public void added(Thing element) {
+    // if (thingIsMyMqttBroker(element)) {
+    // addConnectionOf(element);
+    // }
+    // }
+    //
+    // @Override
+    // public void removed(Thing element) {
+    // if (thingIsMyMqttBroker(element)) {
+    // removeMyBroker();
+    // }
+    // }
+    //
+    // @Override
+    // public void updated(Thing oldElement, Thing element) {
+    // if (thingIsMyMqttBroker(element)) {
+    // removeMyBroker();
+    // addConnectionOf(element);
+    // }
+    // }
 
     @Override
-    public void removed(Thing element) {
-        if (thingIsMyMqttBroker(element)) {
-            removeMyBroker();
+    public void brokerAdded(String brokerID, MqttBrokerConnection broker) {
+        if (brokerID.equals(myBrokerName)) {
+            myBrokerAdded(broker);
         }
     }
 
     @Override
-    public void updated(Thing oldElement, Thing element) {
-        if (thingIsMyMqttBroker(element)) {
+    public void brokerRemoved(String brokerID, MqttBrokerConnection broker) {
+        if (brokerID.equals(myBrokerName)) {
             removeMyBroker();
-            addConnectionOf(element);
         }
     }
 
-    private boolean thingIsMyMqttBroker(Thing thing) {
-        if (!"mqtt:systemBroker".equals(thing.getThingTypeUID().getAsString())
-                && !"mqtt:broker".equals(thing.getThingTypeUID().getAsString())) {
-            return false;
-        }
-        return myBrokerName.equals(thing.getUID().getAsString());
-    }
+    // private boolean thingIsMyMqttBroker(Thing thing) {
+    // if (!"mqtt:systemBroker".equals(thing.getThingTypeUID().getAsString())
+    // && !"mqtt:broker".equals(thing.getThingTypeUID().getAsString())) {
+    // return false;
+    // }
+    // return myBrokerName.equals(thing.getUID().getAsString());
+    // }
 
-    private void addConnectionOf(Thing mqttBroker) {
-        ThingHandler handler = mqttBroker.getHandler();
-        if (handler instanceof AbstractBrokerHandler) {
-            AbstractBrokerHandler abh = (AbstractBrokerHandler) handler;
-            myBrokerAdded(abh.getConnection());
-        }
-    }
+    // private void addConnectionOf(Thing mqttBroker) {
+    // ThingHandler handler = mqttBroker.getHandler();
+    // this.mqttService.addBrokerConnection(myBrokerName, currentBrokerConnection)
+    // if (handler instanceof AbstractBrokerHandler) {
+    // AbstractBrokerHandler abh = (AbstractBrokerHandler) handler;
+    // myBrokerAdded(abh.getConnection());
+    // }
+    // }
 
     @Override
     public void initialize() {
@@ -103,9 +124,18 @@ public abstract class AbstractMqttHandler extends BaseThingHandler
                 myBrokerName = brokerName;
                 logger.debug("Setting myBrokerName to '{}'", myBrokerName);
 
-                for (Thing thing : this.thingRegistry.getAll()) {
-                    if (thingIsMyMqttBroker(thing)) {
-                        addConnectionOf(thing);
+                // for (Thing thing : this.thingRegistry.getAll()) {
+                // if (thingIsMyMqttBroker(thing)) {
+                // addConnectionOf(thing);
+                // }
+                // }
+                MqttService service = this.mqttService;
+                if (service == null) {
+                    logger.debug("No mqtt service yet");
+                } else {
+                    for (Entry<@NonNull String, @NonNull MqttBrokerConnection> entry : service.getAllBrokerConnections()
+                            .entrySet()) {
+                        brokerAdded(entry.getKey(), entry.getValue());
                     }
                 }
             } finally {
@@ -160,6 +190,9 @@ public abstract class AbstractMqttHandler extends BaseThingHandler
 
     public void removeMyBroker() {
         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING, "Broker is offline");
+        if (this.mqttService != null) {
+            this.mqttService.removeBrokerConnection(myBrokerName);
+        }
         currentBrokerConnection = null;
     }
 
@@ -215,17 +248,17 @@ public abstract class AbstractMqttHandler extends BaseThingHandler
     protected boolean subscribeSubTopics() {
         return true;
     }
-
-    /**
-     * Writes a float array from the given input based on the length of the targeted output.
-     *
-     * @param input  the buffer to read from
-     * @param output the array to write in
-     */
-    protected static void writeFloatArray(ByteBuffer input, float[] output) {
-        for (int i = 0; i < output.length; i++) {
-            output[i] = input.getFloat();
-        }
-    }
+    //
+    // /**
+    // * Writes a float array from the given input based on the length of the targeted output.
+    // *
+    // * @param input the buffer to read from
+    // * @param output the array to write in
+    // */
+    // protected static void writeFloatArray(ByteBuffer input, float[] output) {
+    // for (int i = 0; i < output.length; i++) {
+    // output[i] = input.getFloat();
+    // }
+    // }
 
 }
diff --git a/src/main/java/org/openhab/binding/openlicht/handler/AbstractSmartWatchHandler.java b/src/main/java/org/openhab/binding/openlicht/handler/AbstractSmartWatchHandler.java
index 3c827a8..5fece8d 100644
--- a/src/main/java/org/openhab/binding/openlicht/handler/AbstractSmartWatchHandler.java
+++ b/src/main/java/org/openhab/binding/openlicht/handler/AbstractSmartWatchHandler.java
@@ -15,7 +15,7 @@ package org.openhab.binding.openlicht.handler;
 import static org.openhab.binding.openlicht.BindingConstants.*;
 
 import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
+import java.nio.DoubleBuffer;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.ScheduledExecutorService;
@@ -82,21 +82,21 @@ public abstract class AbstractSmartWatchHandler extends AbstractMqttHandler {
         String category = topic.substring(getTopicLength());
         if (byteBaseMessages) {
             ByteBuffer buffer = ByteBuffer.wrap(payload);
-            FloatBuffer floatBuffer;
+            DoubleBuffer doubleBuffer;
             switch (category) {
                 case MQTT_CATEGORY_BRIGHTNESS:
                     updateState(CHANNEL_BRIGHTNESS, new DecimalType(buffer.getFloat()));
                     break;
                 case MQTT_CATEGORY_ACCELERATION:
-                    floatBuffer = buffer.asFloatBuffer();
-                    updateState(CHANNEL_ACCELERATION_X, new DecimalType(floatBuffer.get(0)));
-                    updateState(CHANNEL_ACCELERATION_Y, new DecimalType(floatBuffer.get(1)));
-                    updateState(CHANNEL_ACCELERATION_Z, new DecimalType(floatBuffer.get(2)));
+                    doubleBuffer = buffer.asDoubleBuffer();
+                    updateState(CHANNEL_ACCELERATION_X, new DecimalType(doubleBuffer.get(0)));
+                    updateState(CHANNEL_ACCELERATION_Y, new DecimalType(doubleBuffer.get(1)));
+                    updateState(CHANNEL_ACCELERATION_Z, new DecimalType(doubleBuffer.get(2)));
                 case MQTT_CATEGORY_ROTATION:
-                    floatBuffer = buffer.asFloatBuffer();
-                    updateState(CHANNEL_ROTATION_X, new DecimalType(floatBuffer.get(0)));
-                    updateState(CHANNEL_ROTATION_Y, new DecimalType(floatBuffer.get(1)));
-                    updateState(CHANNEL_ROTATION_Z, new DecimalType(floatBuffer.get(2)));
+                    doubleBuffer = buffer.asDoubleBuffer();
+                    updateState(CHANNEL_ROTATION_X, new DecimalType(doubleBuffer.get(0)));
+                    updateState(CHANNEL_ROTATION_Y, new DecimalType(doubleBuffer.get(1)));
+                    updateState(CHANNEL_ROTATION_Z, new DecimalType(doubleBuffer.get(2)));
                 default:
                     logUnsupportedCategory(category);
             }
@@ -104,7 +104,7 @@ public abstract class AbstractSmartWatchHandler extends AbstractMqttHandler {
             String message = new String(payload);
             switch (category) {
                 case MQTT_CATEGORY_BRIGHTNESS:
-                    updateState(CHANNEL_BRIGHTNESS, new DecimalType(Float.parseFloat(message)));
+                    updateState(CHANNEL_BRIGHTNESS, new DecimalType(Double.parseDouble(message)));
                     break;
                 case MQTT_CATEGORY_ACCELERATION:
                     MqttUtils.handleAcceleration(message, this::updateState);
diff --git a/src/main/java/org/openhab/binding/openlicht/handler/AbstractSmartphoneHandler.java b/src/main/java/org/openhab/binding/openlicht/handler/AbstractSmartphoneHandler.java
index 3840c60..8c1fd5d 100644
--- a/src/main/java/org/openhab/binding/openlicht/handler/AbstractSmartphoneHandler.java
+++ b/src/main/java/org/openhab/binding/openlicht/handler/AbstractSmartphoneHandler.java
@@ -15,7 +15,7 @@ package org.openhab.binding.openlicht.handler;
 import static org.openhab.binding.openlicht.BindingConstants.*;
 
 import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
+import java.nio.DoubleBuffer;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -46,13 +46,7 @@ public abstract class AbstractSmartphoneHandler extends AbstractMqttHandler {
 
     @Override
     public void handleCommand(ChannelUID channelUID, Command command) {
-        String channelId = channelUID.getId();
-        switch (channelId) {
-            case CHANNEL_BRIGHTNESS:
-                break;
-            default:
-                logger.warn("Unknown channel id {}!", channelId);
-        }
+        logger.info("Got command for read-only thing: {} {}", channelUID.getAsString(), command.toFullString());
     }
 
     @Override
@@ -61,16 +55,16 @@ public abstract class AbstractSmartphoneHandler extends AbstractMqttHandler {
         String category = topic.substring(getTopicLength());
         if (byteBaseMessages) {
             ByteBuffer buffer = ByteBuffer.wrap(payload);
-            FloatBuffer floatBuffer;
+            DoubleBuffer doubleBuffer;
             switch (category) {
                 case MQTT_CATEGORY_BRIGHTNESS:
                     updateState(CHANNEL_BRIGHTNESS, new DecimalType(buffer.getFloat()));
                     break;
                 case MQTT_CATEGORY_ROTATION:
-                    floatBuffer = buffer.asFloatBuffer();
-                    updateState(CHANNEL_ROTATION_X, new DecimalType(floatBuffer.get(0)));
-                    updateState(CHANNEL_ROTATION_Y, new DecimalType(floatBuffer.get(1)));
-                    updateState(CHANNEL_ROTATION_Z, new DecimalType(floatBuffer.get(2)));
+                    doubleBuffer = buffer.asDoubleBuffer();
+                    updateState(CHANNEL_ROTATION_X, new DecimalType(doubleBuffer.get(0)));
+                    updateState(CHANNEL_ROTATION_Y, new DecimalType(doubleBuffer.get(1)));
+                    updateState(CHANNEL_ROTATION_Z, new DecimalType(doubleBuffer.get(2)));
                 default:
                     logUnsupportedCategory(category);
             }
@@ -78,7 +72,7 @@ public abstract class AbstractSmartphoneHandler extends AbstractMqttHandler {
             String message = new String(payload);
             switch (category) {
                 case MQTT_CATEGORY_BRIGHTNESS:
-                    updateState(CHANNEL_BRIGHTNESS, new DecimalType(Float.parseFloat(message)));
+                    updateState(CHANNEL_BRIGHTNESS, new DecimalType(Double.parseDouble(message)));
                     break;
                 case MQTT_CATEGORY_ROTATION:
                     MqttUtils.handleRotation(message, this::updateState);
diff --git a/src/main/java/org/openhab/binding/openlicht/handler/MqttUtils.java b/src/main/java/org/openhab/binding/openlicht/handler/MqttUtils.java
index 1eec2e2..5c7328c 100644
--- a/src/main/java/org/openhab/binding/openlicht/handler/MqttUtils.java
+++ b/src/main/java/org/openhab/binding/openlicht/handler/MqttUtils.java
@@ -24,7 +24,7 @@ public class MqttUtils {
         for (String tok : tokens) {
             String[] keyValue = tok.split("=");
             String key = keyValue[0].trim();
-            DecimalType value = new DecimalType(Float.parseFloat(keyValue[1].trim()));
+            DecimalType value = new DecimalType(Double.parseDouble(keyValue[1].trim()));
             result.put(key, value);
         }
         return result;
diff --git a/src/main/java/org/openhab/binding/openlicht/handler/SkyWriterHATHandler.java b/src/main/java/org/openhab/binding/openlicht/handler/SkyWriterHATHandler.java
index a31acaf..6f9be37 100644
--- a/src/main/java/org/openhab/binding/openlicht/handler/SkyWriterHATHandler.java
+++ b/src/main/java/org/openhab/binding/openlicht/handler/SkyWriterHATHandler.java
@@ -31,12 +31,6 @@ public class SkyWriterHATHandler extends AbstractMqttHandler {
     @Override
     public void handleCommand(ChannelUID channelUID, Command command) {
         logger.info("Got command for read-only thing: {} {}", channelUID.getAsString(), command.toFullString());
-        // TODO: handle command
-
-        // Note: if communication with thing fails for some reason,
-        // indicate that by setting the status with detail information
-        // updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-        // "Could not control device at IP address x.x.x.x");
     }
 
     @Override
diff --git a/src/main/java/org/openhab/binding/openlicht/internal/OpenLichtHandlerFactory.java b/src/main/java/org/openhab/binding/openlicht/internal/OpenLichtHandlerFactory.java
index d9760d8..5258721 100644
--- a/src/main/java/org/openhab/binding/openlicht/internal/OpenLichtHandlerFactory.java
+++ b/src/main/java/org/openhab/binding/openlicht/internal/OpenLichtHandlerFactory.java
@@ -132,12 +132,12 @@ public class OpenLichtHandlerFactory extends BaseThingHandlerFactory implements
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC)
     public void setThingRegistry(ThingRegistry thingRegistry) {
-        LoggerFactory.getLogger(OpenLichtHandlerFactory.class).info("Setting mqtt service to {}", thingRegistry);
+        LoggerFactory.getLogger(OpenLichtHandlerFactory.class).info("Setting thing registry to {}", thingRegistry);
         this.thingRegistry = thingRegistry;
     }
 
     public void unsetThingRegistry(ThingRegistry service) {
-        LoggerFactory.getLogger(OpenLichtHandlerFactory.class).info("Deleting mqtt service {}", service);
+        LoggerFactory.getLogger(OpenLichtHandlerFactory.class).info("Deleting thing registry {}", service);
         this.thingRegistry = null;
     }
 }
-- 
GitLab