]> git.basschouten.com Git - openhab-addons.git/commitdiff
[somfytahoma] Setting of channels at init + UoM for channels (#10300)
authorlolodomo <lg.hc@free.fr>
Sun, 14 Mar 2021 13:20:52 +0000 (14:20 +0100)
committerGitHub <noreply@github.com>
Sun, 14 Mar 2021 13:20:52 +0000 (14:20 +0100)
Fix #10291
Fix #10285

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/handler/SomfyTahomaBaseThingHandler.java
bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/handler/SomfyTahomaBridgeHandler.java
bundles/org.openhab.binding.somfytahoma/src/main/java/org/openhab/binding/somfytahoma/internal/model/SomfyTahomaDevice.java

index 4842f337df36a145bee0bc9769c0b6a21bd751c8..54ee305b3a0bb85d74efa24a106b31d24b76cdd5 100644 (file)
@@ -18,12 +18,30 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.measure.Unit;
+
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaDevice;
 import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaState;
 import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatus;
-import org.openhab.core.library.types.*;
-import org.openhab.core.thing.*;
+import org.openhab.core.library.CoreItemFactory;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.OnOffType;
+import org.openhab.core.library.types.OpenClosedType;
+import org.openhab.core.library.types.PercentType;
+import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.library.unit.ImperialUnits;
+import org.openhab.core.library.unit.SIUnits;
+import org.openhab.core.library.unit.Units;
+import org.openhab.core.thing.Bridge;
+import org.openhab.core.thing.Channel;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.ThingStatusInfo;
 import org.openhab.core.thing.binding.BaseThingHandler;
 import org.openhab.core.thing.binding.builder.ChannelBuilder;
 import org.openhab.core.thing.binding.builder.ThingBuilder;
@@ -38,6 +56,7 @@ import org.slf4j.LoggerFactory;
  * The {@link SomfyTahomaBaseThingHandler} is base thing handler for all things.
  *
  * @author Ondrej Pecta - Initial contribution
+ * @author Laurent Garnier - Setting of channels at init + UoM for channels
  */
 @NonNullByDefault
 public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
@@ -46,23 +65,57 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
     private HashMap<String, Integer> typeTable = new HashMap<>();
     protected HashMap<String, String> stateNames = new HashMap<>();
 
+    protected String url = "";
+
+    private Map<String, Unit<?>> units = new HashMap<>();
+
     public SomfyTahomaBaseThingHandler(Thing thing) {
         super(thing);
+        // Define default units
+        units.put("Number:Temperature", SIUnits.CELSIUS);
+        units.put("Number:Energy", Units.WATT_HOUR);
+        units.put("Number:Illuminance", Units.LUX);
+        units.put("Number:Dimensionless", Units.PERCENT);
     }
 
     public HashMap<String, String> getStateNames() {
         return stateNames;
     }
 
-    protected String url = "";
-
     @Override
     public void initialize() {
-        url = getURL();
-        if (getThing().getProperties().containsKey(RSSI_LEVEL_STATE)) {
-            createRSSIChannel();
+        Bridge bridge = getBridge();
+        initializeThing(bridge != null ? bridge.getStatus() : null);
+    }
+
+    @Override
+    public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
+        initializeThing(bridgeStatusInfo.getStatus());
+    }
+
+    public void initializeThing(@Nullable ThingStatus bridgeStatus) {
+        SomfyTahomaBridgeHandler bridgeHandler = getBridgeHandler();
+        if (bridgeHandler != null && bridgeStatus != null) {
+            url = getURL();
+            if (getThing().getProperties().containsKey(RSSI_LEVEL_STATE)) {
+                createRSSIChannel();
+            }
+            if (bridgeStatus == ThingStatus.ONLINE) {
+                SomfyTahomaDevice device = bridgeHandler.getCachedDevice(url);
+                if (device != null) {
+                    updateUnits(device.getAttributes());
+                    List<SomfyTahomaState> states = device.getStates();
+                    updateThingStatus(states);
+                    updateThingChannels(states);
+                } else {
+                    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, UNAVAILABLE);
+                }
+            } else {
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
+            }
+        } else {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED);
         }
-        updateStatus(ThingStatus.ONLINE);
     }
 
     private void createRSSIChannel() {
@@ -178,11 +231,49 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
         }
     }
 
+    private void updateUnits(List<SomfyTahomaState> attributes) {
+        for (SomfyTahomaState attr : attributes) {
+            if ("core:MeasuredValueType".equals(attr.getName()) && attr.getType() == TYPE_STRING) {
+                switch ((String) attr.getValue()) {
+                    case "core:TemperatureInCelcius":
+                    case "core:TemperatureInCelsius":
+                        units.put("Number:Temperature", SIUnits.CELSIUS);
+                        break;
+                    case "core:TemperatureInKelvin":
+                        units.put("Number:Temperature", Units.KELVIN);
+                        break;
+                    case "core:TemperatureInFahrenheit":
+                        units.put("Number:Temperature", ImperialUnits.FAHRENHEIT);
+                        break;
+                    case "core:RelativeValueInPercentage":
+                        units.put("Number:Dimensionless", Units.PERCENT);
+                        break;
+                    case "core:LuminanceInLux":
+                        units.put("Number:Illuminance", Units.LUX);
+                        break;
+                    case "core:ElectricalEnergyInWh":
+                        units.put("Number:Energy", Units.WATT_HOUR);
+                        break;
+                    case "core:ElectricalEnergyInKWh":
+                        units.put("Number:Energy", Units.KILOWATT_HOUR);
+                        break;
+                    case "core:ElectricalEnergyInMWh":
+                        units.put("Number:Energy", Units.MEGAWATT_HOUR);
+                        break;
+                    default:
+                        logger.warn("Unhandled value \"{}\" for attribute \"core:MeasuredValueType\"", attr.getValue());
+                        break;
+                }
+                break;
+            }
+        }
+    }
+
     protected @Nullable State parseTahomaState(@Nullable SomfyTahomaState state) {
         return parseTahomaState(null, state);
     }
 
-    protected @Nullable State parseTahomaState(@Nullable String acceptedState, @Nullable SomfyTahomaState state) {
+    protected @Nullable State parseTahomaState(@Nullable String acceptedItemType, @Nullable SomfyTahomaState state) {
         if (state == null) {
             return UnDefType.NULL;
         }
@@ -205,14 +296,32 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
             switch (type) {
                 case TYPE_PERCENT:
                     Double valPct = Double.parseDouble(state.getValue().toString());
+                    if (acceptedItemType != null && acceptedItemType.startsWith(CoreItemFactory.NUMBER + ":")) {
+                        Unit<?> unit = units.get(acceptedItemType);
+                        if (unit != null) {
+                            return new QuantityType<>(normalizePercent(valPct), unit);
+                        } else {
+                            logger.warn("Do not return a quantity for {} because the unit is unknown",
+                                    acceptedItemType);
+                        }
+                    }
                     return new PercentType(normalizePercent(valPct));
                 case TYPE_DECIMAL:
                     Double valDec = Double.parseDouble(state.getValue().toString());
+                    if (acceptedItemType != null && acceptedItemType.startsWith(CoreItemFactory.NUMBER + ":")) {
+                        Unit<?> unit = units.get(acceptedItemType);
+                        if (unit != null) {
+                            return new QuantityType<>(valDec, unit);
+                        } else {
+                            logger.warn("Do not return a quantity for {} because the unit is unknown",
+                                    acceptedItemType);
+                        }
+                    }
                     return new DecimalType(valDec);
                 case TYPE_STRING:
                 case TYPE_BOOLEAN:
                     String value = state.getValue().toString();
-                    if ("String".equals(acceptedState)) {
+                    if ("String".equals(acceptedItemType)) {
                         return new StringType(value);
                     } else {
                         return parseStringState(value);
@@ -247,9 +356,11 @@ public abstract class SomfyTahomaBaseThingHandler extends BaseThingHandler {
         switch (value.toLowerCase()) {
             case "on":
             case "true":
+            case "active":
                 return OnOffType.ON;
             case "off":
             case "false":
+            case "inactive":
                 return OnOffType.OFF;
             case "notdetected":
             case "nopersoninside":
index c71acdfdc143987ce2543399d6caf0140eb2fbae..cebc4cec948d1fabd131e52b8a250a7fb5709aee 100644 (file)
@@ -17,7 +17,12 @@ import static org.openhab.binding.somfytahoma.internal.SomfyTahomaBindingConstan
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.util.*;
+import java.time.Duration;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ScheduledFuture;
@@ -35,9 +40,25 @@ import org.eclipse.jetty.http.HttpHeader;
 import org.eclipse.jetty.http.HttpMethod;
 import org.openhab.binding.somfytahoma.internal.config.SomfyTahomaConfig;
 import org.openhab.binding.somfytahoma.internal.discovery.SomfyTahomaItemDiscoveryService;
-import org.openhab.binding.somfytahoma.internal.model.*;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaAction;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaActionGroup;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaApplyResponse;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaDevice;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaEvent;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaLoginResponse;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaRegisterEventsResponse;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaSetup;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaState;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatus;
+import org.openhab.binding.somfytahoma.internal.model.SomfyTahomaStatusResponse;
+import org.openhab.core.cache.ExpiringCache;
 import org.openhab.core.io.net.http.HttpClientFactory;
-import org.openhab.core.thing.*;
+import org.openhab.core.thing.Bridge;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.ThingStatusInfo;
 import org.openhab.core.thing.binding.BaseBridgeHandler;
 import org.openhab.core.thing.binding.ThingHandlerService;
 import org.openhab.core.types.Command;
@@ -106,6 +127,9 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
      */
     private String eventsId = "";
 
+    private ExpiringCache<List<SomfyTahomaDevice>> cachedDevices = new ExpiringCache<>(Duration.ofSeconds(30),
+            this::getDevices);
+
     // Gson & parser
     private final Gson gson = new Gson();
 
@@ -331,6 +355,16 @@ public class SomfyTahomaBridgeHandler extends BaseBridgeHandler {
         return response != null ? List.of(response) : List.of();
     }
 
+    public synchronized @Nullable SomfyTahomaDevice getCachedDevice(String url) {
+        List<SomfyTahomaDevice> devices = cachedDevices.getValue();
+        for (SomfyTahomaDevice device : devices) {
+            if (url.equals(device.getDeviceURL())) {
+                return device;
+            }
+        }
+        return null;
+    }
+
     private void getTahomaUpdates() {
         logger.debug("Getting Tahoma Updates...");
         if (ThingStatus.OFFLINE == thing.getStatus() && !reLogin()) {
index 2f4e26d9b97f6b771520c3105391a3fd56ffa96a..8b69b6ea2737c388e5e5679ee6bcf91e3543707a 100644 (file)
@@ -22,6 +22,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
  * to TahomaLink account.
  *
  * @author Ondrej Pecta - Initial contribution
+ * @author Laurent Garnier - Add attributes data
  */
 @NonNullByDefault
 public class SomfyTahomaDevice {
@@ -33,6 +34,7 @@ public class SomfyTahomaDevice {
     private String oid = "";
     private SomfyTahomaDeviceDefinition definition = new SomfyTahomaDeviceDefinition();
     private List<SomfyTahomaState> states = new ArrayList<>();
+    private List<SomfyTahomaState> attributes = new ArrayList<>();
 
     public String getLabel() {
         return label;
@@ -61,4 +63,8 @@ public class SomfyTahomaDevice {
     public List<SomfyTahomaState> getStates() {
         return states;
     }
+
+    public List<SomfyTahomaState> getAttributes() {
+        return attributes;
+    }
 }