Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[unifi] Add network thing #18335

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,18 @@ public final class UniFiBindingConstants {
// List of all Thing Types
public static final ThingTypeUID THING_TYPE_CONTROLLER = new ThingTypeUID(BINDING_ID, "controller");
public static final ThingTypeUID THING_TYPE_SITE = new ThingTypeUID(BINDING_ID, "site");
public static final ThingTypeUID THING_TYPE_NETWORK = new ThingTypeUID(BINDING_ID, "network");
public static final ThingTypeUID THING_TYPE_WLAN = new ThingTypeUID(BINDING_ID, "wlan");
public static final ThingTypeUID THING_TYPE_WIRED_CLIENT = new ThingTypeUID(BINDING_ID, "wiredClient");
public static final ThingTypeUID THING_TYPE_WIRELESS_CLIENT = new ThingTypeUID(BINDING_ID, "wirelessClient");
public static final ThingTypeUID THING_TYPE_POE_PORT = new ThingTypeUID(BINDING_ID, "poePort");
public static final ThingTypeUID THING_TYPE_ACCESS_POINT = new ThingTypeUID(BINDING_ID, "accessPoint");
public static final Set<ThingTypeUID> ALL_THING_TYPE_SUPPORTED = Set.of(THING_TYPE_CONTROLLER, THING_TYPE_SITE,
THING_TYPE_NETWORK, THING_TYPE_WLAN, THING_TYPE_WIRED_CLIENT, THING_TYPE_WIRELESS_CLIENT,
THING_TYPE_POE_PORT, THING_TYPE_ACCESS_POINT);
public static final Set<ThingTypeUID> THING_TYPE_SUPPORTED = Set.of(THING_TYPE_SITE, THING_TYPE_NETWORK,
THING_TYPE_WLAN, THING_TYPE_WIRED_CLIENT, THING_TYPE_WIRELESS_CLIENT, THING_TYPE_POE_PORT,
THING_TYPE_ACCESS_POINT);
public static final Set<ThingTypeUID> THING_TYPE_SUPPORTED = Set.of(THING_TYPE_SITE, THING_TYPE_WLAN,
THING_TYPE_WIRED_CLIENT, THING_TYPE_WIRELESS_CLIENT, THING_TYPE_POE_PORT, THING_TYPE_ACCESS_POINT);

// List of site channels
public static final String CHANNEL_TOTAL_CLIENTS = "totalClients";
Expand All @@ -53,6 +55,9 @@ public final class UniFiBindingConstants {
public static final String CHANNEL_GUEST_VOUCHER = "guestVoucher";
public static final String CHANNEL_GUEST_VOUCHERS_GENERATE = "guestVouchersGenerate";

// List of network channels
public static final String CHANNEL_PURPOSE = "purpose";

// List of wlan channels
public static final String CHANNEL_SECURITY = "security";
public static final String CHANNEL_WLANBAND = "wlanBand";
Expand Down Expand Up @@ -112,6 +117,7 @@ public final class UniFiBindingConstants {
public static final String PARAMETER_CID = "cid";
public static final String PARAMETER_SID = "sid";
public static final String PARAMETER_WID = "wid";
public static final String PARAMETER_NID = "nid";
public static final String PARAMETER_VOUCHER_COUNT = "voucherCount";
public static final String PARAMETER_VOUCHER_EXPIRATION = "voucherExpiration";
public static final String PARAMETER_VOUCHER_USERS = "voucherUsers";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2010-2025 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;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.unifi.internal.handler.UniFiNetworkThingHandler;

/**
* The {@link UniFiNetworkThingConfig} encapsulates all the configuration options for an instance of the
* {@link UniFiNetworkThingHandler}.
*
* @author Thomas Lauterbach - Initial contribution
*/
@NonNullByDefault
@SuppressWarnings("unused")
public class UniFiNetworkThingConfig {

private String nid = "";

public String getNetworkId() {
return nid;
}

private void setNetworkId(final String nid) {
// method to avoid auto format mark the field as final
this.nid = nid;
}

public boolean isValid() {
return !nid.isBlank();
}

@Override
public String toString() {
return String.format("UniFiNetworkThingConfig{nid: '%s'}", nid);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.openhab.binding.unifi.internal.handler.UniFiAccessPointThingHandler;
import org.openhab.binding.unifi.internal.handler.UniFiClientThingHandler;
import org.openhab.binding.unifi.internal.handler.UniFiControllerThingHandler;
import org.openhab.binding.unifi.internal.handler.UniFiNetworkThingHandler;
import org.openhab.binding.unifi.internal.handler.UniFiPoePortThingHandler;
import org.openhab.binding.unifi.internal.handler.UniFiSiteThingHandler;
import org.openhab.binding.unifi.internal.handler.UniFiWlanThingHandler;
Expand Down Expand Up @@ -82,6 +83,8 @@ public boolean supportsThingType(final ThingTypeUID thingTypeUID) {
return new UniFiControllerThingHandler((Bridge) thing, httpClient);
} else if (THING_TYPE_SITE.equals(thingTypeUID)) {
return new UniFiSiteThingHandler(thing);
} else if (THING_TYPE_NETWORK.equals(thingTypeUID)) {
return new UniFiNetworkThingHandler(thing);
} else if (THING_TYPE_WLAN.equals(thingTypeUID)) {
return new UniFiWlanThingHandler(thing);
} else if (THING_TYPE_WIRELESS_CLIENT.equals(thingTypeUID) || THING_TYPE_WIRED_CLIENT.equals(thingTypeUID)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
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.UniFiNetwork;
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;
Expand All @@ -34,6 +35,7 @@
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;
import org.openhab.binding.unifi.internal.api.util.UniFiNetworkInstanceCreator;
import org.openhab.binding.unifi.internal.api.util.UniFiSiteInstanceCreator;
import org.openhab.binding.unifi.internal.api.util.UniFiVoucherInstanceCreator;
import org.openhab.binding.unifi.internal.api.util.UniFiWlanInstanceCreator;
Expand Down Expand Up @@ -85,12 +87,14 @@ public UniFiController(final HttpClient httpClient, final String host, final int
this.unifios = unifios;
this.csrfToken = "";
final UniFiSiteInstanceCreator siteInstanceCreator = new UniFiSiteInstanceCreator(cache);
final UniFiNetworkInstanceCreator networkInstanceCreator = new UniFiNetworkInstanceCreator(cache);
final UniFiWlanInstanceCreator wlanInstanceCreator = new UniFiWlanInstanceCreator(cache);
final UniFiDeviceInstanceCreator deviceInstanceCreator = new UniFiDeviceInstanceCreator(cache);
final UniFiClientInstanceCreator clientInstanceCreator = new UniFiClientInstanceCreator(cache);
final UniFiVoucherInstanceCreator voucherInstanceCreator = new UniFiVoucherInstanceCreator(cache);
this.gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.registerTypeAdapter(UniFiSite.class, siteInstanceCreator)
.registerTypeAdapter(UniFiNetwork.class, networkInstanceCreator)
.registerTypeAdapter(UniFiWlan.class, wlanInstanceCreator)
.registerTypeAdapter(UniFiDevice.class, deviceInstanceCreator)
.registerTypeAdapter(UniFiClient.class, new UniFiClientDeserializer())
Expand Down Expand Up @@ -147,6 +151,7 @@ public void refresh() throws UniFiException {
synchronized (this) {
cache.clear();
final Collection<UniFiSite> sites = refreshSites();
refreshNetworks(sites);
refreshWlans(sites);
refreshDevices(sites);
refreshClients(sites);
Expand Down Expand Up @@ -206,8 +211,17 @@ public void poePowerCycle(final UniFiDevice device, final Integer portIdx) throw
refresh();
}

public void enableNetwork(final UniFiNetwork network, final boolean enable) throws UniFiException {
final UniFiControllerRequest<Void> req = newRequest(Void.class, HttpMethod.PUT, gson);
req.setAPIPath(String.format("/api/s/%s/rest/networkconf/%s", network.getSite().getName(), network.getId()));
req.setBodyParameter("_id", network.getId());
req.setBodyParameter("enabled", enable ? "true" : "false");
executeRequest(req);
refresh();
}

public void enableWifi(final UniFiWlan wlan, final boolean enable) throws UniFiException {
final UniFiControllerRequest<Void> req = newRequest(Void.class, HttpMethod.PUT, poeGson);
final UniFiControllerRequest<Void> req = newRequest(Void.class, HttpMethod.PUT, gson);
req.setAPIPath(String.format("/api/s/%s/rest/wlanconf/%s", wlan.getSite().getName(), wlan.getId()));
req.setBodyParameter("_id", wlan.getId());
req.setBodyParameter("enabled", enable ? "true" : "false");
Expand Down Expand Up @@ -306,6 +320,18 @@ private List<UniFiSite> refreshSites() throws UniFiException {
return cache.setSites(executeRequest(req));
}

private void refreshNetworks(final Collection<UniFiSite> sites) throws UniFiException {
for (final UniFiSite site : sites) {
cache.putNetworks(getNetworks(site));
}
}

private UniFiNetwork @Nullable [] getNetworks(final UniFiSite site) throws UniFiException {
final UniFiControllerRequest<UniFiNetwork[]> req = newRequest(UniFiNetwork[].class, HttpMethod.GET, gson);
req.setAPIPath(String.format("/api/s/%s/rest/networkconf", site.getName()));
return executeRequest(req);
}

private void refreshWlans(final Collection<UniFiSite> sites) throws UniFiException {
for (final UniFiSite site : sites) {
cache.putWlans(getWlans(site));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.jdt.annotation.Nullable;
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.UniFiNetwork;
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;
Expand All @@ -46,6 +47,7 @@ public class UniFiControllerCache {
private final Logger logger = LoggerFactory.getLogger(UniFiControllerCache.class);

private final UniFiSiteCache sitesCache = new UniFiSiteCache();
private final UniFiNetworkCache networksCache = new UniFiNetworkCache();
private final UniFiWlanCache wlansCache = new UniFiWlanCache();
private final UniFiDeviceCache devicesCache = new UniFiDeviceCache();
private final UniFiClientCache clientsCache = new UniFiClientCache();
Expand All @@ -55,6 +57,7 @@ public class UniFiControllerCache {

public void clear() {
sitesCache.clear();
networksCache.clear();
wlansCache.clear();
devicesCache.clear();
clientsCache.clear();
Expand All @@ -77,6 +80,20 @@ public Collection<UniFiSite> getSites() {
return sitesCache.values();
}

// Networks Cache

public void putNetworks(final UniFiNetwork @Nullable [] networks) {
networksCache.putAll(networks);
}

public @Nullable UniFiNetwork getNetwork(@Nullable final String id) {
return networksCache.get(id);
}

public Collection<UniFiNetwork> getNetworks() {
return networksCache.values();
}

// Wlans Cache

public void putWlans(final UniFiWlan @Nullable [] wlans) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2010-2025 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.cache;

import static org.openhab.binding.unifi.internal.api.cache.UniFiCache.Prefix.ID;
import static org.openhab.binding.unifi.internal.api.cache.UniFiCache.Prefix.NAME;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.unifi.internal.api.dto.UniFiNetwork;

/**
* The {@link UniFiWlanCache} is a specific implementation of {@link UniFiCache} for the purpose of caching
* {@link UniFiWlan} instances.
*
* The cache uses the following prefixes: <code>id</code>, <code>name</code>
*
* @author Thomas Lauterbach - Initial contribution
*/
@NonNullByDefault
class UniFiNetworkCache extends UniFiCache<UniFiNetwork> {

public UniFiNetworkCache() {
super(ID, NAME);
}

@Override
protected @Nullable String getSuffix(final UniFiNetwork network, final Prefix prefix) {
switch (prefix) {
case ID:
return network.getId();
case NAME:
return network.getName();
default:
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public abstract class UniFiClient implements HasId {
@SerializedName("satisfaction")
private Integer experience;

private String networkId;

protected UniFiClient(final UniFiControllerCache cache) {
this.cache = cache;
}
Expand Down Expand Up @@ -122,6 +124,10 @@ public Integer getExperience() {
return experience;
}

public UniFiNetwork getNetwork() {
return cache.getNetwork(networkId);
}

@Override
public String toString() {
return String.format(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2010-2025 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 org.openhab.binding.unifi.internal.api.cache.UniFiControllerCache;

import com.google.gson.annotations.SerializedName;

/**
* @author Thomas Lauterbach - Initial contribution
*/
public class UniFiNetwork implements HasId {

protected final transient UniFiControllerCache cache;

@SerializedName("_id")
private String id;

private String name;

private String siteId;

private boolean enabled;

private String purpose;

public UniFiNetwork(final UniFiControllerCache cache) {
this.cache = cache;
}

@Override
public String getId() {
return id;
}

public String getName() {
return name;
}

public UniFiSite getSite() {
return cache.getSite(siteId);
}

public boolean isEnabled() {
return enabled;
}

public String getPurpose() {
return purpose;
}

@Override
public String toString() {
return String.format("UniFiNetwork{id: '%s', name: '%s'}", id, name);
}
}
Loading