[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:
parent
1f1de41bd3
commit
698703b0c6
@ -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 {
|
||||
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());
|
||||
executeRequest(req);
|
||||
refresh();
|
||||
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);
|
||||
executeRequest(req);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void poePowerCycle(final UniFiDevice device, final Integer portIdx) throws UniFiException {
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
|
||||
@ -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])));
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user