]> git.basschouten.com Git - openhab-addons.git/commitdiff
[unifi] Detect all PoE ports, and set PoE thing offline if no data could be found...
authorHilbrand Bouwkamp <hilbrand@h72.nl>
Mon, 3 Oct 2022 11:02:46 +0000 (13:02 +0200)
committerGitHub <noreply@github.com>
Mon, 3 Oct 2022 11:02:46 +0000 (13:02 +0200)
* [unifi] Set PoE thing offline if no data could be found

This would better reflect the PoE thing status if there is a problem with either the data from the api or a configuration problem (like invalid port number).

* [unifi] Fix bug to detect PoE ports when first port is not PoE port

The binding assumed either all ports or no ports were PoE, and asssumed if port 0 was not PoE none was PoE.
However, some switches have ports starting at port 5 to be PoE. Therefor changed code to just test each port if it is PoE.

Signed-off-by: Hilbrand Bouwkamp <hilbrand@h72.nl>
bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/api/cache/UniFiControllerCache.java
bundles/org.openhab.binding.unifi/src/main/java/org/openhab/binding/unifi/internal/handler/UniFiPoePortThingHandler.java
bundles/org.openhab.binding.unifi/src/main/resources/OH-INF/i18n/unifi.properties

index e8189ddaa8c5c57ab2eb03e85ddf757ae4ef1686..698cb42b8fb2b676f10c2704bc5d3fb6ae15fca7 100644 (file)
@@ -26,6 +26,7 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverrideJsonElement;
 import org.openhab.binding.unifi.internal.api.dto.UniFiClient;
 import org.openhab.binding.unifi.internal.api.dto.UniFiDevice;
+import org.openhab.binding.unifi.internal.api.dto.UniFiPortTable;
 import org.openhab.binding.unifi.internal.api.dto.UniFiPortTuple;
 import org.openhab.binding.unifi.internal.api.dto.UniFiSite;
 import org.openhab.binding.unifi.internal.api.dto.UniFiWlan;
@@ -93,25 +94,23 @@ public class UniFiControllerCache {
         devicesCache.putAll(devices);
         if (devices != null) {
             Stream.of(devices).filter(Objects::nonNull).forEach(d -> {
-                Stream.ofNullable(d.getPortTable()).filter(ptl -> ptl.length > 0 && ptl[0].isPortPoe()).forEach(pt -> {
-                    final Map<Integer, UniFiPortTuple> tupleTable = devicesToPortTables.computeIfAbsent(d.getMac(),
-                            p -> new HashMap<>());
-
-                    Stream.of(pt).forEach(p -> {
-                        final UniFiPortTuple tuple = tupleTable.computeIfAbsent(p.getPortIdx(),
-                                t -> new UniFiPortTuple());
-
-                        tuple.setDevice(d);
-                        tuple.setTable(p);
-                    });
-                });
-                Stream.ofNullable(d.getPortOverrides()).filter(ptl -> ptl.length > 0).forEach(po -> {
+                Stream.ofNullable(d.getPortTable()).flatMap(pt -> Stream.of(pt)).filter(UniFiPortTable::isPortPoe)
+                        .forEach(p -> {
+                            final Map<Integer, UniFiPortTuple> tupleTable = devicesToPortTables
+                                    .computeIfAbsent(d.getMac(), tt -> new HashMap<>());
+                            final UniFiPortTuple tuple = tupleTable.computeIfAbsent(p.getPortIdx(),
+                                    t -> new UniFiPortTuple());
+
+                            tuple.setDevice(d);
+                            tuple.setTable(p);
+                        });
+                Stream.ofNullable(d.getPortOverrides()).forEach(po -> {
                     final Map<Integer, UniFiPortTuple> tupleTable = devicesToPortTables.get(d.getMac());
 
                     if (tupleTable != null) {
                         Stream.of(po).filter(pof -> !pof.getAsJsonObject().entrySet().isEmpty())
-                                .map(UnfiPortOverrideJsonElement::new)
-                                .forEach(p -> tupleTable.get(p.getPortIdx()).setJsonElement(p));
+                                .map(UnfiPortOverrideJsonElement::new).forEach(p -> tupleTable
+                                        .computeIfAbsent(p.getPortIdx(), t -> new UniFiPortTuple()).setJsonElement(p));
                     }
                 });
             });
index e0edb5d37094988c3ce4a47fec3d4172a94efce8..90501cb7927b73210fda3114b5128ba1f7265522 100644 (file)
@@ -98,12 +98,15 @@ public class UniFiPoePortThingHandler
 
     @Override
     protected State getChannelState(final Map<Integer, UniFiPortTuple> ports, final String channelId) {
-        final UniFiPortTable port = getPort(ports).getTable();
+        final UniFiPortTuple portTuple = getPort(ports);
+
+        if (portTuple == null) {
+            return setOfflineOnNoPoEPortData();
+        }
+        final UniFiPortTable port = portTuple.getTable();
 
         if (port == null) {
-            logger.debug("No PoE port for thing '{}' could be found in the data. Refresh ignored.",
-                    getThing().getUID());
-            return UnDefType.NULL;
+            return setOfflineOnNoPoEPortData();
         }
         final State state;
 
@@ -132,6 +135,14 @@ public class UniFiPoePortThingHandler
         return state;
     }
 
+    private State setOfflineOnNoPoEPortData() {
+        if (getThing().getStatus() != ThingStatus.OFFLINE) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+                    "@text/error.thing.poe.offline.nodata_error");
+        }
+        return UnDefType.NULL;
+    }
+
     private @Nullable UniFiPortTuple getPort(final Map<Integer, UniFiPortTuple> ports) {
         return ports.get(config.getPortNumber());
     }
index b8c2d0e0e052f981b49a29b86e4c101e4df33a68..cc8e3d5c076706476964ecfa760eac87100c824f 100644 (file)
@@ -140,4 +140,5 @@ error.thing.client.offline.configuration_error = You must define a MAC address,
 error.thing.offline.bridge_offline = The UniFi Controller is currently offline.
 error.thing.offline.configuration_error = You must choose a UniFi Controller for this thing.
 error.thing.poe.offline.configuration_error = The configuration parameter macAddress must be set and not be empty.
+error.thing.poe.offline.nodata_error = No data for the PoE port could be found in the UniFi API data. See TRACE log for actual API data.
 error.thing.site.offline.configuration_error = The configuration parameter sid must be set and not be empty.