[unifi] Fix portoverride to not remove any other data (#13362)

When a user has configured additional settings on a PoE port, like name.
These settings where lost when changing the PoEPort status in openHAB.
This was because in the binding only some information of the override was stored and when writing the new state this information would have been sent too.
In this change the object to store the override has been replaced by a plain json object. Therefore we don't have to know what is in it and all information is kept.

Signed-off-by: Hilbrand Bouwkamp <hilbrand@h72.nl>
This commit is contained in:
Hilbrand Bouwkamp 2022-09-10 16:59:42 +02:00 committed by GitHub
parent 1f1de41bd3
commit 698703b0c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 265 additions and 177 deletions

View File

@ -21,15 +21,16 @@ import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.http.HttpMethod;
import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverride;
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.UniFiUnknownClient;
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.UniFiWlan;
import org.openhab.binding.unifi.internal.api.util.UnfiPortOverrideJsonElementDeserializer;
import org.openhab.binding.unifi.internal.api.util.UniFiClientDeserializer;
import org.openhab.binding.unifi.internal.api.util.UniFiClientInstanceCreator;
import org.openhab.binding.unifi.internal.api.util.UniFiDeviceInstanceCreator;
@ -92,8 +93,9 @@ public class UniFiController {
.registerTypeAdapter(UniFiUnknownClient.class, clientInstanceCreator)
.registerTypeAdapter(UniFiWiredClient.class, clientInstanceCreator)
.registerTypeAdapter(UniFiWirelessClient.class, clientInstanceCreator).create();
this.poeGson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.excludeFieldsWithoutExposeAnnotation().create();
this.poeGson = new GsonBuilder()
.registerTypeAdapter(UnfiPortOverrideJsonElement.class, new UnfiPortOverrideJsonElementDeserializer())
.create();
}
// Public API
@ -151,7 +153,7 @@ public class UniFiController {
return cache;
}
public @Nullable Map<Integer, UniFiPortTable> getSwitchPorts(@Nullable final String deviceId) {
public @Nullable Map<Integer, UniFiPortTuple> getSwitchPorts(@Nullable final String deviceId) {
return cache.getSwitchPorts(deviceId);
}
@ -173,12 +175,20 @@ public class UniFiController {
refresh();
}
public void poeMode(final UniFiDevice device, final Map<Integer, UnfiPortOverride> data) throws UniFiException {
public boolean poeMode(final UniFiDevice device, final List<UnfiPortOverrideJsonElement> data)
throws UniFiException {
// 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())) {
logger.info("Not overriding port for '{}', because port data contains empty json: {}", device.getName(),
poeGson.toJson(data));
return false;
} else {
final UniFiControllerRequest<Void> req = newRequest(Void.class, HttpMethod.PUT, poeGson);
req.setAPIPath(String.format("/api/s/%s/rest/device/%s", device.getSite().getName(), device.getId()));
req.setBodyParameter("port_overrides", data.values());
req.setBodyParameter("port_overrides", data);
executeRequest(req);
refresh();
return true;
}
}
public void poePowerCycle(final UniFiDevice device, final Integer portIdx) throws UniFiException {

View File

@ -230,6 +230,7 @@ class UniFiControllerRequest<T> {
if (!bodyParameters.isEmpty()) {
final String jsonBody = gson.toJson(bodyParameters);
logger.debug("Body parameters for request '{}': {}", request.getPath(), jsonBody);
request.content(
new StringContentProvider(CONTENT_TYPE_APPLICATION_JSON_UTF_8, jsonBody, StandardCharsets.UTF_8));
}

View File

@ -13,19 +13,20 @@
package org.openhab.binding.unifi.internal.api.cache;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault;
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;
import org.slf4j.Logger;
@ -47,7 +48,7 @@ public class UniFiControllerCache {
private final UniFiDeviceCache devicesCache = new UniFiDeviceCache();
private final UniFiClientCache clientsCache = new UniFiClientCache();
private final UniFiClientCache insightsCache = new UniFiClientCache();
private final Map<String, Map<Integer, UniFiPortTable>> devicesToPortTables = new ConcurrentHashMap<>();
private final Map<String, Map<Integer, UniFiPortTuple>> devicesToPortTables = new ConcurrentHashMap<>();
public void clear() {
sitesCache.clear();
@ -93,9 +94,25 @@ public class UniFiControllerCache {
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 -> {
Stream.of(pt).forEach(p -> p.setDevice(d));
devicesToPortTables.put(d.getMac(),
Stream.of(pt).collect(Collectors.toMap(UniFiPortTable::getPortIdx, Function.identity())));
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 -> {
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));
}
});
});
}
@ -105,11 +122,11 @@ public class UniFiControllerCache {
return devicesCache.get(id);
}
public Map<Integer, UniFiPortTable> getSwitchPorts(@Nullable final String deviceId) {
public Map<Integer, UniFiPortTuple> getSwitchPorts(@Nullable final String deviceId) {
return deviceId == null ? Map.of() : devicesToPortTables.getOrDefault(deviceId, Map.of());
}
public Collection<Map<Integer, UniFiPortTable>> getSwitchPorts() {
public Collection<Map<Integer, UniFiPortTuple>> getSwitchPorts() {
return devicesToPortTables.values();
}

View File

@ -1,72 +0,0 @@
/**
* 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 com.google.gson.annotations.Expose;
/**
* The {@link UnfiPortOverride} represents the data model of UniFi port override.
*
* @author Hilbrand Bouwkamp - Initial contribution
*/
public class UnfiPortOverride {
@Expose
private int portIdx;
@Expose
private String portconfId;
@Expose
private String poeMode;
public UnfiPortOverride() {
// Constructor for GSON.
}
public UnfiPortOverride(final int portIdx, final String portconfId, final String poeMode) {
this.portIdx = portIdx;
this.portconfId = portconfId;
this.poeMode = poeMode;
}
public int getPortIdx() {
return portIdx;
}
public String getPortconfId() {
return portconfId;
}
public String getPoeMode() {
return poeMode;
}
public void setPortIdx(final int portIdx) {
this.portIdx = portIdx;
}
public void setPortconfId(final String portconfId) {
this.portconfId = portconfId;
}
public void setPoeMode(final String poeMode) {
this.poeMode = poeMode;
}
@Override
public String toString() {
return String.format("UnfiPortOverride{portIx: '%d', portconfId: '%s', poeMode: '%s'}", portIdx, portconfId,
poeMode);
}
}

View File

@ -0,0 +1,61 @@
/**
* 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 com.google.gson.JsonElement;
import com.google.gson.JsonObject;
/**
* The {@link UnfiPortOverride} represents the data model of UniFi port override.
* Using plain JsonObject to make sure any data in the object is not lost when writing the data back to the UniFi
* device.
*
* @author Hilbrand Bouwkamp - Initial contribution
*/
public class UnfiPortOverrideJsonElement {
private static final String PORT_IDX = "port_idx";
private static final String PORT_CONF_ID = "port_conf_id";
private static final String POE_MODE = "poe_mode";
private final JsonObject jsonObject;
public UnfiPortOverrideJsonElement(final JsonElement element) {
this.jsonObject = element.getAsJsonObject();
}
public JsonObject getJsonObject() {
return jsonObject;
}
public int getPortIdx() {
return jsonObject.get(PORT_IDX).getAsInt();
}
public String getPortConfId() {
return jsonObject.get(PORT_CONF_ID).getAsString();
}
public String getPoeMode() {
return jsonObject.get(POE_MODE).getAsString();
}
public void setPoeMode(final String poeMode) {
jsonObject.addProperty(POE_MODE, poeMode);
}
@Override
public String toString() {
return jsonObject.toString();
}
}

View File

@ -15,6 +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.util.UniFiTidyLowerCaseStringDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
@ -43,6 +44,8 @@ public class UniFiDevice implements HasId {
private UniFiPortTable[] portTable;
private JsonElement[] portOverrides;
public UniFiDevice(final UniFiControllerCache cache) {
this.cache = cache;
}
@ -72,6 +75,10 @@ public class UniFiDevice implements HasId {
return portTable;
}
public JsonElement[] getPortOverrides() {
return portOverrides;
}
@Override
public String toString() {
return String.format("UniFiDevice{mac: '%s', name: '%s', model: '%s', site: %s}", mac, name, model, getSite());

View File

@ -1,42 +0,0 @@
/**
* 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.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
/**
* The {@link UniFiPortOverrides} represents the data model of UniFi port overrides.
*
* @author Hilbrand Bouwkamp - Initial contribution
*/
public class UniFiPortOverrides {
@Expose
private final List<UnfiPortOverride> portOverrides = new ArrayList<>();
public void addPortOverride(final UnfiPortOverride unfiPortOverride) {
portOverrides.add(unfiPortOverride);
}
public void addPortOverride(final int portIdx, final String portconfId, final String poeMode) {
portOverrides.add(new UnfiPortOverride(portIdx, portconfId, poeMode));
}
@Override
public String toString() {
return String.format("UniFiPortOverrides: {}", String.join(", ", portOverrides.toArray(new String[0])));
}
}

View File

@ -12,14 +12,23 @@
*/
package org.openhab.binding.unifi.internal.api.dto;
import com.google.gson.annotations.Expose;
/**
* The {@link UniFiPortTable} represents the data model of UniFi port table, which is an extend of port override.
*
* @author Hilbrand Bouwkamp - Initial contribution
*/
public class UniFiPortTable extends UnfiPortOverride {
public class UniFiPortTable {
private transient UniFiDevice device;
@Expose
private int portIdx;
@Expose
private String portconfId;
@Expose
private String poeMode;
private String name;
@ -40,12 +49,16 @@ public class UniFiPortTable extends UnfiPortOverride {
private String poeCurrent;
public UniFiDevice getDevice() {
return device;
public int getPortIdx() {
return portIdx;
}
public void setDevice(final UniFiDevice device) {
this.device = device;
public String getPortconfId() {
return portconfId;
}
public String getPoeMode() {
return poeMode;
}
public String getName() {
@ -83,7 +96,7 @@ public class UniFiPortTable extends UnfiPortOverride {
@Override
public String toString() {
return String.format(
"UniFiPortTable{name: '%s', enable: '%b', up: '%b', portPoe: '%b', poeEnable: '%b, poePower: '%s', poeVoltage: '%s', poeCurrent: '%s'}",
name, enable, up, portPoe, poeEnable, poePower, poeVoltage, poeCurrent);
"UniFiPortTable{portIx: '%d', portconfId: '%s', poeMode: '%s', name: '%s', enable: '%b', up: '%b', portPoe: '%b', poeEnable: '%b, poePower: '%s', poeVoltage: '%s', poeCurrent: '%s'}",
portIdx, portconfId, poeMode, name, enable, up, portPoe, poeEnable, poePower, poeVoltage, poeCurrent);
}
}

View File

@ -0,0 +1,56 @@
/**
* 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;
/**
* 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.
*
* @author Hilbrand Bouwkamp - Initial contribution
*/
public class UniFiPortTuple {
private UniFiDevice device;
private UniFiPortTable table;
private UnfiPortOverrideJsonElement jsonElement;
public UniFiDevice getDevice() {
return device;
}
public void setDevice(final UniFiDevice device) {
this.device = device;
}
public int getPortIdx() {
return table == null ? 0 : table.getPortIdx();
}
public UniFiPortTable getTable() {
return table;
}
public void setTable(final UniFiPortTable table) {
this.table = table;
}
public UnfiPortOverrideJsonElement getJsonElement() {
return jsonElement;
}
public void setJsonElement(final UnfiPortOverrideJsonElement jsonElement) {
this.jsonElement = jsonElement;
}
}

View File

@ -0,0 +1,37 @@
/**
* 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.util;
import java.lang.reflect.Type;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverrideJsonElement;
import com.google.gson.JsonElement;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
/**
* Serializer for {@link UnfiPortOverrideJsonElement}. Returns the content of the jsonObject in the class.
*
* @author Hilbrand Bouwkamp - Initial contribution
*/
@NonNullByDefault
public class UnfiPortOverrideJsonElementDeserializer implements JsonSerializer<UnfiPortOverrideJsonElement> {
@Override
public JsonElement serialize(final UnfiPortOverrideJsonElement src, final Type typeOfSrc,
final JsonSerializationContext context) {
return src.getJsonObject();
}
}

View File

@ -25,8 +25,10 @@ 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.core.library.unit.MetricPrefix.MILLI;
import java.util.HashMap;
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.ElectricPotential;
@ -38,9 +40,10 @@ import org.openhab.binding.unifi.internal.UniFiPoePortThingConfig;
import org.openhab.binding.unifi.internal.api.UniFiController;
import org.openhab.binding.unifi.internal.api.UniFiException;
import org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;
import org.openhab.binding.unifi.internal.api.dto.UnfiPortOverride;
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.UniFiPortTable;
import org.openhab.binding.unifi.internal.api.dto.UniFiPortTuple;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.StringType;
@ -62,7 +65,7 @@ import org.slf4j.LoggerFactory;
*/
@NonNullByDefault
public class UniFiPoePortThingHandler
extends UniFiBaseThingHandler<Map<Integer, UniFiPortTable>, UniFiPoePortThingConfig> {
extends UniFiBaseThingHandler<Map<Integer, UniFiPortTuple>, UniFiPoePortThingConfig> {
private final Logger logger = LoggerFactory.getLogger(UniFiPoePortThingHandler.class);
@ -89,13 +92,13 @@ public class UniFiPoePortThingHandler
}
@Override
protected @Nullable Map<Integer, UniFiPortTable> getEntity(final UniFiControllerCache cache) {
protected @Nullable Map<Integer, UniFiPortTuple> getEntity(final UniFiControllerCache cache) {
return cache.getSwitchPorts(config.getMacAddress());
}
@Override
protected State getChannelState(final Map<Integer, UniFiPortTable> ports, final String channelId) {
final UniFiPortTable port = getPort(ports);
protected State getChannelState(final Map<Integer, UniFiPortTuple> ports, final String channelId) {
final UniFiPortTable port = getPort(ports).getTable();
if (port == null) {
logger.debug("No PoE port for thing '{}' could be found in the data. Refresh ignored.",
@ -129,12 +132,12 @@ public class UniFiPoePortThingHandler
return state;
}
private @Nullable UniFiPortTable getPort(final Map<Integer, UniFiPortTable> ports) {
private @Nullable UniFiPortTuple getPort(final Map<Integer, UniFiPortTuple> ports) {
return ports.get(config.getPortNumber());
}
@Override
protected boolean handleCommand(final UniFiController controller, final Map<Integer, UniFiPortTable> ports,
protected boolean handleCommand(final UniFiController controller, final Map<Integer, UniFiPortTuple> ports,
final ChannelUID channelUID, final Command command) throws UniFiException {
final String channelID = channelUID.getIdWithoutGroup();
@ -160,44 +163,40 @@ public class UniFiPoePortThingHandler
return false;
}
private boolean handleModeCommand(final UniFiController controller, final Map<Integer, UniFiPortTable> ports,
final @Nullable UniFiPortTable portToUpdate, final String poeMode) throws UniFiException {
private boolean handleModeCommand(final UniFiController controller, final Map<Integer, UniFiPortTuple> ports,
final @Nullable UniFiPortTuple uniFiPortTuple, final String poeMode) throws UniFiException {
final UniFiDevice device = controller.getCache().getDevice(config.getMacAddress());
if (device == null || portToUpdate == null) {
if (device == null || uniFiPortTuple == null) {
logger.info("Could not change the PoE port state for thing '{}': device {} or portToUpdate {} null",
getThing().getUID(), device, portToUpdate);
return false;
getThing().getUID(), device, uniFiPortTuple);
} else {
final UnfiPortOverride override = new UnfiPortOverride();
override.setPortIdx(portToUpdate.getPortIdx());
override.setPortconfId(portToUpdate.getPortconfId());
override.setPoeMode(poeMode);
final Map<Integer, UnfiPortOverride> newMap = new HashMap<>(ports);
final List<UnfiPortOverrideJsonElement> updatedList = ports.entrySet().stream()
.map(e -> e.getValue().getJsonElement()).filter(Objects::nonNull).collect(Collectors.toList());
newMap.put(portToUpdate.getPortIdx(), override);
controller.poeMode(device, newMap);
refresh();
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
// old state.
}
return true;
}
}
private boolean handleCmd(final UniFiController controller, @Nullable final UniFiPortTable portToUpdate,
private boolean handleCmd(final UniFiController controller, @Nullable final UniFiPortTuple portToUpdate,
final String command) throws UniFiException {
final 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",
getThing().getUID(), device, portToUpdate);
return false;
} else {
if (CHANNEL_PORT_POE_CMD_POWER_CYCLE.equalsIgnoreCase(command.replaceAll("[- ]", ""))) {
controller.poePowerCycle(device, portToUpdate.getPortIdx());
return true;
} else {
logger.info("Unknown command '{}' given to PoE port for thing '{}': device {} or portToUpdate {} null",
command, getThing().getUID(), device, portToUpdate);
return false;
}
}
return true;
}
}

View File

@ -23,6 +23,7 @@ import static org.openhab.binding.unifi.internal.UniFiBindingConstants.PARAMETER
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
@ -31,7 +32,7 @@ import org.openhab.binding.unifi.internal.api.UniFiController;
import org.openhab.binding.unifi.internal.api.UniFiException;
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.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;
import org.openhab.core.config.discovery.AbstractDiscoveryService;
@ -58,7 +59,7 @@ public class UniFiThingDiscoveryService extends AbstractDiscoveryService
private static final int UNIFI_DISCOVERY_TIMEOUT_SECONDS = 30;
private static final long TTL_SECONDS = TimeUnit.MINUTES.toSeconds(5);
private static final int THING_ID_LENGTH = 8;
private static final String DEFAULT_PORTNAME = "Port";
private static final Pattern DEFAULT_PORTNAME = Pattern.compile("Port \\d+");
private final Logger logger = LoggerFactory.getLogger(UniFiThingDiscoveryService.class);
@ -160,9 +161,9 @@ public class UniFiThingDiscoveryService extends AbstractDiscoveryService
}
private void discoverPoePorts(final UniFiControllerCache cache, final ThingUID bridgeUID) {
for (final Map<Integer, UniFiPortTable> uc : cache.getSwitchPorts()) {
for (final Entry<Integer, UniFiPortTable> sp : uc.entrySet()) {
final UniFiPortTable pt = sp.getValue();
for (final Map<Integer, UniFiPortTuple> uc : cache.getSwitchPorts()) {
for (final Entry<Integer, UniFiPortTuple> sp : uc.entrySet()) {
final UniFiPortTuple pt = sp.getValue();
final String deviceMac = pt.getDevice().getMac();
final String id = deviceMac.replace(":", "") + "_" + pt.getPortIdx();
final ThingUID thingUID = new ThingUID(UniFiBindingConstants.THING_TYPE_POE_PORT, bridgeUID, id);
@ -182,9 +183,9 @@ public class UniFiThingDiscoveryService extends AbstractDiscoveryService
* @param pt port object
* @return label for the discovered PoE port
*/
private static @Nullable String portName(final UniFiPortTable pt) {
final String portName = pt.getName();
private @Nullable String portName(final UniFiPortTuple pt) {
final String portName = pt.getTable().getName();
return portName.startsWith(DEFAULT_PORTNAME) ? pt.getDevice().getName() + " " + portName : portName;
return DEFAULT_PORTNAME.matcher(portName).find() ? pt.getDevice().getName() + " " + portName : portName;
}
}

View File

@ -69,6 +69,8 @@ channel-type.unifi.macAddress.label = MAC Address
channel-type.unifi.macAddress.description = MAC address of the client
channel-type.unifi.online.label = Online
channel-type.unifi.online.description = Online status of the client
channel-type.unifi.passphrase.label = Passphrase
channel-type.unifi.passphrase.description = Passphrase of the Wi-Fi network
channel-type.unifi.poeCmd.label = PoE Command
channel-type.unifi.poeCmd.description = Command that can be given to the PoE port
channel-type.unifi.poeCmd.command.option.power-cycle = Power Cycle
@ -119,8 +121,6 @@ channel-type.unifi.wpaEnc.label = WPA Encoding
channel-type.unifi.wpaEnc.description = WPA Encoding of the Wi-Fi network
channel-type.unifi.wpaMode.label = WPA Mode
channel-type.unifi.wpaMode.description = WPA Mode of the Wi-Fi network
channel-type.unifi.passphrase.label = Passphrase
channel-type.unifi.passphrase.description = Passphrase of the Wi-Fi network
# channel types config