[unifi] Detect all PoE ports, and set PoE thing offline if no data could be found (#13455)

* [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>
This commit is contained in:
Hilbrand Bouwkamp 2022-10-03 13:02:46 +02:00 committed by GitHub
parent 64d97374ad
commit 0560a0e333
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 18 deletions

View 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 -> {
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()).filter(ptl -> ptl.length > 0).forEach(po -> {
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));
}
});
});

View 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());
}

View 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.