mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-02-04 03:14:07 +01:00
[unifi] Fix bug with combination of other data/ports (#14060)
- It seems to throw an exception when updating internal cache. It can happen if you have a switch that has both PoE ports and other PoE ports or data in the port override. - Fixed logout, should be POST instead of GET. - Fixed typo in channel-type.config.unifi.poeEnable.mode.option.pasv24 should be without appending v. - Removed compiler warnings. Signed-off-by: Hilbrand Bouwkamp <hilbrand@h72.nl>
This commit is contained in:
parent
2d5402656e
commit
202a8647e0
@ -14,18 +14,17 @@ package org.openhab.binding.unifi.internal.api;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
|
import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverrideJsonElement;
|
import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverrideJsonObject;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiClient;
|
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.UniFiDevice;
|
||||||
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.UniFiSite;
|
||||||
|
import org.openhab.binding.unifi.internal.api.dto.UniFiSwitchPorts;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiUnknownClient;
|
import org.openhab.binding.unifi.internal.api.dto.UniFiUnknownClient;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiWiredClient;
|
import org.openhab.binding.unifi.internal.api.dto.UniFiWiredClient;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiWirelessClient;
|
import org.openhab.binding.unifi.internal.api.dto.UniFiWirelessClient;
|
||||||
@ -42,6 +41,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import com.google.gson.FieldNamingPolicy;
|
import com.google.gson.FieldNamingPolicy;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link UniFiController} is the main communication point with an external instance of the Ubiquiti Networks
|
* The {@link UniFiController} is the main communication point with an external instance of the Ubiquiti Networks
|
||||||
@ -94,7 +94,7 @@ public class UniFiController {
|
|||||||
.registerTypeAdapter(UniFiWiredClient.class, clientInstanceCreator)
|
.registerTypeAdapter(UniFiWiredClient.class, clientInstanceCreator)
|
||||||
.registerTypeAdapter(UniFiWirelessClient.class, clientInstanceCreator).create();
|
.registerTypeAdapter(UniFiWirelessClient.class, clientInstanceCreator).create();
|
||||||
this.poeGson = new GsonBuilder()
|
this.poeGson = new GsonBuilder()
|
||||||
.registerTypeAdapter(UnfiPortOverrideJsonElement.class, new UnfiPortOverrideJsonElementDeserializer())
|
.registerTypeAdapter(UnfiPortOverrideJsonObject.class, new UnfiPortOverrideJsonElementDeserializer())
|
||||||
.create();
|
.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ public class UniFiController {
|
|||||||
|
|
||||||
public void logout() throws UniFiException {
|
public void logout() throws UniFiException {
|
||||||
csrfToken = "";
|
csrfToken = "";
|
||||||
final UniFiControllerRequest<Void> req = newRequest(Void.class, HttpMethod.GET, gson);
|
final UniFiControllerRequest<Void> req = newRequest(Void.class, HttpMethod.POST, gson);
|
||||||
req.setPath(unifios ? "/api/auth/logout" : "/logout");
|
req.setPath(unifios ? "/api/auth/logout" : "/logout");
|
||||||
executeRequest(req);
|
executeRequest(req);
|
||||||
}
|
}
|
||||||
@ -153,7 +153,7 @@ public class UniFiController {
|
|||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Map<Integer, UniFiPortTuple> getSwitchPorts(@Nullable final String deviceId) {
|
public @Nullable UniFiSwitchPorts getSwitchPorts(@Nullable final String deviceId) {
|
||||||
return cache.getSwitchPorts(deviceId);
|
return cache.getSwitchPorts(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,10 +175,9 @@ public class UniFiController {
|
|||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean poeMode(final UniFiDevice device, final List<UnfiPortOverrideJsonElement> data)
|
public boolean poeMode(final UniFiDevice device, final List<JsonObject> data) throws UniFiException {
|
||||||
throws UniFiException {
|
|
||||||
// Safety check to make sure no empty data is send to avoid corrupting override data on the device.
|
// Safety check to make sure no empty data is send to avoid corrupting override data on the device.
|
||||||
if (data.isEmpty() || data.stream().anyMatch(p -> p.getJsonObject().entrySet().isEmpty())) {
|
if (data.isEmpty() || data.stream().anyMatch(p -> p.entrySet().isEmpty())) {
|
||||||
logger.info("Not overriding port for '{}', because port data contains empty json: {}", device.getName(),
|
logger.info("Not overriding port for '{}', because port data contains empty json: {}", device.getName(),
|
||||||
poeGson.toJson(data));
|
poeGson.toJson(data));
|
||||||
return false;
|
return false;
|
||||||
@ -225,7 +224,7 @@ public class UniFiController {
|
|||||||
throws UniFiException {
|
throws UniFiException {
|
||||||
T result;
|
T result;
|
||||||
try {
|
try {
|
||||||
result = request.execute();
|
result = (T) request.execute();
|
||||||
csrfToken = request.getCsrfToken();
|
csrfToken = request.getCsrfToken();
|
||||||
} catch (final UniFiExpiredSessionException e) {
|
} catch (final UniFiExpiredSessionException e) {
|
||||||
if (fromLogin) {
|
if (fromLogin) {
|
||||||
@ -234,11 +233,11 @@ public class UniFiController {
|
|||||||
throw new UniFiCommunicationException(e);
|
throw new UniFiCommunicationException(e);
|
||||||
} else {
|
} else {
|
||||||
login();
|
login();
|
||||||
result = executeRequest(request);
|
result = (T) executeRequest(request);
|
||||||
}
|
}
|
||||||
} catch (final UniFiNotAuthorizedException e) {
|
} catch (final UniFiNotAuthorizedException e) {
|
||||||
logger.warn("Not Authorized! Please make sure your controller credentials have administrator rights");
|
logger.warn("Not Authorized! Please make sure your controller credentials have administrator rights");
|
||||||
result = null;
|
result = (T) null;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -124,14 +124,14 @@ class UniFiControllerRequest<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable T execute() throws UniFiException {
|
public @Nullable T execute() throws UniFiException {
|
||||||
T result = null;
|
T result = (T) null;
|
||||||
final String json = getContent();
|
final String json = getContent();
|
||||||
// mgb: only try and unmarshall non-void result types
|
// mgb: only try and unmarshall non-void result types
|
||||||
if (!Void.class.equals(resultType)) {
|
if (!Void.class.equals(resultType)) {
|
||||||
final JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
|
final JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
|
||||||
|
|
||||||
if (jsonObject.has(PROPERTY_DATA) && jsonObject.get(PROPERTY_DATA).isJsonArray()) {
|
if (jsonObject.has(PROPERTY_DATA) && jsonObject.get(PROPERTY_DATA).isJsonArray()) {
|
||||||
result = gson.fromJson(jsonObject.getAsJsonArray(PROPERTY_DATA), resultType);
|
result = (T) gson.fromJson(jsonObject.getAsJsonArray(PROPERTY_DATA), resultType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -106,7 +106,9 @@ abstract class UniFiCache<T extends @Nullable HasId> {
|
|||||||
logger.debug("Put #{} entries in {}: {}", values.length, getClass().getSimpleName(),
|
logger.debug("Put #{} entries in {}: {}", values.length, getClass().getSimpleName(),
|
||||||
lazyFormatAsList(values));
|
lazyFormatAsList(values));
|
||||||
for (final T value : values) {
|
for (final T value : values) {
|
||||||
put(value.getId(), value);
|
if (value != null) {
|
||||||
|
put(value.getId(), value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
package org.openhab.binding.unifi.internal.api.cache;
|
package org.openhab.binding.unifi.internal.api.cache;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -23,12 +22,11 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
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.UniFiClient;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiDevice;
|
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.UniFiPortTuple;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiSite;
|
import org.openhab.binding.unifi.internal.api.dto.UniFiSite;
|
||||||
|
import org.openhab.binding.unifi.internal.api.dto.UniFiSwitchPorts;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiWlan;
|
import org.openhab.binding.unifi.internal.api.dto.UniFiWlan;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -49,7 +47,7 @@ public class UniFiControllerCache {
|
|||||||
private final UniFiDeviceCache devicesCache = new UniFiDeviceCache();
|
private final UniFiDeviceCache devicesCache = new UniFiDeviceCache();
|
||||||
private final UniFiClientCache clientsCache = new UniFiClientCache();
|
private final UniFiClientCache clientsCache = new UniFiClientCache();
|
||||||
private final UniFiClientCache insightsCache = new UniFiClientCache();
|
private final UniFiClientCache insightsCache = new UniFiClientCache();
|
||||||
private final Map<String, Map<Integer, UniFiPortTuple>> devicesToPortTables = new ConcurrentHashMap<>();
|
private final Map<String, UniFiSwitchPorts> devicesToPortTables = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
sitesCache.clear();
|
sitesCache.clear();
|
||||||
@ -94,23 +92,23 @@ public class UniFiControllerCache {
|
|||||||
devicesCache.putAll(devices);
|
devicesCache.putAll(devices);
|
||||||
if (devices != null) {
|
if (devices != null) {
|
||||||
Stream.of(devices).filter(Objects::nonNull).forEach(d -> {
|
Stream.of(devices).filter(Objects::nonNull).forEach(d -> {
|
||||||
Stream.ofNullable(d.getPortTable()).flatMap(pt -> Stream.of(pt)).filter(UniFiPortTable::isPortPoe)
|
Stream.ofNullable(d.getPortTable()).forEach(pt -> {
|
||||||
.forEach(p -> {
|
final UniFiSwitchPorts switchPorts = devicesToPortTables.computeIfAbsent(d.getMac(),
|
||||||
final Map<Integer, UniFiPortTuple> tupleTable = devicesToPortTables
|
p -> new UniFiSwitchPorts());
|
||||||
.computeIfAbsent(d.getMac(), tt -> new HashMap<>());
|
|
||||||
final UniFiPortTuple tuple = tupleTable.computeIfAbsent(p.getPortIdx(),
|
|
||||||
t -> new UniFiPortTuple());
|
|
||||||
|
|
||||||
tuple.setDevice(d);
|
Stream.of(pt).forEach(p -> {
|
||||||
tuple.setTable(p);
|
@SuppressWarnings("null")
|
||||||
});
|
final UniFiPortTuple tuple = switchPorts.computeIfAbsent(p.getPortIdx());
|
||||||
|
|
||||||
|
tuple.setDevice(d);
|
||||||
|
tuple.setTable(p);
|
||||||
|
});
|
||||||
|
});
|
||||||
Stream.ofNullable(d.getPortOverrides()).forEach(po -> {
|
Stream.ofNullable(d.getPortOverrides()).forEach(po -> {
|
||||||
final Map<Integer, UniFiPortTuple> tupleTable = devicesToPortTables.get(d.getMac());
|
final UniFiSwitchPorts tupleTable = devicesToPortTables.get(d.getMac());
|
||||||
|
|
||||||
if (tupleTable != null) {
|
if (tupleTable != null) {
|
||||||
Stream.of(po).filter(pof -> !pof.getAsJsonObject().entrySet().isEmpty())
|
Stream.of(po).forEach(p -> tupleTable.setOverride(p));
|
||||||
.map(UnfiPortOverrideJsonElement::new).forEach(p -> tupleTable
|
|
||||||
.computeIfAbsent(p.getPortIdx(), t -> new UniFiPortTuple()).setJsonElement(p));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -121,11 +119,12 @@ public class UniFiControllerCache {
|
|||||||
return devicesCache.get(id);
|
return devicesCache.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, UniFiPortTuple> getSwitchPorts(@Nullable final String deviceId) {
|
public UniFiSwitchPorts getSwitchPorts(@Nullable final String deviceId) {
|
||||||
return deviceId == null ? Map.of() : devicesToPortTables.getOrDefault(deviceId, Map.of());
|
return deviceId == null ? new UniFiSwitchPorts()
|
||||||
|
: devicesToPortTables.getOrDefault(deviceId, new UniFiSwitchPorts());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Map<Integer, UniFiPortTuple>> getSwitchPorts() {
|
public Collection<UniFiSwitchPorts> getSwitchPorts() {
|
||||||
return devicesToPortTables.values();
|
return devicesToPortTables.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,8 @@ class UniFiDeviceCache extends UniFiCache<UniFiDevice> {
|
|||||||
switch (prefix) {
|
switch (prefix) {
|
||||||
case MAC:
|
case MAC:
|
||||||
return device.getMac();
|
return device.getMac();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.unifi.internal.api.dto;
|
package org.openhab.binding.unifi.internal.api.dto;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,7 +21,7 @@ import com.google.gson.JsonObject;
|
|||||||
*
|
*
|
||||||
* @author Hilbrand Bouwkamp - Initial contribution
|
* @author Hilbrand Bouwkamp - Initial contribution
|
||||||
*/
|
*/
|
||||||
public class UnfiPortOverrideJsonElement {
|
public class UnfiPortOverrideJsonObject {
|
||||||
|
|
||||||
private static final String PORT_IDX = "port_idx";
|
private static final String PORT_IDX = "port_idx";
|
||||||
private static final String PORT_CONF_ID = "port_conf_id";
|
private static final String PORT_CONF_ID = "port_conf_id";
|
||||||
@ -30,14 +29,18 @@ public class UnfiPortOverrideJsonElement {
|
|||||||
|
|
||||||
private final JsonObject jsonObject;
|
private final JsonObject jsonObject;
|
||||||
|
|
||||||
public UnfiPortOverrideJsonElement(final JsonElement element) {
|
public UnfiPortOverrideJsonObject(final JsonObject Object) {
|
||||||
this.jsonObject = element.getAsJsonObject();
|
this.jsonObject = Object.getAsJsonObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonObject getJsonObject() {
|
public JsonObject getJsonObject() {
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasPortIdx(final JsonObject jsonObject) {
|
||||||
|
return jsonObject.has(PORT_IDX);
|
||||||
|
}
|
||||||
|
|
||||||
public int getPortIdx() {
|
public int getPortIdx() {
|
||||||
return jsonObject.get(PORT_IDX).getAsInt();
|
return jsonObject.get(PORT_IDX).getAsInt();
|
||||||
}
|
}
|
@ -15,7 +15,7 @@ package org.openhab.binding.unifi.internal.api.dto;
|
|||||||
import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
|
import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
|
||||||
import org.openhab.binding.unifi.internal.api.util.UniFiTidyLowerCaseStringDeserializer;
|
import org.openhab.binding.unifi.internal.api.util.UniFiTidyLowerCaseStringDeserializer;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.annotations.JsonAdapter;
|
import com.google.gson.annotations.JsonAdapter;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ public class UniFiDevice implements HasId {
|
|||||||
|
|
||||||
private UniFiPortTable[] portTable;
|
private UniFiPortTable[] portTable;
|
||||||
|
|
||||||
private JsonElement[] portOverrides;
|
private JsonObject[] portOverrides;
|
||||||
|
|
||||||
public UniFiDevice(final UniFiControllerCache cache) {
|
public UniFiDevice(final UniFiControllerCache cache) {
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
@ -75,7 +75,7 @@ public class UniFiDevice implements HasId {
|
|||||||
return portTable;
|
return portTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonElement[] getPortOverrides() {
|
public JsonObject[] getPortOverrides() {
|
||||||
return portOverrides;
|
return portOverrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ package org.openhab.binding.unifi.internal.api.dto;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tuple to store both the {@link UniFiPortTable}, which contains the all information related to the port,
|
* Tuple to store both the {@link UniFiPortTable}, which contains the all information related to the port,
|
||||||
* and the {@link UnfiPortOverrideJsonElement}, which contains the raw json data of the port override.
|
* and the {@link UnfiPortOverrideJsonObject}, which contains the raw json data of the port override.
|
||||||
*
|
*
|
||||||
* @author Hilbrand Bouwkamp - Initial contribution
|
* @author Hilbrand Bouwkamp - Initial contribution
|
||||||
*/
|
*/
|
||||||
@ -24,7 +24,7 @@ public class UniFiPortTuple {
|
|||||||
|
|
||||||
private UniFiPortTable table;
|
private UniFiPortTable table;
|
||||||
|
|
||||||
private UnfiPortOverrideJsonElement jsonElement;
|
private UnfiPortOverrideJsonObject jsonElement;
|
||||||
|
|
||||||
public UniFiDevice getDevice() {
|
public UniFiDevice getDevice() {
|
||||||
return device;
|
return device;
|
||||||
@ -46,11 +46,11 @@ public class UniFiPortTuple {
|
|||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnfiPortOverrideJsonElement getJsonElement() {
|
public UnfiPortOverrideJsonObject getJsonElement() {
|
||||||
return jsonElement;
|
return jsonElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJsonElement(final UnfiPortOverrideJsonElement jsonElement) {
|
public void setJsonElement(final UnfiPortOverrideJsonObject jsonElement) {
|
||||||
this.jsonElement = jsonElement;
|
this.jsonElement = jsonElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,122 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.unifi.internal.api.dto;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data object to keep track of all port data, including all port_override data (both for ports and additional data) on
|
||||||
|
* a switch device.
|
||||||
|
*
|
||||||
|
* @author Hilbrand Bouwkamp - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class UniFiSwitchPorts {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Port data grouped by port id.
|
||||||
|
*/
|
||||||
|
private final Map<Integer, UniFiPortTuple> ports = new HashMap<>();
|
||||||
|
/**
|
||||||
|
* Additional none port specific override data. Keep track to send to device when updating override data.
|
||||||
|
*/
|
||||||
|
private final Set<JsonObject> otherOverrides = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return port data for the given port
|
||||||
|
*
|
||||||
|
* @param portIdx port to get the data for
|
||||||
|
* @return Return port data for the given port
|
||||||
|
*/
|
||||||
|
public @Nullable UniFiPortTuple getPort(final int portIdx) {
|
||||||
|
return ports.get(portIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return port data for the given port or if none exists set a new data object and return it.
|
||||||
|
*
|
||||||
|
* @param portIdx port to get the data for
|
||||||
|
* @return Return port data for the given port or if none exists set a new data object and return it.
|
||||||
|
*/
|
||||||
|
public UniFiPortTuple computeIfAbsent(final int portIdx) {
|
||||||
|
final UniFiPortTuple tuple = ports.computeIfAbsent(portIdx, t -> new UniFiPortTuple());
|
||||||
|
if (tuple == null) {
|
||||||
|
// This should never happen because ports can never contain a null value, and computeIfAbsent should never
|
||||||
|
// return null. However to satisfy the compiler a check for null was added.
|
||||||
|
throw new IllegalStateException("UniFiPortTuple is null for portIdx " + portIdx);
|
||||||
|
}
|
||||||
|
return tuple;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the list of PoE Ports.
|
||||||
|
*/
|
||||||
|
public List<UniFiPortTuple> getPoePorts() {
|
||||||
|
return ports.values().stream().filter(e -> e.getTable().isPortPoe()).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the override data as list with json objects after calling the updateMethod on the data for the given
|
||||||
|
* portIdx.
|
||||||
|
* The update method changes the data in the internal structure.
|
||||||
|
*
|
||||||
|
* @param portIdx port to call updateMethod for
|
||||||
|
* @param updateMethod method to call to update data for a specific port
|
||||||
|
* @return Returns a list of json objects of all override data
|
||||||
|
*/
|
||||||
|
public List<JsonObject> updatedList(final int portIdx, final Consumer<UnfiPortOverrideJsonObject> updateMethod) {
|
||||||
|
@SuppressWarnings("null")
|
||||||
|
final List<UnfiPortOverrideJsonObject> updatedList = ports.entrySet().stream()
|
||||||
|
.map(e -> e.getValue().getJsonElement()).filter(Objects::nonNull).collect(Collectors.toList());
|
||||||
|
|
||||||
|
updatedList.stream().filter(p -> p.getPortIdx() == portIdx).findAny().ifPresent(updateMethod::accept);
|
||||||
|
|
||||||
|
return Stream
|
||||||
|
.concat(otherOverrides.stream(), updatedList.stream().map(UnfiPortOverrideJsonObject::getJsonObject))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the port override object. If it's for a specific port set bind it to the port data, otherwise store it as
|
||||||
|
* generic data.
|
||||||
|
*
|
||||||
|
* @param jsonObject json object to set
|
||||||
|
*/
|
||||||
|
public void setOverride(final JsonObject jsonObject) {
|
||||||
|
if (UnfiPortOverrideJsonObject.hasPortIdx(jsonObject)) {
|
||||||
|
final UnfiPortOverrideJsonObject po = new UnfiPortOverrideJsonObject(jsonObject);
|
||||||
|
final UniFiPortTuple tuple = ports.get(po.getPortIdx());
|
||||||
|
|
||||||
|
if (tuple == null) {
|
||||||
|
otherOverrides.add(jsonObject);
|
||||||
|
} else {
|
||||||
|
tuple.setJsonElement(po);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
otherOverrides.add(jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,22 +15,22 @@ package org.openhab.binding.unifi.internal.api.util;
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverrideJsonElement;
|
import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverrideJsonObject;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonSerializationContext;
|
import com.google.gson.JsonSerializationContext;
|
||||||
import com.google.gson.JsonSerializer;
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializer for {@link UnfiPortOverrideJsonElement}. Returns the content of the jsonObject in the class.
|
* Serializer for {@link UnfiPortOverrideJsonObject}. Returns the content of the jsonObject in the class.
|
||||||
*
|
*
|
||||||
* @author Hilbrand Bouwkamp - Initial contribution
|
* @author Hilbrand Bouwkamp - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class UnfiPortOverrideJsonElementDeserializer implements JsonSerializer<UnfiPortOverrideJsonElement> {
|
public class UnfiPortOverrideJsonElementDeserializer implements JsonSerializer<UnfiPortOverrideJsonObject> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonElement serialize(final UnfiPortOverrideJsonElement src, final Type typeOfSrc,
|
public JsonElement serialize(final UnfiPortOverrideJsonObject src, final Type typeOfSrc,
|
||||||
final JsonSerializationContext context) {
|
final JsonSerializationContext context) {
|
||||||
return src.getJsonObject();
|
return src.getJsonObject();
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ public abstract class UniFiBaseThingHandler<E, C> extends BaseThingHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// mgb: derive the config class from the generic type
|
// mgb: derive the config class from the generic type
|
||||||
|
@SuppressWarnings("null")
|
||||||
final Class<?> clazz = (Class<?>) (((ParameterizedType) getClass().getGenericSuperclass())
|
final Class<?> clazz = (Class<?>) (((ParameterizedType) getClass().getGenericSuperclass())
|
||||||
.getActualTypeArguments()[1]);
|
.getActualTypeArguments()[1]);
|
||||||
final C config = (C) getConfigAs(clazz);
|
final C config = (C) getConfigAs(clazz);
|
||||||
@ -99,7 +100,7 @@ public abstract class UniFiBaseThingHandler<E, C> extends BaseThingHandler {
|
|||||||
logger.debug("Handling command = {} for channel = {}", command, channelUID);
|
logger.debug("Handling command = {} for channel = {}", command, channelUID);
|
||||||
// mgb: only handle commands if we're ONLINE
|
// mgb: only handle commands if we're ONLINE
|
||||||
if (getThing().getStatus() == ONLINE) {
|
if (getThing().getStatus() == ONLINE) {
|
||||||
final E entity = getEntity();
|
final @Nullable E entity = getEntity();
|
||||||
final UniFiController controller = getController();
|
final UniFiController controller = getController();
|
||||||
|
|
||||||
if (command == REFRESH) {
|
if (command == REFRESH) {
|
||||||
@ -128,13 +129,13 @@ public abstract class UniFiBaseThingHandler<E, C> extends BaseThingHandler {
|
|||||||
protected final void refresh() {
|
protected final void refresh() {
|
||||||
// mgb: only refresh if we're ONLINE
|
// mgb: only refresh if we're ONLINE
|
||||||
if (getThing().getStatus() == ONLINE) {
|
if (getThing().getStatus() == ONLINE) {
|
||||||
final E entity = getEntity();
|
final @Nullable E entity = getEntity();
|
||||||
|
|
||||||
getThing().getChannels().forEach(channel -> updateState(entity, channel.getUID()));
|
getThing().getChannels().forEach(channel -> updateState(entity, channel.getUID()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateState(final E entity, final ChannelUID channelUID) {
|
private void updateState(final @Nullable E entity, final ChannelUID channelUID) {
|
||||||
final String channelId = channelUID.getId();
|
final String channelId = channelUID.getId();
|
||||||
final State state = Optional.ofNullable(entity).map(e -> getChannelState(e, channelId))
|
final State state = Optional.ofNullable(entity).map(e -> getChannelState(e, channelId))
|
||||||
.orElseGet(() -> getDefaultState(channelId));
|
.orElseGet(() -> getDefaultState(channelId));
|
||||||
|
@ -39,6 +39,7 @@ import org.openhab.core.thing.ThingStatus;
|
|||||||
import org.openhab.core.thing.ThingStatusDetail;
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
import org.openhab.core.thing.ThingStatusInfo;
|
import org.openhab.core.thing.ThingStatusInfo;
|
||||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||||
import org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder;
|
import org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
@ -107,13 +108,15 @@ public class UniFiControllerThingHandler extends BaseBridgeHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
cancelRefreshJob();
|
cancelRefreshJob();
|
||||||
|
final UniFiController controller = this.controller;
|
||||||
|
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
try {
|
try {
|
||||||
controller.stop();
|
controller.stop();
|
||||||
} catch (final UniFiException e) {
|
} catch (final UniFiException e) {
|
||||||
// mgb: nop as we're in dispose
|
// mgb: nop as we're in dispose
|
||||||
}
|
}
|
||||||
controller = null;
|
this.controller = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,8 +191,10 @@ public class UniFiControllerThingHandler extends BaseBridgeHandler {
|
|||||||
uc.refresh();
|
uc.refresh();
|
||||||
// mgb: then refresh all the client things
|
// mgb: then refresh all the client things
|
||||||
getThing().getThings().forEach((thing) -> {
|
getThing().getThings().forEach((thing) -> {
|
||||||
if (thing.getHandler() instanceof UniFiBaseThingHandler) {
|
final ThingHandler handler = thing.getHandler();
|
||||||
((UniFiBaseThingHandler) thing.getHandler()).refresh();
|
|
||||||
|
if (handler instanceof UniFiBaseThingHandler) {
|
||||||
|
((UniFiBaseThingHandler<?, ?>) handler).refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,6 @@ import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_P
|
|||||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_VOLTAGE;
|
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_VOLTAGE;
|
||||||
import static org.openhab.core.library.unit.MetricPrefix.MILLI;
|
import static org.openhab.core.library.unit.MetricPrefix.MILLI;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.measure.quantity.ElectricCurrent;
|
import javax.measure.quantity.ElectricCurrent;
|
||||||
import javax.measure.quantity.ElectricPotential;
|
import javax.measure.quantity.ElectricPotential;
|
||||||
import javax.measure.quantity.Power;
|
import javax.measure.quantity.Power;
|
||||||
@ -40,14 +35,15 @@ import org.openhab.binding.unifi.internal.UniFiPoePortThingConfig;
|
|||||||
import org.openhab.binding.unifi.internal.api.UniFiController;
|
import org.openhab.binding.unifi.internal.api.UniFiController;
|
||||||
import org.openhab.binding.unifi.internal.api.UniFiException;
|
import org.openhab.binding.unifi.internal.api.UniFiException;
|
||||||
import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
|
import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverrideJsonElement;
|
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiDevice;
|
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.UniFiPortTable;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiPortTuple;
|
import org.openhab.binding.unifi.internal.api.dto.UniFiPortTuple;
|
||||||
|
import org.openhab.binding.unifi.internal.api.dto.UniFiSwitchPorts;
|
||||||
import org.openhab.core.library.types.OnOffType;
|
import org.openhab.core.library.types.OnOffType;
|
||||||
import org.openhab.core.library.types.QuantityType;
|
import org.openhab.core.library.types.QuantityType;
|
||||||
import org.openhab.core.library.types.StringType;
|
import org.openhab.core.library.types.StringType;
|
||||||
import org.openhab.core.library.unit.Units;
|
import org.openhab.core.library.unit.Units;
|
||||||
|
import org.openhab.core.thing.Channel;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
import org.openhab.core.thing.ThingStatus;
|
import org.openhab.core.thing.ThingStatus;
|
||||||
@ -64,8 +60,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @author Hilbrand Bouwkamp - Initial contribution
|
* @author Hilbrand Bouwkamp - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class UniFiPoePortThingHandler
|
public class UniFiPoePortThingHandler extends UniFiBaseThingHandler<UniFiSwitchPorts, UniFiPoePortThingConfig> {
|
||||||
extends UniFiBaseThingHandler<Map<Integer, UniFiPortTuple>, UniFiPoePortThingConfig> {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(UniFiPoePortThingHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(UniFiPoePortThingHandler.class);
|
||||||
|
|
||||||
@ -84,20 +79,30 @@ public class UniFiPoePortThingHandler
|
|||||||
"@text/error.thing.poe.offline.configuration_error");
|
"@text/error.thing.poe.offline.configuration_error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final String channelConfigPoeEnableMode = (String) getThing().getChannel(CHANNEL_PORT_POE_ENABLE)
|
return initPoeEnableMode();
|
||||||
.getConfiguration().get(CHANNEL_ENABLE_PARAMETER_MODE);
|
}
|
||||||
poeEnableMode = channelConfigPoeEnableMode.isBlank() ? CHANNEL_ENABLE_PARAMETER_MODE_AUTO
|
|
||||||
: channelConfigPoeEnableMode;
|
private boolean initPoeEnableMode() {
|
||||||
return true;
|
final Channel channel = getThing().getChannel(CHANNEL_PORT_POE_ENABLE);
|
||||||
|
|
||||||
|
if (channel == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
final String channelConfigPoeEnableMode = (String) channel.getConfiguration()
|
||||||
|
.get(CHANNEL_ENABLE_PARAMETER_MODE);
|
||||||
|
poeEnableMode = channelConfigPoeEnableMode.isBlank() ? CHANNEL_ENABLE_PARAMETER_MODE_AUTO
|
||||||
|
: channelConfigPoeEnableMode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected @Nullable Map<Integer, UniFiPortTuple> getEntity(final UniFiControllerCache cache) {
|
protected @Nullable UniFiSwitchPorts getEntity(final UniFiControllerCache cache) {
|
||||||
return cache.getSwitchPorts(config.getMacAddress());
|
return cache.getSwitchPorts(config.getMacAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected State getChannelState(final Map<Integer, UniFiPortTuple> ports, final String channelId) {
|
protected State getChannelState(final UniFiSwitchPorts ports, final String channelId) {
|
||||||
final UniFiPortTuple portTuple = getPort(ports);
|
final UniFiPortTuple portTuple = getPort(ports);
|
||||||
|
|
||||||
if (portTuple == null) {
|
if (portTuple == null) {
|
||||||
@ -143,30 +148,30 @@ public class UniFiPoePortThingHandler
|
|||||||
return UnDefType.NULL;
|
return UnDefType.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Nullable UniFiPortTuple getPort(final Map<Integer, UniFiPortTuple> ports) {
|
private @Nullable UniFiPortTuple getPort(final UniFiSwitchPorts ports) {
|
||||||
return ports.get(config.getPortNumber());
|
return ports.getPort(config.getPortNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean handleCommand(final UniFiController controller, final Map<Integer, UniFiPortTuple> ports,
|
protected boolean handleCommand(final UniFiController controller, final UniFiSwitchPorts ports,
|
||||||
final ChannelUID channelUID, final Command command) throws UniFiException {
|
final ChannelUID channelUID, final Command command) throws UniFiException {
|
||||||
final String channelID = channelUID.getIdWithoutGroup();
|
final String channelID = channelUID.getIdWithoutGroup();
|
||||||
|
|
||||||
switch (channelID) {
|
switch (channelID) {
|
||||||
case CHANNEL_PORT_POE_ENABLE:
|
case CHANNEL_PORT_POE_ENABLE:
|
||||||
if (command instanceof OnOffType) {
|
if (command instanceof OnOffType) {
|
||||||
return handleModeCommand(controller, ports, getPort(ports),
|
return handleModeCommand(controller, ports,
|
||||||
OnOffType.ON == command ? poeEnableMode : CHANNEL_ENABLE_PARAMETER_MODE_OFF);
|
OnOffType.ON == command ? poeEnableMode : CHANNEL_ENABLE_PARAMETER_MODE_OFF);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHANNEL_PORT_POE_MODE:
|
case CHANNEL_PORT_POE_MODE:
|
||||||
if (command instanceof StringType) {
|
if (command instanceof StringType) {
|
||||||
return handleModeCommand(controller, ports, getPort(ports), command.toFullString());
|
return handleModeCommand(controller, ports, command.toFullString());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHANNEL_PORT_POE_CMD:
|
case CHANNEL_PORT_POE_CMD:
|
||||||
if (command instanceof StringType) {
|
if (command instanceof StringType) {
|
||||||
return handleCmd(controller, getPort(ports), command.toFullString());
|
return handleCmd(controller, ports, command.toFullString());
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -174,39 +179,39 @@ public class UniFiPoePortThingHandler
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleModeCommand(final UniFiController controller, final Map<Integer, UniFiPortTuple> ports,
|
private boolean handleModeCommand(final UniFiController controller, final UniFiSwitchPorts ports,
|
||||||
final @Nullable UniFiPortTuple uniFiPortTuple, final String poeMode) throws UniFiException {
|
final String poeMode) throws UniFiException {
|
||||||
final UniFiDevice device = controller.getCache().getDevice(config.getMacAddress());
|
final @Nullable UniFiDevice device = controller.getCache().getDevice(config.getMacAddress());
|
||||||
|
|
||||||
if (device == null || uniFiPortTuple == null) {
|
if (canUpdate(device, ports) && device != null) {
|
||||||
logger.info("Could not change the PoE port state for thing '{}': device {} or portToUpdate {} null",
|
controller.poeMode(device, ports.updatedList(config.getPortNumber(), p -> p.setPoeMode(poeMode)));
|
||||||
getThing().getUID(), device, uniFiPortTuple);
|
|
||||||
} else {
|
|
||||||
final List<UnfiPortOverrideJsonElement> updatedList = ports.entrySet().stream()
|
|
||||||
.map(e -> e.getValue().getJsonElement()).filter(Objects::nonNull).collect(Collectors.toList());
|
|
||||||
|
|
||||||
updatedList.stream().filter(p -> p.getPortIdx() == uniFiPortTuple.getPortIdx()).findAny()
|
|
||||||
.ifPresent(p -> p.setPoeMode(poeMode));
|
|
||||||
controller.poeMode(device, updatedList);
|
|
||||||
// No refresh because UniFi device takes some time to update. Therefore a refresh would only show the
|
// No refresh because UniFi device takes some time to update. Therefore a refresh would only show the
|
||||||
// old state.
|
// old state.
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleCmd(final UniFiController controller, @Nullable final UniFiPortTuple portToUpdate,
|
private boolean handleCmd(final UniFiController controller, final UniFiSwitchPorts ports, final String command)
|
||||||
final String command) throws UniFiException {
|
throws UniFiException {
|
||||||
final UniFiDevice device = controller.getCache().getDevice(config.getMacAddress());
|
final @Nullable UniFiDevice device = controller.getCache().getDevice(config.getMacAddress());
|
||||||
if (device == null || portToUpdate == null) {
|
|
||||||
logger.info("Could not change the PoE port state for thing '{}': device {} or portToUpdate {} null",
|
if (canUpdate(device, ports) && device != null) {
|
||||||
getThing().getUID(), device, portToUpdate);
|
|
||||||
} else {
|
|
||||||
if (CHANNEL_PORT_POE_CMD_POWER_CYCLE.equalsIgnoreCase(command.replaceAll("[- ]", ""))) {
|
if (CHANNEL_PORT_POE_CMD_POWER_CYCLE.equalsIgnoreCase(command.replaceAll("[- ]", ""))) {
|
||||||
controller.poePowerCycle(device, portToUpdate.getPortIdx());
|
controller.poePowerCycle(device, config.getPortNumber());
|
||||||
} else {
|
} else {
|
||||||
logger.info("Unknown command '{}' given to PoE port for thing '{}': device {} or portToUpdate {} null",
|
logger.info("Unknown command '{}' given to PoE port for thing '{}': device {} or portToUpdate {} null",
|
||||||
command, getThing().getUID(), device, portToUpdate);
|
command, getThing().getUID(), device, ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canUpdate(final @Nullable UniFiDevice device, final UniFiSwitchPorts ports) {
|
||||||
|
if (device == null || getPort(ports) == null) {
|
||||||
|
logger.info("Could not change the PoE port state for thing '{}': device {} or portToUpdate {} null",
|
||||||
|
getThing().getUID(), device, config.getPortNumber());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import static org.openhab.binding.unifi.internal.UniFiBindingConstants.PARAMETER
|
|||||||
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.PARAMETER_WIFI_NAME;
|
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.PARAMETER_WIFI_NAME;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -34,6 +33,7 @@ import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
|
|||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiClient;
|
import org.openhab.binding.unifi.internal.api.dto.UniFiClient;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiPortTuple;
|
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.UniFiSite;
|
||||||
|
import org.openhab.binding.unifi.internal.api.dto.UniFiSwitchPorts;
|
||||||
import org.openhab.binding.unifi.internal.api.dto.UniFiWlan;
|
import org.openhab.binding.unifi.internal.api.dto.UniFiWlan;
|
||||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||||
@ -161,9 +161,8 @@ public class UniFiThingDiscoveryService extends AbstractDiscoveryService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void discoverPoePorts(final UniFiControllerCache cache, final ThingUID bridgeUID) {
|
private void discoverPoePorts(final UniFiControllerCache cache, final ThingUID bridgeUID) {
|
||||||
for (final Map<Integer, UniFiPortTuple> uc : cache.getSwitchPorts()) {
|
for (final UniFiSwitchPorts uc : cache.getSwitchPorts()) {
|
||||||
for (final Entry<Integer, UniFiPortTuple> sp : uc.entrySet()) {
|
for (final UniFiPortTuple pt : uc.getPoePorts()) {
|
||||||
final UniFiPortTuple pt = sp.getValue();
|
|
||||||
final String deviceMac = pt.getDevice().getMac();
|
final String deviceMac = pt.getDevice().getMac();
|
||||||
final String id = deviceMac.replace(":", "") + "_" + pt.getPortIdx();
|
final String id = deviceMac.replace(":", "") + "_" + pt.getPortIdx();
|
||||||
final ThingUID thingUID = new ThingUID(UniFiBindingConstants.THING_TYPE_POE_PORT, bridgeUID, id);
|
final ThingUID thingUID = new ThingUID(UniFiBindingConstants.THING_TYPE_POE_PORT, bridgeUID, id);
|
||||||
|
@ -127,7 +127,7 @@ channel-type.unifi.wpaMode.description = WPA Mode of the Wi-Fi network
|
|||||||
channel-type.config.unifi.poeEnable.mode.label = On Mode
|
channel-type.config.unifi.poeEnable.mode.label = On Mode
|
||||||
channel-type.config.unifi.poeEnable.mode.description = The value to set when setting PoE on.
|
channel-type.config.unifi.poeEnable.mode.description = The value to set when setting PoE on.
|
||||||
channel-type.config.unifi.poeEnable.mode.option.auto = Auto
|
channel-type.config.unifi.poeEnable.mode.option.auto = Auto
|
||||||
channel-type.config.unifi.poeEnable.mode.option.pasv24v = 24V
|
channel-type.config.unifi.poeEnable.mode.option.pasv24 = 24V
|
||||||
channel-type.config.unifi.poeEnable.mode.option.passthrough = Passthrough
|
channel-type.config.unifi.poeEnable.mode.option.passthrough = Passthrough
|
||||||
|
|
||||||
# status messages
|
# status messages
|
||||||
|
Loading…
Reference in New Issue
Block a user