- 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>
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
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.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.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.UniFiSwitchPorts;
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 com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
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
.registerTypeAdapter(UniFiWiredClient.class, clientInstanceCreator)
.registerTypeAdapter(UniFiWirelessClient.class, clientInstanceCreator).create();
this.poeGson = new GsonBuilder()
- .registerTypeAdapter(UnfiPortOverrideJsonElement.class, new UnfiPortOverrideJsonElementDeserializer())
+ .registerTypeAdapter(UnfiPortOverrideJsonObject.class, new UnfiPortOverrideJsonElementDeserializer())
.create();
}
public void logout() throws UniFiException {
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");
executeRequest(req);
}
return cache;
}
- public @Nullable Map<Integer, UniFiPortTuple> getSwitchPorts(@Nullable final String deviceId) {
+ public @Nullable UniFiSwitchPorts getSwitchPorts(@Nullable final String deviceId) {
return cache.getSwitchPorts(deviceId);
}
refresh();
}
- public boolean poeMode(final UniFiDevice device, final List<UnfiPortOverrideJsonElement> data)
- throws UniFiException {
+ public boolean poeMode(final UniFiDevice device, final List<JsonObject> 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())) {
+ if (data.isEmpty() || data.stream().anyMatch(p -> p.entrySet().isEmpty())) {
logger.info("Not overriding port for '{}', because port data contains empty json: {}", device.getName(),
poeGson.toJson(data));
return false;
throws UniFiException {
T result;
try {
- result = request.execute();
+ result = (T) request.execute();
csrfToken = request.getCsrfToken();
} catch (final UniFiExpiredSessionException e) {
if (fromLogin) {
throw new UniFiCommunicationException(e);
} else {
login();
- result = executeRequest(request);
+ result = (T) executeRequest(request);
}
} catch (final UniFiNotAuthorizedException e) {
logger.warn("Not Authorized! Please make sure your controller credentials have administrator rights");
- result = null;
+ result = (T) null;
}
return result;
}
}
public @Nullable T execute() throws UniFiException {
- T result = null;
+ T result = (T) null;
final String json = getContent();
// mgb: only try and unmarshall non-void result types
if (!Void.class.equals(resultType)) {
final JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
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;
logger.debug("Put #{} entries in {}: {}", values.length, getClass().getSimpleName(),
lazyFormatAsList(values));
for (final T value : values) {
- put(value.getId(), value);
+ if (value != null) {
+ put(value.getId(), value);
+ }
}
}
}
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 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.UniFiSwitchPorts;
import org.openhab.binding.unifi.internal.api.dto.UniFiWlan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final UniFiDeviceCache devicesCache = new UniFiDeviceCache();
private final UniFiClientCache clientsCache = 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() {
sitesCache.clear();
devicesCache.putAll(devices);
if (devices != null) {
Stream.of(devices).filter(Objects::nonNull).forEach(d -> {
- Stream.ofNullable(d.getPortTable()).flatMap(pt -> Stream.of(pt)).filter(UniFiPortTable::isPortPoe)
- .forEach(p -> {
- final Map<Integer, UniFiPortTuple> tupleTable = devicesToPortTables
- .computeIfAbsent(d.getMac(), tt -> new HashMap<>());
- final UniFiPortTuple tuple = tupleTable.computeIfAbsent(p.getPortIdx(),
- t -> new UniFiPortTuple());
-
- tuple.setDevice(d);
- tuple.setTable(p);
- });
+ Stream.ofNullable(d.getPortTable()).forEach(pt -> {
+ final UniFiSwitchPorts switchPorts = devicesToPortTables.computeIfAbsent(d.getMac(),
+ p -> new UniFiSwitchPorts());
+
+ Stream.of(pt).forEach(p -> {
+ @SuppressWarnings("null")
+ final UniFiPortTuple tuple = switchPorts.computeIfAbsent(p.getPortIdx());
+
+ tuple.setDevice(d);
+ tuple.setTable(p);
+ });
+ });
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) {
- Stream.of(po).filter(pof -> !pof.getAsJsonObject().entrySet().isEmpty())
- .map(UnfiPortOverrideJsonElement::new).forEach(p -> tupleTable
- .computeIfAbsent(p.getPortIdx(), t -> new UniFiPortTuple()).setJsonElement(p));
+ Stream.of(po).forEach(p -> tupleTable.setOverride(p));
}
});
});
return devicesCache.get(id);
}
- public Map<Integer, UniFiPortTuple> getSwitchPorts(@Nullable final String deviceId) {
- return deviceId == null ? Map.of() : devicesToPortTables.getOrDefault(deviceId, Map.of());
+ public UniFiSwitchPorts getSwitchPorts(@Nullable final String deviceId) {
+ return deviceId == null ? new UniFiSwitchPorts()
+ : devicesToPortTables.getOrDefault(deviceId, new UniFiSwitchPorts());
}
- public Collection<Map<Integer, UniFiPortTuple>> getSwitchPorts() {
+ public Collection<UniFiSwitchPorts> getSwitchPorts() {
return devicesToPortTables.values();
}
switch (prefix) {
case MAC:
return device.getMac();
+ default:
+ return null;
}
- return null;
}
}
+++ /dev/null
-/**
- * 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();
- }
-}
--- /dev/null
+/**
+ * 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.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 UnfiPortOverrideJsonObject {
+
+ 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 UnfiPortOverrideJsonObject(final JsonObject Object) {
+ this.jsonObject = Object.getAsJsonObject();
+ }
+
+ public JsonObject getJsonObject() {
+ return jsonObject;
+ }
+
+ public static boolean hasPortIdx(final JsonObject jsonObject) {
+ return jsonObject.has(PORT_IDX);
+ }
+
+ 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();
+ }
+}
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.JsonObject;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
private UniFiPortTable[] portTable;
- private JsonElement[] portOverrides;
+ private JsonObject[] portOverrides;
public UniFiDevice(final UniFiControllerCache cache) {
this.cache = cache;
return portTable;
}
- public JsonElement[] getPortOverrides() {
+ public JsonObject[] getPortOverrides() {
return portOverrides;
}
/**
* 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
*/
private UniFiPortTable table;
- private UnfiPortOverrideJsonElement jsonElement;
+ private UnfiPortOverrideJsonObject jsonElement;
public UniFiDevice getDevice() {
return device;
this.table = table;
}
- public UnfiPortOverrideJsonElement getJsonElement() {
+ public UnfiPortOverrideJsonObject getJsonElement() {
return jsonElement;
}
- public void setJsonElement(final UnfiPortOverrideJsonElement jsonElement) {
+ public void setJsonElement(final UnfiPortOverrideJsonObject jsonElement) {
this.jsonElement = jsonElement;
}
}
--- /dev/null
+/**
+ * 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);
+ }
+ }
+}
import java.lang.reflect.Type;
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.JsonSerializationContext;
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
*/
@NonNullByDefault
-public class UnfiPortOverrideJsonElementDeserializer implements JsonSerializer<UnfiPortOverrideJsonElement> {
+public class UnfiPortOverrideJsonElementDeserializer implements JsonSerializer<UnfiPortOverrideJsonObject> {
@Override
- public JsonElement serialize(final UnfiPortOverrideJsonElement src, final Type typeOfSrc,
+ public JsonElement serialize(final UnfiPortOverrideJsonObject src, final Type typeOfSrc,
final JsonSerializationContext context) {
return src.getJsonObject();
}
return;
}
// mgb: derive the config class from the generic type
+ @SuppressWarnings("null")
final Class<?> clazz = (Class<?>) (((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[1]);
final C config = (C) getConfigAs(clazz);
logger.debug("Handling command = {} for channel = {}", command, channelUID);
// mgb: only handle commands if we're ONLINE
if (getThing().getStatus() == ONLINE) {
- final E entity = getEntity();
+ final @Nullable E entity = getEntity();
final UniFiController controller = getController();
if (command == REFRESH) {
protected final void refresh() {
// mgb: only refresh if we're ONLINE
if (getThing().getStatus() == ONLINE) {
- final E entity = getEntity();
+ final @Nullable E entity = getEntity();
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 State state = Optional.ofNullable(entity).map(e -> getChannelState(e, channelId))
.orElseGet(() -> getDefaultState(channelId));
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.ThingStatusInfo;
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.builder.ThingStatusInfoBuilder;
import org.openhab.core.types.Command;
@Override
public void dispose() {
cancelRefreshJob();
+ final UniFiController controller = this.controller;
+
if (controller != null) {
try {
controller.stop();
} catch (final UniFiException e) {
// mgb: nop as we're in dispose
}
- controller = null;
+ this.controller = null;
}
}
uc.refresh();
// mgb: then refresh all the client things
getThing().getThings().forEach((thing) -> {
- if (thing.getHandler() instanceof UniFiBaseThingHandler) {
- ((UniFiBaseThingHandler) thing.getHandler()).refresh();
+ final ThingHandler handler = thing.getHandler();
+
+ if (handler instanceof UniFiBaseThingHandler) {
+ ((UniFiBaseThingHandler<?, ?>) handler).refresh();
}
});
}
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.CHANNEL_PORT_POE_VOLTAGE;
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.ElectricPotential;
import javax.measure.quantity.Power;
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.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.binding.unifi.internal.api.dto.UniFiSwitchPorts;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.library.unit.Units;
+import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
* @author Hilbrand Bouwkamp - Initial contribution
*/
@NonNullByDefault
-public class UniFiPoePortThingHandler
- extends UniFiBaseThingHandler<Map<Integer, UniFiPortTuple>, UniFiPoePortThingConfig> {
+public class UniFiPoePortThingHandler extends UniFiBaseThingHandler<UniFiSwitchPorts, UniFiPoePortThingConfig> {
private final Logger logger = LoggerFactory.getLogger(UniFiPoePortThingHandler.class);
"@text/error.thing.poe.offline.configuration_error");
return false;
}
- final String channelConfigPoeEnableMode = (String) getThing().getChannel(CHANNEL_PORT_POE_ENABLE)
- .getConfiguration().get(CHANNEL_ENABLE_PARAMETER_MODE);
- poeEnableMode = channelConfigPoeEnableMode.isBlank() ? CHANNEL_ENABLE_PARAMETER_MODE_AUTO
- : channelConfigPoeEnableMode;
- return true;
+ return initPoeEnableMode();
+ }
+
+ private boolean initPoeEnableMode() {
+ 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
- protected @Nullable Map<Integer, UniFiPortTuple> getEntity(final UniFiControllerCache cache) {
+ protected @Nullable UniFiSwitchPorts getEntity(final UniFiControllerCache cache) {
return cache.getSwitchPorts(config.getMacAddress());
}
@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);
if (portTuple == null) {
return UnDefType.NULL;
}
- private @Nullable UniFiPortTuple getPort(final Map<Integer, UniFiPortTuple> ports) {
- return ports.get(config.getPortNumber());
+ private @Nullable UniFiPortTuple getPort(final UniFiSwitchPorts ports) {
+ return ports.getPort(config.getPortNumber());
}
@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 String channelID = channelUID.getIdWithoutGroup();
switch (channelID) {
case CHANNEL_PORT_POE_ENABLE:
if (command instanceof OnOffType) {
- return handleModeCommand(controller, ports, getPort(ports),
+ return handleModeCommand(controller, ports,
OnOffType.ON == command ? poeEnableMode : CHANNEL_ENABLE_PARAMETER_MODE_OFF);
}
break;
case CHANNEL_PORT_POE_MODE:
if (command instanceof StringType) {
- return handleModeCommand(controller, ports, getPort(ports), command.toFullString());
+ return handleModeCommand(controller, ports, command.toFullString());
}
break;
case CHANNEL_PORT_POE_CMD:
if (command instanceof StringType) {
- return handleCmd(controller, getPort(ports), command.toFullString());
+ return handleCmd(controller, ports, command.toFullString());
}
default:
return false;
return false;
}
- 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 || uniFiPortTuple == null) {
- logger.info("Could not change the PoE port state for thing '{}': device {} or portToUpdate {} null",
- getThing().getUID(), device, uniFiPortTuple);
- } else {
- final List<UnfiPortOverrideJsonElement> updatedList = ports.entrySet().stream()
- .map(e -> e.getValue().getJsonElement()).filter(Objects::nonNull).collect(Collectors.toList());
+ private boolean handleModeCommand(final UniFiController controller, final UniFiSwitchPorts ports,
+ final String poeMode) throws UniFiException {
+ final @Nullable UniFiDevice device = controller.getCache().getDevice(config.getMacAddress());
- updatedList.stream().filter(p -> p.getPortIdx() == uniFiPortTuple.getPortIdx()).findAny()
- .ifPresent(p -> p.setPoeMode(poeMode));
- controller.poeMode(device, updatedList);
+ if (canUpdate(device, ports) && device != null) {
+ controller.poeMode(device, ports.updatedList(config.getPortNumber(), p -> p.setPoeMode(poeMode)));
// 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 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);
- } else {
+ private boolean handleCmd(final UniFiController controller, final UniFiSwitchPorts ports, final String command)
+ throws UniFiException {
+ final @Nullable UniFiDevice device = controller.getCache().getDevice(config.getMacAddress());
+
+ if (canUpdate(device, ports) && device != null) {
if (CHANNEL_PORT_POE_CMD_POWER_CYCLE.equalsIgnoreCase(command.replaceAll("[- ]", ""))) {
- controller.poePowerCycle(device, portToUpdate.getPortIdx());
+ controller.poePowerCycle(device, config.getPortNumber());
} else {
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;
}
import static org.openhab.binding.unifi.internal.UniFiBindingConstants.PARAMETER_WIFI_NAME;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
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.UniFiSite;
+import org.openhab.binding.unifi.internal.api.dto.UniFiSwitchPorts;
import org.openhab.binding.unifi.internal.api.dto.UniFiWlan;
import org.openhab.core.config.discovery.AbstractDiscoveryService;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
}
private void discoverPoePorts(final UniFiControllerCache cache, final ThingUID bridgeUID) {
- for (final Map<Integer, UniFiPortTuple> uc : cache.getSwitchPorts()) {
- for (final Entry<Integer, UniFiPortTuple> sp : uc.entrySet()) {
- final UniFiPortTuple pt = sp.getValue();
+ for (final UniFiSwitchPorts uc : cache.getSwitchPorts()) {
+ for (final UniFiPortTuple pt : uc.getPoePorts()) {
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);
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.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
# status messages